ostacky 0.8.0 → 0.8.2

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 CHANGED
@@ -116,7 +116,10 @@ npx ostacky install --scope global # ~/.config/opencode (XDG/APPDATA en Windows
116
116
  npx ostacky install --scope auto # local si existe .opencode/.git, si no global
117
117
  ```
118
118
 
119
- Descarga todos los agentes y commands definidos en el manifest y los escribe en `.opencode/` (scope `local`) o en `~/.config/opencode` (`global`). Herramientas (`tools/`) siempre quedan en `<proyecto>/.opencode/tools`.
119
+ Descarga todos los agentes y commands definidos en el manifest y los escribe en `.opencode/` (scope `local`) o en `~/.config/opencode` (`global`). Además copia los plugins **Ostacky-owned** `ostacky-plugin.ts` + `engram.ts` en `.opencode/plugins/` (el legacy `ostacky-guard.ts` fue fusionado en `ostacky-plugin.ts` y ya no se instala; `ostacky-controller.ts` legacy se limpia automáticamente si quedó de una instalación previa).
120
+
121
+ > **Coherencia local/global:** aunque elijas `global`, los plugins y herramientas (`tools/` con CodeGraph/Engram) permanecen siempre en `<proyecto>/.opencode` local para el hard-gate por worktree. En global solo se escribe el scope global + un espejo local de plugins. Para stack completo por proyecto ejecutá `npx ostacky install --scope local` dentro de cada repo.
122
+ > **Windows — dónde se instala realmente:** `global` es `%APPDATA%\opencode` (`C:\Users\<vos>\AppData\Roaming\opencode`), **no** `C:\Users\<vos>\.opencode`. Si ves `C:\Users\...\ .opencode\tools\codegraph` y esperabas `D:\mi-proyecto\.opencode`, es porque corriste `npx ostacky` desde tu home sin estar dentro del proyecto (sin `.git`). Hacé `cd` al proyecto y re-ejecutá con `--scope local`; el log ahora muestra `projectRoot` y `toolsDir` explícitos para evitar confusión.
120
123
 
121
124
  ### Agregar agentes o commands individualmente
122
125
 
@@ -148,15 +151,21 @@ Solo descarga los items que cambiaron de versión.
148
151
  ### Desinstalar
149
152
 
150
153
  ```bash
151
- npx ostacky uninstall
154
+ npx ostacky uninstall # pregunta local vs global, luego qué borrar
155
+ npx ostacky uninstall --scope local # fuerza scope local
156
+ npx ostacky uninstall --scope global # fuerza scope global
157
+ npx ostacky uninstall --scope auto # auto
152
158
  ```
153
159
 
154
- Borra todos los archivos instalados (los listados en `.opencode/ostacky-lock.json`). Antes de borrar, muestra un preview con los paths a eliminar y pide confirmación.
160
+ **Safe-delete:** solo borra lo trackeado en `.opencode/ostacky-lock.json` (agentes, commands, skills, MCPs) — nunca toca componentes previos del usuario que no estén en el lockfile. Antes de borrar muestra preview con `Scope: <ruta>` + lista de paths y pide confirmación. Los plugins Ostacky-owned (`ostacky-plugin.ts`, `engram.ts` + legacy `ostacky-guard.ts`/`ostacky-controller.ts` si quedaron) se limpian automáticamente via allowlist, nunca se borran plugins custom.
161
+
162
+ > Si el lockfile no existe o está vacío → `No hay nada instalado.` y no borra nada.
155
163
 
156
164
  #### Desinstalar un agente puntual
157
165
 
158
166
  ```bash
159
- npx ostacky uninstall agent <nombre>
167
+ npx ostacky uninstall agent <nombre> # también admite --scope local|global|auto
168
+ npx ostacky uninstall agent # sin nombre → selector de instalados
160
169
  ```
161
170
 
162
171
  Por ejemplo:
@@ -168,7 +177,8 @@ npx ostacky uninstall agent ostacky
168
177
  #### Desinstalar un command puntual
169
178
 
170
179
  ```bash
171
- npx ostacky uninstall command <nombre>
180
+ npx ostacky uninstall command <nombre> # también admite --scope
181
+ npx ostacky uninstall command # sin nombre → selector
172
182
  ```
173
183
 
174
184
  Por ejemplo:
@@ -179,6 +189,15 @@ npx ostacky uninstall command install-stack
179
189
 
180
190
  Si no especificás el nombre, el CLI te muestra un selector con los items instalados para que elijas cuáles desinstalar (puede ser uno o varios).
181
191
 
192
+ #### Desinstalar todo el stack (tools + config)
193
+
194
+ ```bash
195
+ npx ostacky uninstall-stack # pregunta scope, limpia mcp.codegraph/engram de opencode.json + .codegraph/ + .opencode/tools/
196
+ npx ostacky uninstall-stack --scope local
197
+ ```
198
+
199
+ No toca binarios globales ni datos de Engram, solo la configuración del proyecto.
200
+
182
201
  ### Otros
183
202
 
184
203
  ```bash
