@iaforged/context-code 1.1.5 → 1.1.9
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 +32 -0
- package/dist/src/commands/agent/agent.js +62 -0
- package/dist/src/commands/agent/index.js +1 -1
- package/dist/src/commands/orchestrate/index.js +2 -2
- package/dist/src/commands/orchestrate/orchestrate.js +12 -627
- package/dist/src/commands/tasks/index.js +1 -1
- package/dist/src/commands/tasks/tasks.js +8 -3
- package/dist/src/commands/team/index.js +2 -2
- package/dist/src/commands/team/team.js +12 -589
- package/dist/src/commands/workspace/workspace.js +3 -3
- package/dist/src/commands.js +0 -6
- package/dist/src/components/PromptInput/Notifications.js +1 -1
- package/dist/src/components/PromptInput/PromptInput.js +7 -3
- package/dist/src/hooks/useVoice.js +6 -1
- package/dist/src/services/api/errors.js +1 -1
- package/dist/src/services/api/openai.js +70 -22
- package/dist/src/services/api/withRetry.js +3 -2
- package/dist/src/services/localDictation.js +146 -3
- package/dist/src/tools/AgentTool/loadAgentsDir.js +9 -4
- package/dist/src/tools/AgentTool/providerAgents.js +71 -0
- package/dist/src/utils/model/model.js +2 -0
- package/docs/comandos.md +16 -4
- package/package.json +1 -1
|
@@ -1,590 +1,13 @@
|
|
|
1
|
-
import { jsx as _jsx
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
switch (rawProvider.trim().toLowerCase()) {
|
|
14
|
-
case 'z.ai':
|
|
15
|
-
case 'z-ai':
|
|
16
|
-
return 'zai';
|
|
17
|
-
case 'open-router':
|
|
18
|
-
return 'openrouter';
|
|
19
|
-
case 'ollama-cloud':
|
|
20
|
-
case 'ollama_cloud':
|
|
21
|
-
case 'ollamacloud':
|
|
22
|
-
return 'ollama-cloud';
|
|
23
|
-
case 'gemini':
|
|
24
|
-
case 'gemini-api-key':
|
|
25
|
-
case 'google-ai':
|
|
26
|
-
return 'gemini-api';
|
|
27
|
-
case 'gemini-google':
|
|
28
|
-
case 'google':
|
|
29
|
-
case 'google-oauth':
|
|
30
|
-
return 'gemini-google';
|
|
31
|
-
default:
|
|
32
|
-
return rawProvider.trim().toLowerCase();
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
function formatProviderRef(ref) {
|
|
36
|
-
if (!ref) {
|
|
37
|
-
return 'sin asignar';
|
|
38
|
-
}
|
|
39
|
-
return `${ref.provider}/${ref.agent}`;
|
|
40
|
-
}
|
|
41
|
-
function parseProviderRef(rawRef) {
|
|
42
|
-
if (!rawRef) {
|
|
43
|
-
return null;
|
|
44
|
-
}
|
|
45
|
-
const slashIndex = rawRef.indexOf('/');
|
|
46
|
-
if (slashIndex <= 0 || slashIndex >= rawRef.length - 1) {
|
|
47
|
-
return null;
|
|
48
|
-
}
|
|
49
|
-
const provider = normalizeProviderInput(rawRef.slice(0, slashIndex));
|
|
50
|
-
const agent = rawRef.slice(slashIndex + 1).trim();
|
|
51
|
-
if (!provider || !isProfiledProvider(provider) || !agent) {
|
|
52
|
-
return null;
|
|
53
|
-
}
|
|
54
|
-
return { provider, agent };
|
|
55
|
-
}
|
|
56
|
-
function parseArgs(args) {
|
|
57
|
-
if (!args?.trim()) {
|
|
58
|
-
return null;
|
|
59
|
-
}
|
|
60
|
-
const tokens = args.trim().split(/\s+/).filter(Boolean);
|
|
61
|
-
const [command, ...rest] = tokens;
|
|
62
|
-
if (!command) {
|
|
63
|
-
return null;
|
|
64
|
-
}
|
|
65
|
-
return { command: command.toLowerCase(), rest };
|
|
66
|
-
}
|
|
67
|
-
async function ensureWorkspaceId(provider) {
|
|
68
|
-
const workspace = (await getProviderWorkspaceByProvider(provider)) ??
|
|
69
|
-
(await upsertProviderWorkspace({ provider }));
|
|
70
|
-
return workspace.id;
|
|
71
|
-
}
|
|
72
|
-
async function resolveAgentRef(ref, options) {
|
|
73
|
-
const provider = ref.provider;
|
|
74
|
-
let agent = await getAgent(provider, ref.agent);
|
|
75
|
-
let wasCreated = false;
|
|
76
|
-
if (!agent && options?.createIfMissing) {
|
|
77
|
-
agent = await createAgent({
|
|
78
|
-
provider,
|
|
79
|
-
name: ref.agent,
|
|
80
|
-
});
|
|
81
|
-
wasCreated = true;
|
|
82
|
-
if (options.roleHint?.trim()) {
|
|
83
|
-
agent =
|
|
84
|
-
(await setAgentRoleByName(provider, ref.agent, options.roleHint.trim())) ??
|
|
85
|
-
agent;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
if (!agent) {
|
|
89
|
-
throw new Error(`No existe el agente ${ref.provider}/${ref.agent}. Crea el agente primero con /agent create.`);
|
|
90
|
-
}
|
|
91
|
-
const workspaceId = await ensureWorkspaceId(ref.provider);
|
|
92
|
-
return { agent, workspaceId, wasCreated };
|
|
93
|
-
}
|
|
94
|
-
function getTeamAutonomyProfile(unitName) {
|
|
95
|
-
const unit = unitName.trim().toLowerCase();
|
|
96
|
-
const common = [
|
|
97
|
-
{ name: 'planning', weight: 0.8 },
|
|
98
|
-
{ name: 'self-assign-roles', weight: 1 },
|
|
99
|
-
{ name: 'risk-reporting', weight: 0.8 },
|
|
100
|
-
{ name: 'squad-reporting', weight: 1 },
|
|
101
|
-
];
|
|
102
|
-
const byDomain = {
|
|
103
|
-
backend: [
|
|
104
|
-
{ name: 'api-design', weight: 1 },
|
|
105
|
-
{ name: 'database-design', weight: 0.9 },
|
|
106
|
-
{ name: 'server-implementation', weight: 1 },
|
|
107
|
-
{ name: 'backend-testing', weight: 0.8 },
|
|
108
|
-
],
|
|
109
|
-
frontend: [
|
|
110
|
-
{ name: 'ui-architecture', weight: 1 },
|
|
111
|
-
{ name: 'component-design', weight: 1 },
|
|
112
|
-
{ name: 'state-management', weight: 0.8 },
|
|
113
|
-
{ name: 'frontend-testing', weight: 0.8 },
|
|
114
|
-
],
|
|
115
|
-
docs: [
|
|
116
|
-
{ name: 'technical-writing', weight: 1 },
|
|
117
|
-
{ name: 'readme-maintenance', weight: 1 },
|
|
118
|
-
{ name: 'developer-guides', weight: 0.9 },
|
|
119
|
-
],
|
|
120
|
-
planning: [
|
|
121
|
-
{ name: 'requirements-analysis', weight: 1 },
|
|
122
|
-
{ name: 'task-breakdown', weight: 1 },
|
|
123
|
-
{ name: 'cross-team-coordination', weight: 1 },
|
|
124
|
-
],
|
|
125
|
-
tests: [
|
|
126
|
-
{ name: 'test-strategy', weight: 1 },
|
|
127
|
-
{ name: 'regression-testing', weight: 1 },
|
|
128
|
-
{ name: 'quality-gates', weight: 0.9 },
|
|
129
|
-
],
|
|
130
|
-
review: [
|
|
131
|
-
{ name: 'code-review', weight: 1 },
|
|
132
|
-
{ name: 'architecture-review', weight: 0.9 },
|
|
133
|
-
{ name: 'risk-review', weight: 0.9 },
|
|
134
|
-
],
|
|
135
|
-
database: [
|
|
136
|
-
{ name: 'schema-design', weight: 1 },
|
|
137
|
-
{ name: 'migration-planning', weight: 1 },
|
|
138
|
-
{ name: 'query-performance', weight: 0.8 },
|
|
139
|
-
],
|
|
140
|
-
devops: [
|
|
141
|
-
{ name: 'build-pipeline', weight: 1 },
|
|
142
|
-
{ name: 'deployment', weight: 0.9 },
|
|
143
|
-
{ name: 'observability', weight: 0.8 },
|
|
144
|
-
],
|
|
145
|
-
};
|
|
146
|
-
const capabilities = [...common, ...(byDomain[unit] ?? [{ name: unit, weight: 1 }])];
|
|
147
|
-
return {
|
|
148
|
-
role: unit,
|
|
149
|
-
capabilities,
|
|
150
|
-
systemPrompt: [
|
|
151
|
-
`Eres el orquestador autonomo del equipo ${unit}.`,
|
|
152
|
-
'Tu responsabilidad es tomar el objetivo recibido, dividirlo en roles internos temporales y reportar avances claros al orquestador global.',
|
|
153
|
-
'Si no hay miembros extra en el escuadron, asume internamente los roles necesarios para este equipo y explica que roles asumiste.',
|
|
154
|
-
'Reporta: trabajo realizado, decisiones, riesgos, bloqueos, porcentaje estimado y siguientes pasos.',
|
|
155
|
-
].join('\n'),
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
async function applyTeamAutonomyToAgent(agent, unitName) {
|
|
159
|
-
const profile = getTeamAutonomyProfile(unitName);
|
|
160
|
-
const updated = await updateProviderAgent(agent.id, {
|
|
161
|
-
roleKind: profile.role,
|
|
162
|
-
isOrchestrator: true,
|
|
163
|
-
autonomyLevel: 'team-autonomous',
|
|
164
|
-
systemPrompt: agent.systemPrompt?.trim() ? agent.systemPrompt : profile.systemPrompt,
|
|
165
|
-
});
|
|
166
|
-
for (const capability of profile.capabilities) {
|
|
167
|
-
await upsertProviderAgentCapability({
|
|
168
|
-
agentId: updated.id,
|
|
169
|
-
capability: capability.name,
|
|
170
|
-
weight: capability.weight,
|
|
171
|
-
});
|
|
172
|
-
}
|
|
173
|
-
return updated;
|
|
174
|
-
}
|
|
175
|
-
async function findUnitByName(teamId, unitName) {
|
|
176
|
-
const units = await listTeamUnits(teamId);
|
|
177
|
-
return (units.find(unit => unit.unitName.toLowerCase() === unitName.toLowerCase()) ?? null);
|
|
178
|
-
}
|
|
179
|
-
function buildTeamListMessage(teams) {
|
|
180
|
-
if (teams.length === 0) {
|
|
181
|
-
return 'No hay teams guardados.';
|
|
182
|
-
}
|
|
183
|
-
return teams
|
|
184
|
-
.map(team => `- ${team.name} -> orchestrator=${team.globalOrchestratorAgentId ?? 'sin asignar'} | enabled=${team.isEnabled ? 'true' : 'false'}`)
|
|
185
|
-
.join('\n');
|
|
186
|
-
}
|
|
187
|
-
async function resolveTeamAgent(agentId) {
|
|
188
|
-
if (!agentId) {
|
|
189
|
-
return null;
|
|
190
|
-
}
|
|
191
|
-
const agent = await getProviderAgentById(agentId);
|
|
192
|
-
if (!agent) {
|
|
193
|
-
return null;
|
|
194
|
-
}
|
|
195
|
-
const workspace = await getProviderWorkspaceById(agent.workspaceId);
|
|
196
|
-
const profile = agent.profileId ? getProviderProfile(agent.profileId) : null;
|
|
197
|
-
return {
|
|
198
|
-
agent,
|
|
199
|
-
workspace,
|
|
200
|
-
profileLabel: profile ? `${profile.provider}/${profile.name}` : 'sin perfil',
|
|
201
|
-
};
|
|
202
|
-
}
|
|
203
|
-
function formatTeamAgent(resolved, fallbackId) {
|
|
204
|
-
if (!resolved) {
|
|
205
|
-
return fallbackId ? `desconocido (${fallbackId})` : 'sin asignar';
|
|
206
|
-
}
|
|
207
|
-
const provider = resolved.workspace?.provider ?? 'unknown';
|
|
208
|
-
const parts = [
|
|
209
|
-
`profile=${resolved.profileLabel}`,
|
|
210
|
-
resolved.agent.roleKind ? `role=${resolved.agent.roleKind}` : null,
|
|
211
|
-
resolved.agent.isOrchestrator ? 'orchestrator=true' : null,
|
|
212
|
-
resolved.agent.autonomyLevel ? `autonomy=${resolved.agent.autonomyLevel}` : null,
|
|
213
|
-
resolved.agent.modelOverride ? `model=${resolved.agent.modelOverride}` : null,
|
|
214
|
-
resolved.agent.isEnabled ? null : 'disabled',
|
|
215
|
-
].filter(Boolean);
|
|
216
|
-
return `${provider}/${resolved.agent.name}${parts.length > 0 ? ` (${parts.join(', ')})` : ''}`;
|
|
217
|
-
}
|
|
218
|
-
function formatTeamWorkspace(workspace, fallbackId) {
|
|
219
|
-
if (!workspace) {
|
|
220
|
-
return fallbackId ? `desconocido (${fallbackId})` : 'sin workspace';
|
|
221
|
-
}
|
|
222
|
-
const state = workspace.isEnabled ? 'enabled' : 'disabled';
|
|
223
|
-
return `${workspace.displayName} (${workspace.provider}, ${state})`;
|
|
224
|
-
}
|
|
225
|
-
async function buildTeamReadinessStatus(team, units) {
|
|
226
|
-
if (!team) {
|
|
227
|
-
return [];
|
|
228
|
-
}
|
|
229
|
-
const status = [];
|
|
230
|
-
const globalOrchestrator = await resolveTeamAgent(team.globalOrchestratorAgentId);
|
|
231
|
-
if (!team.globalOrchestratorAgentId) {
|
|
232
|
-
status.push(`- Falta orquestador global. Usa /team orchestrator ${team.name} <provider>/<agent>`);
|
|
233
|
-
}
|
|
234
|
-
else if (!globalOrchestrator) {
|
|
235
|
-
status.push(`- El orquestador global configurado no existe: ${team.globalOrchestratorAgentId}`);
|
|
236
|
-
}
|
|
237
|
-
else if (!globalOrchestrator.agent.isEnabled) {
|
|
238
|
-
status.push(`- El orquestador global esta deshabilitado: ${formatTeamAgent(globalOrchestrator)}`);
|
|
239
|
-
}
|
|
240
|
-
if (units.length === 0) {
|
|
241
|
-
status.push(`- No hay equipos internos. Usa /team equipo ${team.name} <equipo> <provider>/<agent>`);
|
|
242
|
-
}
|
|
243
|
-
for (const unit of units) {
|
|
244
|
-
const [workspace, localOrchestrator, lead, members] = await Promise.all([
|
|
245
|
-
unit.workspaceId ? getProviderWorkspaceById(unit.workspaceId) : null,
|
|
246
|
-
resolveTeamAgent(unit.localOrchestratorAgentId),
|
|
247
|
-
resolveTeamAgent(unit.leadAgentId),
|
|
248
|
-
listTeamUnitMembers(unit.id),
|
|
249
|
-
]);
|
|
250
|
-
if (!workspace) {
|
|
251
|
-
status.push(`- ${unit.unitName}: falta workspace/proveedor.`);
|
|
252
|
-
}
|
|
253
|
-
else if (!workspace.isEnabled) {
|
|
254
|
-
status.push(`- ${unit.unitName}: workspace deshabilitado (${workspace.provider}).`);
|
|
255
|
-
}
|
|
256
|
-
if (!localOrchestrator) {
|
|
257
|
-
status.push(`- ${unit.unitName}: falta orquestador local. Usa /team equipo ${team.name} ${unit.unitName} <provider>/<agent>`);
|
|
258
|
-
}
|
|
259
|
-
if (!lead) {
|
|
260
|
-
status.push(`- ${unit.unitName}: falta lead. Usa /team equipo ${team.name} ${unit.unitName} <provider>/<agent>`);
|
|
261
|
-
}
|
|
262
|
-
if (members.length === 0 && localOrchestrator) {
|
|
263
|
-
status.push(`- ${unit.unitName}: modo autonomo. ${formatTeamAgent(localOrchestrator)} asignara roles internos; miembros extra son opcionales.`);
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
return status;
|
|
267
|
-
}
|
|
268
|
-
async function buildTeamShowMessage(teamName) {
|
|
269
|
-
const team = await getTeamByName(teamName);
|
|
270
|
-
if (!team) {
|
|
271
|
-
return `No existe el team ${teamName}.`;
|
|
272
|
-
}
|
|
273
|
-
const units = await listTeamUnits(team.id);
|
|
274
|
-
const globalOrchestrator = await resolveTeamAgent(team.globalOrchestratorAgentId);
|
|
275
|
-
const readinessStatus = await buildTeamReadinessStatus(team, units);
|
|
276
|
-
const lines = [
|
|
277
|
-
`Team: ${team.name}`,
|
|
278
|
-
`ID: ${team.id}`,
|
|
279
|
-
`Orchestrator: ${formatTeamAgent(globalOrchestrator, team.globalOrchestratorAgentId)}`,
|
|
280
|
-
`Enabled: ${team.isEnabled ? 'true' : 'false'}`,
|
|
281
|
-
team.description ? `Descripcion: ${team.description}` : null,
|
|
282
|
-
].filter(Boolean);
|
|
283
|
-
lines.push('', 'Estado de configuracion:');
|
|
284
|
-
if (readinessStatus.length === 0) {
|
|
285
|
-
lines.push('- listo para orquestar');
|
|
286
|
-
}
|
|
287
|
-
else {
|
|
288
|
-
lines.push(...readinessStatus);
|
|
289
|
-
}
|
|
290
|
-
lines.push('', 'Equipos internos:');
|
|
291
|
-
if (units.length === 0) {
|
|
292
|
-
lines.push('- sin equipos internos');
|
|
293
|
-
return lines.join('\n');
|
|
294
|
-
}
|
|
295
|
-
for (const unit of units) {
|
|
296
|
-
const [workspace, localOrchestrator, lead] = await Promise.all([
|
|
297
|
-
unit.workspaceId ? getProviderWorkspaceById(unit.workspaceId) : null,
|
|
298
|
-
resolveTeamAgent(unit.localOrchestratorAgentId),
|
|
299
|
-
resolveTeamAgent(unit.leadAgentId),
|
|
300
|
-
]);
|
|
301
|
-
lines.push(`- ${unit.unitName}`);
|
|
302
|
-
lines.push(` Workspace: ${formatTeamWorkspace(workspace, unit.workspaceId)}`);
|
|
303
|
-
lines.push(` Local orchestrator: ${formatTeamAgent(localOrchestrator, unit.localOrchestratorAgentId)}`);
|
|
304
|
-
lines.push(` Lead: ${formatTeamAgent(lead, unit.leadAgentId)}`);
|
|
305
|
-
lines.push(` Mode: ${unit.selectionMode}`);
|
|
306
|
-
const members = await listTeamUnitMembers(unit.id);
|
|
307
|
-
if (members.length === 0) {
|
|
308
|
-
if (localOrchestrator) {
|
|
309
|
-
lines.push(' - sin miembros extra; el orquestador/lead opera en modo autonomo');
|
|
310
|
-
}
|
|
311
|
-
else {
|
|
312
|
-
lines.push(' - sin miembros');
|
|
313
|
-
}
|
|
314
|
-
continue;
|
|
315
|
-
}
|
|
316
|
-
for (const member of members) {
|
|
317
|
-
const resolvedMember = await resolveTeamAgent(member.agentId);
|
|
318
|
-
lines.push(` - ${formatTeamAgent(resolvedMember, member.agentId)}${member.duty ? ` [${member.duty}]` : ''} priority=${member.priority}`);
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
return lines.join('\n');
|
|
322
|
-
}
|
|
323
|
-
async function handleCreate(onDone, teamName) {
|
|
324
|
-
const trimmedName = teamName.trim();
|
|
325
|
-
if (!trimmedName) {
|
|
326
|
-
onDone('Debes indicar un nombre de team.');
|
|
327
|
-
return;
|
|
328
|
-
}
|
|
329
|
-
const existing = await getTeamByName(trimmedName);
|
|
330
|
-
if (existing) {
|
|
331
|
-
onDone(`Ya existe el team ${existing.name}.`);
|
|
332
|
-
return;
|
|
333
|
-
}
|
|
334
|
-
const created = await createTeam({ name: trimmedName, isEnabled: true });
|
|
335
|
-
onDone(`Team creado: ${created.name}`);
|
|
336
|
-
}
|
|
337
|
-
async function handleOrchestrator(onDone, teamName, refText) {
|
|
338
|
-
const ref = parseProviderRef(refText);
|
|
339
|
-
if (!ref) {
|
|
340
|
-
onDone('Formato invalido. Usa <provider>/<agent>.');
|
|
341
|
-
return;
|
|
342
|
-
}
|
|
343
|
-
const team = await getTeamByName(teamName);
|
|
344
|
-
if (!team) {
|
|
345
|
-
onDone(`No existe el team ${teamName}.`);
|
|
346
|
-
return;
|
|
347
|
-
}
|
|
348
|
-
try {
|
|
349
|
-
const { agent } = await resolveAgentRef(ref);
|
|
350
|
-
const updated = await updateTeam(team.id, {
|
|
351
|
-
globalOrchestratorAgentId: agent.id,
|
|
352
|
-
});
|
|
353
|
-
onDone(`Orchestrator actualizado para ${updated.name}: ${formatProviderRef(ref)}`);
|
|
354
|
-
}
|
|
355
|
-
catch (error) {
|
|
356
|
-
onDone(error instanceof Error ? error.message : String(error));
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
async function handleDomain(onDone, teamName, unitName, refText) {
|
|
360
|
-
const ref = parseProviderRef(refText);
|
|
361
|
-
if (!ref) {
|
|
362
|
-
onDone('Formato invalido. Usa <provider>/<agent>.');
|
|
363
|
-
return;
|
|
364
|
-
}
|
|
365
|
-
const normalizedUnit = unitName.trim().toLowerCase();
|
|
366
|
-
if (!normalizedUnit) {
|
|
367
|
-
onDone('Debes indicar un equipo valido.');
|
|
368
|
-
return;
|
|
369
|
-
}
|
|
370
|
-
const team = await getTeamByName(teamName);
|
|
371
|
-
if (!team) {
|
|
372
|
-
onDone(`No existe el team ${teamName}.`);
|
|
373
|
-
return;
|
|
374
|
-
}
|
|
375
|
-
try {
|
|
376
|
-
const { agent, workspaceId, wasCreated } = await resolveAgentRef(ref, {
|
|
377
|
-
createIfMissing: true,
|
|
378
|
-
roleHint: normalizedUnit,
|
|
379
|
-
});
|
|
380
|
-
const unitAgent = await applyTeamAutonomyToAgent(agent, normalizedUnit);
|
|
381
|
-
const existing = await findUnitByName(team.id, normalizedUnit);
|
|
382
|
-
const unit = existing
|
|
383
|
-
? await updateTeamUnit(existing.id, {
|
|
384
|
-
workspaceId,
|
|
385
|
-
localOrchestratorAgentId: unitAgent.id,
|
|
386
|
-
leadAgentId: unitAgent.id,
|
|
387
|
-
selectionMode: 'manual',
|
|
388
|
-
required: true,
|
|
389
|
-
})
|
|
390
|
-
: await createTeamUnit({
|
|
391
|
-
teamId: team.id,
|
|
392
|
-
unitName: normalizedUnit,
|
|
393
|
-
workspaceId,
|
|
394
|
-
localOrchestratorAgentId: unitAgent.id,
|
|
395
|
-
leadAgentId: unitAgent.id,
|
|
396
|
-
selectionMode: 'manual',
|
|
397
|
-
required: true,
|
|
398
|
-
});
|
|
399
|
-
onDone([
|
|
400
|
-
wasCreated
|
|
401
|
-
? `Agente creado automaticamente: ${formatProviderRef(ref)} con rol ${normalizedUnit}.`
|
|
402
|
-
: null,
|
|
403
|
-
`Autonomia del equipo aplicada: ${formatProviderRef(ref)} queda como orquestador/lead de ${normalizedUnit}.`,
|
|
404
|
-
`Equipo ${unit.unitName} actualizado en ${team.name}: ${formatProviderRef(ref)}`,
|
|
405
|
-
]
|
|
406
|
-
.filter(Boolean)
|
|
407
|
-
.join('\n'));
|
|
408
|
-
}
|
|
409
|
-
catch (error) {
|
|
410
|
-
onDone(error instanceof Error ? error.message : String(error));
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
|
-
async function handleAddMember(onDone, teamName, unitName, refText, dutyText) {
|
|
414
|
-
const ref = parseProviderRef(refText);
|
|
415
|
-
if (!ref) {
|
|
416
|
-
onDone('Formato invalido. Usa <provider>/<agent>.');
|
|
417
|
-
return;
|
|
418
|
-
}
|
|
419
|
-
const normalizedUnit = unitName.trim().toLowerCase();
|
|
420
|
-
if (!normalizedUnit) {
|
|
421
|
-
onDone('Debes indicar un equipo valido.');
|
|
422
|
-
return;
|
|
423
|
-
}
|
|
424
|
-
const team = await getTeamByName(teamName);
|
|
425
|
-
if (!team) {
|
|
426
|
-
onDone(`No existe el team ${teamName}.`);
|
|
427
|
-
return;
|
|
428
|
-
}
|
|
429
|
-
const unit = await findUnitByName(team.id, normalizedUnit);
|
|
430
|
-
if (!unit) {
|
|
431
|
-
onDone(`El equipo ${normalizedUnit} no existe en ${teamName}. Usa /team equipo primero.`);
|
|
432
|
-
return;
|
|
433
|
-
}
|
|
434
|
-
try {
|
|
435
|
-
const { agent } = await resolveAgentRef(ref);
|
|
436
|
-
const members = await listTeamUnitMembers(unit.id);
|
|
437
|
-
const existing = members.find(member => member.agentId === agent.id);
|
|
438
|
-
if (existing) {
|
|
439
|
-
onDone(`El agente ${formatProviderRef(ref)} ya pertenece a ${teamName}/${normalizedUnit}.`);
|
|
440
|
-
return;
|
|
441
|
-
}
|
|
442
|
-
await createTeamUnitMember({
|
|
443
|
-
teamUnitId: unit.id,
|
|
444
|
-
agentId: agent.id,
|
|
445
|
-
duty: dutyText?.trim() || null,
|
|
446
|
-
priority: 0,
|
|
447
|
-
});
|
|
448
|
-
onDone(`Miembro agregado a ${teamName}/${normalizedUnit}: ${formatProviderRef(ref)}${dutyText?.trim() ? ` [${dutyText.trim()}]` : ''}`);
|
|
449
|
-
}
|
|
450
|
-
catch (error) {
|
|
451
|
-
onDone(error instanceof Error ? error.message : String(error));
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
function TeamOrchestratorWizard({ onDone, initialTeamName, }) {
|
|
455
|
-
const [selectedTeamName, setSelectedTeamName] = React.useState(initialTeamName ?? null);
|
|
456
|
-
const [isLoadingTeams, setIsLoadingTeams] = React.useState(!initialTeamName);
|
|
457
|
-
const [isLoadingAgents, setIsLoadingAgents] = React.useState(Boolean(initialTeamName));
|
|
458
|
-
const [teamOptions, setTeamOptions] = React.useState([]);
|
|
459
|
-
const [agentOptions, setAgentOptions] = React.useState([]);
|
|
460
|
-
React.useEffect(() => {
|
|
461
|
-
if (initialTeamName) {
|
|
462
|
-
return;
|
|
463
|
-
}
|
|
464
|
-
let mounted = true;
|
|
465
|
-
setIsLoadingTeams(true);
|
|
466
|
-
void listTeams().then(teams => {
|
|
467
|
-
if (!mounted) {
|
|
468
|
-
return;
|
|
469
|
-
}
|
|
470
|
-
setTeamOptions(teams.map(team => ({
|
|
471
|
-
label: team.name,
|
|
472
|
-
value: team.name,
|
|
473
|
-
description: team.globalOrchestratorAgentId
|
|
474
|
-
? 'Tiene orquestador configurado'
|
|
475
|
-
: 'Sin orquestador principal',
|
|
476
|
-
})));
|
|
477
|
-
setIsLoadingTeams(false);
|
|
478
|
-
});
|
|
479
|
-
return () => {
|
|
480
|
-
mounted = false;
|
|
481
|
-
};
|
|
482
|
-
}, []);
|
|
483
|
-
React.useEffect(() => {
|
|
484
|
-
if (!selectedTeamName) {
|
|
485
|
-
return;
|
|
486
|
-
}
|
|
487
|
-
let mounted = true;
|
|
488
|
-
setIsLoadingAgents(true);
|
|
489
|
-
void listAgents().then(agents => {
|
|
490
|
-
if (!mounted) {
|
|
491
|
-
return;
|
|
492
|
-
}
|
|
493
|
-
setAgentOptions(agents
|
|
494
|
-
.filter(agent => agent.isEnabled)
|
|
495
|
-
.map(agent => ({
|
|
496
|
-
label: `${agent.provider}/${agent.name}`,
|
|
497
|
-
value: `${agent.provider}/${agent.name}`,
|
|
498
|
-
description: `${agent.profile ? `perfil ${agent.profile.name}` : 'sin perfil'} · rol ${agent.roleKind ?? 'worker'}${agent.modelOverride ? ` · modelo ${agent.modelOverride}` : ''}`,
|
|
499
|
-
})));
|
|
500
|
-
setIsLoadingAgents(false);
|
|
501
|
-
});
|
|
502
|
-
return () => {
|
|
503
|
-
mounted = false;
|
|
504
|
-
};
|
|
505
|
-
}, [selectedTeamName]);
|
|
506
|
-
if (!selectedTeamName) {
|
|
507
|
-
if (isLoadingTeams) {
|
|
508
|
-
return (_jsx(Box, { flexDirection: "column", children: _jsx(Text, { dimColor: true, children: "Cargando equipos..." }) }));
|
|
509
|
-
}
|
|
510
|
-
if (teamOptions.length === 0) {
|
|
511
|
-
return (_jsx(TeamAutoDone, { onDone: onDone, getMessage: () => 'No hay equipos guardados. Crea uno primero con /workspace setup.' }));
|
|
512
|
-
}
|
|
513
|
-
return (_jsxs(Box, { flexDirection: "column", gap: 1, children: [_jsx(Text, { bold: true, color: "cyan", children: "Seleccionar equipo" }), _jsx(Text, { dimColor: true, children: "Elige el equipo al que quieres cambiarle el orquestador principal." }), _jsx(Select, { options: teamOptions, onChange: setSelectedTeamName, onCancel: () => onDone('Seleccion de orquestador cancelada.') })] }));
|
|
514
|
-
}
|
|
515
|
-
if (isLoadingAgents) {
|
|
516
|
-
return (_jsx(Box, { flexDirection: "column", children: _jsx(Text, { dimColor: true, children: "Cargando agentes..." }) }));
|
|
517
|
-
}
|
|
518
|
-
if (agentOptions.length === 0) {
|
|
519
|
-
return (_jsx(TeamAutoDone, { onDone: onDone, getMessage: () => 'No hay agentes disponibles. Crea perfiles/equipos primero con /workspace setup.' }));
|
|
520
|
-
}
|
|
521
|
-
return (_jsxs(Box, { flexDirection: "column", gap: 1, children: [_jsxs(Text, { bold: true, color: "cyan", children: ["Elegir orquestador para ", selectedTeamName] }), _jsx(Text, { dimColor: true, children: "Este agente recibira el objetivo global y coordinara los frentes del equipo." }), _jsx(Select, { options: [
|
|
522
|
-
...agentOptions,
|
|
523
|
-
{
|
|
524
|
-
label: 'Volver',
|
|
525
|
-
value: '__back__',
|
|
526
|
-
description: 'Regresar a la seleccion de equipo.',
|
|
527
|
-
},
|
|
528
|
-
], onChange: value => {
|
|
529
|
-
if (value === '__back__') {
|
|
530
|
-
setSelectedTeamName(null);
|
|
531
|
-
return;
|
|
532
|
-
}
|
|
533
|
-
void handleOrchestrator(onDone, selectedTeamName, value);
|
|
534
|
-
}, onCancel: () => setSelectedTeamName(null) })] }));
|
|
535
|
-
}
|
|
536
|
-
function TeamAutoDone({ onDone, getMessage, }) {
|
|
537
|
-
React.useEffect(() => {
|
|
538
|
-
void Promise.resolve(getMessage()).then(message => onDone(message));
|
|
539
|
-
}, [getMessage, onDone]);
|
|
540
|
-
return null;
|
|
541
|
-
}
|
|
542
|
-
export async function call(onDone, _context, args) {
|
|
543
|
-
const parsed = parseArgs(args);
|
|
544
|
-
if (!parsed || parsed.command === 'list') {
|
|
545
|
-
const teams = await listTeams();
|
|
546
|
-
onDone(buildTeamListMessage(teams));
|
|
547
|
-
return null;
|
|
548
|
-
}
|
|
549
|
-
const [first, second, third, ...rest] = parsed.rest;
|
|
550
|
-
if (parsed.command === 'create') {
|
|
551
|
-
await handleCreate(onDone, [first, second, third, ...rest].filter(Boolean).join(' '));
|
|
552
|
-
return null;
|
|
553
|
-
}
|
|
554
|
-
if (parsed.command === 'show') {
|
|
555
|
-
if (!first) {
|
|
556
|
-
onDone('Debes indicar el nombre del team.');
|
|
557
|
-
return null;
|
|
558
|
-
}
|
|
559
|
-
onDone(await buildTeamShowMessage([first, second, third, ...rest].filter(Boolean).join(' ')));
|
|
560
|
-
return null;
|
|
561
|
-
}
|
|
562
|
-
if (parsed.command === 'orchestrator') {
|
|
563
|
-
if (!first) {
|
|
564
|
-
return _jsx(TeamOrchestratorWizard, { onDone: onDone });
|
|
565
|
-
}
|
|
566
|
-
if (!second) {
|
|
567
|
-
return (_jsx(TeamOrchestratorWizard, { onDone: onDone, initialTeamName: first }));
|
|
568
|
-
}
|
|
569
|
-
await handleOrchestrator(onDone, first, second);
|
|
570
|
-
return null;
|
|
571
|
-
}
|
|
572
|
-
if (parsed.command === 'equipo') {
|
|
573
|
-
if (!first || !second || !third) {
|
|
574
|
-
onDone('Uso: /team equipo <team> <equipo> <provider>/<agent>');
|
|
575
|
-
return null;
|
|
576
|
-
}
|
|
577
|
-
await handleDomain(onDone, first, second, third);
|
|
578
|
-
return null;
|
|
579
|
-
}
|
|
580
|
-
if (parsed.command === 'add-member') {
|
|
581
|
-
if (!first || !second || !third) {
|
|
582
|
-
onDone('Uso: /team add-member <team> <equipo> <provider>/<agent> [duty]');
|
|
583
|
-
return null;
|
|
584
|
-
}
|
|
585
|
-
await handleAddMember(onDone, first, second, third, rest.join(' '));
|
|
586
|
-
return null;
|
|
587
|
-
}
|
|
588
|
-
onDone('Uso: /team list, /team create <name>, /team show <name>, /team orchestrator <team> <provider>/<agent>, /team equipo <team> <equipo> <provider>/<agent>, /team add-member <team> <equipo> <provider>/<agent> [duty]');
|
|
589
|
-
return null;
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Text } from '../../ink.js';
|
|
3
|
+
export async function call(onDone, _context) {
|
|
4
|
+
onDone([
|
|
5
|
+
'/team esta en transicion a modo agent-first.',
|
|
6
|
+
'Ahora la configuracion recomendada se hace desde /agent (roles por agente).',
|
|
7
|
+
'Flujo recomendado:',
|
|
8
|
+
'1. /agent',
|
|
9
|
+
'2. Crea agentes por rol (backend, frontend, qa, docs).',
|
|
10
|
+
'3. Pide el objetivo en el hilo principal para delegacion automatica.',
|
|
11
|
+
].join('\n'));
|
|
12
|
+
return _jsx(Text, { dimColor: true, children: "/team migrado a /agent." });
|
|
590
13
|
}
|
|
@@ -169,8 +169,8 @@ function buildSetupGuideMessage() {
|
|
|
169
169
|
'6. Crea o actualiza los equipos internos del team.',
|
|
170
170
|
'',
|
|
171
171
|
'Despues puedes ejecutar:',
|
|
172
|
-
'/
|
|
173
|
-
'
|
|
172
|
+
'/agent',
|
|
173
|
+
'Describe el objetivo directamente en el hilo principal',
|
|
174
174
|
'/run resume <run-id>',
|
|
175
175
|
'',
|
|
176
176
|
'Nota: si todavia no tienes provider/profile listo, abre solo /workspace setup y elige "Preparar proveedor/perfil".',
|
|
@@ -382,7 +382,7 @@ async function runWorkspaceSetup(setup) {
|
|
|
382
382
|
});
|
|
383
383
|
lines.push(`- Equipo creado: ${entry.unitName} -> ${entry.provider}/${entry.agentName}`);
|
|
384
384
|
}
|
|
385
|
-
lines.push('', 'Listo. Siguientes comandos recomendados:',
|
|
385
|
+
lines.push('', 'Listo. Siguientes comandos recomendados:', '/agent', 'Describe tu objetivo y delega en los agentes disponibles', '/run list', '/run resume <run-id>');
|
|
386
386
|
return lines.join('\n');
|
|
387
387
|
}
|
|
388
388
|
async function setWorkspaceState(onDone, provider, enabled) {
|
package/dist/src/commands.js
CHANGED
|
@@ -46,7 +46,6 @@ import session from './commands/session/index.js';
|
|
|
46
46
|
import share from './commands/share/index.js';
|
|
47
47
|
import skills from './commands/skills/index.js';
|
|
48
48
|
import status from './commands/status/index.js';
|
|
49
|
-
import tasks from './commands/tasks/index.js';
|
|
50
49
|
import teleport from './commands/teleport/index.js';
|
|
51
50
|
import telegram from './commands/telegram/index.js';
|
|
52
51
|
import whatsapp from './commands/whatsapp/index.js';
|
|
@@ -150,10 +149,8 @@ import profile from './commands/profile/index.js';
|
|
|
150
149
|
import policy from './commands/policy/index.js';
|
|
151
150
|
import run from './commands/run/index.js';
|
|
152
151
|
import workspace from './commands/workspace/index.js';
|
|
153
|
-
import orchestrate from './commands/orchestrate/index.js';
|
|
154
152
|
import provider from './commands/provider/index.js';
|
|
155
153
|
import tag from './commands/tag/index.js';
|
|
156
|
-
import team from './commands/team/index.js';
|
|
157
154
|
import teamAuto from './commands/team-auto/index.js';
|
|
158
155
|
import limites from './commands/limites/index.js';
|
|
159
156
|
import outputStyle from './commands/output-style/index.js';
|
|
@@ -240,7 +237,6 @@ const COMMANDS = memoize(() => [
|
|
|
240
237
|
policy,
|
|
241
238
|
run,
|
|
242
239
|
workspace,
|
|
243
|
-
orchestrate,
|
|
244
240
|
provider,
|
|
245
241
|
outputStyle,
|
|
246
242
|
remoteEnv,
|
|
@@ -257,7 +253,6 @@ const COMMANDS = memoize(() => [
|
|
|
257
253
|
statusline,
|
|
258
254
|
stickers,
|
|
259
255
|
tag,
|
|
260
|
-
team,
|
|
261
256
|
teamAuto,
|
|
262
257
|
limites,
|
|
263
258
|
theme,
|
|
@@ -291,7 +286,6 @@ const COMMANDS = memoize(() => [
|
|
|
291
286
|
login(),
|
|
292
287
|
passes,
|
|
293
288
|
...(peersCmd ? [peersCmd] : []),
|
|
294
|
-
tasks,
|
|
295
289
|
telegram,
|
|
296
290
|
whatsapp,
|
|
297
291
|
...(workflowsCmd ? [workflowsCmd] : []),
|
|
@@ -217,5 +217,5 @@ function NotificationContent({ ideSelection, mcpClients, notifications, isInOver
|
|
|
217
217
|
if (feature('VOICE_MODE') && voiceEnabled && (voiceState === 'recording' || voiceState === 'processing')) {
|
|
218
218
|
return _jsx(VoiceIndicator, { voiceState: voiceState });
|
|
219
219
|
}
|
|
220
|
-
return _jsxs(_Fragment, { children: [_jsx(IdeStatusIndicator, { ideSelection: ideSelection, mcpClients: mcpClients }), notifications.current && ('jsx' in notifications.current ? _jsx(Text, { wrap: "truncate", children: notifications.current.jsx }, notifications.current.key) : _jsx(Text, { color: notifications.current.color, dimColor: !notifications.current.color, wrap: "truncate", children: notifications.current.text })), isInOverageMode && !isTeamOrEnterprise && _jsx(Box, { children: _jsx(Text, { dimColor: true, wrap: "truncate", children: "Now using extra usage" }) }), apiKeyHelperSlow && _jsxs(Box, { children: [_jsxs(Text, { color: "warning", wrap: "truncate", children: ["apiKeyHelper is taking a while", ' '] }), _jsxs(Text, { dimColor: true, wrap: "truncate", children: ["(", apiKeyHelperSlow, ")"] })] }), (apiKeyStatus === 'invalid' || apiKeyStatus === 'missing') && _jsx(Box, { children: _jsx(Text, { color: "error", wrap: "truncate", children: isEnvTruthy(process.env.CLAUDE_CODE_REMOTE) ? '
|
|
220
|
+
return _jsxs(_Fragment, { children: [_jsx(IdeStatusIndicator, { ideSelection: ideSelection, mcpClients: mcpClients }), notifications.current && ('jsx' in notifications.current ? _jsx(Text, { wrap: "truncate", children: notifications.current.jsx }, notifications.current.key) : _jsx(Text, { color: notifications.current.color, dimColor: !notifications.current.color, wrap: "truncate", children: notifications.current.text })), isInOverageMode && !isTeamOrEnterprise && _jsx(Box, { children: _jsx(Text, { dimColor: true, wrap: "truncate", children: "Now using extra usage" }) }), apiKeyHelperSlow && _jsxs(Box, { children: [_jsxs(Text, { color: "warning", wrap: "truncate", children: ["apiKeyHelper is taking a while", ' '] }), _jsxs(Text, { dimColor: true, wrap: "truncate", children: ["(", apiKeyHelperSlow, ")"] })] }), (apiKeyStatus === 'invalid' || apiKeyStatus === 'missing') && _jsx(Box, { children: _jsx(Text, { color: "error", wrap: "truncate", children: isEnvTruthy(process.env.CLAUDE_CODE_REMOTE) ? 'Error de autenticacion · intenta de nuevo' : 'No has iniciado sesion · Ejecuta /login' }) }), debug && _jsx(Box, { children: _jsx(Text, { color: "warning", wrap: "truncate", children: "Debug mode" }) }), apiKeyStatus !== 'invalid' && apiKeyStatus !== 'missing' && verbose && _jsx(Box, { children: _jsxs(Text, { dimColor: true, wrap: "truncate", children: [tokenUsage, " tokens"] }) }), !isBriefOnly && _jsx(TokenWarning, { tokenUsage: tokenUsage, model: mainLoopModel }), shouldShowAutoUpdater && _jsx(AutoUpdaterWrapper, { verbose: verbose, onAutoUpdaterResult: onAutoUpdaterResult, autoUpdaterResult: autoUpdaterResult, isUpdating: isAutoUpdating, onChangeIsUpdating: onChangeIsUpdating, showSuccessMessage: !isShowingCompactMessage }), feature('VOICE_MODE') ? voiceEnabled && voiceError && _jsx(Box, { children: _jsx(Text, { color: "error", wrap: "truncate", children: voiceError }) }) : null, _jsx(MemoryUsageIndicator, {}), _jsx(SandboxPromptFooterHint, {})] });
|
|
221
221
|
}
|