oficina-opencode 0.0.0-stage → 2.0.1
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/DESIGN.md +145 -0
- package/LICENSE +21 -0
- package/README.md +670 -2
- package/agents/oficina-architect.md +72 -0
- package/agents/oficina-commander.md +108 -0
- package/agents/oficina-critico.md +148 -0
- package/agents/oficina-director.md +160 -0
- package/agents/oficina-guardian.md +128 -0
- package/agents/oficina-integrator.md +98 -0
- package/agents/oficina-verificador.md +88 -0
- package/commands/oficina.md +36 -0
- package/dist/cli.d.ts +12 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +394 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/briefing.d.ts +115 -0
- package/dist/core/briefing.d.ts.map +1 -0
- package/dist/core/briefing.js +410 -0
- package/dist/core/briefing.js.map +1 -0
- package/dist/core/bus.d.ts +132 -0
- package/dist/core/bus.d.ts.map +1 -0
- package/dist/core/bus.js +250 -0
- package/dist/core/bus.js.map +1 -0
- package/dist/core/catalog.d.ts +303 -0
- package/dist/core/catalog.d.ts.map +1 -0
- package/dist/core/catalog.js +816 -0
- package/dist/core/catalog.js.map +1 -0
- package/dist/core/dispatch.d.ts +110 -0
- package/dist/core/dispatch.d.ts.map +1 -0
- package/dist/core/dispatch.js +301 -0
- package/dist/core/dispatch.js.map +1 -0
- package/dist/core/factory.d.ts +74 -0
- package/dist/core/factory.d.ts.map +1 -0
- package/dist/core/factory.js +243 -0
- package/dist/core/factory.js.map +1 -0
- package/dist/core/fsx.d.ts +39 -0
- package/dist/core/fsx.d.ts.map +1 -0
- package/dist/core/fsx.js +113 -0
- package/dist/core/fsx.js.map +1 -0
- package/dist/core/gates.d.ts +97 -0
- package/dist/core/gates.d.ts.map +1 -0
- package/dist/core/gates.js +467 -0
- package/dist/core/gates.js.map +1 -0
- package/dist/core/leases.d.ts +46 -0
- package/dist/core/leases.d.ts.map +1 -0
- package/dist/core/leases.js +94 -0
- package/dist/core/leases.js.map +1 -0
- package/dist/core/log.d.ts +30 -0
- package/dist/core/log.d.ts.map +1 -0
- package/dist/core/log.js +43 -0
- package/dist/core/log.js.map +1 -0
- package/dist/core/mesa.d.ts +82 -0
- package/dist/core/mesa.d.ts.map +1 -0
- package/dist/core/mesa.js +178 -0
- package/dist/core/mesa.js.map +1 -0
- package/dist/core/office.d.ts +208 -0
- package/dist/core/office.d.ts.map +1 -0
- package/dist/core/office.js +618 -0
- package/dist/core/office.js.map +1 -0
- package/dist/core/paths.d.ts +67 -0
- package/dist/core/paths.d.ts.map +1 -0
- package/dist/core/paths.js +136 -0
- package/dist/core/paths.js.map +1 -0
- package/dist/core/retry.d.ts +41 -0
- package/dist/core/retry.d.ts.map +1 -0
- package/dist/core/retry.js +86 -0
- package/dist/core/retry.js.map +1 -0
- package/dist/core/roster.d.ts +47 -0
- package/dist/core/roster.d.ts.map +1 -0
- package/dist/core/roster.js +146 -0
- package/dist/core/roster.js.map +1 -0
- package/dist/core/router.d.ts +67 -0
- package/dist/core/router.d.ts.map +1 -0
- package/dist/core/router.js +186 -0
- package/dist/core/router.js.map +1 -0
- package/dist/core/state.d.ts +89 -0
- package/dist/core/state.d.ts.map +1 -0
- package/dist/core/state.js +303 -0
- package/dist/core/state.js.map +1 -0
- package/dist/core/types.d.ts +333 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +27 -0
- package/dist/core/types.js.map +1 -0
- package/dist/hooks/compacting.d.ts +18 -0
- package/dist/hooks/compacting.d.ts.map +1 -0
- package/dist/hooks/compacting.js +72 -0
- package/dist/hooks/compacting.js.map +1 -0
- package/dist/hooks/scopeGuard.d.ts +39 -0
- package/dist/hooks/scopeGuard.d.ts.map +1 -0
- package/dist/hooks/scopeGuard.js +114 -0
- package/dist/hooks/scopeGuard.js.map +1 -0
- package/dist/hooks/sessionIdle.d.ts +35 -0
- package/dist/hooks/sessionIdle.d.ts.map +1 -0
- package/dist/hooks/sessionIdle.js +110 -0
- package/dist/hooks/sessionIdle.js.map +1 -0
- package/dist/hooks/systemTransform.d.ts +18 -0
- package/dist/hooks/systemTransform.d.ts.map +1 -0
- package/dist/hooks/systemTransform.js +63 -0
- package/dist/hooks/systemTransform.js.map +1 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +103 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/index.d.ts +22 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +854 -0
- package/dist/tools/index.js.map +1 -0
- package/docs/ARCHITECTURE.md +258 -0
- package/docs/QUE-ES.md +337 -0
- package/examples/opencode.json +7 -0
- package/package.json +81 -4
- package/skills/oficina/README.md +120 -0
- package/skills/oficina/SKILL.md +251 -0
- package/skills/oficina/reference/mesh.md +345 -0
- package/skills/oficina/reference/protocol.md +342 -0
- package/skills/oficina/reference/roles.md +171 -0
- package/skills/oficina/reference/templates.md +278 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logging estructurado.
|
|
3
|
+
*
|
|
4
|
+
* El plugin escribe logs con un sink inyectable para que los tests no
|
|
5
|
+
* ensucien stdout y para poder mandar al `client.app.log()` de OpenCode
|
|
6
|
+
* cuando el plugin corre dentro del host.
|
|
7
|
+
*/
|
|
8
|
+
export type LogLevel = "debug" | "info" | "warn" | "error";
|
|
9
|
+
export interface LogEntry {
|
|
10
|
+
level: LogLevel;
|
|
11
|
+
service: string;
|
|
12
|
+
message: string;
|
|
13
|
+
extra?: Record<string, unknown>;
|
|
14
|
+
at: string;
|
|
15
|
+
}
|
|
16
|
+
export type LogSink = (entry: LogEntry) => void;
|
|
17
|
+
/** Configura el sink y el nivel. */
|
|
18
|
+
export declare function configureLogging(options: {
|
|
19
|
+
sink?: LogSink;
|
|
20
|
+
level?: LogLevel;
|
|
21
|
+
}): void;
|
|
22
|
+
/** Crea un logger con scope. */
|
|
23
|
+
export declare function logger(service: string, extra?: Record<string, unknown>): {
|
|
24
|
+
debug: (m: string, e?: Record<string, unknown>) => void;
|
|
25
|
+
info: (m: string, e?: Record<string, unknown>) => void;
|
|
26
|
+
warn: (m: string, e?: Record<string, unknown>) => void;
|
|
27
|
+
error: (m: string, e?: Record<string, unknown>) => void;
|
|
28
|
+
};
|
|
29
|
+
export type Logger = ReturnType<typeof logger>;
|
|
30
|
+
//# sourceMappingURL=log.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../../src/core/log.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAA;AAE1D,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,QAAQ,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC/B,EAAE,EAAE,MAAM,CAAA;CACX;AAED,MAAM,MAAM,OAAO,GAAG,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAA;AAa/C,oCAAoC;AACpC,wBAAgB,gBAAgB,CAAC,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,QAAQ,CAAA;CAAE,GAAG,IAAI,CAGpF;AAED,gCAAgC;AAChC,wBAAgB,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;eAYxD,MAAM,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;cACpC,MAAM,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;cACnC,MAAM,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;eAClC,MAAM,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;EAEjD;AAED,MAAM,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,MAAM,CAAC,CAAA"}
|
package/dist/core/log.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logging estructurado.
|
|
3
|
+
*
|
|
4
|
+
* El plugin escribe logs con un sink inyectable para que los tests no
|
|
5
|
+
* ensucien stdout y para poder mandar al `client.app.log()` de OpenCode
|
|
6
|
+
* cuando el plugin corre dentro del host.
|
|
7
|
+
*/
|
|
8
|
+
const LEVEL_ORDER = { debug: 10, info: 20, warn: 30, error: 40 };
|
|
9
|
+
let currentSink = (entry) => {
|
|
10
|
+
const line = `[${entry.at}] ${entry.level.toUpperCase()} ${entry.service}: ${entry.message}`;
|
|
11
|
+
const extra = entry.extra ? ` ${JSON.stringify(entry.extra)}` : "";
|
|
12
|
+
// eslint-disable-next-line no-console
|
|
13
|
+
console.error(line + extra);
|
|
14
|
+
};
|
|
15
|
+
let currentLevel = "info";
|
|
16
|
+
/** Configura el sink y el nivel. */
|
|
17
|
+
export function configureLogging(options) {
|
|
18
|
+
if (options.sink)
|
|
19
|
+
currentSink = options.sink;
|
|
20
|
+
if (options.level)
|
|
21
|
+
currentLevel = options.level;
|
|
22
|
+
}
|
|
23
|
+
/** Crea un logger con scope. */
|
|
24
|
+
export function logger(service, extra) {
|
|
25
|
+
const emit = (level, message, more) => {
|
|
26
|
+
if (LEVEL_ORDER[level] < LEVEL_ORDER[currentLevel])
|
|
27
|
+
return;
|
|
28
|
+
currentSink({
|
|
29
|
+
level,
|
|
30
|
+
service,
|
|
31
|
+
message,
|
|
32
|
+
at: new Date().toISOString(),
|
|
33
|
+
extra: { ...extra, ...more },
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
return {
|
|
37
|
+
debug: (m, e) => emit("debug", m, e),
|
|
38
|
+
info: (m, e) => emit("info", m, e),
|
|
39
|
+
warn: (m, e) => emit("warn", m, e),
|
|
40
|
+
error: (m, e) => emit("error", m, e),
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=log.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log.js","sourceRoot":"","sources":["../../src/core/log.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAcH,MAAM,WAAW,GAA6B,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAA;AAE1F,IAAI,WAAW,GAAY,CAAC,KAAK,EAAE,EAAE;IACnC,MAAM,IAAI,GAAG,IAAI,KAAK,CAAC,EAAE,KAAK,KAAK,CAAC,KAAK,CAAC,WAAW,EAAE,IAAI,KAAK,CAAC,OAAO,KAAK,KAAK,CAAC,OAAO,EAAE,CAAA;IAC5F,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;IAClE,sCAAsC;IACtC,OAAO,CAAC,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,CAAA;AAC7B,CAAC,CAAA;AAED,IAAI,YAAY,GAAa,MAAM,CAAA;AAEnC,oCAAoC;AACpC,MAAM,UAAU,gBAAgB,CAAC,OAA6C;IAC5E,IAAI,OAAO,CAAC,IAAI;QAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAA;IAC5C,IAAI,OAAO,CAAC,KAAK;QAAE,YAAY,GAAG,OAAO,CAAC,KAAK,CAAA;AACjD,CAAC;AAED,gCAAgC;AAChC,MAAM,UAAU,MAAM,CAAC,OAAe,EAAE,KAA+B;IACrE,MAAM,IAAI,GAAG,CAAC,KAAe,EAAE,OAAe,EAAE,IAA8B,EAAE,EAAE;QAChF,IAAI,WAAW,CAAC,KAAK,CAAC,GAAG,WAAW,CAAC,YAAY,CAAC;YAAE,OAAM;QAC1D,WAAW,CAAC;YACV,KAAK;YACL,OAAO;YACP,OAAO;YACP,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YAC5B,KAAK,EAAE,EAAE,GAAG,KAAK,EAAE,GAAG,IAAI,EAAE;SAC7B,CAAC,CAAA;IACJ,CAAC,CAAA;IACD,OAAO;QACL,KAAK,EAAE,CAAC,CAAS,EAAE,CAA2B,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;QACtE,IAAI,EAAE,CAAC,CAAS,EAAE,CAA2B,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;QACpE,IAAI,EAAE,CAAC,CAAS,EAAE,CAA2B,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;QACpE,KAAK,EAAE,CAAC,CAAS,EAAE,CAA2B,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;KACvE,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mesa: el estado compartido de la oficina.
|
|
3
|
+
*
|
|
4
|
+
* ## Qué es
|
|
5
|
+
*
|
|
6
|
+
* Los subagentes de OpenCode son procesos aislados. No se ven. No saben quién
|
|
7
|
+
* más está trabajando, qué cards están libres, ni a quién le puede preguntar
|
|
8
|
+
* algo.
|
|
9
|
+
*
|
|
10
|
+
* La mesa es la vista compartida: quién está en qué, qué está abierto, qué
|
|
11
|
+
* se está pidiendo. Vive en el disco (el roster + el bus), así que todos la
|
|
12
|
+
* leen sin necesidad de memoria compartida.
|
|
13
|
+
*
|
|
14
|
+
* ## Por qué importa
|
|
15
|
+
*
|
|
16
|
+
* Sin mesa, el trabajo paralelo degenera en caos: dos agentes tocan el mismo
|
|
17
|
+
* archivo, uno espera un dato que nadie tiene, y el claim proactivo nunca
|
|
18
|
+
* pasa porque nadie sabe qué hay para tomar.
|
|
19
|
+
*
|
|
20
|
+
* Con mesa, cada agente sabe: qué tengo yo, qué tienen los demás, qué está
|
|
21
|
+
* libre, y a quién le puedo preguntar.
|
|
22
|
+
*/
|
|
23
|
+
import type { Office } from "./office.js";
|
|
24
|
+
export interface MesaEntry {
|
|
25
|
+
agentId: string;
|
|
26
|
+
role: string;
|
|
27
|
+
displayName: string;
|
|
28
|
+
state: string;
|
|
29
|
+
/** Card en la que está trabajando. */
|
|
30
|
+
card: string | null;
|
|
31
|
+
/** Capabilities por las que le pueden preguntar. */
|
|
32
|
+
capabilities: string[];
|
|
33
|
+
/** Si puede recibir trabajo ahora. */
|
|
34
|
+
available: boolean;
|
|
35
|
+
}
|
|
36
|
+
export interface MesaSnapshot {
|
|
37
|
+
/** Quién está sentado en la mesa. */
|
|
38
|
+
presentes: MesaEntry[];
|
|
39
|
+
/** Quién está trabajando y en qué. */
|
|
40
|
+
trabajando: MesaEntry[];
|
|
41
|
+
/** Quién está libre y puede ayudar. */
|
|
42
|
+
libres: MesaEntry[];
|
|
43
|
+
/** Cards sin owner: candidatas a claim proactivo. */
|
|
44
|
+
sinOwner: {
|
|
45
|
+
cardId: string;
|
|
46
|
+
title: string;
|
|
47
|
+
requiredCapabilities: string[];
|
|
48
|
+
}[];
|
|
49
|
+
/** Pedidos de ayuda sin responder. */
|
|
50
|
+
ayudaAbierta: {
|
|
51
|
+
messageId: string;
|
|
52
|
+
from: string;
|
|
53
|
+
card: string;
|
|
54
|
+
need: string;
|
|
55
|
+
responders: string[];
|
|
56
|
+
}[];
|
|
57
|
+
/** Preguntas abiertas al equipo. */
|
|
58
|
+
preguntasAbiertas: {
|
|
59
|
+
messageId: string;
|
|
60
|
+
from: string;
|
|
61
|
+
question: string;
|
|
62
|
+
}[];
|
|
63
|
+
/** Iteración y presupuesto. */
|
|
64
|
+
iteracion: number;
|
|
65
|
+
presupuesto: {
|
|
66
|
+
cards: string;
|
|
67
|
+
agentes: string;
|
|
68
|
+
spawns: string;
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/** Construye la foto de la mesa. */
|
|
72
|
+
export declare function snapshotMesa(office: Office): Promise<MesaSnapshot>;
|
|
73
|
+
/** Renderiza la mesa como markdown, para que un agente la lea. */
|
|
74
|
+
export declare function renderMesa(snapshot: MesaSnapshot): string;
|
|
75
|
+
/**
|
|
76
|
+
* Resume la mesa para el prompt de auto-continuación.
|
|
77
|
+
*
|
|
78
|
+
* Es lo que el hook inyecta cuando la sesión queda idle: lo mínimo para que
|
|
79
|
+
* el agente sepa si hay trabajo libre, ayuda que ofrecer o algo que responder.
|
|
80
|
+
*/
|
|
81
|
+
export declare function renderMesaBrief(snapshot: MesaSnapshot): string;
|
|
82
|
+
//# sourceMappingURL=mesa.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mesa.d.ts","sourceRoot":"","sources":["../../src/core/mesa.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAGzC,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,MAAM,CAAA;IACb,sCAAsC;IACtC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,oDAAoD;IACpD,YAAY,EAAE,MAAM,EAAE,CAAA;IACtB,sCAAsC;IACtC,SAAS,EAAE,OAAO,CAAA;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,qCAAqC;IACrC,SAAS,EAAE,SAAS,EAAE,CAAA;IACtB,sCAAsC;IACtC,UAAU,EAAE,SAAS,EAAE,CAAA;IACvB,uCAAuC;IACvC,MAAM,EAAE,SAAS,EAAE,CAAA;IACnB,qDAAqD;IACrD,QAAQ,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,oBAAoB,EAAE,MAAM,EAAE,CAAA;KAAE,EAAE,CAAA;IAC7E,sCAAsC;IACtC,YAAY,EAAE;QACZ,SAAS,EAAE,MAAM,CAAA;QACjB,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,EAAE,MAAM,CAAA;QACZ,UAAU,EAAE,MAAM,EAAE,CAAA;KACrB,EAAE,CAAA;IACH,oCAAoC;IACpC,iBAAiB,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IAC1E,+BAA+B;IAC/B,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;CAChE;AAED,oCAAoC;AACpC,wBAAsB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CA6ExE;AAOD,kEAAkE;AAClE,wBAAgB,UAAU,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,CAyDzD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,CAmC9D"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mesa: el estado compartido de la oficina.
|
|
3
|
+
*
|
|
4
|
+
* ## Qué es
|
|
5
|
+
*
|
|
6
|
+
* Los subagentes de OpenCode son procesos aislados. No se ven. No saben quién
|
|
7
|
+
* más está trabajando, qué cards están libres, ni a quién le puede preguntar
|
|
8
|
+
* algo.
|
|
9
|
+
*
|
|
10
|
+
* La mesa es la vista compartida: quién está en qué, qué está abierto, qué
|
|
11
|
+
* se está pidiendo. Vive en el disco (el roster + el bus), así que todos la
|
|
12
|
+
* leen sin necesidad de memoria compartida.
|
|
13
|
+
*
|
|
14
|
+
* ## Por qué importa
|
|
15
|
+
*
|
|
16
|
+
* Sin mesa, el trabajo paralelo degenera en caos: dos agentes tocan el mismo
|
|
17
|
+
* archivo, uno espera un dato que nadie tiene, y el claim proactivo nunca
|
|
18
|
+
* pasa porque nadie sabe qué hay para tomar.
|
|
19
|
+
*
|
|
20
|
+
* Con mesa, cada agente sabe: qué tengo yo, qué tienen los demás, qué está
|
|
21
|
+
* libre, y a quién le puedo preguntar.
|
|
22
|
+
*/
|
|
23
|
+
import { CHANNELS } from "./bus.js";
|
|
24
|
+
/** Construye la foto de la mesa. */
|
|
25
|
+
export async function snapshotMesa(office) {
|
|
26
|
+
const state = await office.loadState();
|
|
27
|
+
const roster = await office.loadRoster(state.runId);
|
|
28
|
+
const agents = Object.values(roster.agents);
|
|
29
|
+
const presentes = agents.map((a) => ({
|
|
30
|
+
agentId: a.id,
|
|
31
|
+
role: a.role,
|
|
32
|
+
displayName: a.displayName,
|
|
33
|
+
state: a.state,
|
|
34
|
+
card: a.currentCard,
|
|
35
|
+
capabilities: a.capabilities.slice(0, 8),
|
|
36
|
+
available: a.state === "idle_available" && a.canAccept,
|
|
37
|
+
}));
|
|
38
|
+
const sinOwner = state.order
|
|
39
|
+
.map((id) => state.cards[id])
|
|
40
|
+
.filter((c) => !!c && c.state === "todo" && !c.owner)
|
|
41
|
+
.map((c) => ({
|
|
42
|
+
cardId: c.id,
|
|
43
|
+
title: c.title,
|
|
44
|
+
requiredCapabilities: c.requiredCapabilities,
|
|
45
|
+
}));
|
|
46
|
+
// Pedidos de ayuda sin responder: un HELP_REQUEST sin ningún HELP_ACCEPT
|
|
47
|
+
// ni HELP_DECLINE dirigido al mismo par.
|
|
48
|
+
const peerMessages = await office.bus.readChannel(CHANNELS.peer);
|
|
49
|
+
const ayudaAbierta = [];
|
|
50
|
+
for (const msg of peerMessages) {
|
|
51
|
+
if (msg.kind !== "HELP_REQUEST")
|
|
52
|
+
continue;
|
|
53
|
+
if (isExpired(msg))
|
|
54
|
+
continue;
|
|
55
|
+
const answered = peerMessages.some((r) => r.kind.startsWith("HELP_") &&
|
|
56
|
+
r.kind !== "HELP_REQUEST" &&
|
|
57
|
+
r.inReplyTo === msg.id);
|
|
58
|
+
if (answered)
|
|
59
|
+
continue;
|
|
60
|
+
ayudaAbierta.push({
|
|
61
|
+
messageId: msg.id,
|
|
62
|
+
from: msg.from,
|
|
63
|
+
card: msg.subject,
|
|
64
|
+
need: String(msg.body?.need ?? "(sin detalle)"),
|
|
65
|
+
responders: msg.to.includes("*") ? [] : msg.to,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
const preguntasAbiertas = [];
|
|
69
|
+
for (const msg of peerMessages) {
|
|
70
|
+
if (msg.kind !== "QUESTION")
|
|
71
|
+
continue;
|
|
72
|
+
if (isExpired(msg))
|
|
73
|
+
continue;
|
|
74
|
+
const answered = peerMessages.some((r) => r.kind === "ANSWER" && r.inReplyTo === msg.id);
|
|
75
|
+
if (answered)
|
|
76
|
+
continue;
|
|
77
|
+
preguntasAbiertas.push({
|
|
78
|
+
messageId: msg.id,
|
|
79
|
+
from: msg.from,
|
|
80
|
+
question: String(msg.body?.question ?? ""),
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
return {
|
|
84
|
+
presentes,
|
|
85
|
+
trabajando: presentes.filter((p) => p.state === "working"),
|
|
86
|
+
libres: presentes.filter((p) => p.available),
|
|
87
|
+
sinOwner,
|
|
88
|
+
ayudaAbierta,
|
|
89
|
+
preguntasAbiertas,
|
|
90
|
+
iteracion: state.iteration,
|
|
91
|
+
presupuesto: {
|
|
92
|
+
cards: `${state.budget.cardsUsed}/${state.budget.maxCards}`,
|
|
93
|
+
agentes: `${state.budget.agentCallsUsed}/${state.budget.maxAgentCalls}`,
|
|
94
|
+
spawns: `${state.budget.spawnsUsed}/${state.budget.maxSpawnsTotal}`,
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
function isExpired(message) {
|
|
99
|
+
const age = (Date.now() - Date.parse(message.createdAt)) / 1000;
|
|
100
|
+
return age > message.ttlSec;
|
|
101
|
+
}
|
|
102
|
+
/** Renderiza la mesa como markdown, para que un agente la lea. */
|
|
103
|
+
export function renderMesa(snapshot) {
|
|
104
|
+
const lines = ["# Mesa de la oficina", ""];
|
|
105
|
+
lines.push(`**Iteración:** ${snapshot.iteracion} · **Presupuesto:** ${snapshot.presupuesto.cards} cards, ${snapshot.presupuesto.agentes} agentes, ${snapshot.presupuesto.spawns} spawns`);
|
|
106
|
+
lines.push("");
|
|
107
|
+
lines.push("## Quién está trabajando");
|
|
108
|
+
lines.push("");
|
|
109
|
+
if (snapshot.trabajando.length === 0) {
|
|
110
|
+
lines.push("(nadie)");
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
for (const p of snapshot.trabajando) {
|
|
114
|
+
lines.push(`- **${p.displayName}** (\`${p.agentId}\`, ${p.role}) → card ${p.card ?? "—"}`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
lines.push("");
|
|
118
|
+
lines.push("## Quién está libre y puede ayudar");
|
|
119
|
+
lines.push("");
|
|
120
|
+
if (snapshot.libres.length === 0) {
|
|
121
|
+
lines.push("(nadie)");
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
for (const p of snapshot.libres) {
|
|
125
|
+
lines.push(`- **${p.displayName}** (\`${p.agentId}\`, ${p.role}) — ${p.capabilities.join(", ")}`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
lines.push("");
|
|
129
|
+
if (snapshot.sinOwner.length > 0) {
|
|
130
|
+
lines.push("## Cards sin owner (reclamables)");
|
|
131
|
+
lines.push("");
|
|
132
|
+
for (const c of snapshot.sinOwner) {
|
|
133
|
+
lines.push(`- **${c.cardId}** ${c.title} — necesita: ${c.requiredCapabilities.join(", ") || "(sin especificar)"}`);
|
|
134
|
+
}
|
|
135
|
+
lines.push("");
|
|
136
|
+
}
|
|
137
|
+
if (snapshot.ayudaAbierta.length > 0) {
|
|
138
|
+
lines.push("## Ayuda pedida (sin responder)");
|
|
139
|
+
lines.push("");
|
|
140
|
+
for (const h of snapshot.ayudaAbierta) {
|
|
141
|
+
lines.push(`- **${h.from}** pide ayuda en \`${h.card}\`: ${h.need}`);
|
|
142
|
+
lines.push(` - respondé con \`oficina_bus\` action=\`respond\` inReplyTo=\`${h.messageId}\``);
|
|
143
|
+
}
|
|
144
|
+
lines.push("");
|
|
145
|
+
}
|
|
146
|
+
if (snapshot.preguntasAbiertas.length > 0) {
|
|
147
|
+
lines.push("## Preguntas abiertas");
|
|
148
|
+
lines.push("");
|
|
149
|
+
for (const q of snapshot.preguntasAbiertas) {
|
|
150
|
+
lines.push(`- **${q.from}**: ${q.question}`);
|
|
151
|
+
}
|
|
152
|
+
lines.push("");
|
|
153
|
+
}
|
|
154
|
+
return lines.join("\n");
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Resume la mesa para el prompt de auto-continuación.
|
|
158
|
+
*
|
|
159
|
+
* Es lo que el hook inyecta cuando la sesión queda idle: lo mínimo para que
|
|
160
|
+
* el agente sepa si hay trabajo libre, ayuda que ofrecer o algo que responder.
|
|
161
|
+
*/
|
|
162
|
+
export function renderMesaBrief(snapshot) {
|
|
163
|
+
const parts = [];
|
|
164
|
+
if (snapshot.ayudaAbierta.length > 0) {
|
|
165
|
+
parts.push("**Hay pedidos de ayuda sin responder:**", ...snapshot.ayudaAbierta.map((h) => `- ${h.from} en ${h.card}: ${h.need} (respondé con \`oficina_bus\` action=\`respond\` inReplyTo=\`${h.messageId}\`)`));
|
|
166
|
+
}
|
|
167
|
+
if (snapshot.preguntasAbiertas.length > 0) {
|
|
168
|
+
parts.push("**Hay preguntas abiertas:**", ...snapshot.preguntasAbiertas.map((q) => `- ${q.from}: ${q.question}`));
|
|
169
|
+
}
|
|
170
|
+
if (snapshot.sinOwner.length > 0) {
|
|
171
|
+
parts.push("**Cards sin owner — podés reclamar una:**", ...snapshot.sinOwner.map((c) => `- ${c.cardId}: ${c.title} (necesita ${c.requiredCapabilities.join(", ") || "cualquiera"})`));
|
|
172
|
+
}
|
|
173
|
+
if (snapshot.libres.length > 0) {
|
|
174
|
+
parts.push(`**Agentes libres (podés pedirles ayuda):** ${snapshot.libres.map((p) => `${p.agentId} (${p.role})`).join(", ")}`);
|
|
175
|
+
}
|
|
176
|
+
return parts.join("\n\n");
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=mesa.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mesa.js","sourceRoot":"","sources":["../../src/core/mesa.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Office: la fachada que amarra los módulos.
|
|
3
|
+
*
|
|
4
|
+
* Es el único objeto que las tools y los hooks tocan. Encapsula paths, bus,
|
|
5
|
+
* roster, leases, state, catálogo y límites. Si algo necesita tocar dos
|
|
6
|
+
* módulos a la vez, pasa por acá.
|
|
7
|
+
*/
|
|
8
|
+
import type { Card, CardType, CatalogAgent, CatalogMatch, Ficha, GateResult, Limits, OfficeState, Roster, RosterEntry } from "./types.js";
|
|
9
|
+
import { Bus } from "./bus.js";
|
|
10
|
+
import { RosterStore } from "./roster.js";
|
|
11
|
+
import { LeaseStore } from "./leases.js";
|
|
12
|
+
import { CandidateRegistry } from "./factory.js";
|
|
13
|
+
import { type RolePanel } from "./catalog.js";
|
|
14
|
+
import { type Briefing } from "./briefing.js";
|
|
15
|
+
import { type CommandRunner } from "./gates.js";
|
|
16
|
+
import { type ResolvedPaths } from "./paths.js";
|
|
17
|
+
export interface OfficeOptions {
|
|
18
|
+
cwd: string;
|
|
19
|
+
limits?: Limits;
|
|
20
|
+
/** Raíz del repo agency-agents para el catálogo. */
|
|
21
|
+
agencyRoot?: string;
|
|
22
|
+
/**
|
|
23
|
+
* Catálogo de roles ya escaneado.
|
|
24
|
+
*
|
|
25
|
+
* Punto de inyección: en producción se autodetecta; en los tests se pasa
|
|
26
|
+
* un catálogo controlado para no depender del repo externo.
|
|
27
|
+
*/
|
|
28
|
+
catalog?: CatalogAgent[];
|
|
29
|
+
/** Runner de comandos para los gates. Inyectable para tests. */
|
|
30
|
+
runner?: CommandRunner;
|
|
31
|
+
clock?: () => number;
|
|
32
|
+
/**
|
|
33
|
+
* Cliente del SDK de OpenCode.
|
|
34
|
+
*
|
|
35
|
+
* Se usa para **desviar subagentes**: `session.prompt` con una parte
|
|
36
|
+
* `subtask` crea un subagente real. Sin cliente, la oficina funciona igual
|
|
37
|
+
* (los agentes se materializan y el LLM los invoca con la tool `task`),
|
|
38
|
+
* pero no puede arrancarlos sola.
|
|
39
|
+
*/
|
|
40
|
+
client?: {
|
|
41
|
+
session: {
|
|
42
|
+
prompt: (input: {
|
|
43
|
+
path: {
|
|
44
|
+
id: string;
|
|
45
|
+
};
|
|
46
|
+
body: {
|
|
47
|
+
parts: Array<{
|
|
48
|
+
type: "subtask";
|
|
49
|
+
prompt: string;
|
|
50
|
+
description: string;
|
|
51
|
+
agent: string;
|
|
52
|
+
}>;
|
|
53
|
+
};
|
|
54
|
+
}) => Promise<unknown>;
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
export declare class Office {
|
|
59
|
+
private readonly options;
|
|
60
|
+
readonly paths: ResolvedPaths;
|
|
61
|
+
readonly limits: Limits;
|
|
62
|
+
readonly bus: Bus;
|
|
63
|
+
readonly rosterStore: RosterStore;
|
|
64
|
+
readonly leases: LeaseStore;
|
|
65
|
+
readonly candidates: CandidateRegistry;
|
|
66
|
+
private catalogCache;
|
|
67
|
+
private toolingCache;
|
|
68
|
+
constructor(options: OfficeOptions);
|
|
69
|
+
/** Resuelve paths reales y crea la estructura. */
|
|
70
|
+
init(): Promise<void>;
|
|
71
|
+
/** Carga o crea el estado de la corrida. Migra v1 → v2 si hace falta. */
|
|
72
|
+
loadState(objective?: string): Promise<OfficeState>;
|
|
73
|
+
saveState(state: OfficeState): Promise<void>;
|
|
74
|
+
loadRoster(runId: string): Promise<Roster>;
|
|
75
|
+
saveRoster(roster: Roster): Promise<void>;
|
|
76
|
+
/** Catálogo de agency-agents (cacheado). */
|
|
77
|
+
catalog(): Promise<CatalogAgent[]>;
|
|
78
|
+
private defaultAgencyRoot;
|
|
79
|
+
/**
|
|
80
|
+
* Resuelve un rol a una ficha.
|
|
81
|
+
*
|
|
82
|
+
* Catálogo primero; si la cobertura es baja, factory. El resultado queda
|
|
83
|
+
* registrado en el roster como agente desplegado.
|
|
84
|
+
*/
|
|
85
|
+
resolveFicha(input: {
|
|
86
|
+
role: string;
|
|
87
|
+
capabilities: string[];
|
|
88
|
+
scope?: {
|
|
89
|
+
mayTouch?: string[];
|
|
90
|
+
forbidden?: string[];
|
|
91
|
+
};
|
|
92
|
+
canDelegate?: boolean;
|
|
93
|
+
delegateBudget?: number;
|
|
94
|
+
peers?: string[];
|
|
95
|
+
objective?: string;
|
|
96
|
+
mission?: string;
|
|
97
|
+
}): Promise<{
|
|
98
|
+
ficha: Ficha;
|
|
99
|
+
source: "agency-agents" | "factory";
|
|
100
|
+
coverage: number;
|
|
101
|
+
/** Por qué se eligió este agente y qué le falta cubrir. */
|
|
102
|
+
match?: CatalogMatch;
|
|
103
|
+
/** Alternativas válidas, por si elCommander quiere repartir carga. */
|
|
104
|
+
alternatives: CatalogMatch[];
|
|
105
|
+
/** El panel completo: primario + complementos + huecos. */
|
|
106
|
+
panel?: RolePanel;
|
|
107
|
+
}>;
|
|
108
|
+
/**
|
|
109
|
+
* Arranca un subagente.
|
|
110
|
+
*
|
|
111
|
+
* Usa `session.prompt` con una parte `subtask`: es la vía que OpenCode
|
|
112
|
+
* provee para crear un subagente real, con su prompt de sistema y su
|
|
113
|
+
* contexto propio.
|
|
114
|
+
*
|
|
115
|
+
* El `agent` que se pasa es `"general"`, y el specialty viaja completo en el
|
|
116
|
+
* prompt. La razón es práctica: OpenCode arma la lista de agentes al
|
|
117
|
+
* arrancar la sesión, así que un `.opencode/agents/oficina-<slug>.md`
|
|
118
|
+
* recién creado puede no estar registrable todavía. Con el prompt embebido
|
|
119
|
+
* el agente funciona siempre.
|
|
120
|
+
*/
|
|
121
|
+
spawnAgent(sessionID: string, agentName: string, prompt: string, description: string): Promise<boolean>;
|
|
122
|
+
/**
|
|
123
|
+
* Construye el briefing de un agente para una card.
|
|
124
|
+
*
|
|
125
|
+
* El briefing es el contrato de información: qué sabe, qué no, qué tiene
|
|
126
|
+
* que entregar y a quién escalar. Se valida antes de usarlo — si le falta
|
|
127
|
+
* una sección requerida, el agente no arranca.
|
|
128
|
+
*
|
|
129
|
+
* El contexto sale del ledger de la corrida (`.oficina/context.md`), que
|
|
130
|
+
* es lo que evita que un agente repita lo que ya se decidió.
|
|
131
|
+
*/
|
|
132
|
+
buildBriefing(ficha: Ficha, card: Card, roster?: Roster, state?: OfficeState): Briefing;
|
|
133
|
+
/**
|
|
134
|
+
* Despliega un agente: lo registra en el roster y escribe su briefing.
|
|
135
|
+
*
|
|
136
|
+
* El briefing se materializa en 4 archivos: `ficha.md`, `misiones.md`,
|
|
137
|
+
* `protocolo.md` y `bus.md`. El agente **no arranca sin `misiones.md`**.
|
|
138
|
+
*/
|
|
139
|
+
deploy(ficha: Ficha, card?: Card, roster?: Roster, state?: OfficeState): Promise<RosterEntry>;
|
|
140
|
+
/** Valida y persiste un plan propuesto por el modelo. */
|
|
141
|
+
savePlan(state: OfficeState, cards: Array<{
|
|
142
|
+
id?: string;
|
|
143
|
+
title: string;
|
|
144
|
+
type: CardType;
|
|
145
|
+
requiredCapabilities?: string[];
|
|
146
|
+
scope?: {
|
|
147
|
+
mayTouch?: string[];
|
|
148
|
+
forbidden?: string[];
|
|
149
|
+
};
|
|
150
|
+
acceptance: string[];
|
|
151
|
+
gate: string;
|
|
152
|
+
dependsOn?: string[];
|
|
153
|
+
}>): Promise<OfficeState>;
|
|
154
|
+
/** Elige y reclama la próxima card para un agente dado. */
|
|
155
|
+
claimNext(state: OfficeState, agentId: string, sessionId?: string): Promise<{
|
|
156
|
+
card: Card | null;
|
|
157
|
+
reason: string;
|
|
158
|
+
}>;
|
|
159
|
+
/** Asocia una sesión con un agente y una card. Lo usa el guard de scope. */
|
|
160
|
+
bindSession(state: OfficeState, sessionId: string, agentId: string, cardId: string | null): void;
|
|
161
|
+
/** Card en curso de una sesión. */
|
|
162
|
+
sessionCard(state: OfficeState, sessionId: string): Card | undefined;
|
|
163
|
+
/** Reclama una card específica (claim proactivo del pool idle). */
|
|
164
|
+
claimCard(state: OfficeState, agentId: string, cardId: string, sessionId?: string): Promise<{
|
|
165
|
+
ok: boolean;
|
|
166
|
+
reason: string;
|
|
167
|
+
}>;
|
|
168
|
+
/** Envía el trabajo de una card a review. */
|
|
169
|
+
submitWork(state: OfficeState, cardId: string, agentId: string, payload: {
|
|
170
|
+
handoff: string;
|
|
171
|
+
evidence?: string;
|
|
172
|
+
}): Promise<{
|
|
173
|
+
ok: boolean;
|
|
174
|
+
reason: string;
|
|
175
|
+
}>;
|
|
176
|
+
/** Registra el veredicto del reviewer. */
|
|
177
|
+
submitReview(state: OfficeState, cardId: string, reviewerId: string, verdict: "approved" | "rejected", payload: {
|
|
178
|
+
review: string;
|
|
179
|
+
reason?: string;
|
|
180
|
+
}): Promise<{
|
|
181
|
+
ok: boolean;
|
|
182
|
+
reason: string;
|
|
183
|
+
action: string;
|
|
184
|
+
}>;
|
|
185
|
+
/** Corre los gates de una card. */
|
|
186
|
+
runGates(state: OfficeState, cardId: string): Promise<GateResult>;
|
|
187
|
+
/** Cierra una card si los gates pasaron. Aplica los invariantes. */
|
|
188
|
+
closeCard(state: OfficeState, cardId: string, gates: GateResult): Promise<{
|
|
189
|
+
ok: boolean;
|
|
190
|
+
reason: string;
|
|
191
|
+
}>;
|
|
192
|
+
/** Enruta un pedido de ayuda a los peers disponibles. */
|
|
193
|
+
routeHelpRequest(state: OfficeState, requesterId: string, cardId: string): Promise<{
|
|
194
|
+
targets: string[];
|
|
195
|
+
reason: string;
|
|
196
|
+
}>;
|
|
197
|
+
/** Snapshot del estado para el prompt. */
|
|
198
|
+
snapshot(): Promise<{
|
|
199
|
+
state: OfficeState;
|
|
200
|
+
roster: Roster;
|
|
201
|
+
idle: RosterEntry[];
|
|
202
|
+
working: RosterEntry[];
|
|
203
|
+
dead: RosterEntry[];
|
|
204
|
+
}>;
|
|
205
|
+
}
|
|
206
|
+
/** Renderiza una ficha como markdown. */
|
|
207
|
+
export declare function renderFicha(ficha: Ficha): string;
|
|
208
|
+
//# sourceMappingURL=office.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"office.d.ts","sourceRoot":"","sources":["../../src/core/office.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EACV,IAAI,EAEJ,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,KAAK,EACL,UAAU,EACV,MAAM,EACN,WAAW,EACX,MAAM,EACN,WAAW,EACZ,MAAM,YAAY,CAAA;AAEnB,OAAO,EAAE,GAAG,EAAY,MAAM,UAAU,CAAA;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAExC,OAAO,EAAe,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAC7D,OAAO,EAA4C,KAAK,SAAS,EAAE,MAAM,cAAc,CAAA;AACvF,OAAO,EAGL,KAAK,QAAQ,EACd,MAAM,eAAe,CAAA;AAGtB,OAAO,EAAkE,KAAK,aAAa,EAAgB,MAAM,YAAY,CAAA;AAE7H,OAAO,EAAyB,KAAK,aAAa,EAAE,MAAM,YAAY,CAAA;AAKtE,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,oDAAoD;IACpD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,YAAY,EAAE,CAAA;IACxB,gEAAgE;IAChE,MAAM,CAAC,EAAE,aAAa,CAAA;IACtB,KAAK,CAAC,EAAE,MAAM,MAAM,CAAA;IACpB;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE;QACP,OAAO,EAAE;YACP,MAAM,EAAE,CAAC,KAAK,EAAE;gBACd,IAAI,EAAE;oBAAE,EAAE,EAAE,MAAM,CAAA;iBAAE,CAAA;gBACpB,IAAI,EAAE;oBACJ,KAAK,EAAE,KAAK,CAAC;wBACX,IAAI,EAAE,SAAS,CAAA;wBACf,MAAM,EAAE,MAAM,CAAA;wBACd,WAAW,EAAE,MAAM,CAAA;wBACnB,KAAK,EAAE,MAAM,CAAA;qBACd,CAAC,CAAA;iBACH,CAAA;aACF,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;SACvB,CAAA;KACF,CAAA;CACF;AAED,qBAAa,MAAM;IAWL,OAAO,CAAC,QAAQ,CAAC,OAAO;IAVpC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAA;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAA;IACjB,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAA;IACjC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAA;IAC3B,QAAQ,CAAC,UAAU,oBAA0B;IAE7C,OAAO,CAAC,YAAY,CAA8B;IAClD,OAAO,CAAC,YAAY,CAAuB;gBAEd,OAAO,EAAE,aAAa;IAuBnD,kDAAkD;IAC5C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA8B3B,yEAAyE;IACnE,SAAS,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAiBnD,SAAS,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAI5C,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAI1C,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ/C,4CAA4C;IACtC,OAAO,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;IAoBxC,OAAO,CAAC,iBAAiB;IAQzB;;;;;OAKG;IACG,YAAY,CAAC,KAAK,EAAE;QACxB,IAAI,EAAE,MAAM,CAAA;QACZ,YAAY,EAAE,MAAM,EAAE,CAAA;QACtB,KAAK,CAAC,EAAE;YAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;YAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;SAAE,CAAA;QACrD,WAAW,CAAC,EAAE,OAAO,CAAA;QACrB,cAAc,CAAC,EAAE,MAAM,CAAA;QACvB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;QAChB,SAAS,CAAC,EAAE,MAAM,CAAA;QAClB,OAAO,CAAC,EAAE,MAAM,CAAA;KACjB,GAAG,OAAO,CAAC;QACV,KAAK,EAAE,KAAK,CAAA;QACZ,MAAM,EAAE,eAAe,GAAG,SAAS,CAAA;QACnC,QAAQ,EAAE,MAAM,CAAA;QAChB,2DAA2D;QAC3D,KAAK,CAAC,EAAE,YAAY,CAAA;QACpB,sEAAsE;QACtE,YAAY,EAAE,YAAY,EAAE,CAAA;QAC5B,2DAA2D;QAC3D,KAAK,CAAC,EAAE,SAAS,CAAA;KAClB,CAAC;IA+DF;;;;;;;;;;;;OAYG;IACG,UAAU,CACd,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,OAAO,CAAC;IAwBnB;;;;;;;;;OASG;IACH,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,WAAW,GAAG,QAAQ;IAmBvF;;;;;OAKG;IACG,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IAwBnG,yDAAyD;IACnD,QAAQ,CACZ,KAAK,EAAE,WAAW,EAClB,KAAK,EAAE,KAAK,CAAC;QACX,EAAE,CAAC,EAAE,MAAM,CAAA;QACX,KAAK,EAAE,MAAM,CAAA;QACb,IAAI,EAAE,QAAQ,CAAA;QACd,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAA;QAC/B,KAAK,CAAC,EAAE;YAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;YAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;SAAE,CAAA;QACrD,UAAU,EAAE,MAAM,EAAE,CAAA;QACpB,IAAI,EAAE,MAAM,CAAA;QACZ,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;KACrB,CAAC,GACD,OAAO,CAAC,WAAW,CAAC;IA2DvB,2DAA2D;IACrD,SAAS,CACb,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,MAAM,EACf,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC;QAAE,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IA6BjD,4EAA4E;IAC5E,WAAW,CAAC,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAUhG,mCAAmC;IACnC,WAAW,CAAC,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;IAMpE,mEAAmE;IAC7D,SAAS,CACb,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAkC3C,6CAA6C;IACvC,UAAU,CACd,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAC9C,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAgC3C,0CAA0C;IACpC,YAAY,CAChB,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,UAAU,GAAG,UAAU,EAChC,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAC3C,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAoC3D,mCAAmC;IAC7B,QAAQ,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAsBvE,oEAAoE;IAC9D,SAAS,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAqChH,yDAAyD;IACnD,gBAAgB,CACpB,KAAK,EAAE,WAAW,EAClB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAejD,0CAA0C;IACpC,QAAQ,IAAI,OAAO,CAAC;QACxB,KAAK,EAAE,WAAW,CAAA;QAClB,MAAM,EAAE,MAAM,CAAA;QACd,IAAI,EAAE,WAAW,EAAE,CAAA;QACnB,OAAO,EAAE,WAAW,EAAE,CAAA;QACtB,IAAI,EAAE,WAAW,EAAE,CAAA;KACpB,CAAC;CAWH;AAyBD,yCAAyC;AACzC,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAmChD"}
|