@@ -188,7 +207,7 @@ npx ostacky --help # muestra la ayuda
188
207
 
189
208
  ## Estructura generada
190
209
 
191
- Tras instalar, el proyecto queda así:
210
+ Tras instalar (`--scope local`), el proyecto queda así:
192
211
 
193
212
  ```
194
213
  .opencode/
@@ -212,44 +231,63 @@ Tras instalar, el proyecto queda así:
212
231
  │ ├── using-superpowers/
213
232
  │ ├── writing-skills/
214
233
  │ └── graceful-degradation/
215
- └── ostacky-lock.json ← versiones instaladas (agentes, commands y skills)
234
+ ├── plugins/
235
+ │ ├── ostacky-plugin.ts ← controller hard-gate (fusiona guard legacy)
236
+ │ └── engram.ts ← plugin Engram
237
+ ├── mcp/
238
+ │ ├── ostacky-controller/ ← MCP thin (observabilidad)
239
+ │ └── openspec/
240
+ ├── tools/
241
+ │ ├── codegraph/bin/codegraph
242
+ │ └── engram/bin/engram
243
+ ├── cache/codegraph/ ← cache local CodeGraph/Discovery
244
+ ├── ostacky-state.json ← estado por worktree (aislado)
245
+ └── ostacky-lock.json ← versiones instaladas (agentes, commands, skills, mcpServers)
216
246
  ```
217
247
 
248
+ > `assets/plugins/ostacky-guard.ts` fue **fusionado en `ostacky-plugin.ts` y eliminado** (re-export legacy). Fresh install solo escribe `ostacky-plugin.ts` + `engram.ts`; si venís de una versión previa con `ostacky-guard.ts` o `ostacky-controller.ts` legacy, el installer los elimina automáticamente.
249
+
218
250
  ### ostacky-lock.json
219
251
 
220
252
  ```json
221
253
  {
222
- "version": "0.8.0",
254
+ "version": "0.8.2",
223
255
  "lockedAt": "2025-01-01T00:00:00.000Z",
224
256
  "repo": "JaimeHoracio/Ostacky",
225
- "tag": "v0.8.0",
257
+ "tag": "v0.8.2",
226
258
  "agents": {
227
259
  "ostacky": {
228
- "version": "0.8.0",
260
+ "version": "0.8.2",
229
261
  "installedAt": "2025-01-01T00:00:00.000Z",
230
262
  "sha256": "abc123..."
231
263
  }
232
264
  },
233
265
  "commands": {
234
266
  "install-stack": {
235
- "version": "0.8.0",
267
+ "version": "0.8.2",
236
268
  "installedAt": "2025-01-01T00:00:00.000Z",
237
269
  "sha256": "def456..."
238
270
  },
239
271
  "opsx-sync": {
240
- "version": "0.8.0",
272
+ "version": "0.8.2",
241
273
  "installedAt": "2025-01-01T00:00:00.000Z",
242
274
  "sha256": "ghi789..."
243
275
  }
244
276
  },
245
277
  "skills": {
246
- "brainstorming": { "version": "0.8.0", ... },
247
- "execution-mode-evaluation": { "version": "0.8.0", ... },
248
- "openspec-propose": { "version": "0.8.0", ... }
278
+ "brainstorming": { "version": "0.8.2", ... },
279
+ "execution-mode-evaluation": { "version": "0.8.2", ... },
280
+ "openspec-propose": { "version": "0.8.2", ... }
281
+ },
282
+ "mcpServers": {
283
+ "ostacky-controller": { "version": "0.8.2", ... },
284
+ "openspec": { "version": "0.8.2", ... }
249
285
  }
250
286
  }
251
287
  ```
252
288
 
289
+ `plugins/` (`ostacky-plugin.ts`, `engram.ts`) y `tools/` **no** se trackean en el lockfile — son allowlist Ostacky-owned y se gestionan via `uninstall` (allowlist) y `uninstall-stack`.
290
+
253
291
  Se recomienda agregar `ostacky-lock.json` al control de versiones para que el equipo instale exactamente las mismas versiones.
254
292
 
255
293
  ## Después de la instalación
@@ -275,7 +313,7 @@ Es opcional y solo necesario si algo falló durante la instalación o si querés
275
313
  ## Seguridad
276
314
 
277
315
  - `opencode.jsonc` se versiona en el repo para compartir permisos y MCP de forma reproducible.
