@jmanuelcorral/openteam 0.1.9 → 0.1.11
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 +20 -2
- package/dist/cli.js +143 -4
- package/dist/commands/dispatch.d.ts +3 -0
- package/dist/commands/dispatch.d.ts.map +1 -1
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/orchestratorAgent.d.ts.map +1 -1
- package/dist/commands/yolo.d.ts +27 -0
- package/dist/commands/yolo.d.ts.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +116 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -198,7 +198,7 @@ El asistente:
|
|
|
198
198
|
1. Sondea los runtimes locales y marca los detectados.
|
|
199
199
|
2. Te deja habilitar runtimes y elegir el modelo por defecto de cada uno (o escribirlo si no se detectan modelos).
|
|
200
200
|
3. Ofrece el modelo frontier baseline a partir del **catálogo completo de [Models.dev](https://models.dev)** que openteam ya integra: una lista rápida con los más **baratos-capaces primero** (incluidos los **gratuitos**, etiquetados como `gratis`), una opción **«Ver todos los modelos por proveedor…»** para navegar el catálogo completo, y **«Otro (custom)»** para escribir un `provider/model`. Si el catálogo no se puede cargar (offline), cae a la lista curada.
|
|
201
|
-
4. Pregunta el modo de routing (`balanced`/`economy`/`quality`)
|
|
201
|
+
4. Pregunta el modo de routing (`balanced`/`economy`/`quality`), la política de privacidad y si quieres activar el **modo YOLO** (auto-aprobar permisos de opencode).
|
|
202
202
|
5. Si ya existe `opencode.json` o `.opencode/openteam.json`, pide confirmación antes de sobrescribir.
|
|
203
203
|
|
|
204
204
|
Tras `init`, autentica el provider frontier (`opencode auth login`), arranca tu runtime local si no estaba activo y abre opencode en el repositorio: openteam enruta local-first automáticamente. Puedes reajustar el baseline después con `openteam baseline set <provider/model>` o `openteam baseline auto`.
|
|
@@ -215,6 +215,8 @@ Como Squad, el equipo tiene **identidad temática**: el orquestador elige (o te
|
|
|
215
215
|
- **ralph** — automatización y triage: monitoriza el trabajo pendiente, lo prioriza, coordina la ejecución y **escala al humano** ante bloqueos o aprobaciones.
|
|
216
216
|
- **guardian** — seguridad y privacidad: **detecta y enmascara datos sensibles** (PII, secretos, API keys, tokens) antes de que salgan a frontier y hace revisión de seguridad; corre siempre en local y respeta `forceLocalOnSensitive`.
|
|
217
217
|
|
|
218
|
+
Antes de delegar, el orquestador **planifica dependencias y paraleliza**: descompone la petición en tareas, y como opencode ejecuta en paralelo todas las llamadas `task` emitidas en un mismo turno (Vercel AI SDK), lanza a la vez las tareas independientes y secuencia por olas solo las que dependen de un resultado previo. El trabajo que colisiona sobre los mismos ficheros se separa en olas distintas para evitar conflictos.
|
|
219
|
+
|
|
218
220
|
## Probar en otra máquina
|
|
219
221
|
|
|
220
222
|
Para instalar y probar openteam en otro equipo que ya tenga [opencode](https://opencode.ai) y [Bun](https://bun.sh):
|
|
@@ -361,9 +363,25 @@ openteam baseline show
|
|
|
361
363
|
openteam baseline set openai/gpt-5-mini
|
|
362
364
|
openteam doctor --config .opencode/openteam.json
|
|
363
365
|
openteam report --telemetry .opencode/openteam-telemetry.jsonl
|
|
366
|
+
openteam yolo status
|
|
367
|
+
openteam yolo on
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
Flags: `--config <path>` y `--telemetry <path>` sobrescriben las rutas por defecto; `--opencode <path>` apunta el comando `yolo` a un `opencode.json` concreto.
|
|
371
|
+
|
|
372
|
+
### Modo YOLO (auto-aprobar permisos)
|
|
373
|
+
|
|
374
|
+
El **modo YOLO** hace que opencode auto-apruebe **todos** los permisos (equivale al flag nativo `opencode --auto`, pero persistente). Escribe la regla global `permission: { "*": "allow" }` en `opencode.json`, conservando el resto de tu configuración:
|
|
375
|
+
|
|
376
|
+
```powershell
|
|
377
|
+
openteam yolo status # ¿está activo?
|
|
378
|
+
openteam yolo on # activa YOLO
|
|
379
|
+
openteam yolo off # desactiva YOLO
|
|
364
380
|
```
|
|
365
381
|
|
|
366
|
-
|
|
382
|
+
También puedes activarlo durante `openteam init` (te lo pregunta), o al vuelo con `opencode --auto` sin tocar la config.
|
|
383
|
+
|
|
384
|
+
> **YOLO no desactiva la privacidad de openteam.** Solo afecta a las aprobaciones de permisos de opencode; con `privacyMode: "forceLocalOnSensitive"`, los prompts sensibles siguen sin salir a frontier. Úsalo solo en entornos de confianza: auto-aprueba también `bash`, escrituras y accesos fuera del workspace (salvo reglas `deny` explícitas).
|
|
367
385
|
|
|
368
386
|
## Ejemplos en Windows
|
|
369
387
|
|
package/dist/cli.js
CHANGED
|
@@ -1031,6 +1031,42 @@ function renderReport(report) {
|
|
|
1031
1031
|
`);
|
|
1032
1032
|
}
|
|
1033
1033
|
|
|
1034
|
+
// src/commands/yolo.ts
|
|
1035
|
+
var CATCH_ALL = "*";
|
|
1036
|
+
var ALLOW = "allow";
|
|
1037
|
+
function asPermissionMap(value) {
|
|
1038
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
|
1039
|
+
return value;
|
|
1040
|
+
}
|
|
1041
|
+
return;
|
|
1042
|
+
}
|
|
1043
|
+
function isYoloEnabled(config) {
|
|
1044
|
+
const permission = asPermissionMap(config.permission);
|
|
1045
|
+
return permission?.[CATCH_ALL] === ALLOW;
|
|
1046
|
+
}
|
|
1047
|
+
function applyYolo(config, enabled) {
|
|
1048
|
+
const next = { ...config };
|
|
1049
|
+
const current = asPermissionMap(config.permission);
|
|
1050
|
+
const permission = current ? { ...current } : {};
|
|
1051
|
+
if (enabled) {
|
|
1052
|
+
permission[CATCH_ALL] = ALLOW;
|
|
1053
|
+
next.permission = permission;
|
|
1054
|
+
return next;
|
|
1055
|
+
}
|
|
1056
|
+
if (permission[CATCH_ALL] === ALLOW) {
|
|
1057
|
+
delete permission[CATCH_ALL];
|
|
1058
|
+
}
|
|
1059
|
+
if (Object.keys(permission).length === 0) {
|
|
1060
|
+
delete next.permission;
|
|
1061
|
+
} else {
|
|
1062
|
+
next.permission = permission;
|
|
1063
|
+
}
|
|
1064
|
+
return next;
|
|
1065
|
+
}
|
|
1066
|
+
function renderYoloStatus(enabled) {
|
|
1067
|
+
return enabled ? "Modo YOLO: ACTIVADO (opencode auto-aprueba todos los permisos)." : "Modo YOLO: desactivado (opencode pide aprobación según sus reglas).";
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1034
1070
|
// src/commands/dispatch.ts
|
|
1035
1071
|
var HELP = [
|
|
1036
1072
|
"openteam — comandos runtime",
|
|
@@ -1042,10 +1078,14 @@ var HELP = [
|
|
|
1042
1078
|
" openteam baseline auto Baseline cheapest-capable (modo auto)",
|
|
1043
1079
|
" openteam doctor Diagnóstico de runtimes y config",
|
|
1044
1080
|
" openteam report Resumen de coste/ahorro (telemetría)",
|
|
1081
|
+
" openteam yolo status Muestra si el modo YOLO está activo",
|
|
1082
|
+
" openteam yolo on Activa YOLO (opencode auto-aprueba todo)",
|
|
1083
|
+
" openteam yolo off Desactiva YOLO",
|
|
1045
1084
|
"",
|
|
1046
1085
|
"Opciones:",
|
|
1047
1086
|
" --config <path> Ruta de .opencode/openteam.json",
|
|
1048
|
-
" --telemetry <path> Ruta del JSONL de telemetría"
|
|
1087
|
+
" --telemetry <path> Ruta del JSONL de telemetría",
|
|
1088
|
+
" --opencode <path> Ruta de opencode.json (para el comando yolo)"
|
|
1049
1089
|
].join(`
|
|
1050
1090
|
`);
|
|
1051
1091
|
function parseArgs(argv) {
|
|
@@ -1065,6 +1105,12 @@ function parseArgs(argv) {
|
|
|
1065
1105
|
result.telemetryPath = value;
|
|
1066
1106
|
}
|
|
1067
1107
|
i += 1;
|
|
1108
|
+
} else if (arg === "--opencode") {
|
|
1109
|
+
const value = argv[i + 1];
|
|
1110
|
+
if (value !== undefined) {
|
|
1111
|
+
result.opencodeConfigPath = value;
|
|
1112
|
+
}
|
|
1113
|
+
i += 1;
|
|
1068
1114
|
} else if (arg !== undefined) {
|
|
1069
1115
|
positionals.push(arg);
|
|
1070
1116
|
}
|
|
@@ -1107,15 +1153,54 @@ async function runBaseline(positionals, deps, configPath) {
|
|
|
1107
1153
|
${HELP}`
|
|
1108
1154
|
};
|
|
1109
1155
|
}
|
|
1156
|
+
async function runYolo(positionals, deps, opencodeConfigPath) {
|
|
1157
|
+
const sub = positionals[1] ?? "status";
|
|
1158
|
+
if (sub !== "status" && sub !== "on" && sub !== "off") {
|
|
1159
|
+
return {
|
|
1160
|
+
exitCode: 1,
|
|
1161
|
+
stdout: `Subcomando de yolo desconocido: ${sub}
|
|
1162
|
+
|
|
1163
|
+
${HELP}`
|
|
1164
|
+
};
|
|
1165
|
+
}
|
|
1166
|
+
const config = await deps.readOpencodeConfig(opencodeConfigPath);
|
|
1167
|
+
if (config === undefined) {
|
|
1168
|
+
return {
|
|
1169
|
+
exitCode: 1,
|
|
1170
|
+
stdout: `No existe ${opencodeConfigPath}. Ejecuta 'openteam init' primero.`
|
|
1171
|
+
};
|
|
1172
|
+
}
|
|
1173
|
+
if (sub === "status") {
|
|
1174
|
+
return { exitCode: 0, stdout: renderYoloStatus(isYoloEnabled(config)) };
|
|
1175
|
+
}
|
|
1176
|
+
const enable = sub === "on";
|
|
1177
|
+
if (isYoloEnabled(config) === enable) {
|
|
1178
|
+
return {
|
|
1179
|
+
exitCode: 0,
|
|
1180
|
+
stdout: `Sin cambios. ${renderYoloStatus(enable)}`
|
|
1181
|
+
};
|
|
1182
|
+
}
|
|
1183
|
+
const next = applyYolo(config, enable);
|
|
1184
|
+
await deps.writeOpencodeConfig(next, opencodeConfigPath);
|
|
1185
|
+
return {
|
|
1186
|
+
exitCode: 0,
|
|
1187
|
+
stdout: `${opencodeConfigPath} actualizado. ${renderYoloStatus(enable)}${enable ? `
|
|
1188
|
+
Nota: YOLO no desactiva la privacidad de openteam; los prompts sensibles siguen sin salir a frontier con forceLocalOnSensitive.` : ""}`
|
|
1189
|
+
};
|
|
1190
|
+
}
|
|
1110
1191
|
async function runCli(argv, deps) {
|
|
1111
1192
|
const parsed = parseArgs(argv);
|
|
1112
1193
|
const command = parsed.positionals[0];
|
|
1113
1194
|
const configPath = parsed.configPath ?? deps.configPath;
|
|
1114
1195
|
const telemetryPath = parsed.telemetryPath ?? deps.telemetryPath;
|
|
1196
|
+
const opencodeConfigPath = parsed.opencodeConfigPath ?? deps.opencodeConfigPath;
|
|
1115
1197
|
try {
|
|
1116
1198
|
if (command === "baseline") {
|
|
1117
1199
|
return await runBaseline(parsed.positionals, deps, configPath);
|
|
1118
1200
|
}
|
|
1201
|
+
if (command === "yolo") {
|
|
1202
|
+
return await runYolo(parsed.positionals, deps, opencodeConfigPath);
|
|
1203
|
+
}
|
|
1119
1204
|
if (command === "doctor") {
|
|
1120
1205
|
const config = await deps.loadConfig(configPath);
|
|
1121
1206
|
const [snapshots, records] = await Promise.all([
|
|
@@ -1179,7 +1264,7 @@ function buildOrchestratorAgent(frontier) {
|
|
|
1179
1264
|
const model = `${frontier.providerID}/${frontier.modelID}`;
|
|
1180
1265
|
const frontmatter = [
|
|
1181
1266
|
"---",
|
|
1182
|
-
'description: "Orquestador openteam estilo Squad: en cada petición comprueba si existe equipo; si no, entiende las tareas y crea el equipo de subagentes a demanda, y
|
|
1267
|
+
'description: "Orquestador openteam estilo Squad: en cada petición comprueba si existe equipo; si no, entiende las tareas y crea el equipo de subagentes a demanda, planifica dependencias y paraleliza el trabajo independiente, con routing local-first."',
|
|
1183
1268
|
"mode: primary",
|
|
1184
1269
|
`model: ${model}`,
|
|
1185
1270
|
"temperature: 0.2",
|
|
@@ -1273,12 +1358,40 @@ function buildOrchestratorAgent(frontier) {
|
|
|
1273
1358
|
" deja pasar datos sensibles a frontier. Revisa las entradas y salidas de los",
|
|
1274
1359
|
" demás agentes cuando toquen datos sensibles.",
|
|
1275
1360
|
"",
|
|
1361
|
+
"## Planificación y paralelización del trabajo",
|
|
1362
|
+
"",
|
|
1363
|
+
"Antes de delegar, **descompón la petición en tareas** y decide qué se puede",
|
|
1364
|
+
"hacer a la vez. opencode ejecuta **en paralelo todas las llamadas `task` que",
|
|
1365
|
+
"emitas en un mismo turno**, así que aprovéchalo:",
|
|
1366
|
+
"",
|
|
1367
|
+
"1. Lista las subtareas y traza sus **dependencias** (qué necesita el output",
|
|
1368
|
+
" de qué). Piensa en un grafo: nodos = tareas, aristas = dependencias.",
|
|
1369
|
+
"2. **Tareas independientes → lánzalas en paralelo**: emite varias llamadas",
|
|
1370
|
+
" `task` en el **mismo mensaje** (una por subagente). Se ejecutan a la vez,",
|
|
1371
|
+
" cada una en su propia subsesión.",
|
|
1372
|
+
"3. **Tareas dependientes → secuéncialas**: espera a que terminen las tareas",
|
|
1373
|
+
" de las que dependen, **sincroniza** sus resultados y solo entonces lanza",
|
|
1374
|
+
" la siguiente ola. Trabaja por olas (topological order): en cada ola,",
|
|
1375
|
+
" paraleliza todo lo que ya no tenga dependencias pendientes.",
|
|
1376
|
+
"4. **No paralelices trabajo que colisione** sobre los mismos ficheros o",
|
|
1377
|
+
" estado: eso son dependencias implícitas; sepáralo en olas distintas para",
|
|
1378
|
+
" evitar conflictos de escritura.",
|
|
1379
|
+
"5. Reparte por **capacidad**: los roles mecánicos/bulk en local, y reserva",
|
|
1380
|
+
" frontier para lo difícil; el paralelismo no cambia el routing de openteam.",
|
|
1381
|
+
"6. El `guardian` sigue siendo el gate previo a frontier **también** en",
|
|
1382
|
+
" paralelo: nada sensible sale sin pasar por él, aunque haya varias olas.",
|
|
1383
|
+
"",
|
|
1384
|
+
"Explica brevemente al usuario tu plan (qué va en paralelo y qué en serie, y",
|
|
1385
|
+
"por qué) antes o mientras lanzas las tareas.",
|
|
1386
|
+
"",
|
|
1276
1387
|
"## Operación",
|
|
1277
1388
|
"",
|
|
1278
1389
|
"- **Empieza siempre comprobando el equipo** (roster + subagentes) antes de",
|
|
1279
1390
|
" delegar; si falta, créalo antes de repartir el trabajo.",
|
|
1280
1391
|
"- Delega el trabajo con la herramienta `task` al subagente adecuado; tú te",
|
|
1281
1392
|
" mantienes como coordinador y no implementas lo que puede hacer un subagente.",
|
|
1393
|
+
"- **Lanza en un solo turno las tareas independientes** para que corran en",
|
|
1394
|
+
" paralelo; secuencia solo las que dependen de un resultado previo.",
|
|
1282
1395
|
"- Crea subagentes **justo cuando el trabajo lo pide**, nunca “por si acaso”.",
|
|
1283
1396
|
" Revisa `.opencode/agent/` y el `roster.md`, y reutiliza los existentes antes",
|
|
1284
1397
|
" de crear uno nuevo.",
|
|
@@ -1425,6 +1538,9 @@ function buildOpencodeConfig(answers) {
|
|
|
1425
1538
|
if (primaryLocal !== undefined) {
|
|
1426
1539
|
config.small_model = `${primaryLocal.id}/${primaryLocal.defaultModelID}`;
|
|
1427
1540
|
}
|
|
1541
|
+
if (answers.yolo) {
|
|
1542
|
+
config.permission = { "*": "allow" };
|
|
1543
|
+
}
|
|
1428
1544
|
return config;
|
|
1429
1545
|
}
|
|
1430
1546
|
function serializeOpencodeConfig(config) {
|
|
@@ -1624,11 +1740,16 @@ async function runInit(deps) {
|
|
|
1624
1740
|
],
|
|
1625
1741
|
initial: "forceLocalOnSensitive"
|
|
1626
1742
|
});
|
|
1743
|
+
const yolo = await prompt.confirm({
|
|
1744
|
+
message: "¿Activar modo YOLO? (opencode auto-aprueba todos los permisos; no afecta a la privacidad de openteam)",
|
|
1745
|
+
initial: false
|
|
1746
|
+
});
|
|
1627
1747
|
const answers = {
|
|
1628
1748
|
runtimes,
|
|
1629
1749
|
frontier,
|
|
1630
1750
|
routerMode,
|
|
1631
|
-
privacyMode
|
|
1751
|
+
privacyMode,
|
|
1752
|
+
yolo
|
|
1632
1753
|
};
|
|
1633
1754
|
const openTeamConfig = buildOpenTeamConfig(answers);
|
|
1634
1755
|
const opencodeConfig = buildOpencodeConfig(answers);
|
|
@@ -1663,6 +1784,7 @@ async function runInit(deps) {
|
|
|
1663
1784
|
prompt.note([
|
|
1664
1785
|
`Baseline frontier: ${frontier.providerID}/${frontier.modelID}`,
|
|
1665
1786
|
`Runtimes locales: ${enabledSummary || "ninguno habilitado"}`,
|
|
1787
|
+
`Modo YOLO: ${yolo ? "activado (auto-aprueba permisos)" : "desactivado"}`,
|
|
1666
1788
|
`Escrito: ${OPENCODE_CONFIG_PATH}, ${DEFAULT_CONFIG_PATH}, ${ORCHESTRATOR_AGENT_PATH}`,
|
|
1667
1789
|
"",
|
|
1668
1790
|
"Siguientes pasos:",
|
|
@@ -1780,6 +1902,22 @@ async function loadConfig(path) {
|
|
|
1780
1902
|
var deps = {
|
|
1781
1903
|
loadConfig,
|
|
1782
1904
|
saveConfig: (config, path) => writeOpenTeamConfigFile(config, path),
|
|
1905
|
+
readOpencodeConfig: async (path) => {
|
|
1906
|
+
try {
|
|
1907
|
+
const content = await readFile2(path, "utf8");
|
|
1908
|
+
return JSON.parse(content);
|
|
1909
|
+
} catch (error) {
|
|
1910
|
+
if (isMissingFile2(error)) {
|
|
1911
|
+
return;
|
|
1912
|
+
}
|
|
1913
|
+
throw error;
|
|
1914
|
+
}
|
|
1915
|
+
},
|
|
1916
|
+
writeOpencodeConfig: async (config, path) => {
|
|
1917
|
+
await mkdir2(dirname2(path), { recursive: true });
|
|
1918
|
+
await writeFile2(path, `${JSON.stringify(config, null, 2)}
|
|
1919
|
+
`, "utf8");
|
|
1920
|
+
},
|
|
1783
1921
|
probe: (config) => {
|
|
1784
1922
|
const registry = new RuntimeRegistry({
|
|
1785
1923
|
fetch: globalThis.fetch,
|
|
@@ -1790,7 +1928,8 @@ var deps = {
|
|
|
1790
1928
|
},
|
|
1791
1929
|
readTelemetry: (path) => readCostRecords(path),
|
|
1792
1930
|
configPath: DEFAULT_CONFIG_PATH,
|
|
1793
|
-
telemetryPath: DEFAULT_TELEMETRY_PATH
|
|
1931
|
+
telemetryPath: DEFAULT_TELEMETRY_PATH,
|
|
1932
|
+
opencodeConfigPath: OPENCODE_CONFIG_PATH
|
|
1794
1933
|
};
|
|
1795
1934
|
function createInitDeps() {
|
|
1796
1935
|
return {
|
|
@@ -6,8 +6,11 @@ export type CliDeps = {
|
|
|
6
6
|
saveConfig: (config: OpenTeamConfig, path: string) => Promise<void>;
|
|
7
7
|
probe: (config: OpenTeamConfig) => Promise<LocalRuntimeSnapshot[]>;
|
|
8
8
|
readTelemetry: (path: string) => Promise<CostRecord[]>;
|
|
9
|
+
readOpencodeConfig: (path: string) => Promise<Record<string, unknown> | undefined>;
|
|
10
|
+
writeOpencodeConfig: (config: Record<string, unknown>, path: string) => Promise<void>;
|
|
9
11
|
configPath: string;
|
|
10
12
|
telemetryPath: string;
|
|
13
|
+
opencodeConfigPath: string;
|
|
11
14
|
};
|
|
12
15
|
export type CliResult = {
|
|
13
16
|
exitCode: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../../src/commands/dispatch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../../src/commands/dispatch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAWrD,MAAM,MAAM,OAAO,GAAG;IACpB,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;IACtD,UAAU,EAAE,CAAC,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpE,KAAK,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAAC;IACnE,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IACvD,kBAAkB,EAAE,CAClB,IAAI,EAAE,MAAM,KACT,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,CAAC;IAClD,mBAAmB,EAAE,CACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,IAAI,EAAE,MAAM,KACT,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAsJF,wBAAsB,MAAM,CAC1B,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,IAAI,EAAE,OAAO,GACZ,OAAO,CAAC,SAAS,CAAC,CAsDpB"}
|
package/dist/commands/init.d.ts
CHANGED
|
@@ -41,6 +41,7 @@ export type InitAnswers = {
|
|
|
41
41
|
frontier: FrontierChoice;
|
|
42
42
|
routerMode: RouterMode;
|
|
43
43
|
privacyMode: PrivacyMode;
|
|
44
|
+
yolo: boolean;
|
|
44
45
|
};
|
|
45
46
|
export type OpencodeProviderConfig = {
|
|
46
47
|
npm: string;
|
|
@@ -58,6 +59,7 @@ export type OpencodeConfig = {
|
|
|
58
59
|
provider?: Record<string, OpencodeProviderConfig>;
|
|
59
60
|
model: string;
|
|
60
61
|
small_model?: string;
|
|
62
|
+
permission?: Record<string, string>;
|
|
61
63
|
};
|
|
62
64
|
/** `true` cuando el modelo no tiene coste de entrada ni de salida (gratis). */
|
|
63
65
|
export declare function isFreeFrontier(profile: ModelCapabilityProfile): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAKpE,OAAO,EAEL,KAAK,cAAc,EAEnB,KAAK,WAAW,EAChB,KAAK,UAAU,EAChB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAM5C,iFAAiF;AACjF,eAAO,MAAM,oBAAoB,4BAA4B,CAAC;AAE9D,2DAA2D;AAC3D,eAAO,MAAM,oBAAoB,kBAAkB,CAAC;AAEpD,MAAM,MAAM,YAAY,GAAG;IACzB,EAAE,EAAE,cAAc,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,SAAS,YAAY,EAmBjD,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,cAAc,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,EAAE,EAAE,cAAc,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,QAAQ,EAAE,cAAc,CAAC;IACzB,UAAU,EAAE,UAAU,CAAC;IACvB,WAAW,EAAE,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orchestratorAgent.d.ts","sourceRoot":"","sources":["../../src/commands/orchestratorAgent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAE7C;;;GAGG;AACH,eAAO,MAAM,uBAAuB,gCAAgC,CAAC;AAErE;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"orchestratorAgent.d.ts","sourceRoot":"","sources":["../../src/commands/orchestratorAgent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAE7C;;;GAGG;AACH,eAAO,MAAM,uBAAuB,gCAAgC,CAAC;AAErE;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,CAsJvE"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Modo YOLO: auto-aprueba todos los permisos de opencode escribiendo la regla
|
|
3
|
+
* global `permission: { "*": "allow" }` en `opencode.json`. Es el equivalente
|
|
4
|
+
* persistente al flag nativo `opencode --auto`, que auto-aprueba todo salvo las
|
|
5
|
+
* reglas `deny` explícitas.
|
|
6
|
+
*
|
|
7
|
+
* Importante: YOLO solo afecta a las **aprobaciones de permisos de opencode**;
|
|
8
|
+
* NO desactiva el routing de privacidad de openteam. Con
|
|
9
|
+
* `privacyMode: "forceLocalOnSensitive"`, los prompts sensibles siguen sin
|
|
10
|
+
* salir a frontier aunque YOLO esté activo.
|
|
11
|
+
*
|
|
12
|
+
* Todas las funciones son puras: operan sobre un objeto de config genérico
|
|
13
|
+
* (`Record<string, unknown>`) para **preservar** cualquier clave que el usuario
|
|
14
|
+
* haya añadido a `opencode.json` (agents, keybinds, etc.). Sin I/O.
|
|
15
|
+
*/
|
|
16
|
+
/** `true` cuando la config tiene la regla global `permission["*"] = "allow"`. */
|
|
17
|
+
export declare function isYoloEnabled(config: Record<string, unknown>): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Devuelve una copia de `config` con YOLO activado o desactivado. Al activar,
|
|
20
|
+
* fija `permission["*"] = "allow"` conservando el resto de reglas. Al
|
|
21
|
+
* desactivar, elimina solo la regla catch-all `allow`; si `permission` queda
|
|
22
|
+
* vacío, elimina la clave. Pure.
|
|
23
|
+
*/
|
|
24
|
+
export declare function applyYolo(config: Record<string, unknown>, enabled: boolean): Record<string, unknown>;
|
|
25
|
+
/** Mensaje legible del estado YOLO actual. Pure. */
|
|
26
|
+
export declare function renderYoloStatus(enabled: boolean): string;
|
|
27
|
+
//# sourceMappingURL=yolo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yolo.d.ts","sourceRoot":"","sources":["../../src/commands/yolo.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAcH,iFAAiF;AACjF,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAGtE;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CACvB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,OAAO,EAAE,OAAO,GACf,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAoBzB;AAED,oDAAoD;AACpD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAIzD"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,EAAuB,MAAM,kBAAkB,CAAC;AAG1E,OAAO,KAAK,EAAE,MAAM,EAAe,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAE7E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAInD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAgBnD,KAAK,gBAAgB,GAAG;IACtB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,UAAU,CAAC;CAChC,CAAC;AAcF,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAGhE;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAGtD;AA0BD,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE,gBAAqB,GAC1B,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAQjC;AAeD,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAOrD;AAED,wBAAgB,aAAa,CAC3B,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,eAAe,EACzB,aAAa,EAAE,MAAM,GACpB,OAAO,CAoCT;AAED,eAAO,MAAM,MAAM,EAAE,MA8BpB,CAAC;AAEF,QAAA,MAAM,MAAM,EAAE,YAGb,CAAC;AAEF,eAAe,MAAM,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
|
-
import { appendFile, mkdir as mkdir2, readFile as readFile2 } from "node:fs/promises";
|
|
2
|
+
import { appendFile, mkdir as mkdir2, readFile as readFile2, writeFile as writeFile2 } from "node:fs/promises";
|
|
3
3
|
import { dirname as dirname2 } from "node:path";
|
|
4
4
|
|
|
5
|
+
// src/config/persist.ts
|
|
6
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
7
|
+
import { dirname } from "node:path";
|
|
8
|
+
|
|
5
9
|
// src/config/schema.ts
|
|
6
10
|
import { z } from "zod";
|
|
7
11
|
var ModelRefSchema = z.object({
|
|
@@ -79,14 +83,7 @@ var OpenTeamConfigSchema = z.object({
|
|
|
79
83
|
privacyMode: PrivacyModeSchema.default("forceLocalOnSensitive")
|
|
80
84
|
});
|
|
81
85
|
|
|
82
|
-
// src/config/load.ts
|
|
83
|
-
function loadOpenTeamConfig(raw) {
|
|
84
|
-
return OpenTeamConfigSchema.parse(raw ?? {});
|
|
85
|
-
}
|
|
86
|
-
|
|
87
86
|
// src/config/persist.ts
|
|
88
|
-
import { mkdir, writeFile } from "node:fs/promises";
|
|
89
|
-
import { dirname } from "node:path";
|
|
90
87
|
var DEFAULT_CONFIG_PATH = ".opencode/openteam.json";
|
|
91
88
|
function serializeOpenTeamConfig(config) {
|
|
92
89
|
const validated = OpenTeamConfigSchema.parse(config);
|
|
@@ -100,6 +97,14 @@ async function writeOpenTeamConfigFile(config, path = DEFAULT_CONFIG_PATH, deps
|
|
|
100
97
|
await writeFileFn(path, serializeOpenTeamConfig(config), "utf8");
|
|
101
98
|
}
|
|
102
99
|
|
|
100
|
+
// src/commands/init.ts
|
|
101
|
+
var OPENCODE_CONFIG_PATH = "opencode.json";
|
|
102
|
+
|
|
103
|
+
// src/config/load.ts
|
|
104
|
+
function loadOpenTeamConfig(raw) {
|
|
105
|
+
return OpenTeamConfigSchema.parse(raw ?? {});
|
|
106
|
+
}
|
|
107
|
+
|
|
103
108
|
// src/local/openai-compatible.ts
|
|
104
109
|
function normalizeBaseURL(baseURL) {
|
|
105
110
|
return baseURL.replace(/\/+$/, "");
|
|
@@ -702,6 +707,42 @@ function renderReport(report) {
|
|
|
702
707
|
`);
|
|
703
708
|
}
|
|
704
709
|
|
|
710
|
+
// src/commands/yolo.ts
|
|
711
|
+
var CATCH_ALL = "*";
|
|
712
|
+
var ALLOW = "allow";
|
|
713
|
+
function asPermissionMap(value) {
|
|
714
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
|
715
|
+
return value;
|
|
716
|
+
}
|
|
717
|
+
return;
|
|
718
|
+
}
|
|
719
|
+
function isYoloEnabled(config) {
|
|
720
|
+
const permission = asPermissionMap(config.permission);
|
|
721
|
+
return permission?.[CATCH_ALL] === ALLOW;
|
|
722
|
+
}
|
|
723
|
+
function applyYolo(config, enabled) {
|
|
724
|
+
const next = { ...config };
|
|
725
|
+
const current = asPermissionMap(config.permission);
|
|
726
|
+
const permission = current ? { ...current } : {};
|
|
727
|
+
if (enabled) {
|
|
728
|
+
permission[CATCH_ALL] = ALLOW;
|
|
729
|
+
next.permission = permission;
|
|
730
|
+
return next;
|
|
731
|
+
}
|
|
732
|
+
if (permission[CATCH_ALL] === ALLOW) {
|
|
733
|
+
delete permission[CATCH_ALL];
|
|
734
|
+
}
|
|
735
|
+
if (Object.keys(permission).length === 0) {
|
|
736
|
+
delete next.permission;
|
|
737
|
+
} else {
|
|
738
|
+
next.permission = permission;
|
|
739
|
+
}
|
|
740
|
+
return next;
|
|
741
|
+
}
|
|
742
|
+
function renderYoloStatus(enabled) {
|
|
743
|
+
return enabled ? "Modo YOLO: ACTIVADO (opencode auto-aprueba todos los permisos)." : "Modo YOLO: desactivado (opencode pide aprobación según sus reglas).";
|
|
744
|
+
}
|
|
745
|
+
|
|
705
746
|
// src/commands/dispatch.ts
|
|
706
747
|
var HELP = [
|
|
707
748
|
"openteam — comandos runtime",
|
|
@@ -713,10 +754,14 @@ var HELP = [
|
|
|
713
754
|
" openteam baseline auto Baseline cheapest-capable (modo auto)",
|
|
714
755
|
" openteam doctor Diagnóstico de runtimes y config",
|
|
715
756
|
" openteam report Resumen de coste/ahorro (telemetría)",
|
|
757
|
+
" openteam yolo status Muestra si el modo YOLO está activo",
|
|
758
|
+
" openteam yolo on Activa YOLO (opencode auto-aprueba todo)",
|
|
759
|
+
" openteam yolo off Desactiva YOLO",
|
|
716
760
|
"",
|
|
717
761
|
"Opciones:",
|
|
718
762
|
" --config <path> Ruta de .opencode/openteam.json",
|
|
719
|
-
" --telemetry <path> Ruta del JSONL de telemetría"
|
|
763
|
+
" --telemetry <path> Ruta del JSONL de telemetría",
|
|
764
|
+
" --opencode <path> Ruta de opencode.json (para el comando yolo)"
|
|
720
765
|
].join(`
|
|
721
766
|
`);
|
|
722
767
|
function parseArgs(argv) {
|
|
@@ -736,6 +781,12 @@ function parseArgs(argv) {
|
|
|
736
781
|
result.telemetryPath = value;
|
|
737
782
|
}
|
|
738
783
|
i += 1;
|
|
784
|
+
} else if (arg === "--opencode") {
|
|
785
|
+
const value = argv[i + 1];
|
|
786
|
+
if (value !== undefined) {
|
|
787
|
+
result.opencodeConfigPath = value;
|
|
788
|
+
}
|
|
789
|
+
i += 1;
|
|
739
790
|
} else if (arg !== undefined) {
|
|
740
791
|
positionals.push(arg);
|
|
741
792
|
}
|
|
@@ -778,15 +829,54 @@ async function runBaseline(positionals, deps, configPath) {
|
|
|
778
829
|
${HELP}`
|
|
779
830
|
};
|
|
780
831
|
}
|
|
832
|
+
async function runYolo(positionals, deps, opencodeConfigPath) {
|
|
833
|
+
const sub = positionals[1] ?? "status";
|
|
834
|
+
if (sub !== "status" && sub !== "on" && sub !== "off") {
|
|
835
|
+
return {
|
|
836
|
+
exitCode: 1,
|
|
837
|
+
stdout: `Subcomando de yolo desconocido: ${sub}
|
|
838
|
+
|
|
839
|
+
${HELP}`
|
|
840
|
+
};
|
|
841
|
+
}
|
|
842
|
+
const config = await deps.readOpencodeConfig(opencodeConfigPath);
|
|
843
|
+
if (config === undefined) {
|
|
844
|
+
return {
|
|
845
|
+
exitCode: 1,
|
|
846
|
+
stdout: `No existe ${opencodeConfigPath}. Ejecuta 'openteam init' primero.`
|
|
847
|
+
};
|
|
848
|
+
}
|
|
849
|
+
if (sub === "status") {
|
|
850
|
+
return { exitCode: 0, stdout: renderYoloStatus(isYoloEnabled(config)) };
|
|
851
|
+
}
|
|
852
|
+
const enable = sub === "on";
|
|
853
|
+
if (isYoloEnabled(config) === enable) {
|
|
854
|
+
return {
|
|
855
|
+
exitCode: 0,
|
|
856
|
+
stdout: `Sin cambios. ${renderYoloStatus(enable)}`
|
|
857
|
+
};
|
|
858
|
+
}
|
|
859
|
+
const next = applyYolo(config, enable);
|
|
860
|
+
await deps.writeOpencodeConfig(next, opencodeConfigPath);
|
|
861
|
+
return {
|
|
862
|
+
exitCode: 0,
|
|
863
|
+
stdout: `${opencodeConfigPath} actualizado. ${renderYoloStatus(enable)}${enable ? `
|
|
864
|
+
Nota: YOLO no desactiva la privacidad de openteam; los prompts sensibles siguen sin salir a frontier con forceLocalOnSensitive.` : ""}`
|
|
865
|
+
};
|
|
866
|
+
}
|
|
781
867
|
async function runCli(argv, deps) {
|
|
782
868
|
const parsed = parseArgs(argv);
|
|
783
869
|
const command = parsed.positionals[0];
|
|
784
870
|
const configPath = parsed.configPath ?? deps.configPath;
|
|
785
871
|
const telemetryPath = parsed.telemetryPath ?? deps.telemetryPath;
|
|
872
|
+
const opencodeConfigPath = parsed.opencodeConfigPath ?? deps.opencodeConfigPath;
|
|
786
873
|
try {
|
|
787
874
|
if (command === "baseline") {
|
|
788
875
|
return await runBaseline(parsed.positionals, deps, configPath);
|
|
789
876
|
}
|
|
877
|
+
if (command === "yolo") {
|
|
878
|
+
return await runYolo(parsed.positionals, deps, opencodeConfigPath);
|
|
879
|
+
}
|
|
790
880
|
if (command === "doctor") {
|
|
791
881
|
const config = await deps.loadConfig(configPath);
|
|
792
882
|
const [snapshots, records] = await Promise.all([
|
|
@@ -1549,10 +1639,26 @@ function createCliDeps(config, registry, telemetryPath) {
|
|
|
1549
1639
|
}
|
|
1550
1640
|
},
|
|
1551
1641
|
saveConfig: (nextConfig, path) => writeOpenTeamConfigFile(nextConfig, path),
|
|
1642
|
+
readOpencodeConfig: async (path) => {
|
|
1643
|
+
try {
|
|
1644
|
+
return JSON.parse(await readFile2(path, "utf8"));
|
|
1645
|
+
} catch (error) {
|
|
1646
|
+
if (isMissingFile2(error)) {
|
|
1647
|
+
return;
|
|
1648
|
+
}
|
|
1649
|
+
throw error;
|
|
1650
|
+
}
|
|
1651
|
+
},
|
|
1652
|
+
writeOpencodeConfig: async (nextConfig, path) => {
|
|
1653
|
+
await mkdir2(dirname2(path), { recursive: true });
|
|
1654
|
+
await writeFile2(path, `${JSON.stringify(nextConfig, null, 2)}
|
|
1655
|
+
`, "utf8");
|
|
1656
|
+
},
|
|
1552
1657
|
probe: (nextConfig) => registry.probe(nextConfig.local.runtimes),
|
|
1553
1658
|
readTelemetry: (path) => readCostRecords(path),
|
|
1554
1659
|
configPath: DEFAULT_CONFIG_PATH,
|
|
1555
|
-
telemetryPath
|
|
1660
|
+
telemetryPath,
|
|
1661
|
+
opencodeConfigPath: OPENCODE_CONFIG_PATH
|
|
1556
1662
|
};
|
|
1557
1663
|
}
|
|
1558
1664
|
var server = async (ctx, rawOptions) => {
|