nexgenk 1.5.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main.mjs +1104 -826
- package/package.json +1 -1
package/dist/main.mjs
CHANGED
|
@@ -47481,6 +47481,14 @@ var init_session$4 = __esmMin((() => {
|
|
|
47481
47481
|
enabled: false
|
|
47482
47482
|
});
|
|
47483
47483
|
}
|
|
47484
|
+
async setWaveMode(enabled) {
|
|
47485
|
+
this.ensureOpen();
|
|
47486
|
+
if (typeof enabled !== "boolean") throw new NexgenError(ErrorCodes$1.REQUEST_INVALID, "Session wave mode must be a boolean");
|
|
47487
|
+
await this.rpc.setWaveMode({
|
|
47488
|
+
sessionId: this.id,
|
|
47489
|
+
enabled
|
|
47490
|
+
});
|
|
47491
|
+
}
|
|
47484
47492
|
async setTowerMode(enabled, base) {
|
|
47485
47493
|
this.ensureOpen();
|
|
47486
47494
|
if (typeof enabled !== "boolean") throw new NexgenError(ErrorCodes$1.REQUEST_INVALID, "Session tower mode must be a boolean");
|
|
@@ -106094,6 +106102,12 @@ var init_statusReader = __esmMin((() => {
|
|
|
106094
106102
|
INBOX_COUNT_LIMIT = 1e3;
|
|
106095
106103
|
RECENT_LOG_LINES = 10;
|
|
106096
106104
|
}));
|
|
106105
|
+
// ../../packages/agent-core-v2/src/features/wave/agent/waveMode.ts
|
|
106106
|
+
var IAgentWaveService;
|
|
106107
|
+
var init_waveMode = __esmMin((() => {
|
|
106108
|
+
init_instantiation();
|
|
106109
|
+
IAgentWaveService = createDecorator("agentWaveService");
|
|
106110
|
+
}));
|
|
106097
106111
|
// ../../packages/agent-core-v2/src/_base/di/descriptors.ts
|
|
106098
106112
|
var SyncDescriptor;
|
|
106099
106113
|
var init_descriptors = __esmMin((() => {
|
|
@@ -125575,17 +125589,18 @@ var init_update_config = __esmMin((() => {
|
|
|
125575
125589
|
};
|
|
125576
125590
|
}));
|
|
125577
125591
|
// ../../packages/agent-core-v2/src/features/wave/wave.ts
|
|
125578
|
-
var WAVE_FLAG_ID, WAVE_FLAG_ENV, WAVE_SEAT_PROFILE, WAVE_TOOL_DOMAIN;
|
|
125592
|
+
var WAVE_FLAG_ID, WAVE_FLAG_ENV, WAVE_SEAT_PROFILE, WAVE_DIRECTOR_PROFILE, WAVE_TOOL_DOMAIN;
|
|
125579
125593
|
var init_wave$3 = __esmMin((() => {
|
|
125580
125594
|
WAVE_FLAG_ID = "wave";
|
|
125581
125595
|
WAVE_FLAG_ENV = "NEXGEN_EXPERIMENTAL_WAVE";
|
|
125582
125596
|
WAVE_SEAT_PROFILE = "wave-seat";
|
|
125597
|
+
WAVE_DIRECTOR_PROFILE = "agent";
|
|
125583
125598
|
WAVE_TOOL_DOMAIN = "wave";
|
|
125584
125599
|
}));
|
|
125585
125600
|
// ../../packages/agent-core-v2/src/features/skill/catalog/builtin/wave.md?raw
|
|
125586
125601
|
var wave_default;
|
|
125587
125602
|
var init_wave$2 = __esmMin((() => {
|
|
125588
|
-
wave_default = "---\nname: wave\ndescription: Run one design wave end to end
|
|
125603
|
+
wave_default = "---\nname: wave\ndescription: Run one design wave end to end as its director — open the wave, contract one agent per seat, then decide, verify and close on the gate. Use when the user enables wave mode and gives an objective for a backlog built with adversarial review instead of a single agent's opinion.\ndisableModelInvocation: true\n---\n\n# Wave (director → asientos → gate)\n\nEl agente principal es el **director**: abre la oleada, contrata asientos y comprueba resultados. **No escribe artefactos.** Cada artefacto lo entrega un asiento `wave-seat` con `WaveSubmit`, que es la única tool que hereda el rol, la ruta y el ticket de su contrato.\n\nUn asiento ve `Read`, `Glob`, `Grep` y `WaveSubmit` — nada más. No tiene gate, ni quórum, ni puede lanzar agentes: si necesita un dato que no tiene, escribe UNKNOWN y lo nombra.\n\n## Qué hace falta antes de empezar\n\n- `workflow.config.json` en la raíz (layout, umbrales, vocabulario, quórum, roles).\n- Un brief real: **siete secciones**, alcance con claves contables, evidencia disponible y rúbrica.\n\nSi falta el config, no hay oleada: pide al usuario que lo cree desde la plantilla. Si el brief tiene menos de siete secciones, `WaveContract` se niega — no lo rodees escribiendo el brief tú.\n\n## El ciclo\n\n1. `WaveOpen({ name })` crea `design/waves/W<n>-<slug>/` con el esqueleto del brief y declara la oleada en el config.\n2. Rellena el brief. Las preguntas de diseño van ahí, no en el prompt de un asiento.\n3. `WaveContract({ wave, round: \"propose\" })` devuelve un contrato por asiento: rol, ruta, ticket y prompt. **Lanza un agente `wave-seat` por contrato** con `Agent` (o `AgentSwarm` si el usuario activó swarm), pasando el prompt tal cual. No lo reescribas: el ticket del prompt es lo que `WaveSubmit` acepta.\n4. `round: \"defend\"` y `round: \"attack\"` en la misma tanda.\n5. `round: \"judge\"`: cada juez devuelve su tabla y su total por propuesta.\n6. `WaveDecide({ wave, verdicts })` con los totales de los jueces: `adopt`, `refine` o `deadlock`. Sin `adopt`, contrata `refine` (R1) y después `audit` (R2).\n7. Aplica los parches de R2 y recompón el backlog (`consolidate` → `backlog`) por script, nunca a mano.\n8. `WaveGate({ wave })`: si sale en rojo, la oleada no está cerrada, por mucho que la prosa diga que sí.\n9. Ejecución: una task por vez; antes de cerrarla, `WaveVerify({ task })` con su `verify` y su mutante.\n\n`WaveContract({ wave, round, report: true })` lista qué asientos ya entregaron y cuáles faltan, sin emitir tickets: úsalo para decidir si relanzas o cierras.\n\n## Reglas que no se negocian\n\n- **Un asiento, un artefacto, un contrato.** El contrato fija rol y ruta; `WaveSubmit` los exige. Un asiento no escribe el artefacto de otro ni toca el backlog, y el director no escribe ninguno.\n- **Aislamiento en la ronda 1.** Un proponente no ve las propuestas de los otros. Si se ven, no son tres propuestas: es una con tres firmas.\n- **Los ataques no puntúan.** Un adversario que dice cuál es mejor está gastando su asiento; su producto son hallazgos con id y una mutación que los demuestra.\n- **Ningún hallazgo entra como párrafo.** Entra como override, task nueva o retirada, aplicado por script. Un defecto que acaba en el acta y no en el backlog no está corregido: está decorado.\n- **Quórum por mediana y por juez.** Un empate en la mediana no corona a nadie. Dos rondas sin quórum se cierran adoptando R1 **con disidencia escrita**, nunca presentándolo como unánime.\n\n## Qué no decir a un asiento\n\nNo le cuentes qué dicen las otras propuestas, no le pidas consenso, no le des el número de hallazgos esperado y no le adelantes qué propuesta quieres que gane. Cualquiera de las cuatro convierte el swarm en teatro.\n\n## Cuándo parar\n\n- Brief que depende de evidencia que no existe: declara `UNKNOWN` con dueño, o trocea la oleada. No se rellena con invención plausible.\n- Gate rojo por causa externa: regístralo como bloqueo con nombre y sigue con lo que no depende de ella. Nunca marques en verde lo que no se ejecutó.\n";
|
|
125589
125604
|
}));
|
|
125590
125605
|
// ../../packages/agent-core-v2/src/features/skill/catalog/builtin/wave.ts
|
|
125591
125606
|
var PSEUDO_PATH$1, parsed$1, WAVE_SKILL;
|
|
@@ -192175,7 +192190,7 @@ var init_host_request_headers = __esmMin((() => {
|
|
|
192175
192190
|
}));
|
|
192176
192191
|
// ../../packages/agent-core-v2/src/human/llm/requester/bases/anthropic/contract.ts
|
|
192177
192192
|
var CONTEXT_MANAGEMENT_BETA;
|
|
192178
|
-
var init_contract$
|
|
192193
|
+
var init_contract$5 = __esmMin((() => {
|
|
192179
192194
|
CONTEXT_MANAGEMENT_BETA = "context-management-2025-06-27";
|
|
192180
192195
|
}));
|
|
192181
192196
|
// ../../packages/agent-core-v2/src/human/llm/syntax-errors.ts
|
|
@@ -192598,7 +192613,7 @@ function nexgenkUnsetCompletionTokens(input) {
|
|
|
192598
192613
|
var NEXGEN_API_KEY_ENV, NEXGEN_BASE_URL_ENV$1, NEXGEN_DEFAULT_BASE_URL, nexgenkEndpoint$1, nexgenkConnection, nexgenkAcceptedImageMimes, nexgenkResponsesTrait, nexgenkOpenAITrait, nexgenkAnthropicTrait;
|
|
192599
192614
|
var init_trait = __esmMin((() => {
|
|
192600
192615
|
init_image_formats();
|
|
192601
|
-
init_contract$
|
|
192616
|
+
init_contract$5();
|
|
192602
192617
|
init_schema$3();
|
|
192603
192618
|
NEXGEN_API_KEY_ENV = "NEXGEN_API_KEY";
|
|
192604
192619
|
NEXGEN_BASE_URL_ENV$1 = "NEXGEN_BASE_URL";
|
|
@@ -196108,7 +196123,7 @@ var init_format$4 = __esmMin((() => {
|
|
|
196108
196123
|
init_syntax_errors();
|
|
196109
196124
|
init_patterns$3();
|
|
196110
196125
|
init_rewrite();
|
|
196111
|
-
init_contract$
|
|
196126
|
+
init_contract$5();
|
|
196112
196127
|
init_lower$3();
|
|
196113
196128
|
init_patterns$2();
|
|
196114
196129
|
init_profile();
|
|
@@ -219258,6 +219273,90 @@ var init_towerService = __esmMin((() => {
|
|
|
219258
219273
|
], AgentTowerService);
|
|
219259
219274
|
registerScopedService("agent", IAgentTowerService, AgentTowerService, 0, "tower");
|
|
219260
219275
|
}));
|
|
219276
|
+
// ../../packages/agent-core-v2/src/features/wave/waveOps.ts
|
|
219277
|
+
var waveModeEnterSchema, WaveModeEnter, waveModeExitSchema, WaveModeExit, waveKey;
|
|
219278
|
+
var init_waveOps = __esmMin((() => {
|
|
219279
|
+
init_zod$1();
|
|
219280
|
+
init_usageEvents();
|
|
219281
|
+
init_event2();
|
|
219282
|
+
init_state$1();
|
|
219283
|
+
waveModeEnterSchema = object$1({ agentId: string() });
|
|
219284
|
+
WaveModeEnter = class extends AgentEvent2 {
|
|
219285
|
+
static type = "wave_mode.enter";
|
|
219286
|
+
static durable = true;
|
|
219287
|
+
static schema = waveModeEnterSchema;
|
|
219288
|
+
};
|
|
219289
|
+
waveModeExitSchema = object$1({ agentId: string() });
|
|
219290
|
+
WaveModeExit = class extends AgentEvent2 {
|
|
219291
|
+
static type = "wave_mode.exit";
|
|
219292
|
+
static durable = true;
|
|
219293
|
+
static schema = waveModeExitSchema;
|
|
219294
|
+
};
|
|
219295
|
+
waveKey = defineState("wave", () => false).replayable({ schema: boolean$1() }).on(WaveModeEnter, (_s, e, ctx) => {
|
|
219296
|
+
ctx.emit(new AgentStatusUpdated({
|
|
219297
|
+
agentId: e.agentId,
|
|
219298
|
+
waveMode: true
|
|
219299
|
+
}));
|
|
219300
|
+
return true;
|
|
219301
|
+
}).on(WaveModeExit, (_s, e, ctx) => {
|
|
219302
|
+
ctx.emit(new AgentStatusUpdated({
|
|
219303
|
+
agentId: e.agentId,
|
|
219304
|
+
waveMode: false
|
|
219305
|
+
}));
|
|
219306
|
+
return false;
|
|
219307
|
+
});
|
|
219308
|
+
}));
|
|
219309
|
+
// ../../packages/agent-core-v2/src/features/wave/agent/waveService.ts
|
|
219310
|
+
var AgentWaveService;
|
|
219311
|
+
var init_waveService = __esmMin((() => {
|
|
219312
|
+
init_lifecycle$2();
|
|
219313
|
+
init_profile$1();
|
|
219314
|
+
init_scopeContext();
|
|
219315
|
+
init_agentState();
|
|
219316
|
+
init_eventBus();
|
|
219317
|
+
init_agentLifecycle();
|
|
219318
|
+
init_eventDispatcher();
|
|
219319
|
+
init_waveOps();
|
|
219320
|
+
init_decorateParam();
|
|
219321
|
+
init_decorate();
|
|
219322
|
+
AgentWaveService = class AgentWaveService extends Disposable {
|
|
219323
|
+
dispatcher;
|
|
219324
|
+
agentCtx;
|
|
219325
|
+
agentState;
|
|
219326
|
+
profile;
|
|
219327
|
+
constructor(dispatcher, agentCtx, agentState, profile, eventBus) {
|
|
219328
|
+
super();
|
|
219329
|
+
this.dispatcher = dispatcher;
|
|
219330
|
+
this.agentCtx = agentCtx;
|
|
219331
|
+
this.agentState = agentState;
|
|
219332
|
+
this.profile = profile;
|
|
219333
|
+
this.agentState.contributeState(waveKey);
|
|
219334
|
+
const republish = () => {
|
|
219335
|
+
if (this.agentCtx.agentId === "main") this.profile.republishStatus();
|
|
219336
|
+
};
|
|
219337
|
+
this._register(eventBus.subscribe(WaveModeEnter, republish));
|
|
219338
|
+
this._register(eventBus.subscribe(WaveModeExit, republish));
|
|
219339
|
+
}
|
|
219340
|
+
async enter() {
|
|
219341
|
+
if (this.agentState.get(waveKey)) return;
|
|
219342
|
+
await this.dispatcher.dispatch(new WaveModeEnter({ agentId: this.agentCtx.agentId }));
|
|
219343
|
+
}
|
|
219344
|
+
async exit() {
|
|
219345
|
+
if (!this.agentState.get(waveKey)) return;
|
|
219346
|
+
await this.dispatcher.dispatch(new WaveModeExit({ agentId: this.agentCtx.agentId }));
|
|
219347
|
+
}
|
|
219348
|
+
get isActive() {
|
|
219349
|
+
return this.agentState.get(waveKey);
|
|
219350
|
+
}
|
|
219351
|
+
};
|
|
219352
|
+
AgentWaveService = __decorate([
|
|
219353
|
+
__decorateParam(0, IEventDispatcher),
|
|
219354
|
+
__decorateParam(1, IAgentScopeContext),
|
|
219355
|
+
__decorateParam(2, IAgentStateService),
|
|
219356
|
+
__decorateParam(3, IAgentProfileService),
|
|
219357
|
+
__decorateParam(4, IEventBus)
|
|
219358
|
+
], AgentWaveService);
|
|
219359
|
+
}));
|
|
219261
219360
|
// ../../packages/agent-core-v2/src/features/wave/seatProfile.ts
|
|
219262
219361
|
var WAVE_SEAT_TOOLS, WAVE_SEAT_ROLE, WAVE_SEAT_PROFILE_DEF;
|
|
219263
219362
|
var init_seatProfile = __esmMin((() => {
|
|
@@ -219279,243 +219378,67 @@ var init_seatProfile = __esmMin((() => {
|
|
|
219279
219378
|
renderSystemPrompt: (context) => renderSystemPromptResult(WAVE_SEAT_ROLE, context, { skillActive: skillActiveFor(WAVE_SEAT_TOOLS) })
|
|
219280
219379
|
});
|
|
219281
219380
|
}));
|
|
219282
|
-
// ../../packages/agent-core-v2/src/features/wave/tools/
|
|
219283
|
-
var
|
|
219284
|
-
var
|
|
219381
|
+
// ../../packages/agent-core-v2/src/features/wave/tools/contract/contract.ts
|
|
219382
|
+
var WAVE_CONTRACT_ROUNDS, WaveContractToolInputSchema, IWaveContractTool;
|
|
219383
|
+
var init_contract$4 = __esmMin((() => {
|
|
219285
219384
|
init_zod$1();
|
|
219286
219385
|
init_instantiation();
|
|
219287
|
-
|
|
219288
|
-
|
|
219289
|
-
|
|
219290
|
-
|
|
219291
|
-
|
|
219292
|
-
|
|
219293
|
-
|
|
219294
|
-
|
|
219295
|
-
|
|
219386
|
+
WAVE_CONTRACT_ROUNDS = [
|
|
219387
|
+
"propose",
|
|
219388
|
+
"defend",
|
|
219389
|
+
"attack",
|
|
219390
|
+
"judge",
|
|
219391
|
+
"refine",
|
|
219392
|
+
"audit"
|
|
219393
|
+
];
|
|
219394
|
+
WaveContractToolInputSchema = object$1({
|
|
219395
|
+
wave: string().min(2),
|
|
219396
|
+
round: _enum(WAVE_CONTRACT_ROUNDS),
|
|
219397
|
+
seats: array(object$1({
|
|
219398
|
+
role: string().min(1).optional(),
|
|
219399
|
+
artifact: string().min(1).optional()
|
|
219400
|
+
}).strict()).optional(),
|
|
219401
|
+
report: boolean$1().optional(),
|
|
219402
|
+
root: string().optional()
|
|
219296
219403
|
}).strict();
|
|
219297
|
-
|
|
219404
|
+
IWaveContractTool = createDecorator("waveContractTool");
|
|
219298
219405
|
}));
|
|
219299
|
-
// ../../packages/agent-core-v2/src/features/wave/core/
|
|
219300
|
-
function
|
|
219301
|
-
|
|
219302
|
-
|
|
219303
|
-
|
|
219304
|
-
|
|
219305
|
-
|
|
219306
|
-
|
|
219307
|
-
|
|
219308
|
-
const refiners = seats("R", roles.refiners);
|
|
219309
|
-
return round === "refine" ? refiners.slice(0, 1) : refiners.slice(1);
|
|
219310
|
-
}
|
|
219311
|
-
function waveConfigState(config) {
|
|
219312
|
-
const state = config;
|
|
219313
|
-
return {
|
|
219314
|
-
...config,
|
|
219315
|
-
version: state.version ?? 1,
|
|
219316
|
-
wavesOpen: state.wavesOpen ?? [],
|
|
219317
|
-
raw: state.raw ?? {}
|
|
219318
|
-
};
|
|
219406
|
+
// ../../packages/agent-core-v2/src/features/wave/core/fsJson.ts
|
|
219407
|
+
function readJson$2(fs, path) {
|
|
219408
|
+
const text = fs.read(path);
|
|
219409
|
+
if (text === void 0) return void 0;
|
|
219410
|
+
try {
|
|
219411
|
+
return JSON.parse(text);
|
|
219412
|
+
} catch {
|
|
219413
|
+
return;
|
|
219414
|
+
}
|
|
219319
219415
|
}
|
|
219320
|
-
function
|
|
219321
|
-
return typeof value === "object" && value !== null && !Array.isArray(value)
|
|
219416
|
+
function isRecord$16(value) {
|
|
219417
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
219322
219418
|
}
|
|
219323
|
-
function
|
|
219324
|
-
return
|
|
219419
|
+
function asRecord$2(value) {
|
|
219420
|
+
return isRecord$16(value) ? value : {};
|
|
219325
219421
|
}
|
|
219326
|
-
function
|
|
219327
|
-
return
|
|
219422
|
+
function asArray$2(value) {
|
|
219423
|
+
return Array.isArray(value) ? value : [];
|
|
219328
219424
|
}
|
|
219329
|
-
function
|
|
219330
|
-
return
|
|
219425
|
+
function asText$1(value) {
|
|
219426
|
+
return typeof value === "string" ? value : "";
|
|
219331
219427
|
}
|
|
219332
|
-
function
|
|
219333
|
-
|
|
219334
|
-
|
|
219335
|
-
const thresholds = record$2(base["thresholds"]);
|
|
219336
|
-
const vocabulary = record$2(base["vocabulary"]);
|
|
219337
|
-
const roles = record$2(base["roles"]);
|
|
219338
|
-
const quorum = record$2(base["quorum"]);
|
|
219339
|
-
return {
|
|
219340
|
-
version: num(base["version"], 1),
|
|
219341
|
-
wavesOpen: strArray$1(base["wavesOpen"], []),
|
|
219342
|
-
raw: base,
|
|
219343
|
-
layout: {
|
|
219344
|
-
waves: text(layout["waves"], DEFAULT_LAYOUT.waves),
|
|
219345
|
-
backlog: text(layout["backlog"], DEFAULT_LAYOUT.backlog),
|
|
219346
|
-
adr: text(layout["adr"], DEFAULT_LAYOUT.adr),
|
|
219347
|
-
inventory: text(layout["inventory"], DEFAULT_LAYOUT.inventory)
|
|
219348
|
-
},
|
|
219349
|
-
waves: strArray$1(base["waves"], ["W0"]),
|
|
219350
|
-
thresholds: {
|
|
219351
|
-
minEpics: num(thresholds["minEpics"], DEFAULT_THRESHOLDS.minEpics),
|
|
219352
|
-
minTasks: num(thresholds["minTasks"], DEFAULT_THRESHOLDS.minTasks),
|
|
219353
|
-
minAcPerTask: num(thresholds["minAcPerTask"], DEFAULT_THRESHOLDS.minAcPerTask),
|
|
219354
|
-
minDecisionBytes: num(thresholds["minDecisionBytes"], DEFAULT_THRESHOLDS.minDecisionBytes),
|
|
219355
|
-
minArtifactBytes: num(thresholds["minArtifactBytes"], DEFAULT_THRESHOLDS.minArtifactBytes),
|
|
219356
|
-
minBriefSections: num(thresholds["minBriefSections"], DEFAULT_THRESHOLDS.minBriefSections),
|
|
219357
|
-
minContextBytes: num(thresholds["minContextBytes"], DEFAULT_THRESHOLDS.minContextBytes),
|
|
219358
|
-
minGoalChars: num(thresholds["minGoalChars"], DEFAULT_THRESHOLDS.minGoalChars),
|
|
219359
|
-
minScopeChars: num(thresholds["minScopeChars"], DEFAULT_THRESHOLDS.minScopeChars),
|
|
219360
|
-
minFieldChars: num(thresholds["minFieldChars"], DEFAULT_THRESHOLDS.minFieldChars),
|
|
219361
|
-
minMetricChars: num(thresholds["minMetricChars"], DEFAULT_THRESHOLDS.minMetricChars)
|
|
219362
|
-
},
|
|
219363
|
-
vocabulary: {
|
|
219364
|
-
areas: strArray$1(vocabulary["areas"], DEFAULT_VOCABULARY.areas),
|
|
219365
|
-
requiredAreas: strArray$1(vocabulary["requiredAreas"], DEFAULT_VOCABULARY.requiredAreas),
|
|
219366
|
-
types: strArray$1(vocabulary["types"], DEFAULT_VOCABULARY.types),
|
|
219367
|
-
estimates: strArray$1(vocabulary["estimates"], DEFAULT_VOCABULARY.estimates),
|
|
219368
|
-
vagueWords: strArray$1(vocabulary["vagueWords"], DEFAULT_VOCABULARY.vagueWords),
|
|
219369
|
-
verifyCommands: strArray$1(vocabulary["verifyCommands"], DEFAULT_VOCABULARY.verifyCommands),
|
|
219370
|
-
verifyPrefixes: strArray$1(vocabulary["verifyPrefixes"], DEFAULT_VOCABULARY.verifyPrefixes)
|
|
219371
|
-
},
|
|
219372
|
-
secrets: strArray$1(base["secrets"], []),
|
|
219373
|
-
roles: {
|
|
219374
|
-
proponents: num(roles["proponents"], DEFAULT_ROLES.proponents),
|
|
219375
|
-
defenders: num(roles["defenders"], DEFAULT_ROLES.defenders),
|
|
219376
|
-
adversaries: num(roles["adversaries"], DEFAULT_ROLES.adversaries),
|
|
219377
|
-
judges: num(roles["judges"], DEFAULT_ROLES.judges),
|
|
219378
|
-
refiners: num(roles["refiners"], DEFAULT_ROLES.refiners)
|
|
219379
|
-
},
|
|
219380
|
-
quorum: {
|
|
219381
|
-
minPoints: num(quorum["minPoints"], DEFAULT_QUORUM.minPoints),
|
|
219382
|
-
minAxes: num(quorum["minAxes"], DEFAULT_QUORUM.minAxes),
|
|
219383
|
-
axes: strArray$1(quorum["axes"], DEFAULT_QUORUM.axes)
|
|
219384
|
-
},
|
|
219385
|
-
loadedFrom
|
|
219386
|
-
};
|
|
219428
|
+
function writeJson(_fs, path, value) {
|
|
219429
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
219430
|
+
writeFileSync(path, `${JSON.stringify(value, null, 2)}\n`);
|
|
219387
219431
|
}
|
|
219388
|
-
function
|
|
219389
|
-
|
|
219390
|
-
const
|
|
219391
|
-
|
|
219392
|
-
|
|
219393
|
-
|
|
219394
|
-
} catch {
|
|
219395
|
-
return;
|
|
219432
|
+
function walk$1(fs, dir, accept, acc = []) {
|
|
219433
|
+
if (!fs.isDirectory(dir)) return acc;
|
|
219434
|
+
for (const name of fs.list(dir)) {
|
|
219435
|
+
const full = join(dir, name);
|
|
219436
|
+
if (fs.isDirectory(full)) walk$1(fs, full, accept, acc);
|
|
219437
|
+
else if (accept(full)) acc.push(full);
|
|
219396
219438
|
}
|
|
219439
|
+
return acc;
|
|
219397
219440
|
}
|
|
219398
|
-
|
|
219399
|
-
const resolvedRoot = resolve(root);
|
|
219400
|
-
const resolved = isAbsolute(candidate) ? resolve(candidate) : resolve(resolvedRoot, candidate);
|
|
219401
|
-
if (resolved !== resolvedRoot && !resolved.startsWith(`${resolvedRoot}${sep}`)) throw new Error(`ruta fuera del workspace: ${candidate}`);
|
|
219402
|
-
return resolved;
|
|
219403
|
-
}
|
|
219404
|
-
var WAVE_ROUNDS, WAVE_ROUND_DIRS, DEFAULT_LAYOUT, DEFAULT_THRESHOLDS, DEFAULT_VOCABULARY, DEFAULT_ROLES, DEFAULT_QUORUM;
|
|
219405
|
-
var init_config$6 = __esmMin((() => {
|
|
219406
|
-
WAVE_ROUNDS = [
|
|
219407
|
-
"propose",
|
|
219408
|
-
"defend",
|
|
219409
|
-
"attack",
|
|
219410
|
-
"judge",
|
|
219411
|
-
"refine",
|
|
219412
|
-
"audit"
|
|
219413
|
-
];
|
|
219414
|
-
WAVE_ROUND_DIRS = {
|
|
219415
|
-
propose: "01-proposals",
|
|
219416
|
-
defend: "02-defenses",
|
|
219417
|
-
attack: "03-attacks",
|
|
219418
|
-
judge: "04-verdicts",
|
|
219419
|
-
refine: "05-refined",
|
|
219420
|
-
audit: "05-refined"
|
|
219421
|
-
};
|
|
219422
|
-
DEFAULT_LAYOUT = {
|
|
219423
|
-
waves: "design/waves",
|
|
219424
|
-
backlog: "backlog",
|
|
219425
|
-
adr: "design/ADR",
|
|
219426
|
-
inventory: "inventory"
|
|
219427
|
-
};
|
|
219428
|
-
DEFAULT_THRESHOLDS = {
|
|
219429
|
-
minEpics: 1,
|
|
219430
|
-
minTasks: 1,
|
|
219431
|
-
minAcPerTask: 2,
|
|
219432
|
-
minDecisionBytes: 200,
|
|
219433
|
-
minArtifactBytes: 100,
|
|
219434
|
-
minBriefSections: 7,
|
|
219435
|
-
minContextBytes: 80,
|
|
219436
|
-
minGoalChars: 40,
|
|
219437
|
-
minScopeChars: 40,
|
|
219438
|
-
minFieldChars: 10,
|
|
219439
|
-
minMetricChars: 4
|
|
219440
|
-
};
|
|
219441
|
-
DEFAULT_VOCABULARY = {
|
|
219442
|
-
areas: [
|
|
219443
|
-
"cliente",
|
|
219444
|
-
"seller",
|
|
219445
|
-
"agent",
|
|
219446
|
-
"admin",
|
|
219447
|
-
"plataforma"
|
|
219448
|
-
],
|
|
219449
|
-
requiredAreas: [],
|
|
219450
|
-
types: [
|
|
219451
|
-
"db",
|
|
219452
|
-
"api",
|
|
219453
|
-
"ui",
|
|
219454
|
-
"domain",
|
|
219455
|
-
"infra",
|
|
219456
|
-
"test",
|
|
219457
|
-
"docs",
|
|
219458
|
-
"app",
|
|
219459
|
-
"contract",
|
|
219460
|
-
"ops",
|
|
219461
|
-
"tooling"
|
|
219462
|
-
],
|
|
219463
|
-
estimates: [
|
|
219464
|
-
"XS",
|
|
219465
|
-
"S",
|
|
219466
|
-
"M",
|
|
219467
|
-
"L",
|
|
219468
|
-
"XL"
|
|
219469
|
-
],
|
|
219470
|
-
vagueWords: [
|
|
219471
|
-
"funciona",
|
|
219472
|
-
"correcto",
|
|
219473
|
-
"adecuado",
|
|
219474
|
-
"rapido",
|
|
219475
|
-
"robusto",
|
|
219476
|
-
"bonito"
|
|
219477
|
-
],
|
|
219478
|
-
verifyCommands: [
|
|
219479
|
-
"pnpm",
|
|
219480
|
-
"npm",
|
|
219481
|
-
"node",
|
|
219482
|
-
"bash",
|
|
219483
|
-
"sh",
|
|
219484
|
-
"make",
|
|
219485
|
-
"python",
|
|
219486
|
-
"go",
|
|
219487
|
-
"cargo",
|
|
219488
|
-
"dotnet"
|
|
219489
|
-
],
|
|
219490
|
-
verifyPrefixes: [
|
|
219491
|
-
"test/unit/",
|
|
219492
|
-
"test/db/",
|
|
219493
|
-
"test/domain/",
|
|
219494
|
-
"test/api/",
|
|
219495
|
-
"test/perf/",
|
|
219496
|
-
"e2e/",
|
|
219497
|
-
"scripts/checks/"
|
|
219498
|
-
]
|
|
219499
|
-
};
|
|
219500
|
-
DEFAULT_ROLES = {
|
|
219501
|
-
proponents: 3,
|
|
219502
|
-
defenders: 3,
|
|
219503
|
-
adversaries: 3,
|
|
219504
|
-
judges: 3,
|
|
219505
|
-
refiners: 2
|
|
219506
|
-
};
|
|
219507
|
-
DEFAULT_QUORUM = {
|
|
219508
|
-
minPoints: 1,
|
|
219509
|
-
minAxes: 2,
|
|
219510
|
-
axes: [
|
|
219511
|
-
"cobertura",
|
|
219512
|
-
"falsabilidad",
|
|
219513
|
-
"riesgo",
|
|
219514
|
-
"coste",
|
|
219515
|
-
"encaje"
|
|
219516
|
-
]
|
|
219517
|
-
};
|
|
219518
|
-
}));
|
|
219441
|
+
var init_fsJson = __esmMin((() => {}));
|
|
219519
219442
|
// ../../packages/agent-core-v2/src/features/wave/core/nodeFs.ts
|
|
219520
219443
|
var nodeWaveFs;
|
|
219521
219444
|
var init_nodeFs = __esmMin((() => {
|
|
@@ -219557,477 +219480,353 @@ var init_nodeFs = __esmMin((() => {
|
|
|
219557
219480
|
}
|
|
219558
219481
|
};
|
|
219559
219482
|
}));
|
|
219560
|
-
// ../../packages/agent-core-v2/src/features/wave/core/
|
|
219561
|
-
function
|
|
219562
|
-
|
|
219563
|
-
const middle = Math.floor(sorted.length / 2);
|
|
219564
|
-
const current = sorted[middle];
|
|
219565
|
-
if (current === void 0) throw new Error("no se puede calcular una mediana sin valores");
|
|
219566
|
-
if (sorted.length % 2 === 1) return current;
|
|
219567
|
-
const previous = sorted[middle - 1];
|
|
219568
|
-
if (previous === void 0) throw new Error("no se puede calcular una mediana sin valores");
|
|
219569
|
-
return (previous + current) / 2;
|
|
219483
|
+
// ../../packages/agent-core-v2/src/features/wave/core/config.ts
|
|
219484
|
+
function seats(prefix, count) {
|
|
219485
|
+
return Array.from({ length: Math.max(0, count) }, (_, index) => `${prefix}${index + 1}`);
|
|
219570
219486
|
}
|
|
219571
|
-
function
|
|
219572
|
-
if (
|
|
219573
|
-
|
|
219574
|
-
if (
|
|
219575
|
-
|
|
219576
|
-
|
|
219577
|
-
|
|
219578
|
-
const keys = Object.keys(verdict.scores).toSorted();
|
|
219579
|
-
if (keys.length !== proposals.length || keys.some((key, index) => key !== proposals[index])) throw new Error(`el juez ${verdict.judge} no puntua el mismo conjunto de propuestas`);
|
|
219580
|
-
for (const proposal of proposals) {
|
|
219581
|
-
const score = verdict.scores[proposal];
|
|
219582
|
-
if (typeof score !== "number" || !Number.isFinite(score) || score < 0) throw new Error(`puntuacion invalida de ${verdict.judge} para ${proposal}`);
|
|
219583
|
-
}
|
|
219584
|
-
}
|
|
219585
|
-
return proposals;
|
|
219487
|
+
function waveRoundSeats(roles, round) {
|
|
219488
|
+
if (round === "propose") return seats("P", roles.proponents);
|
|
219489
|
+
if (round === "defend") return seats("D", roles.defenders);
|
|
219490
|
+
if (round === "attack") return seats("A", roles.adversaries);
|
|
219491
|
+
if (round === "judge") return seats("J", roles.judges);
|
|
219492
|
+
const refiners = seats("R", roles.refiners);
|
|
219493
|
+
return round === "refine" ? refiners.slice(0, 1) : refiners.slice(1);
|
|
219586
219494
|
}
|
|
219587
|
-
function
|
|
219588
|
-
const
|
|
219589
|
-
const minPoints = input.minPoints;
|
|
219590
|
-
const minAxes = Math.max(1, Math.floor(input.minAxes));
|
|
219591
|
-
const round = input.round ?? 0;
|
|
219592
|
-
const medians = {};
|
|
219593
|
-
for (const proposal of proposals) medians[proposal] = median(input.verdicts.map((verdict) => verdict.scores[proposal] ?? 0));
|
|
219594
|
-
const ranked = [...proposals].toSorted((left, right) => {
|
|
219595
|
-
const delta = (medians[right] ?? 0) - (medians[left] ?? 0);
|
|
219596
|
-
return delta === 0 ? left.localeCompare(right) : delta;
|
|
219597
|
-
});
|
|
219598
|
-
const winner = ranked[0];
|
|
219599
|
-
const second = ranked[1];
|
|
219600
|
-
if (winner === void 0) throw new Error("no hay propuestas que comparar");
|
|
219601
|
-
if (second === void 0) return {
|
|
219602
|
-
verdict: "refine",
|
|
219603
|
-
winner,
|
|
219604
|
-
second: void 0,
|
|
219605
|
-
medians,
|
|
219606
|
-
medianMargin: 0,
|
|
219607
|
-
judgesHoldingMargin: 0,
|
|
219608
|
-
perJudge: [],
|
|
219609
|
-
reason: `sin comparacion no hay quorum: solo hay una propuesta (${winner})`
|
|
219610
|
-
};
|
|
219611
|
-
const winnerMedian = medians[winner] ?? 0;
|
|
219612
|
-
const secondMedian = medians[second] ?? 0;
|
|
219613
|
-
const medianMargin = Number((winnerMedian - secondMedian).toFixed(6));
|
|
219614
|
-
if (medianMargin === 0) return {
|
|
219615
|
-
verdict: round >= 2 ? "deadlock" : "refine",
|
|
219616
|
-
winner: void 0,
|
|
219617
|
-
second,
|
|
219618
|
-
medians,
|
|
219619
|
-
medianMargin,
|
|
219620
|
-
judgesHoldingMargin: 0,
|
|
219621
|
-
perJudge: [],
|
|
219622
|
-
reason: `empate en la mediana entre ${winner} y ${second}: no hay ganador`
|
|
219623
|
-
};
|
|
219624
|
-
const perJudge = input.verdicts.map((verdict) => {
|
|
219625
|
-
const margin = (verdict.scores[winner] ?? 0) - (verdict.scores[second] ?? 0);
|
|
219626
|
-
return {
|
|
219627
|
-
judge: verdict.judge,
|
|
219628
|
-
margin,
|
|
219629
|
-
holds: margin >= minPoints
|
|
219630
|
-
};
|
|
219631
|
-
});
|
|
219632
|
-
const judgesHoldingMargin = perJudge.filter((entry) => entry.holds).length;
|
|
219633
|
-
const marginOk = medianMargin >= minPoints;
|
|
219634
|
-
const majorityOk = judgesHoldingMargin >= minAxes;
|
|
219635
|
-
if (marginOk && majorityOk) return {
|
|
219636
|
-
verdict: "adopt",
|
|
219637
|
-
winner,
|
|
219638
|
-
second,
|
|
219639
|
-
medians,
|
|
219640
|
-
medianMargin,
|
|
219641
|
-
judgesHoldingMargin,
|
|
219642
|
-
perJudge,
|
|
219643
|
-
reason: `mediana ${winner} ${winnerMedian} vs ${second} ${secondMedian}: margen ${medianMargin} en ${judgesHoldingMargin}/${perJudge.length} jueces`
|
|
219644
|
-
};
|
|
219645
|
-
const reason = [marginOk ? void 0 : `margen ${medianMargin} < ${minPoints}`, majorityOk ? void 0 : `solo ${judgesHoldingMargin}/${perJudge.length} jueces superan el margen (minimo ${minAxes})`].filter((part) => part !== void 0).join(" y ");
|
|
219495
|
+
function waveConfigState(config) {
|
|
219496
|
+
const state = config;
|
|
219646
219497
|
return {
|
|
219647
|
-
|
|
219648
|
-
|
|
219649
|
-
|
|
219650
|
-
|
|
219651
|
-
medianMargin,
|
|
219652
|
-
judgesHoldingMargin,
|
|
219653
|
-
perJudge,
|
|
219654
|
-
reason: `${reason}: sin quorum`
|
|
219498
|
+
...config,
|
|
219499
|
+
version: state.version ?? 1,
|
|
219500
|
+
wavesOpen: state.wavesOpen ?? [],
|
|
219501
|
+
raw: state.raw ?? {}
|
|
219655
219502
|
};
|
|
219656
219503
|
}
|
|
219657
|
-
|
|
219658
|
-
|
|
219659
|
-
|
|
219660
|
-
|
|
219661
|
-
|
|
219662
|
-
|
|
219663
|
-
|
|
219664
|
-
|
|
219665
|
-
|
|
219666
|
-
|
|
219667
|
-
|
|
219668
|
-
|
|
219669
|
-
|
|
219670
|
-
|
|
219671
|
-
|
|
219672
|
-
|
|
219673
|
-
|
|
219674
|
-
|
|
219675
|
-
|
|
219676
|
-
output: `veredictos invalidos: ${error instanceof Error ? error.message : String(error)}`,
|
|
219677
|
-
isError: true
|
|
219678
|
-
};
|
|
219679
|
-
}
|
|
219680
|
-
const holding = result.perJudge.length === 0 ? "sin comparacion" : `${result.judgesHoldingMargin}/${result.perJudge.length}`;
|
|
219681
|
-
const lines = [
|
|
219682
|
-
`QUORUM — ${result.verdict}`,
|
|
219683
|
-
"",
|
|
219684
|
-
...Object.entries(result.medians).map(([proposal, value]) => ` mediana ${proposal}: ${value}`),
|
|
219685
|
-
"",
|
|
219686
|
-
` ganador: ${result.winner ?? "(empate)"}`,
|
|
219687
|
-
` margen: ${result.medianMargin} (minimo ${input.minPoints ?? config.quorum.minPoints})`,
|
|
219688
|
-
` jueces con margen: ${holding} (minimo ${input.minAxes ?? config.quorum.minAxes})`,
|
|
219689
|
-
...result.perJudge.map((entry) => ` ${entry.judge}: ${entry.margin}${entry.holds ? " ok" : " NO"}`),
|
|
219690
|
-
...result.perJudge.filter((entry) => entry.margin < 0).map((entry) => ` disidencia: ${entry.judge} ${entry.margin}`),
|
|
219691
|
-
"",
|
|
219692
|
-
` motivo: ${result.reason}`
|
|
219693
|
-
];
|
|
219694
|
-
if (result.verdict === "deadlock") lines.push("", " dos rondas sin quorum: adopta R1 con disidencia escrita, nunca la presentes como unanime");
|
|
219504
|
+
function record$2(value) {
|
|
219505
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : {};
|
|
219506
|
+
}
|
|
219507
|
+
function num(value, fallback) {
|
|
219508
|
+
return typeof value === "number" && Number.isFinite(value) ? value : fallback;
|
|
219509
|
+
}
|
|
219510
|
+
function text(value, fallback) {
|
|
219511
|
+
return typeof value === "string" ? value : fallback;
|
|
219512
|
+
}
|
|
219513
|
+
function strArray$1(value, fallback) {
|
|
219514
|
+
return Array.isArray(value) && value.every((item) => typeof item === "string") ? value : fallback;
|
|
219515
|
+
}
|
|
219516
|
+
function makeWaveConfig(raw, loadedFrom) {
|
|
219517
|
+
const base = record$2(raw);
|
|
219518
|
+
const layout = record$2(base["layout"]);
|
|
219519
|
+
const thresholds = record$2(base["thresholds"]);
|
|
219520
|
+
const vocabulary = record$2(base["vocabulary"]);
|
|
219521
|
+
const roles = record$2(base["roles"]);
|
|
219522
|
+
const quorum = record$2(base["quorum"]);
|
|
219695
219523
|
return {
|
|
219696
|
-
|
|
219697
|
-
|
|
219524
|
+
version: num(base["version"], 1),
|
|
219525
|
+
wavesOpen: strArray$1(base["wavesOpen"], []),
|
|
219526
|
+
raw: base,
|
|
219527
|
+
layout: {
|
|
219528
|
+
waves: text(layout["waves"], DEFAULT_LAYOUT.waves),
|
|
219529
|
+
backlog: text(layout["backlog"], DEFAULT_LAYOUT.backlog),
|
|
219530
|
+
adr: text(layout["adr"], DEFAULT_LAYOUT.adr),
|
|
219531
|
+
inventory: text(layout["inventory"], DEFAULT_LAYOUT.inventory)
|
|
219532
|
+
},
|
|
219533
|
+
waves: strArray$1(base["waves"], ["W0"]),
|
|
219534
|
+
thresholds: {
|
|
219535
|
+
minEpics: num(thresholds["minEpics"], DEFAULT_THRESHOLDS.minEpics),
|
|
219536
|
+
minTasks: num(thresholds["minTasks"], DEFAULT_THRESHOLDS.minTasks),
|
|
219537
|
+
minAcPerTask: num(thresholds["minAcPerTask"], DEFAULT_THRESHOLDS.minAcPerTask),
|
|
219538
|
+
minDecisionBytes: num(thresholds["minDecisionBytes"], DEFAULT_THRESHOLDS.minDecisionBytes),
|
|
219539
|
+
minArtifactBytes: num(thresholds["minArtifactBytes"], DEFAULT_THRESHOLDS.minArtifactBytes),
|
|
219540
|
+
minBriefSections: num(thresholds["minBriefSections"], DEFAULT_THRESHOLDS.minBriefSections),
|
|
219541
|
+
minContextBytes: num(thresholds["minContextBytes"], DEFAULT_THRESHOLDS.minContextBytes),
|
|
219542
|
+
minGoalChars: num(thresholds["minGoalChars"], DEFAULT_THRESHOLDS.minGoalChars),
|
|
219543
|
+
minScopeChars: num(thresholds["minScopeChars"], DEFAULT_THRESHOLDS.minScopeChars),
|
|
219544
|
+
minFieldChars: num(thresholds["minFieldChars"], DEFAULT_THRESHOLDS.minFieldChars),
|
|
219545
|
+
minMetricChars: num(thresholds["minMetricChars"], DEFAULT_THRESHOLDS.minMetricChars)
|
|
219546
|
+
},
|
|
219547
|
+
vocabulary: {
|
|
219548
|
+
areas: strArray$1(vocabulary["areas"], DEFAULT_VOCABULARY.areas),
|
|
219549
|
+
requiredAreas: strArray$1(vocabulary["requiredAreas"], DEFAULT_VOCABULARY.requiredAreas),
|
|
219550
|
+
types: strArray$1(vocabulary["types"], DEFAULT_VOCABULARY.types),
|
|
219551
|
+
estimates: strArray$1(vocabulary["estimates"], DEFAULT_VOCABULARY.estimates),
|
|
219552
|
+
vagueWords: strArray$1(vocabulary["vagueWords"], DEFAULT_VOCABULARY.vagueWords),
|
|
219553
|
+
verifyCommands: strArray$1(vocabulary["verifyCommands"], DEFAULT_VOCABULARY.verifyCommands),
|
|
219554
|
+
verifyPrefixes: strArray$1(vocabulary["verifyPrefixes"], DEFAULT_VOCABULARY.verifyPrefixes)
|
|
219555
|
+
},
|
|
219556
|
+
secrets: strArray$1(base["secrets"], []),
|
|
219557
|
+
roles: {
|
|
219558
|
+
proponents: num(roles["proponents"], DEFAULT_ROLES.proponents),
|
|
219559
|
+
defenders: num(roles["defenders"], DEFAULT_ROLES.defenders),
|
|
219560
|
+
adversaries: num(roles["adversaries"], DEFAULT_ROLES.adversaries),
|
|
219561
|
+
judges: num(roles["judges"], DEFAULT_ROLES.judges),
|
|
219562
|
+
refiners: num(roles["refiners"], DEFAULT_ROLES.refiners)
|
|
219563
|
+
},
|
|
219564
|
+
quorum: {
|
|
219565
|
+
minPoints: num(quorum["minPoints"], DEFAULT_QUORUM.minPoints),
|
|
219566
|
+
minAxes: num(quorum["minAxes"], DEFAULT_QUORUM.minAxes),
|
|
219567
|
+
axes: strArray$1(quorum["axes"], DEFAULT_QUORUM.axes)
|
|
219568
|
+
},
|
|
219569
|
+
loadedFrom
|
|
219698
219570
|
};
|
|
219699
219571
|
}
|
|
219700
|
-
|
|
219701
|
-
|
|
219702
|
-
|
|
219703
|
-
|
|
219704
|
-
}));
|
|
219705
|
-
// ../../packages/agent-core-v2/src/features/wave/tools/decide/decide.md?raw
|
|
219706
|
-
var decide_default;
|
|
219707
|
-
var init_decide = __esmMin((() => {
|
|
219708
|
-
decide_default = "Compute the wave quorum from the judges' totals and say what may happen next.\n\nPass one entry per judge with its totals per proposal (`{ judge: \"J1\", scores: { P1: 17, P2: 15, P3: 14 } }`). The tool takes the **median** per proposal and applies both conditions of `core/quorum.ts`: the winner's median must beat the second's by `minPoints` (**margen de medianas**), and at least `minAxes` judges must give the winner that margin or more over the second (**mayoría de jueces**). Thresholds default to `workflow.config.json`.\n\nAnswers `adopt`, `refine` (no quorum yet, compose R1 and audit with R2) or `deadlock` (two rounds without quorum: adopt R1 with written dissent). A tie in the median, or a single proposal with nothing to compare, never crowns a winner and never counts as quorum.\n";
|
|
219709
|
-
}));
|
|
219710
|
-
// ../../packages/agent-core-v2/src/features/wave/tools/decide/decideTool.ts
|
|
219711
|
-
var WaveDecideTool;
|
|
219712
|
-
var init_decideTool = __esmMin((() => {
|
|
219713
|
-
init_sessionContext();
|
|
219714
|
-
init_input_schema();
|
|
219715
|
-
init_decide$1();
|
|
219716
|
-
init_decideRunner();
|
|
219717
|
-
init_decide();
|
|
219718
|
-
init_decorateParam();
|
|
219719
|
-
init_decorate();
|
|
219720
|
-
WaveDecideTool = class WaveDecideTool {
|
|
219721
|
-
sessionContext;
|
|
219722
|
-
name = "WaveDecide";
|
|
219723
|
-
description = decide_default;
|
|
219724
|
-
parameters = toInputJsonSchema(WaveDecideToolInputSchema);
|
|
219725
|
-
constructor(sessionContext) {
|
|
219726
|
-
this.sessionContext = sessionContext;
|
|
219727
|
-
}
|
|
219728
|
-
resolveExecution(args) {
|
|
219729
|
-
return {
|
|
219730
|
-
description: "Computing the wave quorum",
|
|
219731
|
-
approvalRule: this.name,
|
|
219732
|
-
execute: () => Promise.resolve(runWaveDecideForRoot({
|
|
219733
|
-
root: args.root ?? this.sessionContext.cwd,
|
|
219734
|
-
verdicts: args.verdicts,
|
|
219735
|
-
minPoints: args.minPoints,
|
|
219736
|
-
minAxes: args.minAxes,
|
|
219737
|
-
round: args.round
|
|
219738
|
-
}))
|
|
219739
|
-
};
|
|
219740
|
-
}
|
|
219741
|
-
};
|
|
219742
|
-
WaveDecideTool = __decorate([__decorateParam(0, ISessionContext)], WaveDecideTool);
|
|
219743
|
-
}));
|
|
219744
|
-
// ../../packages/agent-core-v2/src/features/wave/tools/gate/gate.ts
|
|
219745
|
-
var WaveGateToolInputSchema, IWaveGateTool;
|
|
219746
|
-
var init_gate$1 = __esmMin((() => {
|
|
219747
|
-
init_zod$1();
|
|
219748
|
-
init_instantiation();
|
|
219749
|
-
WaveGateToolInputSchema = object$1({
|
|
219750
|
-
root: string().optional(),
|
|
219751
|
-
json: boolean$1().optional()
|
|
219752
|
-
}).strict();
|
|
219753
|
-
IWaveGateTool = createDecorator("waveGateTool");
|
|
219754
|
-
}));
|
|
219755
|
-
// ../../packages/agent-core-v2/src/features/wave/tools/open/open.ts
|
|
219756
|
-
var WaveOpenToolInputSchema, IWaveOpenTool;
|
|
219757
|
-
var init_open$1 = __esmMin((() => {
|
|
219758
|
-
init_zod$1();
|
|
219759
|
-
init_instantiation();
|
|
219760
|
-
WaveOpenToolInputSchema = object$1({
|
|
219761
|
-
name: string().min(2),
|
|
219762
|
-
id: string().optional(),
|
|
219763
|
-
root: string().optional()
|
|
219764
|
-
}).strict();
|
|
219765
|
-
IWaveOpenTool = createDecorator("waveOpenTool");
|
|
219766
|
-
}));
|
|
219767
|
-
// ../../packages/agent-core-v2/src/features/wave/core/fsJson.ts
|
|
219768
|
-
function readJson$2(fs, path) {
|
|
219769
|
-
const text = fs.read(path);
|
|
219770
|
-
if (text === void 0) return void 0;
|
|
219572
|
+
function readWaveConfig(fs, root) {
|
|
219573
|
+
const file = resolve(root, "workflow.config.json");
|
|
219574
|
+
const raw = fs.read(file);
|
|
219575
|
+
if (raw === void 0) return void 0;
|
|
219771
219576
|
try {
|
|
219772
|
-
return JSON.parse(
|
|
219577
|
+
return makeWaveConfig(JSON.parse(raw), file);
|
|
219773
219578
|
} catch {
|
|
219774
219579
|
return;
|
|
219775
219580
|
}
|
|
219776
219581
|
}
|
|
219777
|
-
function
|
|
219778
|
-
|
|
219779
|
-
|
|
219780
|
-
|
|
219781
|
-
return
|
|
219782
|
-
}
|
|
219783
|
-
function asArray$2(value) {
|
|
219784
|
-
return Array.isArray(value) ? value : [];
|
|
219785
|
-
}
|
|
219786
|
-
function asText$1(value) {
|
|
219787
|
-
return typeof value === "string" ? value : "";
|
|
219788
|
-
}
|
|
219789
|
-
function writeJson(_fs, path, value) {
|
|
219790
|
-
mkdirSync(dirname(path), { recursive: true });
|
|
219791
|
-
writeFileSync(path, `${JSON.stringify(value, null, 2)}\n`);
|
|
219792
|
-
}
|
|
219793
|
-
function walk$1(fs, dir, accept, acc = []) {
|
|
219794
|
-
if (!fs.isDirectory(dir)) return acc;
|
|
219795
|
-
for (const name of fs.list(dir)) {
|
|
219796
|
-
const full = join(dir, name);
|
|
219797
|
-
if (fs.isDirectory(full)) walk$1(fs, full, accept, acc);
|
|
219798
|
-
else if (accept(full)) acc.push(full);
|
|
219799
|
-
}
|
|
219800
|
-
return acc;
|
|
219801
|
-
}
|
|
219802
|
-
var init_fsJson = __esmMin((() => {}));
|
|
219803
|
-
// ../../packages/agent-core-v2/src/features/wave/tools/open/openRunner.ts
|
|
219804
|
-
function briefTemplate(root) {
|
|
219805
|
-
const fs = nodeWaveFs;
|
|
219806
|
-
const local = join(root, BRIEF_TEMPLATE$1);
|
|
219807
|
-
if (fs.exists(local)) return { file: local };
|
|
219808
|
-
if (fs.isDirectory(join(root, "workflow"))) return { missing: BRIEF_TEMPLATE$1 };
|
|
219809
|
-
return fs.exists(BUNDLED_BRIEF_TEMPLATE) ? { file: BUNDLED_BRIEF_TEMPLATE } : { missing: BRIEF_TEMPLATE$1 };
|
|
219810
|
-
}
|
|
219811
|
-
function nextEpic(backlogDir) {
|
|
219812
|
-
const numbers = asArray$2(asRecord$2(readJson$2(nodeWaveFs, join(backlogDir, "epics.json")) ?? {})["epics"]).map((epic) => /^E(\d{2,})$/.exec(String(asRecord$2(epic)["id"]))?.[1]).filter((value) => value !== void 0).map(Number);
|
|
219813
|
-
const next = numbers.length > 0 ? Math.max(...numbers) + 1 : 1;
|
|
219814
|
-
return `E${String(next).padStart(2, "0")}`;
|
|
219815
|
-
}
|
|
219816
|
-
function slugify(name) {
|
|
219817
|
-
return name.normalize("NFD").replaceAll(/[\u0300-\u036F]/g, "").toLowerCase().replaceAll(/[^a-z0-9-]+/g, "-").replaceAll(/^-+|-+$/g, "");
|
|
219582
|
+
function containedPath(root, candidate) {
|
|
219583
|
+
const resolvedRoot = resolve(root);
|
|
219584
|
+
const resolved = isAbsolute(candidate) ? resolve(candidate) : resolve(resolvedRoot, candidate);
|
|
219585
|
+
if (resolved !== resolvedRoot && !resolved.startsWith(`${resolvedRoot}${sep}`)) throw new Error(`ruta fuera del workspace: ${candidate}`);
|
|
219586
|
+
return resolved;
|
|
219818
219587
|
}
|
|
219819
|
-
|
|
219820
|
-
|
|
219821
|
-
|
|
219822
|
-
|
|
219823
|
-
|
|
219824
|
-
|
|
219825
|
-
|
|
219826
|
-
|
|
219827
|
-
|
|
219828
|
-
|
|
219829
|
-
|
|
219830
|
-
|
|
219831
|
-
|
|
219832
|
-
|
|
219833
|
-
|
|
219834
|
-
|
|
219835
|
-
|
|
219836
|
-
} catch (error) {
|
|
219837
|
-
return {
|
|
219838
|
-
output: error instanceof Error ? error.message : String(error),
|
|
219839
|
-
isError: true
|
|
219840
|
-
};
|
|
219841
|
-
}
|
|
219842
|
-
const template = briefTemplate(input.root);
|
|
219843
|
-
if (template.file === void 0) return {
|
|
219844
|
-
output: `falta ${template.missing ?? BRIEF_TEMPLATE$1}: no se genera un brief sin la plantilla unica`,
|
|
219845
|
-
isError: true
|
|
219588
|
+
var WAVE_ROUNDS, WAVE_ROUND_DIRS, DEFAULT_LAYOUT, DEFAULT_THRESHOLDS, DEFAULT_VOCABULARY, DEFAULT_ROLES, DEFAULT_QUORUM;
|
|
219589
|
+
var init_config$6 = __esmMin((() => {
|
|
219590
|
+
WAVE_ROUNDS = [
|
|
219591
|
+
"propose",
|
|
219592
|
+
"defend",
|
|
219593
|
+
"attack",
|
|
219594
|
+
"judge",
|
|
219595
|
+
"refine",
|
|
219596
|
+
"audit"
|
|
219597
|
+
];
|
|
219598
|
+
WAVE_ROUND_DIRS = {
|
|
219599
|
+
propose: "01-proposals",
|
|
219600
|
+
defend: "02-defenses",
|
|
219601
|
+
attack: "03-attacks",
|
|
219602
|
+
judge: "04-verdicts",
|
|
219603
|
+
refine: "05-refined",
|
|
219604
|
+
audit: "05-refined"
|
|
219846
219605
|
};
|
|
219847
|
-
|
|
219848
|
-
|
|
219849
|
-
|
|
219850
|
-
|
|
219606
|
+
DEFAULT_LAYOUT = {
|
|
219607
|
+
waves: "design/waves",
|
|
219608
|
+
backlog: "backlog",
|
|
219609
|
+
adr: "design/ADR",
|
|
219610
|
+
inventory: "inventory"
|
|
219851
219611
|
};
|
|
219852
|
-
|
|
219853
|
-
|
|
219854
|
-
|
|
219855
|
-
|
|
219856
|
-
|
|
219612
|
+
DEFAULT_THRESHOLDS = {
|
|
219613
|
+
minEpics: 1,
|
|
219614
|
+
minTasks: 1,
|
|
219615
|
+
minAcPerTask: 2,
|
|
219616
|
+
minDecisionBytes: 200,
|
|
219617
|
+
minArtifactBytes: 100,
|
|
219618
|
+
minBriefSections: 7,
|
|
219619
|
+
minContextBytes: 80,
|
|
219620
|
+
minGoalChars: 40,
|
|
219621
|
+
minScopeChars: 40,
|
|
219622
|
+
minFieldChars: 10,
|
|
219623
|
+
minMetricChars: 4
|
|
219857
219624
|
};
|
|
219858
|
-
|
|
219859
|
-
|
|
219860
|
-
|
|
219861
|
-
|
|
219625
|
+
DEFAULT_VOCABULARY = {
|
|
219626
|
+
areas: [
|
|
219627
|
+
"cliente",
|
|
219628
|
+
"seller",
|
|
219629
|
+
"agent",
|
|
219630
|
+
"admin",
|
|
219631
|
+
"plataforma"
|
|
219632
|
+
],
|
|
219633
|
+
requiredAreas: [],
|
|
219634
|
+
types: [
|
|
219635
|
+
"db",
|
|
219636
|
+
"api",
|
|
219637
|
+
"ui",
|
|
219638
|
+
"domain",
|
|
219639
|
+
"infra",
|
|
219640
|
+
"test",
|
|
219641
|
+
"docs",
|
|
219642
|
+
"app",
|
|
219643
|
+
"contract",
|
|
219644
|
+
"ops",
|
|
219645
|
+
"tooling"
|
|
219646
|
+
],
|
|
219647
|
+
estimates: [
|
|
219648
|
+
"XS",
|
|
219649
|
+
"S",
|
|
219650
|
+
"M",
|
|
219651
|
+
"L",
|
|
219652
|
+
"XL"
|
|
219653
|
+
],
|
|
219654
|
+
vagueWords: [
|
|
219655
|
+
"funciona",
|
|
219656
|
+
"correcto",
|
|
219657
|
+
"adecuado",
|
|
219658
|
+
"rapido",
|
|
219659
|
+
"robusto",
|
|
219660
|
+
"bonito"
|
|
219661
|
+
],
|
|
219662
|
+
verifyCommands: [
|
|
219663
|
+
"pnpm",
|
|
219664
|
+
"npm",
|
|
219665
|
+
"node",
|
|
219666
|
+
"bash",
|
|
219667
|
+
"sh",
|
|
219668
|
+
"make",
|
|
219669
|
+
"python",
|
|
219670
|
+
"go",
|
|
219671
|
+
"cargo",
|
|
219672
|
+
"dotnet"
|
|
219673
|
+
],
|
|
219674
|
+
verifyPrefixes: [
|
|
219675
|
+
"test/unit/",
|
|
219676
|
+
"test/db/",
|
|
219677
|
+
"test/domain/",
|
|
219678
|
+
"test/api/",
|
|
219679
|
+
"test/perf/",
|
|
219680
|
+
"e2e/",
|
|
219681
|
+
"scripts/checks/"
|
|
219682
|
+
]
|
|
219862
219683
|
};
|
|
219863
|
-
|
|
219864
|
-
|
|
219865
|
-
|
|
219684
|
+
DEFAULT_ROLES = {
|
|
219685
|
+
proponents: 3,
|
|
219686
|
+
defenders: 3,
|
|
219687
|
+
adversaries: 3,
|
|
219688
|
+
judges: 3,
|
|
219689
|
+
refiners: 2
|
|
219866
219690
|
};
|
|
219867
|
-
|
|
219868
|
-
|
|
219869
|
-
|
|
219870
|
-
|
|
219871
|
-
|
|
219872
|
-
|
|
219873
|
-
|
|
219874
|
-
|
|
219875
|
-
|
|
219876
|
-
|
|
219877
|
-
`oleada creada: ${next}-${slug}`,
|
|
219878
|
-
` brief: ${wavesRel}/${next}-${slug}/00-brief.md (rellena las ${minimum} secciones antes de lanzar asientos)`,
|
|
219879
|
-
` config: ${next} declarada en workflow.config.json (el gate la exige desde ahora)`
|
|
219880
|
-
].join("\n") };
|
|
219881
|
-
}
|
|
219882
|
-
var SUBDIRS, BRIEF_TEMPLATE$1, BUNDLED_BRIEF_TEMPLATE;
|
|
219883
|
-
var init_openRunner = __esmMin((() => {
|
|
219884
|
-
init_config$6();
|
|
219885
|
-
init_fsJson();
|
|
219886
|
-
init_nodeFs();
|
|
219887
|
-
SUBDIRS = [
|
|
219888
|
-
"01-proposals",
|
|
219889
|
-
"02-defenses",
|
|
219890
|
-
"03-attacks",
|
|
219891
|
-
"04-verdicts",
|
|
219892
|
-
"05-refined"
|
|
219893
|
-
];
|
|
219894
|
-
BRIEF_TEMPLATE$1 = "workflow/templates/brief.md";
|
|
219895
|
-
BUNDLED_BRIEF_TEMPLATE = resolve(import.meta.dirname, "../../../../../../../workflow/templates/brief.md");
|
|
219896
|
-
}));
|
|
219897
|
-
// ../../packages/agent-core-v2/src/features/wave/tools/open/open.md?raw
|
|
219898
|
-
var open_default;
|
|
219899
|
-
var init_open = __esmMin((() => {
|
|
219900
|
-
open_default = "Open a wave: create its artifact tree and a brief skeleton, and declare the wave in `workflow.config.json`.\n\nThe brief starts with the seven mandatory sections and nothing else — a brief that already contains the answer makes the twelve seats theatre. Fill it before launching any seat; the gate rejects a brief with fewer than seven sections.\n\nOpening a wave also declares it in the config, so the package gate will require its artifacts from then on.\n";
|
|
219901
|
-
}));
|
|
219902
|
-
// ../../packages/agent-core-v2/src/features/wave/tools/open/openTool.ts
|
|
219903
|
-
var WaveOpenTool;
|
|
219904
|
-
var init_openTool = __esmMin((() => {
|
|
219905
|
-
init_sessionContext();
|
|
219906
|
-
init_input_schema();
|
|
219907
|
-
init_open$1();
|
|
219908
|
-
init_openRunner();
|
|
219909
|
-
init_open();
|
|
219910
|
-
init_decorateParam();
|
|
219911
|
-
init_decorate();
|
|
219912
|
-
WaveOpenTool = class WaveOpenTool {
|
|
219913
|
-
sessionContext;
|
|
219914
|
-
name = "WaveOpen";
|
|
219915
|
-
description = open_default;
|
|
219916
|
-
parameters = toInputJsonSchema(WaveOpenToolInputSchema);
|
|
219917
|
-
constructor(sessionContext) {
|
|
219918
|
-
this.sessionContext = sessionContext;
|
|
219919
|
-
}
|
|
219920
|
-
resolveExecution(args) {
|
|
219921
|
-
return {
|
|
219922
|
-
description: `Opening wave ${args.name}`,
|
|
219923
|
-
approvalRule: this.name,
|
|
219924
|
-
execute: () => Promise.resolve(runWaveOpenForRoot({
|
|
219925
|
-
root: args.root ?? this.sessionContext.cwd,
|
|
219926
|
-
name: args.name,
|
|
219927
|
-
id: args.id
|
|
219928
|
-
}))
|
|
219929
|
-
};
|
|
219930
|
-
}
|
|
219691
|
+
DEFAULT_QUORUM = {
|
|
219692
|
+
minPoints: 1,
|
|
219693
|
+
minAxes: 2,
|
|
219694
|
+
axes: [
|
|
219695
|
+
"cobertura",
|
|
219696
|
+
"falsabilidad",
|
|
219697
|
+
"riesgo",
|
|
219698
|
+
"coste",
|
|
219699
|
+
"encaje"
|
|
219700
|
+
]
|
|
219931
219701
|
};
|
|
219932
|
-
WaveOpenTool = __decorate([__decorateParam(0, ISessionContext)], WaveOpenTool);
|
|
219933
|
-
}));
|
|
219934
|
-
// ../../packages/agent-core-v2/src/features/wave/tools/round/round.ts
|
|
219935
|
-
var WaveRoundToolInputSchema, IWaveRoundTool;
|
|
219936
|
-
var init_round$1 = __esmMin((() => {
|
|
219937
|
-
init_zod$1();
|
|
219938
|
-
init_instantiation();
|
|
219939
|
-
WaveRoundToolInputSchema = object$1({
|
|
219940
|
-
wave: string().min(2),
|
|
219941
|
-
round: _enum([
|
|
219942
|
-
"propose",
|
|
219943
|
-
"defend",
|
|
219944
|
-
"attack",
|
|
219945
|
-
"judge",
|
|
219946
|
-
"refine",
|
|
219947
|
-
"audit"
|
|
219948
|
-
]),
|
|
219949
|
-
root: string().optional()
|
|
219950
|
-
}).strict();
|
|
219951
|
-
IWaveRoundTool = createDecorator("waveRoundTool");
|
|
219952
219702
|
}));
|
|
219953
|
-
// ../../packages/agent-core-v2/src/features/wave/
|
|
219703
|
+
// ../../packages/agent-core-v2/src/features/wave/core/seats.ts
|
|
219704
|
+
function contractedSeats(fs, registryFile) {
|
|
219705
|
+
const raw = fs.read(registryFile);
|
|
219706
|
+
if (raw === void 0) return void 0;
|
|
219707
|
+
try {
|
|
219708
|
+
return (JSON.parse(raw).seats ?? []).filter((seat) => typeof seat["round"] === "string" && typeof seat["role"] === "string").map((seat) => ({
|
|
219709
|
+
round: String(seat["round"]),
|
|
219710
|
+
role: String(seat["role"])
|
|
219711
|
+
}));
|
|
219712
|
+
} catch {
|
|
219713
|
+
return;
|
|
219714
|
+
}
|
|
219715
|
+
}
|
|
219954
219716
|
function seatTicketHash(ticket) {
|
|
219955
219717
|
return createHash("sha256").update(ticket).digest("hex");
|
|
219956
219718
|
}
|
|
219957
|
-
function
|
|
219719
|
+
function waveBase(input) {
|
|
219958
219720
|
const fs = nodeWaveFs;
|
|
219959
|
-
const
|
|
219960
|
-
|
|
219961
|
-
|
|
219721
|
+
const rawConfig = readJson$2(fs, join(input.root, "workflow.config.json"));
|
|
219722
|
+
if (rawConfig === void 0) return { error: `no hay workflow.config.json en ${input.root}` };
|
|
219723
|
+
const wavesRel = makeWaveConfig(rawConfig).layout.waves;
|
|
219724
|
+
let wavesDir;
|
|
219725
|
+
try {
|
|
219726
|
+
wavesDir = containedPath(input.root, wavesRel);
|
|
219727
|
+
} catch (error) {
|
|
219728
|
+
return { error: error instanceof Error ? error.message : String(error) };
|
|
219729
|
+
}
|
|
219730
|
+
const name = fs.list(wavesDir).filter((entry) => fs.isDirectory(join(wavesDir, entry))).find((entry) => entry === input.wave || entry.startsWith(`${input.wave}-`));
|
|
219731
|
+
if (name === void 0) return { error: `no existe la oleada ${input.wave} en ${wavesRel}` };
|
|
219732
|
+
return {
|
|
219733
|
+
base: join(wavesDir, name),
|
|
219734
|
+
wavesRel
|
|
219735
|
+
};
|
|
219962
219736
|
}
|
|
219963
|
-
function
|
|
219737
|
+
function runWaveContract(input) {
|
|
219964
219738
|
const fs = nodeWaveFs;
|
|
219965
219739
|
const rawConfig = readJson$2(fs, join(input.root, "workflow.config.json"));
|
|
219966
219740
|
if (rawConfig === void 0) return {
|
|
219967
219741
|
output: `no hay workflow.config.json en ${input.root}`,
|
|
219742
|
+
seats: [],
|
|
219968
219743
|
isError: true
|
|
219969
219744
|
};
|
|
219970
|
-
const
|
|
219971
|
-
|
|
219972
|
-
|
|
219973
|
-
|
|
219974
|
-
output: `seats.unknown_seat: el rol "${input.role}" no pertenece a la ronda ${input.round} (esperado ${seats.join(", ")})`,
|
|
219745
|
+
const located = waveBase(input);
|
|
219746
|
+
if (located.base === void 0) return {
|
|
219747
|
+
output: located.error ?? "oleada no encontrada",
|
|
219748
|
+
seats: [],
|
|
219975
219749
|
isError: true
|
|
219976
219750
|
};
|
|
219977
|
-
|
|
219978
|
-
|
|
219979
|
-
|
|
219980
|
-
|
|
219751
|
+
const base = located.base;
|
|
219752
|
+
const roundDir = WAVE_ROUND_DIRS[input.round];
|
|
219753
|
+
const roles = waveRoundSeats(makeWaveConfig(rawConfig).roles, input.round);
|
|
219754
|
+
if (input.report === true) {
|
|
219755
|
+
const delivered = roles.filter((role) => fs.exists(join(base, roundDir, `${role}.md`)));
|
|
219756
|
+
const missing = roles.filter((role) => !delivered.includes(role));
|
|
219981
219757
|
return {
|
|
219982
|
-
output:
|
|
219983
|
-
|
|
219758
|
+
output: [
|
|
219759
|
+
`CONTRATOS ${input.round} de ${input.wave}: ${delivered.length}/${roles.length} entregados`,
|
|
219760
|
+
...roles.map((role) => `${delivered.includes(role) ? "ok " : "FIJA"} ${role} ${roundDir}/${role}.md`),
|
|
219761
|
+
...missing.length === 0 ? [] : ["", `faltan: ${missing.join(", ")}`]
|
|
219762
|
+
].join("\n"),
|
|
219763
|
+
seats: [],
|
|
219764
|
+
isError: missing.length > 0
|
|
219984
219765
|
};
|
|
219985
219766
|
}
|
|
219986
|
-
|
|
219987
|
-
|
|
219988
|
-
|
|
219989
|
-
|
|
219990
|
-
|
|
219991
|
-
const dir = join(base, dirName);
|
|
219992
|
-
if (!fs.isDirectory(dir)) return {
|
|
219993
|
-
output: `falta el directorio ${dirName} en la oleada ${input.wave}`,
|
|
219994
|
-
isError: true
|
|
219995
|
-
};
|
|
219996
|
-
const seatsDir = join(base, WAVE_SEATS_DIR);
|
|
219997
|
-
if (fs.isDirectory(seatsDir) && fs.list(seatsDir).length > 0) {
|
|
219998
|
-
const presented = (input.ticket ?? "").trim();
|
|
219999
|
-
if (presented === "") return {
|
|
220000
|
-
output: `seats.foreign_replace: el asiento ${input.role} no presento el ticket que emitio la ronda`,
|
|
219767
|
+
const declared = input.seats ?? [];
|
|
219768
|
+
for (const seat of declared) {
|
|
219769
|
+
if (seat.role !== void 0 && !roles.includes(seat.role)) return {
|
|
219770
|
+
output: `rol desconocido "${seat.role}" para la ronda ${input.round}: ${roles.join(", ")}`,
|
|
219771
|
+
seats: [],
|
|
220001
219772
|
isError: true
|
|
220002
219773
|
};
|
|
220003
|
-
|
|
220004
|
-
|
|
220005
|
-
|
|
219774
|
+
if (seat.artifact !== void 0 && !seat.artifact.startsWith(`${roundDir}/`)) return {
|
|
219775
|
+
output: `el artefacto "${seat.artifact}" queda fuera de ${roundDir}/`,
|
|
219776
|
+
seats: [],
|
|
220006
219777
|
isError: true
|
|
220007
219778
|
};
|
|
220008
|
-
|
|
220009
|
-
|
|
219779
|
+
}
|
|
219780
|
+
const requested = declared.length === 0 ? roles.map((role) => ({ role })) : declared;
|
|
219781
|
+
const resolved = [];
|
|
219782
|
+
for (const [index, seat] of requested.entries()) {
|
|
219783
|
+
const role = seat.role ?? roles[index];
|
|
219784
|
+
if (role === void 0) return {
|
|
219785
|
+
output: "se contrataron más asientos que roles tiene la ronda",
|
|
219786
|
+
seats: [],
|
|
220010
219787
|
isError: true
|
|
220011
219788
|
};
|
|
219789
|
+
resolved.push({
|
|
219790
|
+
role,
|
|
219791
|
+
file: seat.artifact ?? `${roundDir}/${role}.md`
|
|
219792
|
+
});
|
|
220012
219793
|
}
|
|
220013
|
-
const
|
|
220014
|
-
|
|
220015
|
-
|
|
220016
|
-
|
|
220017
|
-
|
|
220018
|
-
|
|
220019
|
-
|
|
220020
|
-
|
|
219794
|
+
const seatsDir = join(base, WAVE_SEATS_DIR);
|
|
219795
|
+
const entries = asArray$2(asRecord$2(readJson$2(fs, join(seatsDir, "seats.json")) ?? {})["seats"]).map(asRecord$2).filter((entry) => !resolved.some((seat) => entry["round"] === input.round && entry["role"] === seat.role));
|
|
219796
|
+
const contracts = [];
|
|
219797
|
+
for (const seat of resolved) {
|
|
219798
|
+
const ticket = randomBytes(16).toString("hex");
|
|
219799
|
+
fs.write(join(seatsDir, seat.role), `${seatTicketHash(ticket)}\n`);
|
|
219800
|
+
entries.push({
|
|
219801
|
+
role: seat.role,
|
|
219802
|
+
round: input.round,
|
|
219803
|
+
file: seat.file,
|
|
219804
|
+
ticket: seatTicketHash(ticket)
|
|
219805
|
+
});
|
|
219806
|
+
contracts.push({
|
|
219807
|
+
...seat,
|
|
219808
|
+
ticket,
|
|
219809
|
+
prompt: input.buildPrompt({
|
|
219810
|
+
wave: input.wave,
|
|
219811
|
+
round: input.round,
|
|
219812
|
+
...seat,
|
|
219813
|
+
ticket
|
|
219814
|
+
})
|
|
219815
|
+
});
|
|
219816
|
+
}
|
|
219817
|
+
writeJson(fs, join(seatsDir, "seats.json"), { seats: entries });
|
|
219818
|
+
return {
|
|
219819
|
+
output: [`CONTRATOS ${input.round} de ${input.wave}: ${contracts.length} asiento(s)`, ...contracts.map((contract) => `\n=== ${contract.role} -> ${contract.file}\n${contract.prompt}`)].join("\n"),
|
|
219820
|
+
seats: contracts
|
|
220021
219821
|
};
|
|
220022
|
-
fs.write(file, input.artifact.endsWith("\n") ? input.artifact : `${input.artifact}\n`);
|
|
220023
|
-
return { output: `escrito ${wavesRel}/${base.split("/").pop()}/${dirName}/${input.role}.md` };
|
|
220024
219822
|
}
|
|
220025
|
-
var WAVE_SEATS_DIR;
|
|
220026
|
-
var
|
|
219823
|
+
var WAVE_SEATS_DIR, WAVE_CONTRACTS_FILE;
|
|
219824
|
+
var init_seats = __esmMin((() => {
|
|
220027
219825
|
init_config$6();
|
|
220028
219826
|
init_fsJson();
|
|
220029
219827
|
init_nodeFs();
|
|
220030
219828
|
WAVE_SEATS_DIR = ".seats";
|
|
219829
|
+
WAVE_CONTRACTS_FILE = `${WAVE_SEATS_DIR}/seats.json`;
|
|
220031
219830
|
}));
|
|
220032
219831
|
// ../../packages/agent-core-v2/src/features/wave/tools/round/prompts.ts
|
|
220033
219832
|
var SEAT_PRELUDE, ROLE_PROMPTS, JUDGE_BIASES;
|
|
@@ -220055,188 +219854,290 @@ var init_prompts$2 = __esmMin((() => {
|
|
|
220055
219854
|
"encaje"
|
|
220056
219855
|
];
|
|
220057
219856
|
}));
|
|
220058
|
-
// ../../packages/agent-core-v2/src/features/wave/tools/
|
|
220059
|
-
function
|
|
220060
|
-
const
|
|
220061
|
-
|
|
220062
|
-
|
|
220063
|
-
|
|
220064
|
-
|
|
220065
|
-
|
|
220066
|
-
|
|
220067
|
-
|
|
220068
|
-
|
|
220069
|
-
|
|
220070
|
-
|
|
220071
|
-
|
|
220072
|
-
|
|
220073
|
-
|
|
220074
|
-
|
|
220075
|
-
|
|
220076
|
-
|
|
220077
|
-
|
|
220078
|
-
|
|
220079
|
-
|
|
220080
|
-
|
|
220081
|
-
|
|
220082
|
-
|
|
220083
|
-
isError: true
|
|
220084
|
-
};
|
|
220085
|
-
const briefRel = `${wavesRel}/${waveDir}/00-brief.md`;
|
|
220086
|
-
const brief = fs.read(join(wavesDir, waveDir, "00-brief.md"));
|
|
220087
|
-
if (brief === void 0) return {
|
|
220088
|
-
output: `falta ${briefRel}`,
|
|
220089
|
-
seats: [],
|
|
220090
|
-
isError: true
|
|
220091
|
-
};
|
|
220092
|
-
const sections = brief.match(/^##\s+\S/gm)?.length ?? 0;
|
|
220093
|
-
const minimum = config.thresholds.minBriefSections;
|
|
220094
|
-
if (sections < minimum) return {
|
|
220095
|
-
output: `el brief tiene ${sections} secciones < ${minimum}: rellena las ${minimum} antes de lanzar la ronda`,
|
|
220096
|
-
seats: [],
|
|
220097
|
-
isError: true
|
|
220098
|
-
};
|
|
220099
|
-
const dir = WAVE_ROUND_DIRS[input.round];
|
|
220100
|
-
const seatsDir = join(wavesDir, waveDir, WAVE_SEATS_DIR);
|
|
220101
|
-
const seats = waveRoundSeats(config.roles, input.round).map((role) => {
|
|
220102
|
-
const bias = input.round === "judge" ? JUDGE_BIASES[(Number(role.slice(1)) - 1) % JUDGE_BIASES.length] : void 0;
|
|
220103
|
-
const file = `${wavesRel}/${waveDir}/${dir}/${role}.md`;
|
|
220104
|
-
const ticket = randomBytes(16).toString("hex");
|
|
220105
|
-
fs.write(join(seatsDir, role), `${seatTicketHash(ticket)}\n`);
|
|
220106
|
-
const lines = [
|
|
220107
|
-
SEAT_PRELUDE,
|
|
220108
|
-
"",
|
|
220109
|
-
ROLE_PROMPTS[input.round] ?? "",
|
|
220110
|
-
"",
|
|
220111
|
-
`Perfil: ${WAVE_SEAT_PROFILE}`,
|
|
220112
|
-
`Oleada: ${input.wave}. Brief: ${briefRel}.`,
|
|
220113
|
-
`Escribe: ${file}.`,
|
|
220114
|
-
`Ticket de asiento: ${ticket}. Es capacidad, no identidad: la ronda lo emitio para este asiento y WaveSubmit lo exige.`,
|
|
220115
|
-
`Entrega con WaveSubmit({ wave: "${input.wave}", round: "${input.round}", role: "${role}", ticket: "${ticket}", artifact: "..." }).`
|
|
220116
|
-
];
|
|
220117
|
-
if (bias !== void 0) lines.push(`Tu sesgo declarado es ${bias}: puntua CON el, no contra el.`);
|
|
220118
|
-
return {
|
|
220119
|
-
role,
|
|
220120
|
-
file,
|
|
220121
|
-
ticket,
|
|
220122
|
-
prompt: lines.join("\n")
|
|
220123
|
-
};
|
|
219857
|
+
// ../../packages/agent-core-v2/src/features/wave/tools/contract/contractRunner.ts
|
|
219858
|
+
function briefRel(root, wave) {
|
|
219859
|
+
const wavesRel = readJson$2(nodeWaveFs, join(root, "workflow.config.json"))?.layout?.waves ?? "design/waves";
|
|
219860
|
+
return `${wavesRel}/${nodeWaveFs.list(join(root, wavesRel)).find((entry) => entry === wave || entry.startsWith(`${wave}-`)) ?? wave}/00-brief.md`;
|
|
219861
|
+
}
|
|
219862
|
+
function runWaveContractForRoot(input) {
|
|
219863
|
+
const brief = briefRel(input.root, input.wave);
|
|
219864
|
+
return runWaveContract({
|
|
219865
|
+
...input,
|
|
219866
|
+
buildPrompt: (seat) => {
|
|
219867
|
+
const bias = input.round === "judge" ? JUDGE_BIASES[(Number(seat.role.slice(1)) - 1) % JUDGE_BIASES.length] : void 0;
|
|
219868
|
+
const lines = [
|
|
219869
|
+
SEAT_PRELUDE,
|
|
219870
|
+
"",
|
|
219871
|
+
ROLE_PROMPTS[input.round] ?? "",
|
|
219872
|
+
"",
|
|
219873
|
+
`Perfil: ${WAVE_SEAT_PROFILE}`,
|
|
219874
|
+
`Oleada: ${input.wave}. Brief: ${brief}.`,
|
|
219875
|
+
`Escribe: ${seat.file}.`,
|
|
219876
|
+
`Ticket de asiento: ${seat.ticket}. Es capacidad, no identidad: el contrato lo emitió para este asiento y WaveSubmit lo exige.`,
|
|
219877
|
+
`Entrega con WaveSubmit({ wave: "${input.wave}", round: "${input.round}", role: "${seat.role}", ticket: "${seat.ticket}", artifact: "..." }).`
|
|
219878
|
+
];
|
|
219879
|
+
if (bias !== void 0) lines.push(`Tu sesgo declarado es ${bias}: puntúa CON él, no contra él.`);
|
|
219880
|
+
return lines.join("\n");
|
|
219881
|
+
}
|
|
220124
219882
|
});
|
|
220125
|
-
return {
|
|
220126
|
-
output: [`RONDA ${input.round} de ${input.wave}: ${seats.length} asiento(s)`, ...seats.map((seat) => `\n=== ${seat.role} -> ${seat.file}\n${seat.prompt}`)].join("\n"),
|
|
220127
|
-
seats
|
|
220128
|
-
};
|
|
220129
219883
|
}
|
|
220130
|
-
var
|
|
220131
|
-
init_config$6();
|
|
219884
|
+
var init_contractRunner = __esmMin((() => {
|
|
220132
219885
|
init_fsJson();
|
|
220133
219886
|
init_nodeFs();
|
|
220134
|
-
|
|
220135
|
-
init_submitRunner();
|
|
219887
|
+
init_seats();
|
|
220136
219888
|
init_prompts$2();
|
|
219889
|
+
init_wave$3();
|
|
220137
219890
|
}));
|
|
220138
|
-
// ../../packages/agent-core-v2/src/features/wave/tools/
|
|
220139
|
-
var
|
|
220140
|
-
var
|
|
220141
|
-
|
|
219891
|
+
// ../../packages/agent-core-v2/src/features/wave/tools/contract/contract.md?raw
|
|
219892
|
+
var contract_default;
|
|
219893
|
+
var init_contract$3 = __esmMin((() => {
|
|
219894
|
+
contract_default = "Create the round's contracts and hand each seat its exact prompt.\n\nReturns one contract per seat: `role`, `artifact` path, `ticket` and the ready-to-launch prompt. Launch one agent per contract with `Agent(subagent_type: \"wave-seat\")` (or `AgentSwarm` when the user enabled swarm) and pass the prompt unchanged — the ticket in it is what `WaveSubmit` accepts.\n\n- Seats and artifact paths come from `roles.*` in `workflow.config.json` and the round's directory. You may narrow them with `seats` (`role`, `artifact`), but an artifact must stay inside the round's directory.\n- You do not write artifacts: `WaveSubmit` is the seat's tool. Contract, launch, then read the results.\n- `report: true` lists which seats of the round have already delivered, without issuing tickets.\n\nClose the round with `WaveDecide` (judges), `WaveVerify` (tasks) and `WaveGate` (package). The wave is not closed until the gate is green.\n";
|
|
220142
219895
|
}));
|
|
220143
|
-
// ../../packages/agent-core-v2/src/features/wave/tools/
|
|
220144
|
-
var
|
|
220145
|
-
var
|
|
219896
|
+
// ../../packages/agent-core-v2/src/features/wave/tools/contract/contractTool.ts
|
|
219897
|
+
var WaveContractTool;
|
|
219898
|
+
var init_contractTool = __esmMin((() => {
|
|
220146
219899
|
init_sessionContext();
|
|
220147
219900
|
init_input_schema();
|
|
220148
|
-
|
|
220149
|
-
|
|
220150
|
-
|
|
219901
|
+
init_contract$4();
|
|
219902
|
+
init_contractRunner();
|
|
219903
|
+
init_contract$3();
|
|
220151
219904
|
init_decorateParam();
|
|
220152
219905
|
init_decorate();
|
|
220153
|
-
|
|
219906
|
+
WaveContractTool = class WaveContractTool {
|
|
220154
219907
|
sessionContext;
|
|
220155
|
-
name = "
|
|
220156
|
-
description =
|
|
220157
|
-
parameters = toInputJsonSchema(
|
|
219908
|
+
name = "WaveContract";
|
|
219909
|
+
description = contract_default;
|
|
219910
|
+
parameters = toInputJsonSchema(WaveContractToolInputSchema);
|
|
220158
219911
|
constructor(sessionContext) {
|
|
220159
219912
|
this.sessionContext = sessionContext;
|
|
220160
219913
|
}
|
|
220161
219914
|
resolveExecution(args) {
|
|
220162
219915
|
return {
|
|
220163
|
-
description: `
|
|
219916
|
+
description: `Contracting ${args.round} seats of ${args.wave}`,
|
|
220164
219917
|
approvalRule: this.name,
|
|
220165
|
-
execute: () => Promise.resolve(
|
|
219918
|
+
execute: () => Promise.resolve(runWaveContractForRoot({
|
|
220166
219919
|
root: args.root ?? this.sessionContext.cwd,
|
|
220167
219920
|
wave: args.wave,
|
|
220168
|
-
round: args.round
|
|
219921
|
+
round: args.round,
|
|
219922
|
+
seats: args.seats,
|
|
219923
|
+
report: args.report
|
|
220169
219924
|
}))
|
|
220170
219925
|
};
|
|
220171
219926
|
}
|
|
220172
219927
|
};
|
|
220173
|
-
|
|
219928
|
+
WaveContractTool = __decorate([__decorateParam(0, ISessionContext)], WaveContractTool);
|
|
220174
219929
|
}));
|
|
220175
|
-
// ../../packages/agent-core-v2/src/features/wave/tools/
|
|
220176
|
-
var
|
|
220177
|
-
var
|
|
219930
|
+
// ../../packages/agent-core-v2/src/features/wave/tools/decide/decide.ts
|
|
219931
|
+
var WaveDecideToolInputSchema, IWaveDecideTool;
|
|
219932
|
+
var init_decide$1 = __esmMin((() => {
|
|
220178
219933
|
init_zod$1();
|
|
220179
219934
|
init_instantiation();
|
|
220180
|
-
|
|
220181
|
-
|
|
220182
|
-
|
|
220183
|
-
|
|
220184
|
-
|
|
220185
|
-
|
|
220186
|
-
|
|
220187
|
-
|
|
220188
|
-
|
|
220189
|
-
]),
|
|
220190
|
-
role: string().min(2),
|
|
220191
|
-
artifact: string().min(1),
|
|
220192
|
-
ticket: string().optional(),
|
|
220193
|
-
reason: string().optional(),
|
|
220194
|
-
replace: boolean$1().optional(),
|
|
220195
|
-
root: string().optional()
|
|
219935
|
+
WaveDecideToolInputSchema = object$1({
|
|
219936
|
+
root: string().optional(),
|
|
219937
|
+
verdicts: array(object$1({
|
|
219938
|
+
judge: string().min(1),
|
|
219939
|
+
scores: record$3(string(), number$1())
|
|
219940
|
+
}).strict()).min(1),
|
|
219941
|
+
minPoints: number$1().optional(),
|
|
219942
|
+
minAxes: number$1().optional(),
|
|
219943
|
+
round: number$1().optional()
|
|
220196
219944
|
}).strict();
|
|
220197
|
-
|
|
219945
|
+
IWaveDecideTool = createDecorator("waveDecideTool");
|
|
220198
219946
|
}));
|
|
220199
|
-
// ../../packages/agent-core-v2/src/features/wave/
|
|
220200
|
-
|
|
220201
|
-
|
|
220202
|
-
|
|
219947
|
+
// ../../packages/agent-core-v2/src/features/wave/core/quorum.ts
|
|
219948
|
+
function median(values) {
|
|
219949
|
+
const sorted = [...values].toSorted((left, right) => left - right);
|
|
219950
|
+
const middle = Math.floor(sorted.length / 2);
|
|
219951
|
+
const current = sorted[middle];
|
|
219952
|
+
if (current === void 0) throw new Error("no se puede calcular una mediana sin valores");
|
|
219953
|
+
if (sorted.length % 2 === 1) return current;
|
|
219954
|
+
const previous = sorted[middle - 1];
|
|
219955
|
+
if (previous === void 0) throw new Error("no se puede calcular una mediana sin valores");
|
|
219956
|
+
return (previous + current) / 2;
|
|
219957
|
+
}
|
|
219958
|
+
function validate$1(verdicts) {
|
|
219959
|
+
if (verdicts.length === 0) throw new Error("el quorum exige al menos un veredicto");
|
|
219960
|
+
const first = verdicts[0];
|
|
219961
|
+
if (first === void 0) throw new Error("el quorum exige al menos un veredicto");
|
|
219962
|
+
const proposals = Object.keys(first.scores).toSorted();
|
|
219963
|
+
if (proposals.length === 0) throw new Error("el veredicto no puntua ninguna propuesta");
|
|
219964
|
+
for (const verdict of verdicts) {
|
|
219965
|
+
const keys = Object.keys(verdict.scores).toSorted();
|
|
219966
|
+
if (keys.length !== proposals.length || keys.some((key, index) => key !== proposals[index])) throw new Error(`el juez ${verdict.judge} no puntua el mismo conjunto de propuestas`);
|
|
219967
|
+
for (const proposal of proposals) {
|
|
219968
|
+
const score = verdict.scores[proposal];
|
|
219969
|
+
if (typeof score !== "number" || !Number.isFinite(score) || score < 0) throw new Error(`puntuacion invalida de ${verdict.judge} para ${proposal}`);
|
|
219970
|
+
}
|
|
219971
|
+
}
|
|
219972
|
+
return proposals;
|
|
219973
|
+
}
|
|
219974
|
+
function evaluateQuorum(input) {
|
|
219975
|
+
const proposals = validate$1(input.verdicts);
|
|
219976
|
+
const minPoints = input.minPoints;
|
|
219977
|
+
const minAxes = Math.max(1, Math.floor(input.minAxes));
|
|
219978
|
+
const round = input.round ?? 0;
|
|
219979
|
+
const medians = {};
|
|
219980
|
+
for (const proposal of proposals) medians[proposal] = median(input.verdicts.map((verdict) => verdict.scores[proposal] ?? 0));
|
|
219981
|
+
const ranked = [...proposals].toSorted((left, right) => {
|
|
219982
|
+
const delta = (medians[right] ?? 0) - (medians[left] ?? 0);
|
|
219983
|
+
return delta === 0 ? left.localeCompare(right) : delta;
|
|
219984
|
+
});
|
|
219985
|
+
const winner = ranked[0];
|
|
219986
|
+
const second = ranked[1];
|
|
219987
|
+
if (winner === void 0) throw new Error("no hay propuestas que comparar");
|
|
219988
|
+
if (second === void 0) return {
|
|
219989
|
+
verdict: "refine",
|
|
219990
|
+
winner,
|
|
219991
|
+
second: void 0,
|
|
219992
|
+
medians,
|
|
219993
|
+
medianMargin: 0,
|
|
219994
|
+
judgesHoldingMargin: 0,
|
|
219995
|
+
perJudge: [],
|
|
219996
|
+
reason: `sin comparacion no hay quorum: solo hay una propuesta (${winner})`
|
|
219997
|
+
};
|
|
219998
|
+
const winnerMedian = medians[winner] ?? 0;
|
|
219999
|
+
const secondMedian = medians[second] ?? 0;
|
|
220000
|
+
const medianMargin = Number((winnerMedian - secondMedian).toFixed(6));
|
|
220001
|
+
if (medianMargin === 0) return {
|
|
220002
|
+
verdict: round >= 2 ? "deadlock" : "refine",
|
|
220003
|
+
winner: void 0,
|
|
220004
|
+
second,
|
|
220005
|
+
medians,
|
|
220006
|
+
medianMargin,
|
|
220007
|
+
judgesHoldingMargin: 0,
|
|
220008
|
+
perJudge: [],
|
|
220009
|
+
reason: `empate en la mediana entre ${winner} y ${second}: no hay ganador`
|
|
220010
|
+
};
|
|
220011
|
+
const perJudge = input.verdicts.map((verdict) => {
|
|
220012
|
+
const margin = (verdict.scores[winner] ?? 0) - (verdict.scores[second] ?? 0);
|
|
220013
|
+
return {
|
|
220014
|
+
judge: verdict.judge,
|
|
220015
|
+
margin,
|
|
220016
|
+
holds: margin >= minPoints
|
|
220017
|
+
};
|
|
220018
|
+
});
|
|
220019
|
+
const judgesHoldingMargin = perJudge.filter((entry) => entry.holds).length;
|
|
220020
|
+
const marginOk = medianMargin >= minPoints;
|
|
220021
|
+
const majorityOk = judgesHoldingMargin >= minAxes;
|
|
220022
|
+
if (marginOk && majorityOk) return {
|
|
220023
|
+
verdict: "adopt",
|
|
220024
|
+
winner,
|
|
220025
|
+
second,
|
|
220026
|
+
medians,
|
|
220027
|
+
medianMargin,
|
|
220028
|
+
judgesHoldingMargin,
|
|
220029
|
+
perJudge,
|
|
220030
|
+
reason: `mediana ${winner} ${winnerMedian} vs ${second} ${secondMedian}: margen ${medianMargin} en ${judgesHoldingMargin}/${perJudge.length} jueces`
|
|
220031
|
+
};
|
|
220032
|
+
const reason = [marginOk ? void 0 : `margen ${medianMargin} < ${minPoints}`, majorityOk ? void 0 : `solo ${judgesHoldingMargin}/${perJudge.length} jueces superan el margen (minimo ${minAxes})`].filter((part) => part !== void 0).join(" y ");
|
|
220033
|
+
return {
|
|
220034
|
+
verdict: round >= 2 ? "deadlock" : "refine",
|
|
220035
|
+
winner,
|
|
220036
|
+
second,
|
|
220037
|
+
medians,
|
|
220038
|
+
medianMargin,
|
|
220039
|
+
judgesHoldingMargin,
|
|
220040
|
+
perJudge,
|
|
220041
|
+
reason: `${reason}: sin quorum`
|
|
220042
|
+
};
|
|
220043
|
+
}
|
|
220044
|
+
var init_quorum = __esmMin((() => {}));
|
|
220045
|
+
// ../../packages/agent-core-v2/src/features/wave/tools/decide/decideRunner.ts
|
|
220046
|
+
function runWaveDecideForRoot(input) {
|
|
220047
|
+
const root = resolve(input.root);
|
|
220048
|
+
const config = readWaveConfig(nodeWaveFs, root);
|
|
220049
|
+
if (config === void 0) return {
|
|
220050
|
+
output: `no hay workflow.config.json en ${root}`,
|
|
220051
|
+
isError: true
|
|
220052
|
+
};
|
|
220053
|
+
let result;
|
|
220054
|
+
try {
|
|
220055
|
+
result = evaluateQuorum({
|
|
220056
|
+
verdicts: input.verdicts,
|
|
220057
|
+
minPoints: input.minPoints ?? config.quorum.minPoints,
|
|
220058
|
+
minAxes: input.minAxes ?? config.quorum.minAxes,
|
|
220059
|
+
round: input.round
|
|
220060
|
+
});
|
|
220061
|
+
} catch (error) {
|
|
220062
|
+
return {
|
|
220063
|
+
output: `veredictos invalidos: ${error instanceof Error ? error.message : String(error)}`,
|
|
220064
|
+
isError: true
|
|
220065
|
+
};
|
|
220066
|
+
}
|
|
220067
|
+
const holding = result.perJudge.length === 0 ? "sin comparacion" : `${result.judgesHoldingMargin}/${result.perJudge.length}`;
|
|
220068
|
+
const lines = [
|
|
220069
|
+
`QUORUM — ${result.verdict}`,
|
|
220070
|
+
"",
|
|
220071
|
+
...Object.entries(result.medians).map(([proposal, value]) => ` mediana ${proposal}: ${value}`),
|
|
220072
|
+
"",
|
|
220073
|
+
` ganador: ${result.winner ?? "(empate)"}`,
|
|
220074
|
+
` margen: ${result.medianMargin} (minimo ${input.minPoints ?? config.quorum.minPoints})`,
|
|
220075
|
+
` jueces con margen: ${holding} (minimo ${input.minAxes ?? config.quorum.minAxes})`,
|
|
220076
|
+
...result.perJudge.map((entry) => ` ${entry.judge}: ${entry.margin}${entry.holds ? " ok" : " NO"}`),
|
|
220077
|
+
...result.perJudge.filter((entry) => entry.margin < 0).map((entry) => ` disidencia: ${entry.judge} ${entry.margin}`),
|
|
220078
|
+
"",
|
|
220079
|
+
` motivo: ${result.reason}`
|
|
220080
|
+
];
|
|
220081
|
+
if (result.verdict === "deadlock") lines.push("", " dos rondas sin quorum: adopta R1 con disidencia escrita, nunca la presentes como unanime");
|
|
220082
|
+
return {
|
|
220083
|
+
output: lines.join("\n"),
|
|
220084
|
+
isError: result.verdict !== "adopt"
|
|
220085
|
+
};
|
|
220086
|
+
}
|
|
220087
|
+
var init_decideRunner = __esmMin((() => {
|
|
220088
|
+
init_config$6();
|
|
220089
|
+
init_nodeFs();
|
|
220090
|
+
init_quorum();
|
|
220203
220091
|
}));
|
|
220204
|
-
// ../../packages/agent-core-v2/src/features/wave/tools/
|
|
220205
|
-
var
|
|
220206
|
-
var
|
|
220092
|
+
// ../../packages/agent-core-v2/src/features/wave/tools/decide/decide.md?raw
|
|
220093
|
+
var decide_default;
|
|
220094
|
+
var init_decide = __esmMin((() => {
|
|
220095
|
+
decide_default = "Compute the wave quorum from the judges' totals and say what may happen next.\n\nPass one entry per judge with its totals per proposal (`{ judge: \"J1\", scores: { P1: 17, P2: 15, P3: 14 } }`). The tool takes the **median** per proposal and applies both conditions of `core/quorum.ts`: the winner's median must beat the second's by `minPoints` (**margen de medianas**), and at least `minAxes` judges must give the winner that margin or more over the second (**mayoría de jueces**). Thresholds default to `workflow.config.json`.\n\nAnswers `adopt`, `refine` (no quorum yet, compose R1 and audit with R2) or `deadlock` (two rounds without quorum: adopt R1 with written dissent). A tie in the median, or a single proposal with nothing to compare, never crowns a winner and never counts as quorum.\n";
|
|
220096
|
+
}));
|
|
220097
|
+
// ../../packages/agent-core-v2/src/features/wave/tools/decide/decideTool.ts
|
|
220098
|
+
var WaveDecideTool;
|
|
220099
|
+
var init_decideTool = __esmMin((() => {
|
|
220207
220100
|
init_sessionContext();
|
|
220208
220101
|
init_input_schema();
|
|
220209
|
-
|
|
220210
|
-
|
|
220211
|
-
|
|
220102
|
+
init_decide$1();
|
|
220103
|
+
init_decideRunner();
|
|
220104
|
+
init_decide();
|
|
220212
220105
|
init_decorateParam();
|
|
220213
220106
|
init_decorate();
|
|
220214
|
-
|
|
220107
|
+
WaveDecideTool = class WaveDecideTool {
|
|
220215
220108
|
sessionContext;
|
|
220216
|
-
name = "
|
|
220217
|
-
description =
|
|
220218
|
-
parameters = toInputJsonSchema(
|
|
220109
|
+
name = "WaveDecide";
|
|
220110
|
+
description = decide_default;
|
|
220111
|
+
parameters = toInputJsonSchema(WaveDecideToolInputSchema);
|
|
220219
220112
|
constructor(sessionContext) {
|
|
220220
220113
|
this.sessionContext = sessionContext;
|
|
220221
220114
|
}
|
|
220222
220115
|
resolveExecution(args) {
|
|
220223
220116
|
return {
|
|
220224
|
-
description:
|
|
220117
|
+
description: "Computing the wave quorum",
|
|
220225
220118
|
approvalRule: this.name,
|
|
220226
|
-
execute: () => Promise.resolve(
|
|
220119
|
+
execute: () => Promise.resolve(runWaveDecideForRoot({
|
|
220227
220120
|
root: args.root ?? this.sessionContext.cwd,
|
|
220228
|
-
|
|
220229
|
-
|
|
220230
|
-
|
|
220231
|
-
|
|
220232
|
-
ticket: args.ticket,
|
|
220233
|
-
reason: args.reason,
|
|
220234
|
-
replace: args.replace
|
|
220121
|
+
verdicts: args.verdicts,
|
|
220122
|
+
minPoints: args.minPoints,
|
|
220123
|
+
minAxes: args.minAxes,
|
|
220124
|
+
round: args.round
|
|
220235
220125
|
}))
|
|
220236
220126
|
};
|
|
220237
220127
|
}
|
|
220238
220128
|
};
|
|
220239
|
-
|
|
220129
|
+
WaveDecideTool = __decorate([__decorateParam(0, ISessionContext)], WaveDecideTool);
|
|
220130
|
+
}));
|
|
220131
|
+
// ../../packages/agent-core-v2/src/features/wave/tools/gate/gate.ts
|
|
220132
|
+
var WaveGateToolInputSchema, IWaveGateTool;
|
|
220133
|
+
var init_gate$1 = __esmMin((() => {
|
|
220134
|
+
init_zod$1();
|
|
220135
|
+
init_instantiation();
|
|
220136
|
+
WaveGateToolInputSchema = object$1({
|
|
220137
|
+
root: string().optional(),
|
|
220138
|
+
json: boolean$1().optional()
|
|
220139
|
+
}).strict();
|
|
220140
|
+
IWaveGateTool = createDecorator("waveGateTool");
|
|
220240
220141
|
}));
|
|
220241
220142
|
// ../../packages/agent-core-v2/src/features/wave/core/verify/runner.ts
|
|
220242
220143
|
function splitCommand(command) {
|
|
@@ -220881,7 +220782,7 @@ function runWaveGate(fs, root, cfg) {
|
|
|
220881
220782
|
}
|
|
220882
220783
|
});
|
|
220883
220784
|
block("brief", () => {
|
|
220884
|
-
const templateFile = join(root, BRIEF_TEMPLATE);
|
|
220785
|
+
const templateFile = join(root, BRIEF_TEMPLATE$1);
|
|
220885
220786
|
if (!fs.exists(templateFile)) return;
|
|
220886
220787
|
const template = briefSections(fs.read(templateFile) ?? "");
|
|
220887
220788
|
if (wavesDir === void 0 || !fs.isDirectory(wavesDir)) return;
|
|
@@ -220893,11 +220794,11 @@ function runWaveGate(fs, root, cfg) {
|
|
|
220893
220794
|
if (text === void 0) continue;
|
|
220894
220795
|
const at = relative$1(root, file);
|
|
220895
220796
|
const sections = briefSections(text);
|
|
220896
|
-
if (sections.length !== template.length) add("waves.brief_template_drift", at, `${sections.length} secciones frente a ${template.length} de ${BRIEF_TEMPLATE}: el brief ya no sigue la plantilla`);
|
|
220797
|
+
if (sections.length !== template.length) add("waves.brief_template_drift", at, `${sections.length} secciones frente a ${template.length} de ${BRIEF_TEMPLATE$1}: el brief ya no sigue la plantilla`);
|
|
220897
220798
|
for (const [index, expected] of template.entries()) {
|
|
220898
220799
|
const section = sections[index];
|
|
220899
220800
|
if (section === void 0) continue;
|
|
220900
|
-
if (sectionKeyword(section.title) !== sectionKeyword(expected.title)) add("waves.brief_template_drift", at, `la seccion ${index + 1} se titula "${section.title}" y ${BRIEF_TEMPLATE} exige "${expected.title}"`);
|
|
220801
|
+
if (sectionKeyword(section.title) !== sectionKeyword(expected.title)) add("waves.brief_template_drift", at, `la seccion ${index + 1} se titula "${section.title}" y ${BRIEF_TEMPLATE$1} exige "${expected.title}"`);
|
|
220901
220802
|
}
|
|
220902
220803
|
for (const section of sections) if (section.body === "") add("waves.brief_empty_section", at, `la seccion "${section.title}" no tiene contenido`);
|
|
220903
220804
|
}
|
|
@@ -221186,6 +221087,19 @@ function runWaveGate(fs, root, cfg) {
|
|
|
221186
221087
|
}
|
|
221187
221088
|
});
|
|
221188
221089
|
block("hygiene", () => {
|
|
221090
|
+
const wavesDir = join(root, cfg.layout.waves);
|
|
221091
|
+
for (const wave of cfg.waves) {
|
|
221092
|
+
const dir = fs.list(wavesDir).find((entry) => entry === wave || entry.startsWith(`${wave}-`));
|
|
221093
|
+
if (dir === void 0) continue;
|
|
221094
|
+
const contracted = contractedSeats(fs, join(wavesDir, dir, WAVE_CONTRACTS_FILE));
|
|
221095
|
+
if (contracted === void 0) continue;
|
|
221096
|
+
for (const round of WAVE_ROUNDS) for (const role of waveRoundSeats(cfg.roles, round)) {
|
|
221097
|
+
const path = `${cfg.layout.waves}/${dir}/${WAVE_ROUND_DIRS[round]}/${role}.md`;
|
|
221098
|
+
if (!fs.exists(join(root, path))) continue;
|
|
221099
|
+
if (contracted.some((seat) => seat.round === round && seat.role === role)) continue;
|
|
221100
|
+
add("contracts.uncontracted", path, `el asiento ${role} de ${round} entrego sin contrato de WaveContract`);
|
|
221101
|
+
}
|
|
221102
|
+
}
|
|
221189
221103
|
const secrets = cfg.secrets.filter((secret) => secret.length >= 6);
|
|
221190
221104
|
if (secrets.length === 0) return;
|
|
221191
221105
|
const files = [...walk(fs, join(root, cfg.layout.waves), (path) => /\.(md|json|txt)$/.test(path)), ...walk(fs, join(root, cfg.layout.backlog), (path) => /\.(md|json|txt)$/.test(path))];
|
|
@@ -221207,12 +221121,13 @@ function runWaveGate(fs, root, cfg) {
|
|
|
221207
221121
|
}
|
|
221208
221122
|
};
|
|
221209
221123
|
}
|
|
221210
|
-
var DECISION_FILE, BRIEF_TEMPLATE, AC_FIELDS, OPERATOR_WITH_NUMBER, EXACT_VALUE, ASSERTION, escapeRegExp$1, NOT_RUN_BLOCKS, normalize$1, relative$1, DECISION_SEPARATOR, DECISION_PROPOSAL, DECISION_LEADING_NUMBER, DECISION_JUDGE, DECISION_SIGNED_MARGIN;
|
|
221124
|
+
var DECISION_FILE, BRIEF_TEMPLATE$1, AC_FIELDS, OPERATOR_WITH_NUMBER, EXACT_VALUE, ASSERTION, escapeRegExp$1, NOT_RUN_BLOCKS, normalize$1, relative$1, DECISION_SEPARATOR, DECISION_PROPOSAL, DECISION_LEADING_NUMBER, DECISION_JUDGE, DECISION_SIGNED_MARGIN;
|
|
221211
221125
|
var init_checks = __esmMin((() => {
|
|
221212
221126
|
init_config$6();
|
|
221127
|
+
init_seats();
|
|
221213
221128
|
init_runner();
|
|
221214
221129
|
DECISION_FILE = "06-DECISION.md";
|
|
221215
|
-
BRIEF_TEMPLATE = "workflow/templates/brief.md";
|
|
221130
|
+
BRIEF_TEMPLATE$1 = "workflow/templates/brief.md";
|
|
221216
221131
|
AC_FIELDS = [
|
|
221217
221132
|
"id",
|
|
221218
221133
|
"given",
|
|
@@ -221314,6 +221229,290 @@ var init_gateTool = __esmMin((() => {
|
|
|
221314
221229
|
};
|
|
221315
221230
|
WaveGateTool = __decorate([__decorateParam(0, ISessionContext)], WaveGateTool);
|
|
221316
221231
|
}));
|
|
221232
|
+
// ../../packages/agent-core-v2/src/features/wave/tools/open/open.ts
|
|
221233
|
+
var WaveOpenToolInputSchema, IWaveOpenTool;
|
|
221234
|
+
var init_open$1 = __esmMin((() => {
|
|
221235
|
+
init_zod$1();
|
|
221236
|
+
init_instantiation();
|
|
221237
|
+
WaveOpenToolInputSchema = object$1({
|
|
221238
|
+
name: string().min(2),
|
|
221239
|
+
id: string().optional(),
|
|
221240
|
+
root: string().optional()
|
|
221241
|
+
}).strict();
|
|
221242
|
+
IWaveOpenTool = createDecorator("waveOpenTool");
|
|
221243
|
+
}));
|
|
221244
|
+
// ../../packages/agent-core-v2/src/features/wave/tools/open/openRunner.ts
|
|
221245
|
+
function briefTemplate(root) {
|
|
221246
|
+
const fs = nodeWaveFs;
|
|
221247
|
+
const local = join(root, BRIEF_TEMPLATE);
|
|
221248
|
+
if (fs.exists(local)) return { file: local };
|
|
221249
|
+
if (fs.isDirectory(join(root, "workflow"))) return { missing: BRIEF_TEMPLATE };
|
|
221250
|
+
return fs.exists(BUNDLED_BRIEF_TEMPLATE) ? { file: BUNDLED_BRIEF_TEMPLATE } : { missing: BRIEF_TEMPLATE };
|
|
221251
|
+
}
|
|
221252
|
+
function nextEpic(backlogDir) {
|
|
221253
|
+
const numbers = asArray$2(asRecord$2(readJson$2(nodeWaveFs, join(backlogDir, "epics.json")) ?? {})["epics"]).map((epic) => /^E(\d{2,})$/.exec(String(asRecord$2(epic)["id"]))?.[1]).filter((value) => value !== void 0).map(Number);
|
|
221254
|
+
const next = numbers.length > 0 ? Math.max(...numbers) + 1 : 1;
|
|
221255
|
+
return `E${String(next).padStart(2, "0")}`;
|
|
221256
|
+
}
|
|
221257
|
+
function slugify(name) {
|
|
221258
|
+
return name.normalize("NFD").replaceAll(/[\u0300-\u036F]/g, "").toLowerCase().replaceAll(/[^a-z0-9-]+/g, "-").replaceAll(/^-+|-+$/g, "");
|
|
221259
|
+
}
|
|
221260
|
+
function runWaveOpenForRoot(input) {
|
|
221261
|
+
const fs = nodeWaveFs;
|
|
221262
|
+
const configFile = join(input.root, "workflow.config.json");
|
|
221263
|
+
const rawConfig = readJson$2(fs, configFile);
|
|
221264
|
+
if (rawConfig === void 0) return {
|
|
221265
|
+
output: `no hay workflow.config.json en ${input.root}`,
|
|
221266
|
+
isError: true
|
|
221267
|
+
};
|
|
221268
|
+
const layout = asRecord$2(asRecord$2(rawConfig)["layout"]);
|
|
221269
|
+
const wavesRel = typeof layout["waves"] === "string" ? layout["waves"] : "design/waves";
|
|
221270
|
+
const backlogRel = typeof layout["backlog"] === "string" ? layout["backlog"] : "backlog";
|
|
221271
|
+
const minimum = makeWaveConfig(rawConfig).thresholds.minBriefSections;
|
|
221272
|
+
let wavesDir;
|
|
221273
|
+
let backlogDir;
|
|
221274
|
+
try {
|
|
221275
|
+
wavesDir = containedPath(input.root, wavesRel);
|
|
221276
|
+
backlogDir = containedPath(input.root, backlogRel);
|
|
221277
|
+
} catch (error) {
|
|
221278
|
+
return {
|
|
221279
|
+
output: error instanceof Error ? error.message : String(error),
|
|
221280
|
+
isError: true
|
|
221281
|
+
};
|
|
221282
|
+
}
|
|
221283
|
+
const template = briefTemplate(input.root);
|
|
221284
|
+
if (template.file === void 0) return {
|
|
221285
|
+
output: `falta ${template.missing ?? BRIEF_TEMPLATE}: no se genera un brief sin la plantilla unica`,
|
|
221286
|
+
isError: true
|
|
221287
|
+
};
|
|
221288
|
+
const source = fs.read(template.file);
|
|
221289
|
+
if (source === void 0) return {
|
|
221290
|
+
output: `no se pudo leer ${template.file}`,
|
|
221291
|
+
isError: true
|
|
221292
|
+
};
|
|
221293
|
+
const existing = fs.list(wavesDir).filter((name) => fs.isDirectory(join(wavesDir, name))).map((name) => Number(/^W(\d+)/.exec(name)?.[1] ?? NaN)).filter((value) => !Number.isNaN(value));
|
|
221294
|
+
const next = input.id ?? `W${existing.length > 0 ? Math.max(...existing) + 1 : 0}`;
|
|
221295
|
+
if (!/^W\d{1,2}$/.test(next)) return {
|
|
221296
|
+
output: `id de oleada invalido "${next}"`,
|
|
221297
|
+
isError: true
|
|
221298
|
+
};
|
|
221299
|
+
const slug = slugify(input.name);
|
|
221300
|
+
if (slug === "") return {
|
|
221301
|
+
output: "el nombre de la oleada queda vacio al normalizarlo",
|
|
221302
|
+
isError: true
|
|
221303
|
+
};
|
|
221304
|
+
if (fs.list(wavesDir).some((name) => name === next || name.startsWith(`${next}-`))) return {
|
|
221305
|
+
output: `la oleada ${next} ya existe`,
|
|
221306
|
+
isError: true
|
|
221307
|
+
};
|
|
221308
|
+
const dir = join(wavesDir, `${next}-${slug}`);
|
|
221309
|
+
const brief = source.replaceAll("{{WAVE}}", next).replaceAll("{{NAME}}", slug).replaceAll("{{NEXT_EPIC}}", nextEpic(backlogDir));
|
|
221310
|
+
for (const sub of SUBDIRS) fs.mkdir(join(dir, sub));
|
|
221311
|
+
fs.write(join(dir, "00-brief.md"), brief);
|
|
221312
|
+
const declared = asArray$2(asRecord$2(rawConfig)["waves"]).map(String);
|
|
221313
|
+
if (!declared.includes(next)) writeJson(fs, configFile, {
|
|
221314
|
+
...asRecord$2(rawConfig),
|
|
221315
|
+
waves: [...declared, next].toSorted()
|
|
221316
|
+
});
|
|
221317
|
+
return { output: [
|
|
221318
|
+
`oleada creada: ${next}-${slug}`,
|
|
221319
|
+
` brief: ${wavesRel}/${next}-${slug}/00-brief.md (rellena las ${minimum} secciones antes de lanzar asientos)`,
|
|
221320
|
+
` config: ${next} declarada en workflow.config.json (el gate la exige desde ahora)`
|
|
221321
|
+
].join("\n") };
|
|
221322
|
+
}
|
|
221323
|
+
var SUBDIRS, BRIEF_TEMPLATE, BUNDLED_BRIEF_TEMPLATE;
|
|
221324
|
+
var init_openRunner = __esmMin((() => {
|
|
221325
|
+
init_config$6();
|
|
221326
|
+
init_fsJson();
|
|
221327
|
+
init_nodeFs();
|
|
221328
|
+
SUBDIRS = [
|
|
221329
|
+
"01-proposals",
|
|
221330
|
+
"02-defenses",
|
|
221331
|
+
"03-attacks",
|
|
221332
|
+
"04-verdicts",
|
|
221333
|
+
"05-refined"
|
|
221334
|
+
];
|
|
221335
|
+
BRIEF_TEMPLATE = "workflow/templates/brief.md";
|
|
221336
|
+
BUNDLED_BRIEF_TEMPLATE = resolve(import.meta.dirname, "../../../../../../../workflow/templates/brief.md");
|
|
221337
|
+
}));
|
|
221338
|
+
// ../../packages/agent-core-v2/src/features/wave/tools/open/open.md?raw
|
|
221339
|
+
var open_default;
|
|
221340
|
+
var init_open = __esmMin((() => {
|
|
221341
|
+
open_default = "Open a wave: create its artifact tree and a brief skeleton, and declare the wave in `workflow.config.json`.\n\nThe brief starts with the seven mandatory sections and nothing else — a brief that already contains the answer makes the twelve seats theatre. Fill it before launching any seat; the gate rejects a brief with fewer than seven sections.\n\nOpening a wave also declares it in the config, so the package gate will require its artifacts from then on.\n";
|
|
221342
|
+
}));
|
|
221343
|
+
// ../../packages/agent-core-v2/src/features/wave/tools/open/openTool.ts
|
|
221344
|
+
var WaveOpenTool;
|
|
221345
|
+
var init_openTool = __esmMin((() => {
|
|
221346
|
+
init_sessionContext();
|
|
221347
|
+
init_input_schema();
|
|
221348
|
+
init_open$1();
|
|
221349
|
+
init_openRunner();
|
|
221350
|
+
init_open();
|
|
221351
|
+
init_decorateParam();
|
|
221352
|
+
init_decorate();
|
|
221353
|
+
WaveOpenTool = class WaveOpenTool {
|
|
221354
|
+
sessionContext;
|
|
221355
|
+
name = "WaveOpen";
|
|
221356
|
+
description = open_default;
|
|
221357
|
+
parameters = toInputJsonSchema(WaveOpenToolInputSchema);
|
|
221358
|
+
constructor(sessionContext) {
|
|
221359
|
+
this.sessionContext = sessionContext;
|
|
221360
|
+
}
|
|
221361
|
+
resolveExecution(args) {
|
|
221362
|
+
return {
|
|
221363
|
+
description: `Opening wave ${args.name}`,
|
|
221364
|
+
approvalRule: this.name,
|
|
221365
|
+
execute: () => Promise.resolve(runWaveOpenForRoot({
|
|
221366
|
+
root: args.root ?? this.sessionContext.cwd,
|
|
221367
|
+
name: args.name,
|
|
221368
|
+
id: args.id
|
|
221369
|
+
}))
|
|
221370
|
+
};
|
|
221371
|
+
}
|
|
221372
|
+
};
|
|
221373
|
+
WaveOpenTool = __decorate([__decorateParam(0, ISessionContext)], WaveOpenTool);
|
|
221374
|
+
}));
|
|
221375
|
+
// ../../packages/agent-core-v2/src/features/wave/tools/submit/submit.ts
|
|
221376
|
+
var WaveSubmitToolInputSchema, IWaveSubmitTool;
|
|
221377
|
+
var init_submit$1 = __esmMin((() => {
|
|
221378
|
+
init_zod$1();
|
|
221379
|
+
init_instantiation();
|
|
221380
|
+
WaveSubmitToolInputSchema = object$1({
|
|
221381
|
+
wave: string().min(2),
|
|
221382
|
+
round: _enum([
|
|
221383
|
+
"propose",
|
|
221384
|
+
"defend",
|
|
221385
|
+
"attack",
|
|
221386
|
+
"judge",
|
|
221387
|
+
"refine",
|
|
221388
|
+
"audit"
|
|
221389
|
+
]),
|
|
221390
|
+
role: string().min(2),
|
|
221391
|
+
artifact: string().min(1),
|
|
221392
|
+
ticket: string().optional(),
|
|
221393
|
+
reason: string().optional(),
|
|
221394
|
+
replace: boolean$1().optional(),
|
|
221395
|
+
root: string().optional()
|
|
221396
|
+
}).strict();
|
|
221397
|
+
IWaveSubmitTool = createDecorator("waveSubmitTool");
|
|
221398
|
+
}));
|
|
221399
|
+
// ../../packages/agent-core-v2/src/features/wave/tools/submit/submitRunner.ts
|
|
221400
|
+
function findWaveDir(root, wavesRel, wave) {
|
|
221401
|
+
const fs = nodeWaveFs;
|
|
221402
|
+
const wavesDir = containedPath(root, wavesRel);
|
|
221403
|
+
const name = fs.list(wavesDir).filter((entry) => fs.isDirectory(join(wavesDir, entry))).find((entry) => entry === wave || entry.startsWith(`${wave}-`));
|
|
221404
|
+
return name === void 0 ? void 0 : join(wavesDir, name);
|
|
221405
|
+
}
|
|
221406
|
+
function runWaveSubmitForRoot(input) {
|
|
221407
|
+
const fs = nodeWaveFs;
|
|
221408
|
+
const rawConfig = readJson$2(fs, join(input.root, "workflow.config.json"));
|
|
221409
|
+
if (rawConfig === void 0) return {
|
|
221410
|
+
output: `no hay workflow.config.json en ${input.root}`,
|
|
221411
|
+
isError: true
|
|
221412
|
+
};
|
|
221413
|
+
const config = makeWaveConfig(rawConfig);
|
|
221414
|
+
const wavesRel = config.layout.waves;
|
|
221415
|
+
const seats = waveRoundSeats(config.roles, input.round);
|
|
221416
|
+
if (!seats.includes(input.role)) return {
|
|
221417
|
+
output: `seats.unknown_seat: el rol "${input.role}" no pertenece a la ronda ${input.round} (esperado ${seats.join(", ")})`,
|
|
221418
|
+
isError: true
|
|
221419
|
+
};
|
|
221420
|
+
let base;
|
|
221421
|
+
try {
|
|
221422
|
+
base = findWaveDir(input.root, wavesRel, input.wave);
|
|
221423
|
+
} catch (error) {
|
|
221424
|
+
return {
|
|
221425
|
+
output: error instanceof Error ? error.message : String(error),
|
|
221426
|
+
isError: true
|
|
221427
|
+
};
|
|
221428
|
+
}
|
|
221429
|
+
if (base === void 0) return {
|
|
221430
|
+
output: `no existe la oleada ${input.wave} en ${wavesRel}`,
|
|
221431
|
+
isError: true
|
|
221432
|
+
};
|
|
221433
|
+
const dirName = WAVE_ROUND_DIRS[input.round];
|
|
221434
|
+
const dir = join(base, dirName);
|
|
221435
|
+
if (!fs.isDirectory(dir)) return {
|
|
221436
|
+
output: `falta el directorio ${dirName} en la oleada ${input.wave}`,
|
|
221437
|
+
isError: true
|
|
221438
|
+
};
|
|
221439
|
+
const seatsDir = join(base, WAVE_SEATS_DIR);
|
|
221440
|
+
if (fs.isDirectory(seatsDir) && fs.list(seatsDir).length > 0) {
|
|
221441
|
+
const presented = (input.ticket ?? "").trim();
|
|
221442
|
+
if (presented === "") return {
|
|
221443
|
+
output: `seats.foreign_replace: el asiento ${input.role} no presento el ticket que emitio la ronda`,
|
|
221444
|
+
isError: true
|
|
221445
|
+
};
|
|
221446
|
+
const stored = (fs.read(join(seatsDir, input.role)) ?? "").trim();
|
|
221447
|
+
if (stored === "" || stored !== seatTicketHash(presented)) return {
|
|
221448
|
+
output: `seats.foreign_replace: el ticket presentado no es el del asiento ${input.role}`,
|
|
221449
|
+
isError: true
|
|
221450
|
+
};
|
|
221451
|
+
if (input.replace === true && (input.reason ?? "").trim() === "") return {
|
|
221452
|
+
output: `seats.replace_without_reason: reescribir el artefacto del asiento ${input.role} exige un motivo no vacio`,
|
|
221453
|
+
isError: true
|
|
221454
|
+
};
|
|
221455
|
+
}
|
|
221456
|
+
const file = join(dir, `${input.role}.md`);
|
|
221457
|
+
if (fs.exists(file) && input.replace !== true) return {
|
|
221458
|
+
output: `el asiento ${input.role} ya entrego su artefacto; un asiento escribe una vez (usa replace solo para relanzar un fallo)`,
|
|
221459
|
+
isError: true
|
|
221460
|
+
};
|
|
221461
|
+
if (input.artifact.trim() === "") return {
|
|
221462
|
+
output: "el artefacto esta vacio: un asiento que no escribe, fallo",
|
|
221463
|
+
isError: true
|
|
221464
|
+
};
|
|
221465
|
+
fs.write(file, input.artifact.endsWith("\n") ? input.artifact : `${input.artifact}\n`);
|
|
221466
|
+
return { output: `escrito ${wavesRel}/${base.split("/").pop()}/${dirName}/${input.role}.md` };
|
|
221467
|
+
}
|
|
221468
|
+
var init_submitRunner = __esmMin((() => {
|
|
221469
|
+
init_config$6();
|
|
221470
|
+
init_fsJson();
|
|
221471
|
+
init_nodeFs();
|
|
221472
|
+
init_seats();
|
|
221473
|
+
}));
|
|
221474
|
+
// ../../packages/agent-core-v2/src/features/wave/tools/submit/submit.md?raw
|
|
221475
|
+
var submit_default;
|
|
221476
|
+
var init_submit = __esmMin((() => {
|
|
221477
|
+
submit_default = "Deliver the artifact for your seat. This is the only way a seat writes: the tool binds the role to its slot and refuses anything else.\n\nRole and round must match — `propose` accepts P1..Pn, `defend` D1..Dn, `attack` A1..An, `judge` J1..Jn, `refine` R1, `audit` R2..Rn. A seat writes once; use `replace` only to relaunch a failed seat after its artifact was already written.\n\nPass the `ticket` the round gave you: the tool hashes it and compares it with the sha256 the round left in `design/waves/<W>/.seats/<role>`. A missing ticket, or the ticket of another seat, is refused as `seats.foreign_replace`. The ticket is capacity, not identity (capacidad, no identidad): it proves the orchestrator issued this seat, it does not say who wrote the artifact. `replace` also needs a non-empty `reason`, or the tool refuses it as `seats.replace_without_reason`: a silent overwrite is the substitution this tool exists to prevent.\n\nPass the artifact as the text/JSON body. An empty artifact is rejected: a seat that did not write has failed, and the round must be relaunched rather than summarized by the orchestrator.\n";
|
|
221478
|
+
}));
|
|
221479
|
+
// ../../packages/agent-core-v2/src/features/wave/tools/submit/submitTool.ts
|
|
221480
|
+
var WaveSubmitTool;
|
|
221481
|
+
var init_submitTool = __esmMin((() => {
|
|
221482
|
+
init_sessionContext();
|
|
221483
|
+
init_input_schema();
|
|
221484
|
+
init_submit$1();
|
|
221485
|
+
init_submitRunner();
|
|
221486
|
+
init_submit();
|
|
221487
|
+
init_decorateParam();
|
|
221488
|
+
init_decorate();
|
|
221489
|
+
WaveSubmitTool = class WaveSubmitTool {
|
|
221490
|
+
sessionContext;
|
|
221491
|
+
name = "WaveSubmit";
|
|
221492
|
+
description = submit_default;
|
|
221493
|
+
parameters = toInputJsonSchema(WaveSubmitToolInputSchema);
|
|
221494
|
+
constructor(sessionContext) {
|
|
221495
|
+
this.sessionContext = sessionContext;
|
|
221496
|
+
}
|
|
221497
|
+
resolveExecution(args) {
|
|
221498
|
+
return {
|
|
221499
|
+
description: `Submitting ${args.role}`,
|
|
221500
|
+
approvalRule: this.name,
|
|
221501
|
+
execute: () => Promise.resolve(runWaveSubmitForRoot({
|
|
221502
|
+
root: args.root ?? this.sessionContext.cwd,
|
|
221503
|
+
wave: args.wave,
|
|
221504
|
+
round: args.round,
|
|
221505
|
+
role: args.role,
|
|
221506
|
+
artifact: args.artifact,
|
|
221507
|
+
ticket: args.ticket,
|
|
221508
|
+
reason: args.reason,
|
|
221509
|
+
replace: args.replace
|
|
221510
|
+
}))
|
|
221511
|
+
};
|
|
221512
|
+
}
|
|
221513
|
+
};
|
|
221514
|
+
WaveSubmitTool = __decorate([__decorateParam(0, ISessionContext)], WaveSubmitTool);
|
|
221515
|
+
}));
|
|
221317
221516
|
// ../../packages/agent-core-v2/src/features/wave/tools/verify/verify.ts
|
|
221318
221517
|
var WaveVerifyToolInputSchema, IWaveVerifyTool;
|
|
221319
221518
|
var init_verify$1 = __esmMin((() => {
|
|
@@ -221428,28 +221627,35 @@ var init_verifyTool = __esmMin((() => {
|
|
|
221428
221627
|
WaveVerifyTool = __decorate([__decorateParam(0, ISessionContext)], WaveVerifyTool);
|
|
221429
221628
|
}));
|
|
221430
221629
|
// ../../packages/agent-core-v2/src/features/wave/waveFeature.ts
|
|
221630
|
+
function profileHolds(accessor, profile) {
|
|
221631
|
+
return accessor.get(IAgentProfileService).data().profileName === profile;
|
|
221632
|
+
}
|
|
221431
221633
|
function isWaveFeatureAssembled(flags) {
|
|
221432
221634
|
return assembledOverrideForTests ?? assembledFlagServices.has(flags);
|
|
221433
221635
|
}
|
|
221434
221636
|
var WAVE_TOOL_CONTRIBUTIONS, WaveFeature, assembledFlagServices, assembledOverrideForTests;
|
|
221435
221637
|
var init_waveFeature = __esmMin((() => {
|
|
221638
|
+
init_instantiation();
|
|
221639
|
+
init_profile$1();
|
|
221436
221640
|
init_flag$7();
|
|
221437
221641
|
init_feature();
|
|
221438
221642
|
init_featureRegistry();
|
|
221439
|
-
|
|
221643
|
+
init_waveService();
|
|
221644
|
+
init_waveMode();
|
|
221440
221645
|
init_seatProfile();
|
|
221646
|
+
init_contract$4();
|
|
221647
|
+
init_contractTool();
|
|
221441
221648
|
init_decide$1();
|
|
221442
221649
|
init_decideTool();
|
|
221443
221650
|
init_gate$1();
|
|
221651
|
+
init_gateTool();
|
|
221444
221652
|
init_open$1();
|
|
221445
221653
|
init_openTool();
|
|
221446
|
-
init_round$1();
|
|
221447
|
-
init_roundTool();
|
|
221448
221654
|
init_submit$1();
|
|
221449
221655
|
init_submitTool();
|
|
221450
|
-
init_gateTool();
|
|
221451
221656
|
init_verify$1();
|
|
221452
221657
|
init_verifyTool();
|
|
221658
|
+
init_wave$3();
|
|
221453
221659
|
init_decorateParam();
|
|
221454
221660
|
init_decorate();
|
|
221455
221661
|
WAVE_TOOL_CONTRIBUTIONS = [
|
|
@@ -221473,15 +221679,15 @@ var init_waveFeature = __esmMin((() => {
|
|
|
221473
221679
|
ctor: WaveOpenTool,
|
|
221474
221680
|
name: "WaveOpen"
|
|
221475
221681
|
},
|
|
221682
|
+
{
|
|
221683
|
+
id: IWaveContractTool,
|
|
221684
|
+
ctor: WaveContractTool,
|
|
221685
|
+
name: "WaveContract"
|
|
221686
|
+
},
|
|
221476
221687
|
{
|
|
221477
221688
|
id: IWaveSubmitTool,
|
|
221478
221689
|
ctor: WaveSubmitTool,
|
|
221479
221690
|
name: "WaveSubmit"
|
|
221480
|
-
},
|
|
221481
|
-
{
|
|
221482
|
-
id: IWaveRoundTool,
|
|
221483
|
-
ctor: WaveRoundTool,
|
|
221484
|
-
name: "WaveRound"
|
|
221485
221691
|
}
|
|
221486
221692
|
];
|
|
221487
221693
|
WaveFeature = class WaveFeature extends Feature {
|
|
@@ -221493,10 +221699,15 @@ var init_waveFeature = __esmMin((() => {
|
|
|
221493
221699
|
this.onDispose(() => {
|
|
221494
221700
|
assembledFlagServices.delete(flags);
|
|
221495
221701
|
});
|
|
221496
|
-
|
|
221497
|
-
|
|
221498
|
-
|
|
221499
|
-
|
|
221702
|
+
this.contributeAgentService(IAgentWaveService, AgentWaveService, { activation: 0 });
|
|
221703
|
+
for (const tool of WAVE_TOOL_CONTRIBUTIONS) {
|
|
221704
|
+
const profile = tool.name === "WaveSubmit" ? WAVE_SEAT_PROFILE : WAVE_DIRECTOR_PROFILE;
|
|
221705
|
+
this.contributeTool(tool.id, tool.ctor, {
|
|
221706
|
+
name: tool.name,
|
|
221707
|
+
domain: WAVE_TOOL_DOMAIN,
|
|
221708
|
+
when: (accessor) => profileHolds(accessor, profile)
|
|
221709
|
+
});
|
|
221710
|
+
}
|
|
221500
221711
|
this.contributeProfiles([WAVE_SEAT_PROFILE_DEF]);
|
|
221501
221712
|
}
|
|
221502
221713
|
};
|
|
@@ -221521,6 +221732,27 @@ var init_flag$2 = __esmMin((() => {
|
|
|
221521
221732
|
};
|
|
221522
221733
|
registerFlagDefinition(waveFlag);
|
|
221523
221734
|
}));
|
|
221735
|
+
var init_round = __esmMin((() => {
|
|
221736
|
+
init_zod$1();
|
|
221737
|
+
init_instantiation();
|
|
221738
|
+
object$1({
|
|
221739
|
+
wave: string().min(2),
|
|
221740
|
+
round: _enum([
|
|
221741
|
+
"propose",
|
|
221742
|
+
"defend",
|
|
221743
|
+
"attack",
|
|
221744
|
+
"judge",
|
|
221745
|
+
"refine",
|
|
221746
|
+
"audit"
|
|
221747
|
+
]),
|
|
221748
|
+
root: string().optional()
|
|
221749
|
+
}).strict();
|
|
221750
|
+
createDecorator("waveRoundTool");
|
|
221751
|
+
}));
|
|
221752
|
+
// ../../packages/agent-core-v2/src/features/wave/tools/round/roundRunner.ts
|
|
221753
|
+
var init_roundRunner = __esmMin((() => {
|
|
221754
|
+
init_prompts$2();
|
|
221755
|
+
}));
|
|
221524
221756
|
// ../../packages/agent-core-v2/src/agent/usage/cacheProbe.ts
|
|
221525
221757
|
var IAgentCacheProbeService;
|
|
221526
221758
|
var init_cacheProbe = __esmMin((() => {
|
|
@@ -224085,6 +224317,7 @@ var AGENT_TOOLS, CODER_TOOLS, EXPLORE_TOOLS, CODER_ROLE;
|
|
|
224085
224317
|
var init_profiles = __esmMin((() => {
|
|
224086
224318
|
init_gitContext();
|
|
224087
224319
|
init_contribution();
|
|
224320
|
+
init_wave$3();
|
|
224088
224321
|
init_profile_shared();
|
|
224089
224322
|
init_explore_overlay();
|
|
224090
224323
|
AGENT_TOOLS = [
|
|
@@ -224119,6 +224352,8 @@ var init_profiles = __esmMin((() => {
|
|
|
224119
224352
|
"TowerStatus",
|
|
224120
224353
|
"TowerTeardown",
|
|
224121
224354
|
"WaveOpen",
|
|
224355
|
+
"WaveRound",
|
|
224356
|
+
"WaveContract",
|
|
224122
224357
|
"WaveSubmit",
|
|
224123
224358
|
"WaveGate",
|
|
224124
224359
|
"WaveDecide",
|
|
@@ -224165,7 +224400,8 @@ var init_profiles = __esmMin((() => {
|
|
|
224165
224400
|
subagents: [
|
|
224166
224401
|
"coder",
|
|
224167
224402
|
"explore",
|
|
224168
|
-
"plan"
|
|
224403
|
+
"plan",
|
|
224404
|
+
WAVE_SEAT_PROFILE
|
|
224169
224405
|
],
|
|
224170
224406
|
renderSystemPrompt: (context) => renderSystemPromptResult("", context, { skillActive: skillActiveFor(AGENT_TOOLS) })
|
|
224171
224407
|
});
|
|
@@ -282337,6 +282573,8 @@ var init_src$10 = __esmMin((() => {
|
|
|
282337
282573
|
init_flag$2();
|
|
282338
282574
|
init_wave$3();
|
|
282339
282575
|
init_waveFeature();
|
|
282576
|
+
init_waveMode();
|
|
282577
|
+
init_waveOps();
|
|
282340
282578
|
init_gate$1();
|
|
282341
282579
|
init_gateRunner();
|
|
282342
282580
|
init_decide$1();
|
|
@@ -282348,9 +282586,12 @@ var init_src$10 = __esmMin((() => {
|
|
|
282348
282586
|
init_submit$1();
|
|
282349
282587
|
init_submitRunner();
|
|
282350
282588
|
init_seatProfile();
|
|
282351
|
-
init_round
|
|
282589
|
+
init_round();
|
|
282352
282590
|
init_roundRunner();
|
|
282353
282591
|
init_prompts$2();
|
|
282592
|
+
init_seats();
|
|
282593
|
+
init_contract$4();
|
|
282594
|
+
init_contractRunner();
|
|
282354
282595
|
init_flag$2();
|
|
282355
282596
|
init_waveFeature();
|
|
282356
282597
|
init_usage();
|
|
@@ -288686,6 +288927,7 @@ var init_sdk_rpc_client_v2 = __esmMin((() => {
|
|
|
288686
288927
|
init_connection_manager();
|
|
288687
288928
|
init_towerRateLimit();
|
|
288688
288929
|
init_statusReader();
|
|
288930
|
+
init_waveMode();
|
|
288689
288931
|
init_configLoader();
|
|
288690
288932
|
init_fs$1();
|
|
288691
288933
|
init_appendLogStore$1();
|
|
@@ -289971,6 +290213,7 @@ var init_sdk_rpc_client_v2 = __esmMin((() => {
|
|
|
289971
290213
|
permission: agent.accessor.get(IAgentPermissionModeService).mode,
|
|
289972
290214
|
planMode: plan !== null,
|
|
289973
290215
|
swarmMode: agent.accessor.get(IAgentSwarmService).isActive,
|
|
290216
|
+
waveMode: agent.accessor.get(IAgentWaveService).isActive,
|
|
289974
290217
|
towerMode: agent.accessor.get(IAgentTowerService).isActive,
|
|
289975
290218
|
contextTokens,
|
|
289976
290219
|
maxContextTokens,
|
|
@@ -290258,6 +290501,11 @@ var init_sdk_rpc_client_v2 = __esmMin((() => {
|
|
|
290258
290501
|
});
|
|
290259
290502
|
return this.prompt(input);
|
|
290260
290503
|
}
|
|
290504
|
+
async setWaveMode(input) {
|
|
290505
|
+
const wave = (await this.agentScope(input.sessionId)).accessor.get(IAgentWaveService);
|
|
290506
|
+
if (input.enabled) await wave.enter();
|
|
290507
|
+
else await wave.exit();
|
|
290508
|
+
}
|
|
290261
290509
|
/** Through the agent scope (`IAgentTowerService.enter` / `.exit`) — no klient facade exists. */
|
|
290262
290510
|
async setTowerMode(input) {
|
|
290263
290511
|
const agent = await this.agentScope(input.sessionId);
|
|
@@ -395450,11 +395698,9 @@ var init_registry$2 = __esmMin((() => {
|
|
|
395450
395698
|
{
|
|
395451
395699
|
name: "wave",
|
|
395452
395700
|
aliases: [],
|
|
395453
|
-
description: "
|
|
395701
|
+
description: "Turn the wave mode on or off, or open a design wave with an objective",
|
|
395454
395702
|
priority: 90,
|
|
395455
|
-
argumentHint: "<objetivo de la oleada>"
|
|
395456
|
-
availability: "idle-only",
|
|
395457
|
-
experimentalFlag: "wave"
|
|
395703
|
+
argumentHint: "[on|off] | <objetivo de la oleada>"
|
|
395458
395704
|
},
|
|
395459
395705
|
{
|
|
395460
395706
|
name: "model",
|
|
@@ -472337,6 +472583,7 @@ var init_footer = __esmMin((() => {
|
|
|
472337
472583
|
if (state.permissionMode === "yolo") modes.push(chalk.hex(colors.warning).bold(PERMISSION_MODE_DISPLAY_NAMES.yolo));
|
|
472338
472584
|
if (state.planMode) modes.push(chalk.hex(colors.primary).bold("plan"));
|
|
472339
472585
|
if (state.swarmMode) modes.push(chalk.hex(colors.accent).bold("swarm"));
|
|
472586
|
+
if (state.waveMode) modes.push(chalk.hex(colors.accent).bold("wave"));
|
|
472340
472587
|
if (state.towerMode) modes.push(chalk.hex(colors.accent).bold("tower"));
|
|
472341
472588
|
if (modes.length > 0) slots["mode"] = [modes.join(" ")];
|
|
472342
472589
|
const goalBadge = formatGoalBadge(state.goal, colors, this.goalWallClockMs(state.goal));
|
|
@@ -478074,30 +478321,58 @@ var init_swarm = __esmMin((() => {
|
|
|
478074
478321
|
SWARM_USAGE_NOTICE = "High usage: Swarm is built for large parallel jobs and can use many times the tokens of a normal task. Start small, and run /swarm off when you're done.";
|
|
478075
478322
|
}));
|
|
478076
478323
|
// src/tui/commands/wave.ts
|
|
478077
|
-
function buildWavePrompt(
|
|
478324
|
+
function buildWavePrompt(objective) {
|
|
478078
478325
|
return [
|
|
478079
|
-
`
|
|
478326
|
+
`Abre una oleada del método workflow para: ${objective}`,
|
|
478080
478327
|
"",
|
|
478081
|
-
"Reglas
|
|
478082
|
-
"-
|
|
478083
|
-
"-
|
|
478084
|
-
"-
|
|
478085
|
-
"-
|
|
478086
|
-
"- Sin `adopt` de `WaveDecide`, lanza `refine` y después `audit`; con dos rondas sin quórum, adopta R1 con disidencia escrita.",
|
|
478087
|
-
"- La oleada no está cerrada hasta que `WaveGate` sale en verde. Si sale en rojo, dilo con los códigos de hallazgo."
|
|
478328
|
+
"Reglas:",
|
|
478329
|
+
"- Redacta primero el plan de la oleada (WaveOpen con nombre, alcance, evidencia y rondas) y crea el Goal con completionCriterion \"WaveGate verde sobre la oleada W<n> y WaveVerify 0 en todas sus tasks\".",
|
|
478330
|
+
"- No ejecutes la oleada en este turno: el plan se revisa antes de aprobarse.",
|
|
478331
|
+
"- Tras la aprobación, contrata con WaveContract y lanza un agente `wave-seat` por asiento. Tú no escribes artefactos: WaveSubmit es del asiento.",
|
|
478332
|
+
"- Cierras con WaveDecide, WaveVerify y WaveGate; la oleada no está cerrada hasta que WaveGate sale en verde."
|
|
478088
478333
|
].join("\n");
|
|
478089
478334
|
}
|
|
478090
478335
|
async function handleWaveCommand(host, args) {
|
|
478091
|
-
const
|
|
478092
|
-
if (
|
|
478093
|
-
host.
|
|
478336
|
+
const session = host.session;
|
|
478337
|
+
if (session === void 0) {
|
|
478338
|
+
host.showError(NO_ACTIVE_SESSION_MESSAGE);
|
|
478094
478339
|
return;
|
|
478095
478340
|
}
|
|
478096
|
-
|
|
478341
|
+
const input = args.trim();
|
|
478342
|
+
const command = input.toLowerCase();
|
|
478343
|
+
if (command === "on" || command === "off" || command === "") {
|
|
478344
|
+
await applyWaveMode(host, command === "" ? !host.state.appState.waveMode : command === "on");
|
|
478345
|
+
return;
|
|
478346
|
+
}
|
|
478347
|
+
if (!host.state.appState.waveMode && !await applyWaveMode(host, true)) return;
|
|
478348
|
+
if (!host.state.appState.planMode) await applyPlanMode(host, session, true);
|
|
478349
|
+
host.sendNormalUserInput(buildWavePrompt(input));
|
|
478350
|
+
}
|
|
478351
|
+
async function applyWaveMode(host, enabled) {
|
|
478352
|
+
if (enabled === host.state.appState.waveMode) {
|
|
478353
|
+
host.showStatus(`Wave mode is already ${enabled ? "on" : "off"}.`);
|
|
478354
|
+
return true;
|
|
478355
|
+
}
|
|
478356
|
+
try {
|
|
478357
|
+
await host.requireSession().setWaveMode(enabled);
|
|
478358
|
+
} catch (error) {
|
|
478359
|
+
host.showError(`Failed to ${enabled ? "enable" : "disable"} wave mode: ${formatErrorMessage$2(error)}`);
|
|
478360
|
+
return false;
|
|
478361
|
+
}
|
|
478362
|
+
host.setAppState({ waveMode: enabled });
|
|
478363
|
+
host.showNotice(`Wave mode: ${enabled ? "ON" : "OFF"}`);
|
|
478364
|
+
return true;
|
|
478097
478365
|
}
|
|
478098
|
-
var WAVE_USAGE;
|
|
478099
478366
|
var init_wave = __esmMin((() => {
|
|
478100
|
-
|
|
478367
|
+
init_nexgenk_tui();
|
|
478368
|
+
init_event_payload();
|
|
478369
|
+
init_config();
|
|
478370
|
+
[
|
|
478371
|
+
"Uso:",
|
|
478372
|
+
" /wave enciende o apaga el modo wave",
|
|
478373
|
+
" /wave off lo apaga",
|
|
478374
|
+
" /wave <objetivo> lo enciende y abre el plan de una oleada"
|
|
478375
|
+
].join("\n");
|
|
478101
478376
|
}));
|
|
478102
478377
|
// src/tui/commands/tower.ts
|
|
478103
478378
|
async function handleTowerCommand(host, args) {
|
|
@@ -494813,6 +495088,7 @@ var SessionEventHandler = class {
|
|
|
494813
495088
|
}
|
|
494814
495089
|
if (event.planMode !== void 0) patch.planMode = event.planMode;
|
|
494815
495090
|
if (event.swarmMode !== void 0) patch.swarmMode = event.swarmMode;
|
|
495091
|
+
if (event.waveMode !== void 0) patch.waveMode = event.waveMode;
|
|
494816
495092
|
if (event.towerMode !== void 0) patch.towerMode = event.towerMode;
|
|
494817
495093
|
if (event.permission !== void 0) patch.permissionMode = event.permission;
|
|
494818
495094
|
if (event.model !== void 0) patch.model = event.model;
|
|
@@ -499981,6 +500257,7 @@ function createInitialAppState(input) {
|
|
|
499981
500257
|
planMode: input.cliOptions.plan,
|
|
499982
500258
|
inputMode: "prompt",
|
|
499983
500259
|
swarmMode: false,
|
|
500260
|
+
waveMode: false,
|
|
499984
500261
|
towerMode: false,
|
|
499985
500262
|
thinkingEffort: "off",
|
|
499986
500263
|
contextUsage: 0,
|
|
@@ -501750,6 +502027,7 @@ var NexgenTUI = class {
|
|
|
501750
502027
|
permissionMode: status.permission,
|
|
501751
502028
|
planMode: status.planMode,
|
|
501752
502029
|
swarmMode: status.swarmMode ?? false,
|
|
502030
|
+
waveMode: status.waveMode ?? false,
|
|
501753
502031
|
towerMode: status.towerMode ?? false,
|
|
501754
502032
|
contextTokens: status.contextTokens,
|
|
501755
502033
|
maxContextTokens: status.maxContextTokens,
|