278
- - Las URLs de descarga usan **tags de GitHub** (ej. `v0.8.0`), nunca `main` — instalaciones reproducibles
316
+ - Las URLs de descarga usan **tags de GitHub** (ej. `v0.8.2`), nunca `main` — instalaciones reproducibles
279
317
  - Cada path de archivo descargado es validado para prevenir **path traversal**
280
318
  - Los archivos incluyen **checksum SHA-256** opcional; si el manifest lo define, el contenido se verifica antes de escribir
281
319
  - El cache local (`.opencode/cache/`) también valida integridad al servir archivos cacheados
@@ -291,7 +329,7 @@ Es opcional y solo necesario si algo falló durante la instalación o si querés
291
329
  - Variable `OSTACKY_SENSITIVE_PATTERNS` overridea los patrones por defecto (`**/.env*`, `**/.secrets/**`, `**/*.pem`, `**/*.key`, `**/.aws/**`, `**/.ssh/**`, `**/credentials.json`, `**/.npmrc`).
292
330
  - Ejemplo: `OSTACKY_SENSITIVE_PATTERNS="**/.env*,**/.secrets/**" bunx ostacky doctor` — `doctor` imprime el patrón efectivo.
293
331
  - Allowlist: `.env.example`, `.env.template`, `.env.sample` nunca se bloquean.
294
- - Fuente única: `src/security.ts` (`SENSITIVE_DEFAULT`, `isSensitive`, `BASH_SENSITIVE_RE`) — guard y controller usan la misma lógica (ver `doctor` para verificar).
332
+ - Fuente única: `src/security.ts` (`SENSITIVE_DEFAULT`, `isSensitive`, `BASH_SENSITIVE_RE`) — `ostacky-plugin.ts` importa de ahí (legacy `ostacky-guard.ts` eliminado, fusionado en el plugin). Ver `doctor` para verificar.
295
333
 
296
334
  #### Aislamiento de worktrees (harness-prod-hardening)
297
335
 
@@ -332,6 +370,8 @@ CodeGraph está instalado en `.opencode/tools/codegraph/bin/codegraph` y se conf
332
370
  | `.opencode/tools/codegraph/bin/codegraph status` | Muestra estado del index y archivos pendientes |
333
371
  | `.opencode/tools/codegraph/bin/codegraph install --target opencode --location local --yes` | Configura CodeGraph para OpenCode y genera AGENTS.md |
334
372
 
373
+ > **Windows:** si ves `Command failed: cmd.exe /d /c call ... codegraph.cmd init -i` durante `npx ostacky install`, es un _warning_ no fatal — el binario se instaló pero el índice no se pudo crear. Reintentá con `npx ostacky install-stack --scope local` o ejecutá manualmente `.opencode\tools\codegraph\bin\codegraph.exe init -i` (o `codegraph.cmd` si no hay `.exe`) dentro del proyecto. Desde v0.8.2 el instalador usa el patrón resiliente de Engram (strip 0 + búsqueda recursiva) y loguea `projectRoot|toolsDir` para diagnosticar scope.
374
+
335
375
  ## Licencia
336
376
 
337
377
  MIT
@@ -1,12 +1,12 @@
1
1
  ---
2
2
  description: Orquestador principal — rutea por nivel, orquesta CodeGraph + OpenSpec + Superpowers.
3
3
  mode: primary
4
- version: 0.8.0
4
+ version: 0.8.2
5
5
  ---
6
6
 
7
- Sos **Ostacky v0.8.0**, orquestás, no implementás. Interpretás, clasificás (0/0+1/1+), ruteás y coordinás.
7
+ Sos **Ostacky v0.8.2**, orquestás, no implementás. Interpretás, clasificás (0/0+1/1+), ruteás y coordinás.
8
8
 
9
- > **Versión:** `0.8.0` (sincronizada desde `package.json` vía `scripts/sync-version.ts`). Cuando te pregunten qué versión tenés, qué versión sos, o `¿qué versión tenés?` / `version` / `¿en qué versión estás?`, respondé exactamente: **"Ostacky v0.8.0"** (o `v0.8.0` si te piden solo el número). No inventes otra versión.
9
+ > **Versión:** `0.8.2` (sincronizada desde `package.json` vía `scripts/sync-version.ts`). Cuando te pregunten qué versión tenés, qué versión sos, o `¿qué versión tenés?` / `version` / `¿en qué versión estás?`, respondé exactamente: **"Ostacky v0.8.2"** (o `v0.8.2` si te piden solo el número). No inventes otra versión.
10
10
 
11
11
  ## Reglas innegociables
12
12
 
@@ -1,17 +1,17 @@
1
1
  ---
