oficina-opencode 2.1.0 → 3.0.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/README.md +46 -10
- package/commands/oficina.md +22 -9
- package/dist/cli.js +14 -1
- package/dist/cli.js.map +1 -1
- package/dist/core/docsync.d.ts.map +1 -1
- package/dist/core/docsync.js +13 -3
- package/dist/core/docsync.js.map +1 -1
- package/dist/core/systemPrompt.d.ts +23 -0
- package/dist/core/systemPrompt.d.ts.map +1 -0
- package/dist/core/systemPrompt.js +62 -0
- package/dist/core/systemPrompt.js.map +1 -0
- package/dist/hooks/systemTransform.d.ts +5 -1
- package/dist/hooks/systemTransform.d.ts.map +1 -1
- package/dist/hooks/systemTransform.js +9 -40
- package/dist/hooks/systemTransform.js.map +1 -1
- package/dist/pluginEntry.d.ts +33 -0
- package/dist/pluginEntry.d.ts.map +1 -0
- package/dist/pluginEntry.js +106 -0
- package/dist/pluginEntry.js.map +1 -0
- package/dist/tools/index.d.ts +43 -2
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +20 -7
- package/dist/tools/index.js.map +1 -1
- package/dist/v1.d.ts +46 -0
- package/dist/v1.d.ts.map +1 -0
- package/dist/v1.js +305 -0
- package/dist/v1.js.map +1 -0
- package/dist/v2.d.ts +45 -0
- package/dist/v2.d.ts.map +1 -0
- package/dist/v2.js +419 -0
- package/dist/v2.js.map +1 -0
- package/docs/COMPATIBILITY.md +83 -42
- package/docs/QUE-ES.md +2 -2
- package/package.json +22 -8
- package/skills/oficina/SKILL.md +191 -69
- package/skills/oficina/reference/mesh.md +11 -2
package/dist/v2.js
ADDED
|
@@ -0,0 +1,419 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OFICINA — entry point del plugin para **OpenCode v2**.
|
|
3
|
+
*
|
|
4
|
+
* ## Por qué existe este archivo
|
|
5
|
+
*
|
|
6
|
+
* OpenCode v1 y v2 tienen APIs de plugins **incomunes**: no es que
|
|
7
|
+
* cambiara una firma, es que cambió la forma. v1 exportaba una funcion que
|
|
8
|
+
* devuelve hooks; v2 exige `export default { id, setup(ctx) }`. Un plugin
|
|
9
|
+
* v1 bajo v2 falla con:
|
|
10
|
+
*
|
|
11
|
+
* PluginModule.LoadError: Plugin must export a default definition with
|
|
12
|
+
* an id and an effect or setup function.
|
|
13
|
+
*
|
|
14
|
+
* Y al reves: un plugin v2 bajo v1 no carga.
|
|
15
|
+
*
|
|
16
|
+
* Este archivo es la implementacion **v2**. La de v1 vive en `v1.ts` y el
|
|
17
|
+
* motor (`core/`, `tools/`) no depende de ninguna de las dos APIs: define
|
|
18
|
+
* las tools en una forma neutra y cada entry la traduce.
|
|
19
|
+
*
|
|
20
|
+
* ## Que registra
|
|
21
|
+
*
|
|
22
|
+
* - **Tools** (`oficina_*`): la superficie de trabajo, via `ctx.tool.transform`.
|
|
23
|
+
* - **Guard de scope** (`ctx.tool.hook` + `ctx.permission.hook`): dos capas.
|
|
24
|
+
* La primera intercepta la tool; la segunda es el punto de enforcement del
|
|
25
|
+
* framework y puede `deny` de verdad.
|
|
26
|
+
* - **Tripwire** (`ctx.tool.hook("execute.after")`): detecta escrituras que se
|
|
27
|
+
* colaron por un comando de shell.
|
|
28
|
+
* - **Estado de la oficina** (`ctx.session.hook("context")`): el agente no
|
|
29
|
+
* repregunta lo que ya sabe.
|
|
30
|
+
* - **Auto-continuacion** (`session.idle`): la corrida sigue sola cuando el
|
|
31
|
+
* modelo para.
|
|
32
|
+
* - **Costo** (`session.usage.recorded`): el numero real que reporta el motor.
|
|
33
|
+
*/
|
|
34
|
+
import { Plugin } from "@opencode/plugin";
|
|
35
|
+
import { z } from "zod";
|
|
36
|
+
import { Office } from "./core/office.js";
|
|
37
|
+
import { buildTools } from "./tools/index.js";
|
|
38
|
+
import { analyzeShellCommand, checkScope } from "./core/sandbox.js";
|
|
39
|
+
import { extractCommand, extractPaths, resolveScopeCard } from "./hooks/scopeGuard.js";
|
|
40
|
+
import { Tripwire } from "./core/tripwire.js";
|
|
41
|
+
import { logger } from "./core/log.js";
|
|
42
|
+
const log = logger("oficina:v2");
|
|
43
|
+
/** Tools que escriben un archivo. */
|
|
44
|
+
const FILE_WRITE_TOOLS = new Set([
|
|
45
|
+
"edit",
|
|
46
|
+
"write",
|
|
47
|
+
"patch",
|
|
48
|
+
"multiedit",
|
|
49
|
+
"apply_patch",
|
|
50
|
+
"notebook_edit",
|
|
51
|
+
"str_replace",
|
|
52
|
+
"str_replace_editor",
|
|
53
|
+
"edit_file",
|
|
54
|
+
"edit_notebook_file",
|
|
55
|
+
"create_file",
|
|
56
|
+
"write_file",
|
|
57
|
+
"create_or_update_file",
|
|
58
|
+
]);
|
|
59
|
+
/** Tools que ejecutan shell. */
|
|
60
|
+
const SHELL_TOOLS = new Set([
|
|
61
|
+
"bash",
|
|
62
|
+
"shell",
|
|
63
|
+
"run",
|
|
64
|
+
"run_command",
|
|
65
|
+
"execute_command",
|
|
66
|
+
"terminal",
|
|
67
|
+
"powershell",
|
|
68
|
+
"cmd",
|
|
69
|
+
]);
|
|
70
|
+
/** Acciones de permiso que implican escribir un archivo. */
|
|
71
|
+
const WRITE_ACTIONS = new Set(["edit", "write", "patch", "multiedit", "apply_patch"]);
|
|
72
|
+
/**
|
|
73
|
+
* Convierte un schema zod a JSON Schema.
|
|
74
|
+
*
|
|
75
|
+
* v2 exige JSON Schema plano en `tool.input`. zod v4 lo hace nativo.
|
|
76
|
+
*/
|
|
77
|
+
function toJsonSchema(schema) {
|
|
78
|
+
if (!schema)
|
|
79
|
+
return { type: "object", additionalProperties: true };
|
|
80
|
+
try {
|
|
81
|
+
const converted = z.toJSONSchema(schema, {
|
|
82
|
+
io: "input",
|
|
83
|
+
unrepresentable: "any",
|
|
84
|
+
});
|
|
85
|
+
// Si el schema no es de un objeto, se acepta igual pero se documenta.
|
|
86
|
+
if (converted["type"] !== "object") {
|
|
87
|
+
return { type: "object", additionalProperties: true, description: converted["description"] };
|
|
88
|
+
}
|
|
89
|
+
return { ...converted, additionalProperties: false };
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
return { type: "object", additionalProperties: true };
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
export default Plugin.define({
|
|
96
|
+
id: "oficina",
|
|
97
|
+
async setup(ctx) {
|
|
98
|
+
const options = (ctx.options ?? {});
|
|
99
|
+
const enforce = options.enforceScope !== false;
|
|
100
|
+
const directory = ctx.location.directory;
|
|
101
|
+
const office = new Office({ cwd: directory });
|
|
102
|
+
await office.init();
|
|
103
|
+
const tripwire = new Tripwire(office.paths.projectRoot, {
|
|
104
|
+
maxFiles: options.tripwireMaxFiles ?? 4000,
|
|
105
|
+
});
|
|
106
|
+
/** El scope que aplica a una sesion, si tiene. */
|
|
107
|
+
const scopeOf = async (sessionID) => {
|
|
108
|
+
try {
|
|
109
|
+
const state = await office.loadState();
|
|
110
|
+
const card = await resolveScopeCard(state, sessionID, { enforce });
|
|
111
|
+
if (!card)
|
|
112
|
+
return undefined;
|
|
113
|
+
const policy = {
|
|
114
|
+
mayTouch: card.scope.mayTouch,
|
|
115
|
+
forbidden: card.scope.forbidden,
|
|
116
|
+
};
|
|
117
|
+
return { card, policy };
|
|
118
|
+
}
|
|
119
|
+
catch (err) {
|
|
120
|
+
log.debug("no se pudo resolver el scope de la sesion", { sessionID, error: String(err) });
|
|
121
|
+
return undefined;
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
/* ────────────────────────────────────────────────────────────────────────
|
|
125
|
+
* 1. TOOLS
|
|
126
|
+
* ──────────────────────────────────────────────────────────────────────── */
|
|
127
|
+
const defs = buildTools(office);
|
|
128
|
+
await ctx.tool.transform((editor) => {
|
|
129
|
+
for (const [name, def] of Object.entries(defs)) {
|
|
130
|
+
editor.add({
|
|
131
|
+
name,
|
|
132
|
+
description: def.description,
|
|
133
|
+
input: toJsonSchema(def.args),
|
|
134
|
+
execute: async (input, toolCtx) => {
|
|
135
|
+
const result = await def.execute((input ?? {}), {
|
|
136
|
+
directory,
|
|
137
|
+
sessionID: toolCtx.sessionID,
|
|
138
|
+
agent: toolCtx.agent,
|
|
139
|
+
messageID: toolCtx.messageID,
|
|
140
|
+
});
|
|
141
|
+
return {
|
|
142
|
+
content: result.output,
|
|
143
|
+
metadata: result.metadata,
|
|
144
|
+
};
|
|
145
|
+
},
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
/* ────────────────────────────────────────────────────────────────────────
|
|
150
|
+
* 2. GUARD DE SCOPE
|
|
151
|
+
*
|
|
152
|
+
* Dos capas, porque cada una cubre lo que la otra no:
|
|
153
|
+
*
|
|
154
|
+
* - `tool.hook("execute.before")`: ve el path exacto de cada tool que
|
|
155
|
+
* escribe, incluso los que no pasan por el sistema de permisos.
|
|
156
|
+
* - `permission.hook("evaluate")`: es el punto de enforcement del
|
|
157
|
+
* framework y puede `deny` de verdad, con motivo.
|
|
158
|
+
* ──────────────────────────────────────────────────────────────────────── */
|
|
159
|
+
/** Verifica un path contra el scope. Devuelve el motivo si viola. */
|
|
160
|
+
const violation = async (sessionID, rawPath) => {
|
|
161
|
+
const scope = await scopeOf(sessionID);
|
|
162
|
+
if (!scope)
|
|
163
|
+
return undefined;
|
|
164
|
+
const verdict = await checkScope(office.paths.projectRoot, rawPath, scope.policy);
|
|
165
|
+
if (verdict.allowed)
|
|
166
|
+
return undefined;
|
|
167
|
+
return { reason: verdict.reason, kind: verdict.kind };
|
|
168
|
+
};
|
|
169
|
+
await ctx.tool.hook("execute.before", async (event) => {
|
|
170
|
+
const tool = String(event.tool);
|
|
171
|
+
const input = (event.input ?? {});
|
|
172
|
+
// Lecturas: nunca se tocan.
|
|
173
|
+
if (!FILE_WRITE_TOOLS.has(tool) && !SHELL_TOOLS.has(tool))
|
|
174
|
+
return;
|
|
175
|
+
const scope = await scopeOf(event.sessionID);
|
|
176
|
+
if (!scope)
|
|
177
|
+
return;
|
|
178
|
+
if (FILE_WRITE_TOOLS.has(tool)) {
|
|
179
|
+
for (const rawPath of extractPaths(tool, input)) {
|
|
180
|
+
const bad = await violation(event.sessionID, rawPath);
|
|
181
|
+
if (!bad)
|
|
182
|
+
continue;
|
|
183
|
+
const mensaje = `[OFICINA] Scope violado: ${bad.reason} (card ${scope.card.id})`;
|
|
184
|
+
log.warn("scope violado (archivo)", { card: scope.card.id, path: rawPath, kind: bad.kind });
|
|
185
|
+
if (enforce)
|
|
186
|
+
throw new Error(mensaje);
|
|
187
|
+
}
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
if (SHELL_TOOLS.has(tool)) {
|
|
191
|
+
const command = extractCommand(input);
|
|
192
|
+
if (!command)
|
|
193
|
+
return;
|
|
194
|
+
for (const candidate of analyzeShellCommand(command)) {
|
|
195
|
+
if (candidate.uncertain) {
|
|
196
|
+
// Hay una escritura que no sabemos interpretar. No se bloquea
|
|
197
|
+
// (seria inservible), pero el tripwire va a mirar.
|
|
198
|
+
log.warn("shell con escritura no interpretable", {
|
|
199
|
+
card: scope.card.id,
|
|
200
|
+
op: candidate.op,
|
|
201
|
+
});
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
const bad = await violation(event.sessionID, candidate.target);
|
|
205
|
+
if (!bad)
|
|
206
|
+
continue;
|
|
207
|
+
const mensaje = `[OFICINA] Scope violado: ${bad.reason} (card ${scope.card.id})`;
|
|
208
|
+
log.warn("scope violado (shell)", {
|
|
209
|
+
card: scope.card.id,
|
|
210
|
+
target: candidate.target,
|
|
211
|
+
kind: bad.kind,
|
|
212
|
+
});
|
|
213
|
+
if (enforce && options.enforceScope !== false)
|
|
214
|
+
throw new Error(mensaje);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
await ctx.permission.hook("evaluate", async (event) => {
|
|
219
|
+
if (!WRITE_ACTIONS.has(String(event.action)))
|
|
220
|
+
return;
|
|
221
|
+
const scope = await scopeOf(event.sessionID);
|
|
222
|
+
if (!scope)
|
|
223
|
+
return;
|
|
224
|
+
for (const resource of event.resources) {
|
|
225
|
+
const bad = await violation(event.sessionID, resource);
|
|
226
|
+
if (!bad)
|
|
227
|
+
continue;
|
|
228
|
+
event.effect = "deny";
|
|
229
|
+
event.message = `[OFICINA] ${bad.reason} (card ${scope.card.id})`;
|
|
230
|
+
log.warn("permiso denegado por scope", {
|
|
231
|
+
card: scope.card.id,
|
|
232
|
+
resource,
|
|
233
|
+
kind: bad.kind,
|
|
234
|
+
});
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
/* ────────────────────────────────────────────────────────────────────────
|
|
239
|
+
* 3. TRIPWIRE
|
|
240
|
+
*
|
|
241
|
+
* Fotografia el arbol antes de una tool y compara despues. Lo que cambio
|
|
242
|
+
* fuera del scope se reporta por el bus: detecta, no revierte.
|
|
243
|
+
* ──────────────────────────────────────────────────────────────────────── */
|
|
244
|
+
await ctx.tool.hook("execute.before", async (event) => {
|
|
245
|
+
const scope = await scopeOf(event.sessionID);
|
|
246
|
+
if (!scope)
|
|
247
|
+
return;
|
|
248
|
+
await tripwire.arm(String(event.id), scope.policy.mayTouch);
|
|
249
|
+
});
|
|
250
|
+
await ctx.tool.hook("execute.after", async (event) => {
|
|
251
|
+
const scope = await scopeOf(event.sessionID);
|
|
252
|
+
if (!scope)
|
|
253
|
+
return;
|
|
254
|
+
const cambios = await tripwire.check(String(event.id), scope.policy.mayTouch);
|
|
255
|
+
if (cambios.length === 0)
|
|
256
|
+
return;
|
|
257
|
+
const detalle = cambios.map((c) => ` - ${c.kind}: ${c.path}`).join("\n");
|
|
258
|
+
log.warn("escrituras fuera del scope detectadas", {
|
|
259
|
+
card: scope.card.id,
|
|
260
|
+
tool: event.tool,
|
|
261
|
+
cambios: cambios.length,
|
|
262
|
+
});
|
|
263
|
+
await office.bus
|
|
264
|
+
.send("peer", {
|
|
265
|
+
from: "oficina",
|
|
266
|
+
to: ["*"],
|
|
267
|
+
kind: "NOTICE",
|
|
268
|
+
subject: scope.card.id,
|
|
269
|
+
body: {
|
|
270
|
+
notice: "scope",
|
|
271
|
+
message: `Se detectaron ${cambios.length} cambio(s) fuera del scope de la card ${scope.card.id} ` +
|
|
272
|
+
`durante \`${event.tool}\`:\n${detalle}\n\n` +
|
|
273
|
+
`Si fue deliberado, avisalo por el bus. Si no, revisé lo que tocaste.`,
|
|
274
|
+
},
|
|
275
|
+
})
|
|
276
|
+
.catch(() => undefined);
|
|
277
|
+
});
|
|
278
|
+
/* ────────────────────────────────────────────────────────────────────────
|
|
279
|
+
* 4. EL ESTADO DE LA OFICINA VIAJA CON CADA LLAMADA
|
|
280
|
+
* ──────────────────────────────────────────────────────────────────────── */
|
|
281
|
+
await ctx.session.hook("context", async (event) => {
|
|
282
|
+
try {
|
|
283
|
+
const { buildSystemPrompt } = await import("./core/systemPrompt.js");
|
|
284
|
+
const state = await office.loadState();
|
|
285
|
+
event.system.push({ type: "text", text: await buildSystemPrompt(office, state) });
|
|
286
|
+
}
|
|
287
|
+
catch (err) {
|
|
288
|
+
log.debug("no se pudo inyectar el estado", { error: String(err) });
|
|
289
|
+
}
|
|
290
|
+
});
|
|
291
|
+
/* ────────────────────────────────────────────────────────────────────────
|
|
292
|
+
* 5. COMPACTACION
|
|
293
|
+
*
|
|
294
|
+
* El estado sobrevive a la compactacion: se lee del disco, no de la
|
|
295
|
+
* memoria de la conversacion.
|
|
296
|
+
* ──────────────────────────────────────────────────────────────────────── */
|
|
297
|
+
await ctx.session.hook("compaction", async (event) => {
|
|
298
|
+
try {
|
|
299
|
+
const { buildSystemPrompt } = await import("./core/systemPrompt.js");
|
|
300
|
+
const state = await office.loadState();
|
|
301
|
+
event.system.push({ type: "text", text: await buildSystemPrompt(office, state) });
|
|
302
|
+
}
|
|
303
|
+
catch (err) {
|
|
304
|
+
log.debug("no se pudo inyectar el estado al compactar", { error: String(err) });
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
/* ────────────────────────────────────────────────────────────────────────
|
|
308
|
+
* 6. EVENTOS: auto-continuacion y costo
|
|
309
|
+
* ──────────────────────────────────────────────────────────────────────── */
|
|
310
|
+
const maxAutoResumes = options.maxAutoResumes ?? 25;
|
|
311
|
+
const resumes = new Map();
|
|
312
|
+
const lastResume = new Map();
|
|
313
|
+
const controller = new AbortController();
|
|
314
|
+
void (async () => {
|
|
315
|
+
try {
|
|
316
|
+
for await (const event of ctx.event.subscribe({ signal: controller.signal })) {
|
|
317
|
+
/* ── Auto-continuacion ── */
|
|
318
|
+
if (event.type === "session.idle") {
|
|
319
|
+
const sessionID = event.data?.sessionID;
|
|
320
|
+
if (!sessionID)
|
|
321
|
+
continue;
|
|
322
|
+
try {
|
|
323
|
+
const state = await office.loadState();
|
|
324
|
+
if (state.status !== "running")
|
|
325
|
+
continue;
|
|
326
|
+
if (state.halt)
|
|
327
|
+
continue;
|
|
328
|
+
const cards = Object.values(state.cards);
|
|
329
|
+
const pending = cards.filter((c) => c.state !== "done");
|
|
330
|
+
if (pending.length === 0)
|
|
331
|
+
continue;
|
|
332
|
+
const count = resumes.get(sessionID) ?? 0;
|
|
333
|
+
if (count >= maxAutoResumes) {
|
|
334
|
+
log.warn("tope de auto-reanudaciones alcanzado", { sessionID, count });
|
|
335
|
+
continue;
|
|
336
|
+
}
|
|
337
|
+
const last = lastResume.get(sessionID);
|
|
338
|
+
if (last !== undefined && Date.now() - last < 1_500)
|
|
339
|
+
continue;
|
|
340
|
+
lastResume.set(sessionID, Date.now());
|
|
341
|
+
resumes.set(sessionID, count + 1);
|
|
342
|
+
const { renderMesaBrief, snapshotMesa } = await import("./core/mesa.js");
|
|
343
|
+
const mesa = await snapshotMesa(office);
|
|
344
|
+
const mesaBrief = renderMesaBrief(mesa);
|
|
345
|
+
const texto = [
|
|
346
|
+
"[OFICINA - auto-continuacion]",
|
|
347
|
+
"",
|
|
348
|
+
`La corrida sigue abierta. Quedan ${pending.length} card(s) sin terminar.`,
|
|
349
|
+
"",
|
|
350
|
+
...(mesaBrief ? ["---", "", "**La mesa:**", "", mesaBrief] : []),
|
|
351
|
+
"",
|
|
352
|
+
"Usá `oficina_board` para el panorama y `oficina_mesa` para ver la mesa.",
|
|
353
|
+
"No declares la corrida terminada mientras queden cards sin DONE.",
|
|
354
|
+
].join("\n");
|
|
355
|
+
await ctx.session.synthetic({
|
|
356
|
+
sessionID,
|
|
357
|
+
text: texto,
|
|
358
|
+
description: "OFICINA: auto-continuacion",
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
catch (err) {
|
|
362
|
+
log.error("fallo en la auto-continuacion", { error: String(err) });
|
|
363
|
+
}
|
|
364
|
+
continue;
|
|
365
|
+
}
|
|
366
|
+
/* ── Costo ── */
|
|
367
|
+
//
|
|
368
|
+
// El evento trae el numero REAL que reporto el motor. No se estima.
|
|
369
|
+
//
|
|
370
|
+
// El tipo del stream publicado no incluye los eventos de usage (el
|
|
371
|
+
// union tipado es mas angosto que el manifiesto del schema), asi
|
|
372
|
+
// que se lee de forma laxa y a mano: si la forma no coincide, se
|
|
373
|
+
// ignora en vez de romper.
|
|
374
|
+
const raw = event;
|
|
375
|
+
if (raw.type === "session.usage.recorded" || raw.type === "session.usage.updated") {
|
|
376
|
+
const data = raw.data;
|
|
377
|
+
if (!data?.sessionID)
|
|
378
|
+
continue;
|
|
379
|
+
try {
|
|
380
|
+
const state = await office.loadState();
|
|
381
|
+
const binding = state.sessions[data.sessionID];
|
|
382
|
+
await office.recordUsage({
|
|
383
|
+
agentId: binding?.agentId ?? data.sessionID,
|
|
384
|
+
role: binding?.agentId ?? "agente",
|
|
385
|
+
cardId: binding?.cardId ?? null,
|
|
386
|
+
phase: binding?.cardId ? "implementation" : "exploration",
|
|
387
|
+
model: "desconocido",
|
|
388
|
+
provider: "desconocido",
|
|
389
|
+
cost: data.cost ?? 0,
|
|
390
|
+
tokens: {
|
|
391
|
+
input: data.tokens?.input ?? 0,
|
|
392
|
+
output: data.tokens?.output ?? 0,
|
|
393
|
+
reasoning: data.tokens?.reasoning ?? 0,
|
|
394
|
+
cache: { read: data.tokens?.cache?.read ?? 0, write: data.tokens?.cache?.write ?? 0 },
|
|
395
|
+
},
|
|
396
|
+
latencyMs: 0,
|
|
397
|
+
});
|
|
398
|
+
}
|
|
399
|
+
catch (err) {
|
|
400
|
+
log.debug("no se pudo registrar el uso", { error: String(err) });
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
catch (err) {
|
|
406
|
+
if (!controller.signal.aborted) {
|
|
407
|
+
log.error("el stream de eventos se corto", { error: String(err) });
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
})();
|
|
411
|
+
log.info("plugin inicializado", {
|
|
412
|
+
directory,
|
|
413
|
+
tools: Object.keys(defs).length,
|
|
414
|
+
officeDir: office.paths.officeDir,
|
|
415
|
+
});
|
|
416
|
+
return () => controller.abort();
|
|
417
|
+
},
|
|
418
|
+
});
|
|
419
|
+
//# sourceMappingURL=v2.js.map
|
package/dist/v2.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"v2.js","sourceRoot":"","sources":["../src/v2.ts"],"names":[],"mappings":"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"}
|
package/docs/COMPATIBILITY.md
CHANGED
|
@@ -9,43 +9,69 @@ nadie verificó.
|
|
|
9
9
|
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
-
##
|
|
12
|
+
## ⚠️ El cambio de API de plugins es el punto que hay que entender
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
**OpenCode v1 y v2 tienen APIs de plugins incompatibles.** No es que cambiara
|
|
15
|
+
una firma: cambió la forma.
|
|
16
|
+
|
|
17
|
+
| | OpenCode v1 | OpenCode v2 |
|
|
15
18
|
|---|---|---|
|
|
16
|
-
|
|
|
17
|
-
|
|
|
18
|
-
|
|
|
19
|
+
| Export default | una **función** que devuelve hooks | un **objeto** `{ id, setup(ctx) }` |
|
|
20
|
+
| Registrar tools | `hooks.tool = { nombre: tool({...}) }` | `ctx.tool.transform(editor => editor.add({...}))` |
|
|
21
|
+
| Forma de los args | schema **zod** | **JSON Schema** plano |
|
|
22
|
+
| Interceptar tools | hook `tool.execute.before` | `ctx.tool.hook("execute.before")` |
|
|
23
|
+
| Denegar una acción | hook `permission.ask` | `ctx.permission.hook("evaluate")` → `effect = "deny"` |
|
|
24
|
+
| Inyectar al system prompt | `experimental.chat.system.transform` | `ctx.session.hook("context")` |
|
|
25
|
+
| Eventos | hook `event` | `ctx.event.subscribe({ signal })` |
|
|
26
|
+
| Auto-continuación | `client.session.promptAsync` | `ctx.session.synthetic({...})` |
|
|
19
27
|
|
|
20
|
-
|
|
21
|
-
**la compatibilidad se verifica en tiempo de compilación**, no por
|
|
22
|
-
inspección visual.
|
|
28
|
+
Un plugin v1 bajo v2 falla con:
|
|
23
29
|
|
|
24
|
-
|
|
30
|
+
```
|
|
31
|
+
PluginModule.LoadError: Plugin must export a default definition with an id
|
|
32
|
+
and an effect or setup function.
|
|
33
|
+
```
|
|
25
34
|
|
|
26
|
-
|
|
27
|
-
|---|---|---|
|
|
28
|
-
| `event` (`session.idle`) | Auto-reanudación de la corrida | La corrida sigue, pero no se reanuda sola. |
|
|
29
|
-
| `event` (`message.updated`) | Contabilidad de costo | No hay registro de costo. La oficina sigue funcionando. |
|
|
30
|
-
| `tool.execute.before` | Guard de scope | **Sin protección**: el scope pasa a ser una instrucción, no una restricción. |
|
|
31
|
-
| `tool.execute.after` | Tripwire | No hay detección de escrituras coladas. |
|
|
32
|
-
| `permission.ask` | Segunda capa de enforcement | Queda solo la primera capa. |
|
|
33
|
-
| `experimental.chat.system.transform` | El estado viaja con cada llamada | El agente tiene que preguntar el estado. |
|
|
34
|
-
| `experimental.session.compacting` | El estado sobrevive a la compactación | La compactación pierde el contexto de la oficina. |
|
|
35
|
-
| `experimental.compaction.autocontinue` | Freno de emergencia | El freno frena el trabajo, pero la auto-continuación post-compactación sigue. |
|
|
35
|
+
Y al revés, un plugin v2 bajo v1 no carga.
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
### Cómo lo resuelve AI-OFFICE
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
el proyecto declara un mínimo:
|
|
39
|
+
El **motor** (`core/`, `tools/`) no depende de ninguna de las dos APIs:
|
|
41
40
|
|
|
42
|
-
-
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
- Las tools se definen en una **forma neutra** (`{ description, args, execute }`).
|
|
42
|
+
- `src/v2.ts` las traduce a v2 (zod → JSON Schema con `z.toJSONSchema`).
|
|
43
|
+
- `src/v1.ts` las traduce a v1 (el helper `tool()` del plugin v1).
|
|
45
44
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
El texto del system prompt también es compartido: vive en
|
|
46
|
+
`core/systemPrompt.ts` y cada entry lo inyecta donde su API lo permite. Si
|
|
47
|
+
viviera dentro de cada hook, las dos copias se desincronizarían.
|
|
48
|
+
|
|
49
|
+
| Entry | Versión de OpenCode |
|
|
50
|
+
|---|---|
|
|
51
|
+
| `oficina-opencode` (`.`) | **v2** — la principal |
|
|
52
|
+
| `oficina-opencode/v1` | v1 (legacy) |
|
|
53
|
+
|
|
54
|
+
## Versiones
|
|
55
|
+
|
|
56
|
+
| Componente | Versión | Cómo se verificó |
|
|
57
|
+
|---|---|---|
|
|
58
|
+
| `@opencode/plugin` | `^2.1.2` | Compilación con `strict` + `noUncheckedIndexedAccess` contra los tipos reales. Un hook que no exista en el tipo **no compila**. |
|
|
59
|
+
| `@opencode-ai/plugin` | `^1.15.11` *(peer opcional)* | Solo lo necesita el entry `./v1`. |
|
|
60
|
+
| OpenCode CLI | `2.1.1` | Probado con el servicio real: el plugin carga, registra las 16 tools y responde. |
|
|
61
|
+
| Node.js | `>=20` | CI corre la matriz `[20, 22]` en `ubuntu-latest` y `windows-latest`. |
|
|
62
|
+
| TypeScript | `>=5.8` | `tsc --noEmit` en modo `strict`. |
|
|
63
|
+
|
|
64
|
+
## Hooks que usa el plugin v2
|
|
65
|
+
|
|
66
|
+
| Hook | Para qué | Si el host no lo soporta |
|
|
67
|
+
|---|---|---|
|
|
68
|
+
| `ctx.tool.transform` | Registra las 16 tools | **Sin tools, la oficina no existe.** |
|
|
69
|
+
| `ctx.tool.hook("execute.before")` | Guard de scope + armado del tripwire | El scope pasa a ser una instrucción. |
|
|
70
|
+
| `ctx.tool.hook("execute.after")` | Tripwire: detecta escrituras coladas | No hay detección. |
|
|
71
|
+
| `ctx.permission.hook("evaluate")` | Segunda capa: `deny` real | Queda solo el guard propio. |
|
|
72
|
+
| `ctx.session.hook("context")` | El estado viaja con cada llamada | El agente repregunta lo que ya sabe. |
|
|
73
|
+
| `ctx.session.hook("compaction")` | El estado sobrevive a la compactación | La compactación pierde el contexto. |
|
|
74
|
+
| `ctx.event.subscribe` | Auto-continuación (`session.idle`) y costo (`session.usage.recorded`) | Sin auto-continuación ni contabilidad de costo. |
|
|
49
75
|
|
|
50
76
|
## Pruebas de integración por versión
|
|
51
77
|
|
|
@@ -56,26 +82,21 @@ os: [ubuntu-latest, windows-latest]
|
|
|
56
82
|
node: [20, 22]
|
|
57
83
|
```
|
|
58
84
|
|
|
59
|
-
En cada combinación
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
2. `npm run test` — la suite completa (los tests del plugin usan un host
|
|
63
|
-
simulado con la misma forma que el real).
|
|
64
|
-
3. `npm run build` — el `dist/` se genera.
|
|
65
|
-
4. `npm pack --dry-run` — el paquete se puede armar.
|
|
85
|
+
En cada combinación: `npm run typecheck`, `npm run test`, `npm run build`,
|
|
86
|
+
`npm pack --dry-run`. Y en un job aparte, el smoke del CLI sobre el `dist/`
|
|
87
|
+
real.
|
|
66
88
|
|
|
67
|
-
|
|
89
|
+
Los tests del plugin v2 (`tests/pluginV2.test.ts`) mockean el contexto de v2
|
|
90
|
+
y comprueban que las tools se registran con JSON Schema, que los hooks se
|
|
91
|
+
instalan y que las tools responden.
|
|
68
92
|
|
|
69
93
|
## OpenCode
|
|
70
94
|
|
|
71
95
|
| Versión de OpenCode | Soporte |
|
|
72
96
|
|---|---|
|
|
73
|
-
|
|
|
74
|
-
|
|
|
75
|
-
|
|
76
|
-
El plugin **no fija** una versión de OpenCode: se instala como plugin y usa
|
|
77
|
-
el API que el host expone. Lo que sí fija es la versión del **API de
|
|
78
|
-
plugin**, que es lo que usa directamente.
|
|
97
|
+
| **v2.x** (>= 2.1) | **Sí.** Es la que se prueba en desarrollo y en el servicio real. |
|
|
98
|
+
| v1 (>= 1.18.29) | Legacy, via `oficina-opencode/v1`. Los hooks v1 funcionan; los de v2 no. |
|
|
99
|
+
| v1 anteriores a 1.18.29 | No. La forma de objeto no estaba soportada. |
|
|
79
100
|
|
|
80
101
|
## Requisitos del usuario, no del plugin
|
|
81
102
|
|
|
@@ -87,6 +108,26 @@ plugin**, que es lo que usa directamente.
|
|
|
87
108
|
|
|
88
109
|
---
|
|
89
110
|
|
|
111
|
+
## Un detalle que obliga a resolver el paquete en runtime
|
|
112
|
+
|
|
113
|
+
El loader de plugins de OpenCode v2 **no resuelve bare specifiers** desde
|
|
114
|
+
`~/.config/opencode/plugins/`. Un `export { default } from "oficina-opencode"`
|
|
115
|
+
falla con:
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
Cannot find package 'oficina-opencode' imported from
|
|
119
|
+
C:\Users\...\ .config\opencode\plugins\oficina.js
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Node sí lo resolvería (subiendo por los `node_modules`). Bun, que es el
|
|
123
|
+
runtime de OpenCode, no.
|
|
124
|
+
|
|
125
|
+
Por eso `oficina install` escribe un entry (`dist/pluginEntry.js`) que
|
|
126
|
+
**busca el paquete en runtime** — en el `node_modules` de la config, en la
|
|
127
|
+
cache de npm de OpenCode, o subiendo desde el propio archivo — y lo importa
|
|
128
|
+
por ruta absoluta. Se resuelve en runtime y no al instalar, así que
|
|
129
|
+
reinstalar el paquete en otro lugar no rompe el entry.
|
|
130
|
+
|
|
90
131
|
## Cómo se mantiene esta tabla
|
|
91
132
|
|
|
92
133
|
Las cifras de versiones salen del `package.json` real y se verifican en el
|
package/docs/QUE-ES.md
CHANGED
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
<!-- BEGIN GENERATED: facts -->
|
|
4
4
|
| | |
|
|
5
5
|
|---|---|
|
|
6
|
-
| **Paquete** | `oficina-opencode`
|
|
6
|
+
| **Paquete** | `oficina-opencode` v3.0.0 |
|
|
7
7
|
| **Tools** | 16 |
|
|
8
8
|
| **Hooks** | 7 |
|
|
9
|
-
| **API de plugin** | `@opencode
|
|
9
|
+
| **API de plugin** | `@opencode/plugin@2.1.2` |
|
|
10
10
|
| **Node** | >=20 |
|
|
11
11
|
| **Catálogo** | 258 agentes resolubles en 18 divisiones |
|
|
12
12
|
| **Divisiones** | academic, design, engineering, finance, game-development, gis, healthcare, marketing, paid-media, product, project-management, research, sales, spatial-computing, specialized, strategy, support, testing |
|