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,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Router: qué agente hace qué card, y con qué rotación.
|
|
3
|
+
*
|
|
4
|
+
* Dos reglas hardcoded que vienen de los síntomas reportados:
|
|
5
|
+
*
|
|
6
|
+
* 1. **El revisor nunca es el owner.** Sin auto-aprobación.
|
|
7
|
+
* 2. **Rotación.** Si el mismo agente sería owner de 3 cards del mismo tipo
|
|
8
|
+
* seguidas, la cuarta la toma otro. El "subagente monotono" es un bug de
|
|
9
|
+
* routing, no de capacidad.
|
|
10
|
+
*
|
|
11
|
+
* La extensión: la rotación también aplica a la ayuda. Si el par A↔B ya se
|
|
12
|
+
* ayudaron dos veces, el tercer pedido se enruta a un tercero.
|
|
13
|
+
*/
|
|
14
|
+
import { matchCapabilities } from "./catalog.js";
|
|
15
|
+
/** Tipo de card → rol canónico que debería ejecutarla. */
|
|
16
|
+
export const ROLE_BY_CARD_TYPE = {
|
|
17
|
+
exploration: ["code-explorer", "researcher", "explorer"],
|
|
18
|
+
design: ["code-architect", "architect", "system-designer"],
|
|
19
|
+
implementation: ["frontend-developer", "backend-developer", "developer", "engineer"],
|
|
20
|
+
bugfix: ["bug-fixer", "developer", "engineer", "code-architect"],
|
|
21
|
+
refactor: ["refactorer", "developer", "engineer"],
|
|
22
|
+
testing: ["qa-engineer", "test-engineer", "developer"],
|
|
23
|
+
docs: ["technical-writer", "documentation-writer"],
|
|
24
|
+
security: ["security-auditor", "security-engineer"],
|
|
25
|
+
infra: ["devops-engineer", "sre", "platform-engineer"],
|
|
26
|
+
};
|
|
27
|
+
export const DEFAULT_ROTATION_THRESHOLD = 3;
|
|
28
|
+
export const DEFAULT_PAIR_ROTATION_THRESHOLD = 2;
|
|
29
|
+
/**
|
|
30
|
+
* Elige owner y reviewer para una card.
|
|
31
|
+
*
|
|
32
|
+
* Preferencia de owner:
|
|
33
|
+
* 1. Rol canónico del tipo de card (si está en el roster y está libre).
|
|
34
|
+
* 2. Mejor match por capabilities entre los agentes libres.
|
|
35
|
+
* 3. Agente idle del pool (para repartir carga).
|
|
36
|
+
*
|
|
37
|
+
* El reviewer se elige entre los que NO son el owner, priorizando los que no
|
|
38
|
+
* hayan reciente-compliant colaborado con el owner (umbral de anti-monotonía).
|
|
39
|
+
*/
|
|
40
|
+
export function routeCard(card, roster, catalog = [], options = {}) {
|
|
41
|
+
const rotationThreshold = options.rotationThreshold ?? DEFAULT_ROTATION_THRESHOLD;
|
|
42
|
+
const pairThreshold = options.pairRotationThreshold ?? DEFAULT_PAIR_ROTATION_THRESHOLD;
|
|
43
|
+
const all = Object.values(roster.agents).filter((a) => a.state !== "retired");
|
|
44
|
+
const free = all.filter((a) => a.currentCard === null && a.state !== "blocked");
|
|
45
|
+
// 1. Rol canónico del tipo de card.
|
|
46
|
+
const preferredRoles = ROLE_BY_CARD_TYPE[card.type] ?? [];
|
|
47
|
+
let owner = preferredRoles
|
|
48
|
+
.map((role) => free.find((a) => a.role === role))
|
|
49
|
+
.find((a) => !!a) ?? null;
|
|
50
|
+
let reason = owner
|
|
51
|
+
? `rol canónico del tipo ${card.type}`
|
|
52
|
+
: "";
|
|
53
|
+
// 2. Mejor match por capabilities.
|
|
54
|
+
if (!owner && card.requiredCapabilities.length > 0) {
|
|
55
|
+
const match = matchCapabilities(catalog, card.requiredCapabilities);
|
|
56
|
+
if (match) {
|
|
57
|
+
owner = free.find((a) => a.role === match.agent.slug) ?? null;
|
|
58
|
+
if (owner)
|
|
59
|
+
reason = `match de catálogo con cobertura ${(match.coverage * 100).toFixed(0)}%`;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// 3. Pool idle por capacidad.
|
|
63
|
+
if (!owner && card.requiredCapabilities.length > 0) {
|
|
64
|
+
const scored = free
|
|
65
|
+
.map((a) => ({
|
|
66
|
+
agent: a,
|
|
67
|
+
score: a.capabilities.filter((c) => card.requiredCapabilities.some((r) => c.includes(r) || r.includes(c))).length,
|
|
68
|
+
}))
|
|
69
|
+
.filter((s) => s.score > 0)
|
|
70
|
+
.sort((a, b) => b.score - a.score);
|
|
71
|
+
if (scored[0]) {
|
|
72
|
+
owner = scored[0].agent;
|
|
73
|
+
reason = `mejor match de capabilities (${scored[0].score})`;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// 4. Cualquiera libre — SOLO si la card no pide capabilities.
|
|
77
|
+
//
|
|
78
|
+
// Si la card pide capacidades específicas y ningún agente las cubre, NO se
|
|
79
|
+
// fuerza un mal match: un rol medio-tonto en el equipo arruina más de lo
|
|
80
|
+
// que aporta. En ese caso se devuelve null y las capabilities faltantes,
|
|
81
|
+
// para que la oficina fabrique el rol o pida ayuda.
|
|
82
|
+
if (!owner && card.requiredCapabilities.length === 0 && free.length > 0) {
|
|
83
|
+
owner = free[0];
|
|
84
|
+
reason = "único agente libre (la card no exige capabilities)";
|
|
85
|
+
}
|
|
86
|
+
// 5. Anti-monotonía: si el owner lleva una racha, rotar.
|
|
87
|
+
if (owner && (options.ownerStreak ?? 0) >= rotationThreshold) {
|
|
88
|
+
const alternative = free.find((a) => a.id !== owner.id);
|
|
89
|
+
if (alternative) {
|
|
90
|
+
owner = alternative;
|
|
91
|
+
reason = `rotación anti-monotonía (racha de ${options.ownerStreak})`;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// Reviewer: nunca el owner, idealmente sin colaboración reciente.
|
|
95
|
+
const candidates = all.filter((a) => a.id !== owner?.id);
|
|
96
|
+
let reviewer = candidates.find((a) => {
|
|
97
|
+
const pair = owner ? owner.helpedPeers.includes(a.id) : false;
|
|
98
|
+
const collabs = options.pairCollaborationCount ?? 0;
|
|
99
|
+
return !pair || collabs < pairThreshold;
|
|
100
|
+
});
|
|
101
|
+
if (!reviewer) {
|
|
102
|
+
// Todos colaboraron mucho: se permite igual, pero se anota.
|
|
103
|
+
reviewer = candidates[0];
|
|
104
|
+
}
|
|
105
|
+
const missing = owner
|
|
106
|
+
? []
|
|
107
|
+
: card.requiredCapabilities.filter((c) => !all.some((a) => a.capabilities.includes(c)));
|
|
108
|
+
return {
|
|
109
|
+
owner: owner ?? null,
|
|
110
|
+
reviewer: reviewer ?? null,
|
|
111
|
+
reason: reason || "sin agente disponible",
|
|
112
|
+
missing,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* A quién enrutar un pedido de ayuda.
|
|
117
|
+
*
|
|
118
|
+
* 1. Los peers declarados en la ficha que estén libres.
|
|
119
|
+
* 2. Un tercero si el par ya colaboró demasiado (anti-monotonía extendida).
|
|
120
|
+
*/
|
|
121
|
+
export function routeHelp(requesterId, roster, requesterPeers = [], options = {}) {
|
|
122
|
+
const pairThreshold = options.pairRotationThreshold ?? DEFAULT_PAIR_ROTATION_THRESHOLD;
|
|
123
|
+
const all = Object.values(roster.agents);
|
|
124
|
+
const requester = roster.agents[requesterId];
|
|
125
|
+
const peers = requesterPeers
|
|
126
|
+
.map((role) => all.find((a) => a.role === role || a.id === role))
|
|
127
|
+
.filter((a) => !!a && a.id !== requesterId);
|
|
128
|
+
const fresh = peers.filter((p) => {
|
|
129
|
+
const count = requester?.helpedPeers.includes(p.id)
|
|
130
|
+
? (options.pairCollaborationCount ?? 0)
|
|
131
|
+
: 0;
|
|
132
|
+
return count < pairThreshold;
|
|
133
|
+
});
|
|
134
|
+
if (fresh.length > 0) {
|
|
135
|
+
return { targets: fresh.map((a) => a.id), reason: "peer declarado, colaboración bajo el umbral" };
|
|
136
|
+
}
|
|
137
|
+
const third = all.find((a) => a.id !== requesterId &&
|
|
138
|
+
!peers.some((p) => p.id === a.id) &&
|
|
139
|
+
a.state !== "retired" &&
|
|
140
|
+
a.currentCard === null);
|
|
141
|
+
if (third) {
|
|
142
|
+
return { targets: [third.id], reason: "rotación: pares ya colaboraron demasiado" };
|
|
143
|
+
}
|
|
144
|
+
return { targets: [], reason: "sin pares disponibles" };
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Calcula la racha de cards del mismo tipo con el mismo owner.
|
|
148
|
+
*
|
|
149
|
+
* Se usa para decidir rotación.
|
|
150
|
+
*/
|
|
151
|
+
export function ownerStreak(cards, order, ownerId, type) {
|
|
152
|
+
const get = (id) => Array.isArray(cards) ? cards.find((c) => c.id === id) : cards[id];
|
|
153
|
+
let streak = 0;
|
|
154
|
+
for (let i = order.length - 1; i >= 0; i--) {
|
|
155
|
+
const card = get(order[i]);
|
|
156
|
+
if (!card)
|
|
157
|
+
continue;
|
|
158
|
+
if (card.type !== type)
|
|
159
|
+
break;
|
|
160
|
+
if (card.owner !== ownerId)
|
|
161
|
+
break;
|
|
162
|
+
if (card.state === "todo")
|
|
163
|
+
continue;
|
|
164
|
+
streak++;
|
|
165
|
+
}
|
|
166
|
+
return streak;
|
|
167
|
+
}
|
|
168
|
+
/** Construye la ficha de un agente de roster (para renderizar artefactos). */
|
|
169
|
+
export function fichaFromEntry(entry, source) {
|
|
170
|
+
return {
|
|
171
|
+
id: entry.id,
|
|
172
|
+
role: entry.role,
|
|
173
|
+
displayName: entry.displayName,
|
|
174
|
+
source: source ?? entry.source,
|
|
175
|
+
capabilities: entry.capabilities,
|
|
176
|
+
tools: ["read", "glob", "grep", "edit", "write", "bash"],
|
|
177
|
+
scope: { mayTouch: ["**"], forbidden: ["**/*.env"] },
|
|
178
|
+
canDelegate: false,
|
|
179
|
+
delegateBudget: 0,
|
|
180
|
+
peers: [],
|
|
181
|
+
mustNot: [],
|
|
182
|
+
onFinish: "idle-join",
|
|
183
|
+
escalateTo: "integrator",
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/core/router.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Máquina de estados de la oficina.
|
|
3
|
+
*
|
|
4
|
+
* Regla de diseño (de `workflow-engine-design`): los estados y las transiciones
|
|
5
|
+
* válidas se nombran ANTES de escribir código, y el estado se persiste
|
|
6
|
+
* durablemente ANTES de ejecutar efectos. Acá está la tabla de transiciones y
|
|
7
|
+
* los invariantes que el código —no el prompt— garantiza.
|
|
8
|
+
*/
|
|
9
|
+
import type { Card, CardState, OfficeState, RunStatus } from "./types.js";
|
|
10
|
+
import { type Limits } from "./types.js";
|
|
11
|
+
/** Transiciones válidas de card. Todo lo demás es un bug del motor. */
|
|
12
|
+
export declare const CARD_TRANSITIONS: Record<CardState, readonly CardState[]>;
|
|
13
|
+
/** Estados terminales de una card. */
|
|
14
|
+
export declare const TERMINAL_CARD_STATES: readonly CardState[];
|
|
15
|
+
/** Estados que bloquean el avance del plan. */
|
|
16
|
+
export declare const BLOCKING_CARD_STATES: readonly CardState[];
|
|
17
|
+
export declare class InvalidTransitionError extends Error {
|
|
18
|
+
readonly cardId: string;
|
|
19
|
+
readonly from: string;
|
|
20
|
+
readonly to: string;
|
|
21
|
+
constructor(cardId: string, from: string, to: string);
|
|
22
|
+
}
|
|
23
|
+
export declare class InvariantViolationError extends Error {
|
|
24
|
+
readonly invariant: string;
|
|
25
|
+
readonly detail: string;
|
|
26
|
+
constructor(invariant: string, detail: string);
|
|
27
|
+
}
|
|
28
|
+
/** ¿La transición está permitida? */
|
|
29
|
+
export declare function canTransition(from: CardState, to: CardState): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Aplica una transición, validando la tabla.
|
|
32
|
+
*
|
|
33
|
+
* Mutar el estado en un solo lugar evita que dos rutas distintas construyan
|
|
34
|
+
* estados imposibles.
|
|
35
|
+
*/
|
|
36
|
+
export declare function transitionCard(state: OfficeState, cardId: string, to: CardState, patch?: Partial<Card>): Card;
|
|
37
|
+
export interface InvariantContext {
|
|
38
|
+
card?: Card;
|
|
39
|
+
state: OfficeState;
|
|
40
|
+
limits: Limits;
|
|
41
|
+
/** Veredicto de los gates de la card, si se corrieron. */
|
|
42
|
+
gatesPassed?: boolean;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Verifica los invariantes duros.
|
|
46
|
+
*
|
|
47
|
+
* Estos no son sugerencias. Si un flujo de código intenta violarlos, el
|
|
48
|
+
* sistema se niega a avanzar. Es la diferencia entre "el modelo se porto bien"
|
|
49
|
+
* y "el modelo no puede romperlo".
|
|
50
|
+
*/
|
|
51
|
+
export declare function assertInvariants(ctx: InvariantContext): void;
|
|
52
|
+
/**
|
|
53
|
+
* Migra un estado v1 (el que escribía el skill de OFICINA v1) al schema v2.
|
|
54
|
+
*
|
|
55
|
+
* Sin esto, una corrida empezada con el skill queda ilegible para el
|
|
56
|
+
* plugin: los budgets vienen con nombres distintos, el `scope` era un array
|
|
57
|
+
* en vez de un objeto, y las cards no tienen los campos de malla.
|
|
58
|
+
*
|
|
59
|
+
* La migración es aditiva y no destructiva: el objetivo, las cards y sus
|
|
60
|
+
* resultados se conservan. Lo que se completa son los campos nuevos con
|
|
61
|
+
* valores por defecto seguros.
|
|
62
|
+
*/
|
|
63
|
+
export declare function migrateState(raw: unknown, limits?: Limits): OfficeState | undefined;
|
|
64
|
+
/** Crea una corrida nueva. */
|
|
65
|
+
export declare function createRun(objective: string, runId: string, limits?: Limits): OfficeState;
|
|
66
|
+
/** Transiciones de la corrida. */
|
|
67
|
+
export declare const RUN_TRANSITIONS: Record<RunStatus, readonly RunStatus[]>;
|
|
68
|
+
export declare function canTransitionRun(from: RunStatus, to: RunStatus): boolean;
|
|
69
|
+
export declare function transitionRun(state: OfficeState, to: RunStatus): void;
|
|
70
|
+
export interface NextCardResult {
|
|
71
|
+
card: Card | null;
|
|
72
|
+
reason: string;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Elige la próxima card a trabajar.
|
|
76
|
+
*
|
|
77
|
+
* Orden de prioridad:
|
|
78
|
+
* 1. Rework (trabajo ya empezado, hay que terminarlo).
|
|
79
|
+
* 2. Cards `todo` cuyas dependencias estén todas `done`.
|
|
80
|
+
* 3. Cards `in_progress` (retomar).
|
|
81
|
+
*
|
|
82
|
+
* Empates se rompen por posición en `order`, que el planificador define.
|
|
83
|
+
*/
|
|
84
|
+
export declare function selectNextCard(state: OfficeState): NextCardResult;
|
|
85
|
+
/** ¿La corrida terminó? Todas las cards en done. */
|
|
86
|
+
export declare function isRunComplete(state: OfficeState): boolean;
|
|
87
|
+
/** Cards bloqueadas o escaladas. */
|
|
88
|
+
export declare function blockingCards(state: OfficeState): Card[];
|
|
89
|
+
//# sourceMappingURL=state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/core/state.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AACzE,OAAO,EAAkB,KAAK,MAAM,EAAE,MAAM,YAAY,CAAA;AAGxD,uEAAuE;AACvE,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,SAAS,EAAE,SAAS,SAAS,EAAE,CAWpE,CAAA;AAED,sCAAsC;AACtC,eAAO,MAAM,oBAAoB,EAAE,SAAS,SAAS,EAAa,CAAA;AAElE,+CAA+C;AAC/C,eAAO,MAAM,oBAAoB,EAAE,SAAS,SAAS,EAA6B,CAAA;AAElF,qBAAa,sBAAuB,SAAQ,KAAK;IAE7C,QAAQ,CAAC,MAAM,EAAE,MAAM;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM;IACrB,QAAQ,CAAC,EAAE,EAAE,MAAM;gBAFV,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM;CAKtB;AAED,qBAAa,uBAAwB,SAAQ,KAAK;IAE9C,QAAQ,CAAC,SAAS,EAAE,MAAM;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM;gBADd,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM;CAK1B;AAED,qCAAqC;AACrC,wBAAgB,aAAa,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,SAAS,GAAG,OAAO,CAErE;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,SAAS,EACb,KAAK,GAAE,OAAO,CAAC,IAAI,CAAM,GACxB,IAAI,CAUN;AAMD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,IAAI,CAAA;IACX,KAAK,EAAE,WAAW,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,0DAA0D;IAC1D,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,gBAAgB,GAAG,IAAI,CA8D5D;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,GAAE,MAAuB,GAAG,WAAW,GAAG,SAAS,CAiFnG;AAED,8BAA8B;AAC9B,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,GAAE,MAAuB,GAAG,WAAW,CA0BxG;AAED,kCAAkC;AAClC,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,SAAS,EAAE,SAAS,SAAS,EAAE,CAQnE,CAAA;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,SAAS,GAAG,OAAO,CAExE;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,WAAW,EAAE,EAAE,EAAE,SAAS,GAAG,IAAI,CAMrE;AAMD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,IAAI,GAAG,IAAI,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;CACf;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,WAAW,GAAG,cAAc,CA2CjE;AAED,oDAAoD;AACpD,wBAAgB,aAAa,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAGzD;AAED,oCAAoC;AACpC,wBAAgB,aAAa,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,EAAE,CAExD"}
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Máquina de estados de la oficina.
|
|
3
|
+
*
|
|
4
|
+
* Regla de diseño (de `workflow-engine-design`): los estados y las transiciones
|
|
5
|
+
* válidas se nombran ANTES de escribir código, y el estado se persiste
|
|
6
|
+
* durablemente ANTES de ejecutar efectos. Acá está la tabla de transiciones y
|
|
7
|
+
* los invariantes que el código —no el prompt— garantiza.
|
|
8
|
+
*/
|
|
9
|
+
import { DEFAULT_LIMITS } from "./types.js";
|
|
10
|
+
import { nowIso } from "./fsx.js";
|
|
11
|
+
/** Transiciones válidas de card. Todo lo demás es un bug del motor. */
|
|
12
|
+
export const CARD_TRANSITIONS = {
|
|
13
|
+
todo: ["in_progress", "blocked", "escalated"],
|
|
14
|
+
in_progress: ["review", "rework", "blocked", "escalated"],
|
|
15
|
+
review: ["done", "rework", "blocked", "escalated"],
|
|
16
|
+
// Desde rework se puede volver a trabajo o re-entregar directamente a
|
|
17
|
+
// revisión: si el owner corrigió y volvió a entregar, la card vuelve al
|
|
18
|
+
// ciclo sin pasar obrigatoriamente por in_progress.
|
|
19
|
+
rework: ["in_progress", "review", "blocked", "escalated"],
|
|
20
|
+
done: ["rework"],
|
|
21
|
+
blocked: ["todo", "in_progress", "escalated"],
|
|
22
|
+
escalated: ["todo", "in_progress", "rework"],
|
|
23
|
+
};
|
|
24
|
+
/** Estados terminales de una card. */
|
|
25
|
+
export const TERMINAL_CARD_STATES = ["done"];
|
|
26
|
+
/** Estados que bloquean el avance del plan. */
|
|
27
|
+
export const BLOCKING_CARD_STATES = ["blocked", "escalated"];
|
|
28
|
+
export class InvalidTransitionError extends Error {
|
|
29
|
+
cardId;
|
|
30
|
+
from;
|
|
31
|
+
to;
|
|
32
|
+
constructor(cardId, from, to) {
|
|
33
|
+
super(`Transición inválida para ${cardId}: ${from} → ${to}`);
|
|
34
|
+
this.cardId = cardId;
|
|
35
|
+
this.from = from;
|
|
36
|
+
this.to = to;
|
|
37
|
+
this.name = "InvalidTransitionError";
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export class InvariantViolationError extends Error {
|
|
41
|
+
invariant;
|
|
42
|
+
detail;
|
|
43
|
+
constructor(invariant, detail) {
|
|
44
|
+
super(`Invariante violado [${invariant}]: ${detail}`);
|
|
45
|
+
this.invariant = invariant;
|
|
46
|
+
this.detail = detail;
|
|
47
|
+
this.name = "InvariantViolationError";
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/** ¿La transición está permitida? */
|
|
51
|
+
export function canTransition(from, to) {
|
|
52
|
+
return CARD_TRANSITIONS[from].includes(to);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Aplica una transición, validando la tabla.
|
|
56
|
+
*
|
|
57
|
+
* Mutar el estado en un solo lugar evita que dos rutas distintas construyan
|
|
58
|
+
* estados imposibles.
|
|
59
|
+
*/
|
|
60
|
+
export function transitionCard(state, cardId, to, patch = {}) {
|
|
61
|
+
const card = state.cards[cardId];
|
|
62
|
+
if (!card)
|
|
63
|
+
throw new InvariantViolationError("card-exists", `No existe la card ${cardId}`);
|
|
64
|
+
if (!canTransition(card.state, to)) {
|
|
65
|
+
throw new InvalidTransitionError(cardId, card.state, to);
|
|
66
|
+
}
|
|
67
|
+
const next = { ...card, ...patch, state: to };
|
|
68
|
+
state.cards[cardId] = next;
|
|
69
|
+
state.updatedAt = nowIso();
|
|
70
|
+
return next;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Verifica los invariantes duros.
|
|
74
|
+
*
|
|
75
|
+
* Estos no son sugerencias. Si un flujo de código intenta violarlos, el
|
|
76
|
+
* sistema se niega a avanzar. Es la diferencia entre "el modelo se porto bien"
|
|
77
|
+
* y "el modelo no puede romperlo".
|
|
78
|
+
*/
|
|
79
|
+
export function assertInvariants(ctx) {
|
|
80
|
+
const { card, state, limits, gatesPassed } = ctx;
|
|
81
|
+
if (card) {
|
|
82
|
+
// Invariante duro: el revisor nunca es el owner.
|
|
83
|
+
if (limits.reviewerNeqOwner && card.owner && card.reviewer && card.owner === card.reviewer) {
|
|
84
|
+
throw new InvariantViolationError("reviewer-neq-owner", `${card.id}: owner y reviewer son el mismo agente (${card.owner})`);
|
|
85
|
+
}
|
|
86
|
+
// Invariante duro: sin gates en PASS no hay DONE.
|
|
87
|
+
if (limits.gateRequiredBeforeDone && card.state === "done") {
|
|
88
|
+
if (gatesPassed !== true) {
|
|
89
|
+
throw new InvariantViolationError("gate-required-before-done", `${card.id}: marcada DONE sin gates en PASS`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// Invariante duro: una card no puede reventar el presupuesto de reviews.
|
|
93
|
+
if (card.rejections > limits.maxReviewRejections) {
|
|
94
|
+
throw new InvariantViolationError("max-review-rejections", `${card.id}: ${card.rejections} rechazos exceden el máximo ${limits.maxReviewRejections}`);
|
|
95
|
+
}
|
|
96
|
+
// Invariante duro: la cadena de ayuda no excede los saltos permitidos.
|
|
97
|
+
if (card.helpHops > limits.maxHelpChainHops) {
|
|
98
|
+
throw new InvariantViolationError("max-help-chain-hops", `${card.id}: cadena de ayuda de ${card.helpHops} saltos excede el máximo ${limits.maxHelpChainHops}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
// Invariante duro: el presupuesto de cards no se excede.
|
|
102
|
+
if (state.budget.cardsUsed > state.budget.maxCards) {
|
|
103
|
+
throw new InvariantViolationError("max-cards", `Presupuesto de cards excedido: ${state.budget.cardsUsed} > ${state.budget.maxCards}`);
|
|
104
|
+
}
|
|
105
|
+
// Invariante duro: el presupuesto de invocaciones no se excede.
|
|
106
|
+
if (state.budget.agentCallsUsed > state.budget.maxAgentCalls) {
|
|
107
|
+
throw new InvariantViolationError("max-agent-calls", `Presupuesto de agentes excedido: ${state.budget.agentCallsUsed} > ${state.budget.maxAgentCalls}`);
|
|
108
|
+
}
|
|
109
|
+
// Invariante duro: el presupuesto de spawns no se excede.
|
|
110
|
+
if (state.budget.spawnsUsed > state.budget.maxSpawnsTotal) {
|
|
111
|
+
throw new InvariantViolationError("max-spawns-total", `Presupuesto de spawns excedido: ${state.budget.spawnsUsed} > ${state.budget.maxSpawnsTotal}`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
115
|
+
// Ciclo de vida de la corrida
|
|
116
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
117
|
+
/**
|
|
118
|
+
* Migra un estado v1 (el que escribía el skill de OFICINA v1) al schema v2.
|
|
119
|
+
*
|
|
120
|
+
* Sin esto, una corrida empezada con el skill queda ilegible para el
|
|
121
|
+
* plugin: los budgets vienen con nombres distintos, el `scope` era un array
|
|
122
|
+
* en vez de un objeto, y las cards no tienen los campos de malla.
|
|
123
|
+
*
|
|
124
|
+
* La migración es aditiva y no destructiva: el objetivo, las cards y sus
|
|
125
|
+
* resultados se conservan. Lo que se completa son los campos nuevos con
|
|
126
|
+
* valores por defecto seguros.
|
|
127
|
+
*/
|
|
128
|
+
export function migrateState(raw, limits = DEFAULT_LIMITS) {
|
|
129
|
+
if (!raw || typeof raw !== "object")
|
|
130
|
+
return undefined;
|
|
131
|
+
const input = raw;
|
|
132
|
+
// Ya es v2: tiene `budget.maxCards`.
|
|
133
|
+
const budgetRaw = (input.budget ?? {});
|
|
134
|
+
if (typeof budgetRaw.maxCards === "number") {
|
|
135
|
+
return raw;
|
|
136
|
+
}
|
|
137
|
+
const num = (value, fallback) => typeof value === "number" && Number.isFinite(value) ? value : fallback;
|
|
138
|
+
const cards = {};
|
|
139
|
+
const rawCards = (input.cards ?? {});
|
|
140
|
+
for (const [id, rawCard] of Object.entries(rawCards)) {
|
|
141
|
+
const scopeRaw = rawCard.scope;
|
|
142
|
+
const scope = Array.isArray(scopeRaw)
|
|
143
|
+
? { mayTouch: scopeRaw, forbidden: ["**/*.env", "**/*.env.*"] }
|
|
144
|
+
: {
|
|
145
|
+
mayTouch: (scopeRaw?.mayTouch ?? ["**"]),
|
|
146
|
+
forbidden: (scopeRaw?.forbidden ?? ["**/*.env"]),
|
|
147
|
+
};
|
|
148
|
+
const rejectionsRaw = rawCard.rejections;
|
|
149
|
+
const rejections = Array.isArray(rejectionsRaw) ? rejectionsRaw.length : num(rejectionsRaw, 0);
|
|
150
|
+
cards[id] = {
|
|
151
|
+
id: rawCard.id ?? id,
|
|
152
|
+
title: rawCard.title ?? id,
|
|
153
|
+
type: rawCard.type ?? "implementation",
|
|
154
|
+
state: (rawCard.state ?? "todo"),
|
|
155
|
+
owner: rawCard.owner ?? null,
|
|
156
|
+
reviewer: rawCard.reviewer ?? null,
|
|
157
|
+
requiredCapabilities: rawCard.requiredCapabilities ?? [],
|
|
158
|
+
scope,
|
|
159
|
+
acceptance: rawCard.acceptance ?? [],
|
|
160
|
+
gate: rawCard.gate ?? "",
|
|
161
|
+
dependsOn: rawCard.dependsOn ?? (rawCard.depends_on ?? []),
|
|
162
|
+
attempts: num(rawCard.attempts, 0),
|
|
163
|
+
rejections,
|
|
164
|
+
artifacts: rawCard.artifacts ?? `.oficina/artifacts/${id}`,
|
|
165
|
+
result: rawCard.result ?? null,
|
|
166
|
+
helpRequests: rawCard.helpRequests ?? [],
|
|
167
|
+
helpHops: num(rawCard.helpHops, 0),
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
const order = input.order ?? Object.keys(cards);
|
|
171
|
+
return {
|
|
172
|
+
version: 2,
|
|
173
|
+
runId: input.runId ?? `run-${num(input.created, Date.now())}`,
|
|
174
|
+
objective: input.objective ?? "",
|
|
175
|
+
createdAt: input.createdAt ?? input.created ?? new Date().toISOString(),
|
|
176
|
+
updatedAt: input.updatedAt ?? input.updated ?? new Date().toISOString(),
|
|
177
|
+
status: (input.status ?? "planning"),
|
|
178
|
+
cards,
|
|
179
|
+
order,
|
|
180
|
+
budget: {
|
|
181
|
+
cardsUsed: num(budgetRaw.cardsUsed ?? budgetRaw.cards_used, Object.keys(cards).length),
|
|
182
|
+
maxCards: num(budgetRaw.maxCards ?? budgetRaw.max_cards, limits.maxCards),
|
|
183
|
+
agentCallsUsed: num(budgetRaw.agentCallsUsed ?? budgetRaw.agent_calls_used, 0),
|
|
184
|
+
maxAgentCalls: num(budgetRaw.maxAgentCalls ?? budgetRaw.max_agent_calls, limits.maxAgentCalls),
|
|
185
|
+
spawnsUsed: num(budgetRaw.spawnsUsed ?? budgetRaw.spawns_used, 0),
|
|
186
|
+
maxSpawnsTotal: num(budgetRaw.maxSpawnsTotal ?? budgetRaw.max_spawns_total, limits.maxSpawnsTotal),
|
|
187
|
+
},
|
|
188
|
+
decisions: input.decisions ?? [],
|
|
189
|
+
escalations: [],
|
|
190
|
+
context: {
|
|
191
|
+
decisions: [],
|
|
192
|
+
constraints: [],
|
|
193
|
+
pieces: [],
|
|
194
|
+
traps: [],
|
|
195
|
+
open: [],
|
|
196
|
+
},
|
|
197
|
+
iteration: num(input.iteration, 0),
|
|
198
|
+
pendingGates: [],
|
|
199
|
+
sessions: {},
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
/** Crea una corrida nueva. */
|
|
203
|
+
export function createRun(objective, runId, limits = DEFAULT_LIMITS) {
|
|
204
|
+
const ts = nowIso();
|
|
205
|
+
return {
|
|
206
|
+
version: 2,
|
|
207
|
+
runId,
|
|
208
|
+
objective,
|
|
209
|
+
createdAt: ts,
|
|
210
|
+
updatedAt: ts,
|
|
211
|
+
status: "planning",
|
|
212
|
+
cards: {},
|
|
213
|
+
order: [],
|
|
214
|
+
budget: {
|
|
215
|
+
cardsUsed: 0,
|
|
216
|
+
maxCards: limits.maxCards,
|
|
217
|
+
agentCallsUsed: 0,
|
|
218
|
+
maxAgentCalls: limits.maxAgentCalls,
|
|
219
|
+
spawnsUsed: 0,
|
|
220
|
+
maxSpawnsTotal: limits.maxSpawnsTotal,
|
|
221
|
+
},
|
|
222
|
+
decisions: [],
|
|
223
|
+
escalations: [],
|
|
224
|
+
context: { decisions: [], constraints: [], pieces: [], traps: [], open: [] },
|
|
225
|
+
iteration: 0,
|
|
226
|
+
pendingGates: [],
|
|
227
|
+
sessions: {},
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
/** Transiciones de la corrida. */
|
|
231
|
+
export const RUN_TRANSITIONS = {
|
|
232
|
+
planning: ["running", "abandoned"],
|
|
233
|
+
running: ["paused", "delivered", "blocked", "escalated", "abandoned"],
|
|
234
|
+
paused: ["running", "abandoned"],
|
|
235
|
+
delivered: ["running"],
|
|
236
|
+
blocked: ["running", "escalated", "abandoned"],
|
|
237
|
+
escalated: ["running", "abandoned"],
|
|
238
|
+
abandoned: [],
|
|
239
|
+
};
|
|
240
|
+
export function canTransitionRun(from, to) {
|
|
241
|
+
return RUN_TRANSITIONS[from].includes(to);
|
|
242
|
+
}
|
|
243
|
+
export function transitionRun(state, to) {
|
|
244
|
+
if (!canTransitionRun(state.status, to)) {
|
|
245
|
+
throw new InvalidTransitionError("run", state.status, to);
|
|
246
|
+
}
|
|
247
|
+
state.status = to;
|
|
248
|
+
state.updatedAt = nowIso();
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Elige la próxima card a trabajar.
|
|
252
|
+
*
|
|
253
|
+
* Orden de prioridad:
|
|
254
|
+
* 1. Rework (trabajo ya empezado, hay que terminarlo).
|
|
255
|
+
* 2. Cards `todo` cuyas dependencias estén todas `done`.
|
|
256
|
+
* 3. Cards `in_progress` (retomar).
|
|
257
|
+
*
|
|
258
|
+
* Empates se rompen por posición en `order`, que el planificador define.
|
|
259
|
+
*/
|
|
260
|
+
export function selectNextCard(state) {
|
|
261
|
+
const byOrder = (a, b) => state.order.indexOf(a.id) - state.order.indexOf(b.id);
|
|
262
|
+
const ordered = state.order
|
|
263
|
+
.map((id) => state.cards[id])
|
|
264
|
+
.filter((c) => !!c);
|
|
265
|
+
// 1. Trabajo ya empezado: terminarlo antes de abrir algo nuevo. Una card
|
|
266
|
+
// en rework tiene contexto, evidencia parcial y un owner esperando: es
|
|
267
|
+
// la que más rinde continuar.
|
|
268
|
+
const inFlight = ordered
|
|
269
|
+
.filter((c) => c.state === "in_progress" || c.state === "rework")
|
|
270
|
+
.sort(byOrder);
|
|
271
|
+
if (inFlight.length > 0) {
|
|
272
|
+
const card = inFlight[0];
|
|
273
|
+
return { card, reason: "retomando card en curso" };
|
|
274
|
+
}
|
|
275
|
+
// 2. Cards nuevas cuyas dependencias estén satisfechas.
|
|
276
|
+
const ready = ordered
|
|
277
|
+
.filter((c) => c.state === "todo")
|
|
278
|
+
.filter((c) => c.dependsOn.every((dep) => state.cards[dep]?.state === "done"))
|
|
279
|
+
.sort(byOrder);
|
|
280
|
+
if (ready.length > 0) {
|
|
281
|
+
const card = ready[0];
|
|
282
|
+
return { card, reason: "card lista (dependencias satisfechas)" };
|
|
283
|
+
}
|
|
284
|
+
const blocked = ordered.filter((c) => c.state === "blocked" || c.state === "escalated");
|
|
285
|
+
if (blocked.length > 0) {
|
|
286
|
+
return { card: null, reason: `bloqueada: ${blocked.map((c) => c.id).join(", ")}` };
|
|
287
|
+
}
|
|
288
|
+
const pending = ordered.filter((c) => c.state === "review");
|
|
289
|
+
if (pending.length > 0) {
|
|
290
|
+
return { card: null, reason: `esperando gates de: ${pending.map((c) => c.id).join(", ")}` };
|
|
291
|
+
}
|
|
292
|
+
return { card: null, reason: "no quedan cards pendientes" };
|
|
293
|
+
}
|
|
294
|
+
/** ¿La corrida terminó? Todas las cards en done. */
|
|
295
|
+
export function isRunComplete(state) {
|
|
296
|
+
const cards = Object.values(state.cards);
|
|
297
|
+
return cards.length > 0 && cards.every((c) => c.state === "done");
|
|
298
|
+
}
|
|
299
|
+
/** Cards bloqueadas o escaladas. */
|
|
300
|
+
export function blockingCards(state) {
|
|
301
|
+
return Object.values(state.cards).filter((c) => BLOCKING_CARD_STATES.includes(c.state));
|
|
302
|
+
}
|
|
303
|
+
//# sourceMappingURL=state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/core/state.ts"],"names":[],"mappings":"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"}
|