2
- description: Instala CodeGraph, skills curadas, OpenSpec, Engram y Context7 localmente para OpenCode únicamente
2
+ description: Instala CodeGraph, skills curadas, OpenSpec y Engram localmente para OpenCode únicamente
3
3
  agent: build
4
4
  ---
5
5
 
6
6
  Instala el stack tecnológico de desarrollo para OpenCode. **IMPORTANTE:** las herramientas se instalan por separado (cada una con su propio CLI/comando). `npx ostacky install` solo instala el agente y commands de Ostacky en `.opencode/`. Este comando (`/install-stack`) es la guía de referencia para la instalación manual completa paso a paso.
7
7
 
8
- **Nota:** A partir de v0.8.0, `npx ostacky install` ya instala automáticamente el stack completo (CodeGraph, OpenSpec, Engram, Context7, MCPs bundleados) además del agente y skills. Este comando es útil para instalación manual, verificación, o cuando algo falló y necesita reinstalarse.
8
+ **Nota:** A partir de v0.8.2, `npx ostacky install` ya instala automáticamente el stack completo (CodeGraph, OpenSpec, Engram, MCPs bundleados) además del agente y skills. Este comando es útil para instalación manual, verificación, o cuando algo falló y necesita reinstalarse.
9
9
 
10
10
  **RESTRICCIÓN ABSOLUTA:** instalar ÚNICAMENTE para OpenCode. Está terminantemente prohibido crear o modificar archivos en `.claude/`, `.kiro/`, `.cursor/`, `.gemini/`, `.codex/`, `.antigravity/`, `.windsurf/` o cualquier otro directorio de plataformas externas.
11
11
 
12
- **Origen del set curado:** el set de 15 skills referenciado en `assets/agents/ostacky.md` está bundleado en `assets/skills/` dentro del paquete npm. Context7 agrega su propio skill vía `npx ctx7 setup --opencode`. La definición del set y su trazabilidad viven en `manifest.json` y `.opencode/ostacky-lock.json`.
12
+ **Origen del set curado:** el set de 15 skills referenciado en `assets/agents/ostacky.md` está bundleado en `assets/skills/` dentro del paquete npm. La definición del set y su trazabilidad viven en `manifest.json` y `.opencode/ostacky-lock.json`.
13
13
 
14
- ## Scope de instalación — local vs global (desde v0.8.0)
14
+ ## Scope de instalación — local vs global (desde v0.8.2)
15
15
 
16
16
  `npx ostacky install` soporta `--scope local|global|auto` (también `--scope=...`):
17
17
 
@@ -164,7 +164,7 @@ Ostacky automáticamente detecta la ausencia del controller y opera en modo degr
164
164
 
165
165
  ## Paso 2 — Skills curadas (bundleadas)
166
166
 
167
- Las **15 skills curadas** están bundleadas dentro del paquete Ostacky en `assets/skills/`. No se descargan ni clonan; ya vienen en el paquete npm. Context7 agrega su propia skill aparte (Paso 6).
167
+ Las **15 skills curadas** están bundleadas dentro del paquete Ostacky en `assets/skills/`. No se descargan ni clonan; ya vienen en el paquete npm.
168
168
 
169
169
  Copiá cada skill bundleada a `.opencode/skills/<nombre>/` preservando la estructura interna (incluyendo `SKILL.md` y cualquier subdirectorio como `scripts/` o `references/`):
170
170
 
@@ -215,11 +215,6 @@ Leé `opencode.json` (o `opencode.jsonc`) en la raíz del proyecto.
215
215
  "command": [".opencode/tools/engram/bin/engram", "mcp"],
216
216
  "enabled": true
217
217
  },
218
- "context7": {
219
- "type": "remote",
220
- "url": "https://mcp.context7.com/mcp",
221
- "enabled": true
222
- },
223
218
  "ostacky-controller": {
224
219
  "type": "local",
225
220
  "command": ["node", ".opencode/mcp/ostacky-controller/index.js"],
@@ -353,99 +348,6 @@ rm -rf ~/.engram/
353
348
 
354
349
  ---
355
350
 
356
- ## Paso 6 — Context7
357
-
358
- [Context7](https://context7.com) provee documentación actualizada de librerías y APIs directamente en el contexto del agente. Se instala como un CLI vía `npx`, sin dependencias globales ni MCP server necesario (aunque también soporta MCP).
359
-
360
- **RESTRICCIÓN:** configurar ÚNICAMENTE para OpenCode. Está terminantemente prohibido crear archivos en `.claude/`, `.kiro/`, `.cursor/`, `.gemini/`, `.codex/`, `.antigravity/`, `.windsurf/` o cualquier otro directorio de plataformas externas.
361
-
362
- ### Verificar instalación actual
363
-
364
- Chequeá si Context7 ya está configurado para OpenCode:
365
-
366
- ```bash
367
- ls -la .opencode/skills/context7/ 2>/dev/null || echo "no-instalado"
368
- ```
369
-
370
- También podés verificar si el MCP server de Context7 está en `opencode.json`:
371
-
372
- ```bash
373
- grep -c "context7" opencode.json 2>/dev/null || echo "no-configurado"
374
- ```
375
-
376
- ### Instalar
377
-
378
- **Opción recomendada — setup automático (CLI + skills):**
379
-
380
- ```bash
381
- npx ctx7 setup --opencode
382
- ```
383
-
384
- Este comando:
385
-
386
- - Autentica vía OAuth y genera una API key
387
- - Instala un skill en `.opencode/skills/context7/` que el agente Ostacky usa automáticamente
388
- - Pregunta si preferís modo CLI + Skills o MCP
389
- - **NO** toca `.claude/`, `.cursor/`, `.gemini/` ni ninguna otra plataforma
390
-
391
- **Alternativa — solo MCP (si preferís el server remoto):**
392
-
393
- Agregá manualmente la entrada MCP en `opencode.json`:
394
-
395
- ```json
396
- {
397
- "mcp": {
398
- "context7": {
399
- "type": "remote",
400
- "url": "https://mcp.context7.com/mcp"
401
- }
402
- }
403
- }
404
- ```
405
-
406
- Si tenés una API key de Context7 (recomendado para mejores rate limits):
407
-
408
- ```json
409
- {
410
- "mcp": {
411
- "context7": {
412
- "type": "remote",
413
- "url": "https://mcp.context7.com/mcp",
414
- "headers": {
415
- "CONTEXT7_API_KEY": "{env:CONTEXT7_API_KEY}"
416
- }
417
- }
418
- }
419
- }
420
- ```
421
-
422
- ### Desinstalar
423
-
424
- Para remover la configuración generada por `npx ctx7 setup`:
425
-
426
- ```bash
427
- npx ctx7 remove
428
- ```
429
-
430
- Esto elimina el skill y la configuración de Context7. Si instalaste el CLI globalmente con `npm install -g ctx7`, también necesitás:
431
-
432
- ```bash
433
- npm uninstall -g ctx7
434
- ```
435
-
436
- Para remover la entrada MCP manual, editá `opencode.json` y eliminá el bloque `mcp.context7`.
437
-
438
- ### Cómo lo usa Ostacky
439
-
440
- El skill de Context7 instalado le indica al agente Ostacky que use Context7 automáticamente cuando necesite documentación de librerías, APIs o frameworks. También se puede invocar explícitamente:
441
-
442
- ```
443
- usá context7 para mostrarme la API de autenticación de Supabase
444
- use context7 to find Next.js 15 app router examples
445
- ```
446
-
447
- ---
448
-
449
351
  ## Estructura de herramientas
450
352
 
451
353
  Cada herramienta se instala en su propia carpeta dentro de `.opencode/` para mantener una instalación limpia y aislada. El installer crea automáticamente `.opencode/tools/<nombre>/` para cada herramienta externa:
@@ -481,10 +383,9 @@ Cada herramienta se instala en su propia carpeta dentro de `.opencode/` para man
481
383
  │ ├── using-superpowers/
482
384
  │ ├── writing-skills/
483
385
  │ └── graceful-degradation/
484
- ├── tools/ # Config y archivos de herramientas externas
485
- │ ├── codegraph/ # Config de CodeGraph (AGENTS.md si codegraph lo crea)
486
- ├── engram/ # Config project-local de Engram
487
- │ └── context7/ # Config de Context7
386
+ ├── tools/ # Binarios locales de herramientas externas
387
+ │ ├── codegraph/ # Binario local de CodeGraph
388
+ └── engram/ # Binario local de Engram
488
389
  └── plugins/ # Plugins de OpenCode
489
390
  ```
490
391
 
@@ -493,24 +394,23 @@ Cada herramienta se instala en su propia carpeta dentro de `.opencode/` para man
493
394
  - `.codegraph/` (índice de CodeGraph) vive en la raíz del proyecto — CodeGraph lo espera ahí.
494
395
  - El binario de CodeGraph es **local al proyecto** en `.opencode/tools/codegraph/bin/`; en Windows puede ser `codegraph.cmd`. No se instala globalmente.
495
396
  - El binario de Engram es **local al proyecto** en `.opencode/tools/engram/bin/engram` (o `engram.exe` en Windows). No se instala globalmente.
496
- - Context7 se registra como MCP remoto en `opencode.jsonc`. Su skill opcional se instala via `npx ctx7 setup --opencode` en `.opencode/skills/context7/`.
397
+ - El binary de CodeGraph y Engram vive siempre en `<proyecto>/.opencode/tools/` por reproducibilidad, nunca global.
497
398
  - El controller publicado se bundlea como un único `index.js`; durante desarrollo el installer instala sus dependencias en staging y valida el servidor antes de activarlo.
498
399
 
499
400
  ## Verificación final
500
401
 
501
402
  Confirmá que:
502
403
 
503
- 1. `.opencode/skills/` contiene las 15 skills curadas y opcionalmente `context7/` si se instaló con `npx ctx7 setup --opencode`
404
+ 1. `.opencode/skills/` contiene las 15 skills curadas
504
405
  2. `.opencode/commands/` contiene los commands bundleados por Ostacky (`install-stack`, `opsx-sync`) y los 4 commands generados por OpenSpec (`opsx-apply`, `opsx-archive`, `opsx-explore`, `opsx-propose`) si OpenSpec fue inicializado
505
- 3. `opencode.json` (o `.jsonc`) tiene los bloques MCP: `codegraph`, `engram`, `context7`, `ostacky-controller` — sin campo `plugin`
406
+ 3. `opencode.json` (o `.jsonc`) tiene los bloques MCP: `codegraph`, `engram`, `ostacky-controller` — sin campo `plugin`
506
407
  4. `.codegraph/` existe en la raíz del proyecto (índice local de CodeGraph)
507
408
  5. El launcher local de CodeGraph funciona (`codegraph.cmd --version` en Windows o `codegraph --version` en Unix)
508
409
  6. El binario local de Engram funciona (`engram.exe --version` en Windows o `engram --version` en Unix)
509
- 7. Context7 configurado: `mcp.context7` presente en `opencode.jsonc` y/o `.opencode/skills/context7/SKILL.md` existe
510
- 8. OpenSpec generó sus commands/skills para OpenCode mediante `openspec init --tools opencode`
511
- 9. `.opencode/tools/` contiene subdirectorios para `codegraph/`, `engram/` y `context7/`
512
- 10. **NO existen** archivos generados en `.claude/`, `.kiro/`, `.cursor/`, `.gemini/`, `.codex/` ni ningún directorio de otra plataforma
513
- 11. Un `AGENTS.md` preexistente en la raíz del proyecto se preserva sin cambios
410
+ 7. OpenSpec generó sus commands/skills para OpenCode mediante `openspec init --tools opencode` (si se usó)
411
+ 8. `.opencode/tools/` contiene subdirectorios para `codegraph/` y `engram/`
412
+ 9. **NO existen** archivos generados en `.claude/`, `.kiro/`, `.cursor/`, `.gemini/`, `.codex/` ni ningún directorio de otra plataforma
413
+ 10. Un `AGENTS.md` preexistente en la raíz del proyecto se preserva sin cambios
514
414
 
515
415
  Reportá el estado de cada componente con ✓ o ✗.
516
416
 
@@ -26,7 +26,6 @@ BLOCKED: replan→INTERPRETATION_PENDING, abandon→DONE
26
26
  | codegraph_* | 10s | 1 | Engram → Read+Glob |
27
27
  | controller_* | 5s | 1 | degraded |
28
28
  | engram_* | 5s | 1 | sin memoria |
29
- | context7_* | 10s | 1 | sin docs |
30
29
 
31
30
  ## Cache
32
31
 
@@ -75,5 +74,4 @@ Principio: **eficacia > recorte** — si recorte rompiera caché y saliera más
75
74
 
76
75
  - `ostacky.md` 109→72 líneas (diet estable cacheable). Tiered vía suffix, no reemplazo `system[0]`.
77
76
  - `controller` descriptions <150 chars
78
- - `context7` lazy: `enabled:false` default, trigger `docs|api|lib|Context7` habilita
79
77
  - `MEMORY_INSTRUCTIONS` lazy: siempre pointer (~1 línea) en `system.transform`; full vive en `assets/docs/engram-protocol.md` on-demand via `Read` (ahorro ~1.2k en FULL, trivial ya era pointer)
@@ -2371,7 +2371,7 @@ function safeHandler(fn, options = {}) {
2371
2371
 
2372
2372
  const server = new McpServer({
2373
2373
  name: 'ostacky-controller',
2374
- version: '0.8.0',
2374
+ version: '0.8.2',
2375
2375
  });
2376
2376
 
2377
2377
  server.registerTool(
@@ -2971,7 +2971,7 @@ function setupGracefulShutdown(ctrl) {
2971
2971
  }
2972
2972
 
2973
2973
  async function main() {
2974
- log('Starting ostacky-controller MCP v0.8.0...');
2974
+ log('Starting ostacky-controller MCP v0.8.2...');
2975
2975
  log('State path:', { path: statePath });
2976
2976
  // Clean up stale tmp/lock files from previous runs
2977
2977
  cleanupTmpFiles(statePath);
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ostacky-controller",
3
- "version": "0.8.0",
3
+ "version": "0.8.2",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "dependencies": {
@@ -20,6 +20,10 @@ import { isTrivial } from "../../src/tiered.ts"
20
20
  // ─── Constants ───────────────────────────────────────────────────────────────
21
21
 
22
22
  const MAX_STATE_FILE_SIZE = 2 * 1024 * 1024
23
+ const PING_INTERVAL_MS = 60_000
24
+ const IDLE_THRESHOLD_MS = 45_000
25
+ const PURPLE_TENUE = "\x1b[38;5;183m"
26
+ const PURPLE_RESET = "\x1b[0m"
23
27
 
24
28
  const STATES = Object.freeze({
25
29
  INTERPRETATION_PENDING: "INTERPRETATION_PENDING",
@@ -254,6 +258,9 @@ function isCodegraphAvailable(directory: string): boolean {
254
258
  const trivialBySession = new Map<string, boolean>()
255
259
  // Track discovery hit per requestId to avoid blocking after hit
256
260
  const discoveryHitByRequest = new Map<string, boolean>()
261
+ // ─── Heartbeat ping — evita sensación de trancado en tareas largas ──
262
+ let lastPingTs = 0
263
+ let pingInterval: ReturnType<typeof setInterval> | null = null
257
264
 
258
265
  // ─── Plugin ──────────────────────────────────────────────────────────────────
259
266
 
@@ -267,6 +274,30 @@ export const OstackyController: Plugin = async (ctx) => {
267
274
  let lastCheck: { revision: number; result: string } | null = null
268
275
  let checkCount = 0
269
276
 
277
+ // Heartbeat ping — purple tenue, evita sensación de trancado en tareas largas
278
+ if (!pingInterval) {
279
+ pingInterval = setInterval(async () => {
280
+ try {
281
+ const s = readState(ctx.directory)
282
+ if (!s || !["EXECUTING_INLINE", "EXECUTING_SUBAGENTS", "SYNC"].includes(s.state)) return
283
+ const now = Date.now()
284
+ const lastHeartbeat = s.lastHeartbeat || s.ts || now
285
+ const idle = now - lastHeartbeat
286
+ if (idle < IDLE_THRESHOLD_MS) return
287
+ if (now - lastPingTs < PING_INTERVAL_MS) return
288
+ lastPingTs = now
289
+ const completed = Object.values(s.tasks || {}).filter((t: any) => t.status === "COMPLETED").length
290
+ const total = s.expectedTaskCount ?? s.expectedTasks?.length ?? "?"
291
+ const pending = Array.isArray(s.expectedTasks) ? s.expectedTasks.filter((id: string) => !s.tasks?.[id] || s.tasks[id].status !== "COMPLETED").length : "?"
292
+ const msg = `🟣 ${PURPLE_TENUE}[OSTACKY]${PURPLE_RESET} ⏳ Sigo trabajando — ${s.state} • ${completed}/${total} (${pending} pendientes) • hace ${Math.round(idle/1000)}s sin output`
293
+ try { await (ctx as any).client?.tui?.showToast?.({ body: { message: msg, variant: "info" } } as any) } catch {}
294
+ try { await (ctx as any).client?.app?.log?.({ body: { service: "ostacky-ping", level: "info", message: msg } } as any) } catch {}
295
+ try { const st = readState(ctx.directory); if (st) { (st as any).lastPingTs = now; persistState(ctx.directory, st) } } catch {}
296
+ } catch {}
297
+ }, 30_000)
298
+ if (pingInterval && typeof (pingInterval as any).unref === 'function') (pingInterval as any).unref()
299
+ }
300
+
270
301
  return {
271
302
  // ── Tiered: suffix hint on user message (cache-friendly, no system replace) ──
272
303
  "chat.message": async (input: any, output: any) => {
@@ -527,6 +558,18 @@ export const OstackyController: Plugin = async (ctx) => {
527
558
  const s = readState((input as any).ctx?.directory ?? "")
528
559
  } catch {}
529
560
  }
561
+ // Heartbeat + color purple tenue: Ostacky vs modelo (fácil)
562
+ try {
563
+ const dir = ctx.directory
564
+ const s = readState(dir)
565
+ if (s) {
566
+ s.lastHeartbeat = Date.now()
567
+ try { persistState(dir, s) } catch {}
568
+ if (["EXECUTING_INLINE", "EXECUTING_SUBAGENTS", "SYNC"].includes(s.state) && output && typeof output.title === "string" && output.title && !output.title.includes("🟣")) {
569
+ output.title = `🟣 ${PURPLE_TENUE}[OSTACKY]${PURPLE_RESET} ${output.title}`
570
+ }
571
+ }
572
+ } catch {}
530
573
  },
531
574
 
532
575
  // ── Observable tools (MCP thin replacement) ──
@@ -622,6 +665,11 @@ export const OstackyController: Plugin = async (ctx) => {
622
665
  }
623
666
  },
624
667
 
668
+ dispose: async () => {
669
+ try { if (pingInterval) clearInterval(pingInterval) } catch {}
670
+ pingInterval = null
671
+ },
672
+
625
673
  "experimental.session.compacting": async (input: any, output: any) => {
626
674
  try {
627
675
  const statePath = getStatePath(ctx.directory)
@@ -38,7 +38,7 @@ Do NOT invoke any implementation skill, write any code, or scaffold any project
38
38
 
39
39
  1. **Check discovery-cache first** — `src/discovery-cache.ts` `getDiscoverySnapshot(query)` + `getEngramDedup(query, requestId)`. Si hit válido (TTL+gitDiffHash), **reusar** sin llamar tools. Solo si miss → `engram_mem_search` + `codegraph_codegraph_explore` y **SHALL `putDiscoverySnapshot`** antes de avanzar. No re-llamar si área difiere <30% del snapshot.
40
40
  2. **Ask clarifying questions** — one at a time, understand purpose/constraints/success criteria
41
- 4. **Propose 2-3 approaches (hardening-v2 — SHALL)** — con tabla trade-offs (coste|riesgo|complejidad) + evidencia CodeGraph+Engram (+Context7 si librería) sin alucinar, YAGNI, y recomendación con razón; cada approach cita symbols existentes y mem_search hits verificables
41
+ 4. **Propose 2-3 approaches (hardening-v2 — SHALL)** — con tabla trade-offs (coste|riesgo|complejidad) + evidencia CodeGraph+Engram sin alucinar, YAGNI, y recomendación con razón; cada approach cita symbols existentes y mem_search hits verificables
42
42
  5. **Present design** — in sections scaled to complexity, get user approval after each section. **Gate post-brainstorming (hardening-v2):** tras presentar diseño, preguntar "¿Procedo con este diseño o querés ajustar algo?" y esperar confirmación explícita antes de `record_discovery`, `openspec-propose` o implementación directa
43
43
  6. **Write design doc (output path condicional — router exclusivo):**
44
44
  - Si trigger + `level 1+` no-downgradeable (`estLines>30` o `fileCount>2` o API pública) y change activo → escribir `openspec/changes/<id>/design.md` sección `## Alternatives Considered` con 2-3 approaches (tabla coste|riesgo|complejidad + evidencia CodeGraph+Engram), no `docs/`. No invocar `openspec-propose` separado — este es el diseño.
@@ -20,7 +20,6 @@ When critical tools are unavailable, this skill provides a systematic approach t
20
20
  | CodeGraph | MCP server | Engram → Read + Glob | No structural analysis, manual exploration |
21
21
  | Engram | MCP server | Continue without memory | No persistence across sessions |
22
22
  | Controller | MCP server | Inline validation + manual state | No state machine, no edit validation |
23
- | Context7 | MCP server (remote) | Skip documentation | No external API docs |
24
23
 
25
24
  ## Detection
26
25
 
@@ -108,12 +107,6 @@ Incluso en degraded, el guard de credenciales sigue activo (hard gate incluso en
108
107
  - No state persistence across crashes
109
108
  - No pending state enforcement (check_pending_state unavailable)
110
109
 
111
- ### Without Context7
112
-
113
- **Impact:** Minimal — only affects external API documentation lookups.
114
-
115
- **Workflow:** Proceed normally. Use existing knowledge.
116
-
117
110
  ## Communication Protocol
118
111
 
119
112
  ### Status Report Format
@@ -141,7 +134,6 @@ Herramientas disponibles:
141
134
  ✅ Controller — ping OK
142
135
  ❌ CodeGraph — timeout 10s
143
136
  ✅ Engram — disponible
144
- ✅ Context7 — disponible
145
137
 
146
138
  ¿Continuar con lectura manual de archivos?
147
139
  ```
@@ -154,7 +146,6 @@ Herramientas disponibles:
154
146
  ❌ Controller — no responde
155
147
  ❌ CodeGraph — no instalado
156
148
  ❌ Engram — timeout 5s
157
- ✅ Context7 — disponible (pero sin docs relevantes)
158
149
 
159
150
  Modo básico: sin validación de edits, sin memoria persistente, sin análisis estructural.
160
151
  ¿Continuar o cancelar?