ostacky 0.9.5 → 0.9.6

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
@@ -250,37 +250,37 @@ Tras instalar (`--scope local`), el proyecto queda así:
250
250
 
251
251
  ```json
252
252
  {
253
- "version": "0.9.5",
253
+ "version": "0.9.6",
254
254
  "lockedAt": "2025-01-01T00:00:00.000Z",
255
255
  "repo": "JaimeHoracio/Ostacky",
256
- "tag": "v0.9.5",
256
+ "tag": "v0.9.6",
257
257
  "agents": {
258
258
  "ostacky": {
259
- "version": "0.9.5",
259
+ "version": "0.9.6",
260
260
  "installedAt": "2025-01-01T00:00:00.000Z",
261
261
  "sha256": "abc123..."
262
262
  }
263
263
  },
264
264
  "commands": {
265
265
  "install-stack": {
266
- "version": "0.9.5",
266
+ "version": "0.9.6",
267
267
  "installedAt": "2025-01-01T00:00:00.000Z",
268
268
  "sha256": "def456..."
269
269
  },
270
270
  "opsx-sync": {
271
- "version": "0.9.5",
271
+ "version": "0.9.6",
272
272
  "installedAt": "2025-01-01T00:00:00.000Z",
273
273
  "sha256": "ghi789..."
274
274
  }
275
275
  },
276
276
  "skills": {
277
- "brainstorming": { "version": "0.9.5", ... },
278
- "execution-mode-evaluation": { "version": "0.9.5", ... },
279
- "openspec-propose": { "version": "0.9.5", ... }
277
+ "brainstorming": { "version": "0.9.6", ... },
278
+ "execution-mode-evaluation": { "version": "0.9.6", ... },
279
+ "openspec-propose": { "version": "0.9.6", ... }
280
280
  },
281
281
  "mcpServers": {
282
- "ostacky-controller": { "version": "0.9.5", ... },
283
- "openspec": { "version": "0.9.5", ... }
282
+ "ostacky-controller": { "version": "0.9.6", ... },
283
+ "openspec": { "version": "0.9.6", ... }
284
284
  }
285
285
  }
286
286
  ```
@@ -312,7 +312,7 @@ Es opcional y solo necesario si algo falló durante la instalación o si querés
312
312
  ## Seguridad
313
313
 
314
314
  - `opencode.jsonc` se versiona en el repo para compartir permisos y MCP de forma reproducible.
315
- - Las URLs de descarga usan **tags de GitHub** (ej. `v0.9.5`), nunca `main` — instalaciones reproducibles
315
+ - Las URLs de descarga usan **tags de GitHub** (ej. `v0.9.6`), nunca `main` — instalaciones reproducibles
316
316
  - Cada path de archivo descargado es validado para prevenir **path traversal**
317
317
  - Los archivos incluyen **checksum SHA-256** opcional; si el manifest lo define, el contenido se verifica antes de escribir
318
318
  - El cache local (`.opencode/cache/`) también valida integridad al servir archivos cacheados
@@ -369,7 +369,7 @@ CodeGraph está instalado en `.opencode/tools/codegraph/bin/codegraph` y se conf
369
369
  | `.opencode/tools/codegraph/bin/codegraph status` | Muestra estado del index y archivos pendientes |
370
370
  | `.opencode/tools/codegraph/bin/codegraph install --target opencode --location local --yes` | Configura CodeGraph para OpenCode y genera AGENTS.md |
371
371
 
372
- > **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.9.5 el instalador usa el patrón resiliente de Engram (strip 0 + búsqueda recursiva) y loguea `projectRoot|toolsDir` para diagnosticar scope.
372
+ > **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.9.6 el instalador usa el patrón resiliente de Engram (strip 0 + búsqueda recursiva) y loguea `projectRoot|toolsDir` para diagnosticar scope.
373
373
 
374
374
  ## Licencia
375
375
 
@@ -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.9.5
4
+ version: 0.9.6
5
5
  ---
6
6
 
7
- Sos **Ostacky v0.9.5**, orquestás, no implementás. Interpretás, clasificás (0/0+1/1+), ruteás y coordinás.
7
+ Sos **Ostacky v0.9.6**, orquestás, no implementás. Interpretás, clasificás (0/0+1/1+), ruteás y coordinás.
8
8
 
9
- > **Versión:** `0.9.5` (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.9.5"** (o `v0.9.5` si te piden solo el número). No inventes otra versión.
9
+ > **Versión:** `0.9.6` (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.9.6"** (o `v0.9.6` si te piden solo el número). No inventes otra versión.
10
10
 
11
11
  ## Reglas innegociables
12
12
 
@@ -5,13 +5,13 @@ agent: build
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.9.5, `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.
8
+ **Nota:** A partir de v0.9.6, `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
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.9.5)
14
+ ## Scope de instalación — local vs global (desde v0.9.6)
15
15
 
16
16
  `npx ostacky install` soporta `--scope local|global|auto` (también `--scope=...`):
17
17
 
@@ -2996,7 +2996,7 @@ function safeHandler(fn, options = {}) {
2996
2996
 
2997
2997
  const server = new McpServer({
2998
2998
  name: 'ostacky-controller',
2999
- version: '0.9.5',
2999
+ version: '0.9.6',
3000
3000
  });
3001
3001
 
3002
3002
  server.registerTool(
@@ -3598,7 +3598,7 @@ function setupGracefulShutdown(ctrl) {
3598
3598
  }
3599
3599
 
3600
3600
  async function main() {
3601
- log('Starting ostacky-controller MCP v0.9.5...');
3601
+ log('Starting ostacky-controller MCP v0.9.6...');
3602
3602
  log('State path:', { path: statePath });
3603
3603
  // Clean up stale tmp/lock files from previous runs
3604
3604
  cleanupTmpFiles(statePath);
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ostacky-controller",
3
- "version": "0.9.5",
3
+ "version": "0.9.6",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "dependencies": {
package/dist/cli.js CHANGED
@@ -244,16 +244,7 @@ function findProjectRoot(startDir = process.cwd()) {
244
244
  if (out && existsSync(out))
245
245
  return resolve(out);
246
246
  } catch {}
247
- let current = resolve(startDir);
248
- while (true) {
249
- if (existsSync(join(current, ".opencode")) || existsSync(join(current, ".git"))) {
250
- return current;
251
- }
252
- const parent = dirname(current);
253
- if (parent === current)
254
- return resolve(startDir);
255
- current = parent;
256
- }
247
+ return resolve(startDir);
257
248
  }
258
249
  function isGitRepo(dir = process.cwd()) {
259
250
  try {
@@ -267,10 +258,10 @@ function isGitRepo(dir = process.cwd()) {
267
258
  return false;
268
259
  }
269
260
  }
261
+ function initGitRepo(dir) {
262
+ execFileSync("git", ["init"], { cwd: dir, stdio: "pipe" });
263
+ }
270
264
  function getOpenCodeDirForScope(scope, cwd = process.cwd()) {
271
- const existing = findOpenCodeDir(cwd);
272
- if (existing)
273
- return existing;
274
265
  return join(findProjectRoot(cwd), ".opencode");
275
266
  }
276
267
  function ensureOpenCodePaths(opencodeDir) {
@@ -633,31 +624,31 @@ var init_fs = __esm(() => {
633
624
  var manifest_default;
634
625
  var init_manifest = __esm(() => {
635
626
  manifest_default = {
636
- version: "0.9.5",
627
+ version: "0.9.6",
637
628
  repo: "JaimeHoracio/Ostacky",
638
- tag: "v0.9.5",
629
+ tag: "v0.9.6",
639
630
  agents: [
640
631
  {
641
632
  name: "ostacky",
642
633
  file: "assets/agents/ostacky.md",
643
- description: "Orquestador con recuperación automática (nunca se congela), ruteo por nivel de impacto, controller MCP con SDK oficial, edición segura con fallback inline, y delegación en OpenSpec + Superpowers. v0.9.5: prune de skills obsoletas, lastHandoff, getAvailableTransitions, consecutiveFailures real, mem_session_summary automático al cierre.",
644
- version: "0.9.5",
645
- sha256: "986c41356dcdea8d74fea6a17127a45e78e16a5cda43152efb5c7ffd11593b8c"
634
+ description: "Orquestador con recuperación automática (nunca se congela), ruteo por nivel de impacto, controller MCP con SDK oficial, edición segura con fallback inline, y delegación en OpenSpec + Superpowers. v0.9.6: prune de skills obsoletas, lastHandoff, getAvailableTransitions, consecutiveFailures real, mem_session_summary automático al cierre.",
635
+ version: "0.9.6",
636
+ sha256: "29e435104f6915905a85e15ca768a339c3e5b0898fc923ae147afb7c4f20a716"
646
637
  }
647
638
  ],
648
639
  commands: [
649
640
  {
650
641
  name: "install-stack",
651
642
  file: "assets/commands/install-stack.md",
652
- description: "Instala el stack tecnológico del proyecto (CodeGraph, skills, OpenSpec, Engram, controller plugin). v0.9.5: controller plugin como alma hard-gate, Context7 removido del stack.",
653
- version: "0.9.5",
654
- sha256: "e218ec7db404fc8bd5fa1d92312eef5ea517bb0940af054f8665048ec2e9da5f"
643
+ description: "Instala el stack tecnológico del proyecto (CodeGraph, skills, OpenSpec, Engram, controller plugin). v0.9.6: controller plugin como alma hard-gate, Context7 removido del stack.",
644
+ version: "0.9.6",
645
+ sha256: "88da074ab02bef60bcaebd1fed9592ea13f95d245850ec9f2467cf69a7f2fc4c"
655
646
  },
656
647
  {
657
648
  name: "opsx-sync",
658
649
  file: "assets/commands/opsx-sync.md",
659
650
  description: "Sincroniza delta specs del change activo sin inicializar CodeGraph si ya existe índice",
660
- version: "0.9.5",
651
+ version: "0.9.6",
661
652
  sha256: "fe0158478f2ca63b315037a85fc1632b77868532e319af6c7384285441767d64"
662
653
  }
663
654
  ],
@@ -665,16 +656,16 @@ var init_manifest = __esm(() => {
665
656
  {
666
657
  name: "ostacky-controller",
667
658
  file: "assets/mcp/ostacky-controller/",
668
- description: "Máquina de estados persistida con @modelcontextprotocol/server SDK. v0.9.5: 22 tools (incluye set_handoff, get_handoff, clear_handoff, get_available_transitions funcional). Bugfixes: consecutiveFailures real, lastHandoff state, defaultChoice persistido. Robustez: degraded mode automático tras 3 fallos, persistence condicional para Nivel 0, prune de skills obsoletas.",
669
- version: "0.9.5",
670
- sha256: "775f4b8b28a315e97f9192d71a9433fa28235fe84c29401451ace628829c7076"
659
+ description: "Máquina de estados persistida con @modelcontextprotocol/server SDK. v0.9.6: 22 tools (incluye set_handoff, get_handoff, clear_handoff, get_available_transitions funcional). Bugfixes: consecutiveFailures real, lastHandoff state, defaultChoice persistido. Robustez: degraded mode automático tras 3 fallos, persistence condicional para Nivel 0, prune de skills obsoletas.",
660
+ version: "0.9.6",
661
+ sha256: "6669c464c47a285a21f3eea6456487c92b725a40e7938ade5ecfff97e2537427"
671
662
  },
672
663
  {
673
664
  name: "openspec",
674
665
  file: "assets/mcp/openspec/",
675
666
  description: "MCP server local para OpenSpec - proposal, apply, archive, sync de cambios",
676
- version: "0.9.5",
677
- sha256: "fa4be28bfc1e75db8f1a037e2580f04a60066c80e8e5934e90e1041020d04609"
667
+ version: "0.9.6",
668
+ sha256: "bdb283fe8ec2dfcba2ec4f38191f4039e58cd7ae12e44e66310783b42c827638"
678
669
  }
679
670
  ],
680
671
  skills: [
@@ -682,105 +673,105 @@ var init_manifest = __esm(() => {
682
673
  name: "brainstorming",
683
674
  file: "assets/skills/brainstorming/SKILL.md",
684
675
  description: "Skill unificado de pensamiento con dos modos: creative-design (producción de diseño → transición a implementación directa o openspec-propose) y open-exploration (exploración libre)",
685
- version: "0.9.5",
676
+ version: "0.9.6",
686
677
  sha256: "f1013a86a8f27914d85a716e23c7fd32db1786d93615e8b0834b13d184308549"
687
678
  },
688
679
  {
689
680
  name: "execution-mode-evaluation",
690
681
  file: "assets/skills/execution-mode-evaluation/SKILL.md",
691
682
  description: "Skill de análisis de modo de ejecución — output reconciliado con controller snapshot contract (recommendation field)",
692
- version: "0.9.5",
683
+ version: "0.9.6",
693
684
  sha256: "2158a6864c0912e868a9d720db7fd79441e6cc298e3320833d2527c9727c852e"
694
685
  },
695
686
  {
696
687
  name: "tdd",
697
688
  file: "assets/skills/tdd/SKILL.md",
698
689
  description: "Skill de test-driven development (Superpowers)",
699
- version: "0.9.5",
690
+ version: "0.9.6",
700
691
  sha256: "f0ebfbbc43a8868d31a3fd2df37ae7f60fe8add09c6475862395a68269e5ff7f"
701
692
  },
702
693
  {
703
694
  name: "subagent-driven-development",
704
695
  file: "assets/skills/subagent-driven-development/SKILL.md",
705
696
  description: "Skill de ejecución con subagentes (Superpowers) — ejecuta solo después de confirmación del coordinador Ostacky",
706
- version: "0.9.5",
697
+ version: "0.9.6",
707
698
  sha256: "1a42d714a9a13faf05f0bf7b580e8d837c2e77a5633839542ccce603023419e8"
708
699
  },
709
700
  {
710
701
  name: "dispatching-parallel-agents",
711
702
  file: "assets/skills/dispatching-parallel-agents/SKILL.md",
712
703
  description: "Skill de dispatch paralelo de agentes (Superpowers)",
713
- version: "0.9.5",
704
+ version: "0.9.6",
714
705
  sha256: "7e7b712ef742d5631e302e6a71583e2bbbd33094da9281abfb84b43505fc3ef1"
715
706
  },
716
707
  {
717
708
  name: "review",
718
709
  file: "assets/skills/review/SKILL.md",
719
710
  description: "Skill de revisión de código (Superpowers)",
720
- version: "0.9.5",
711
+ version: "0.9.6",
721
712
  sha256: "b19650ed4d1d4d9857a4dd5b7e08e91328a1a1fc9c45bcc2fb600fa9d0213279"
722
713
  },
723
714
  {
724
715
  name: "receiving-code-review",
725
716
  file: "assets/skills/receiving-code-review/SKILL.md",
726
717
  description: "Skill de recibir y procesar feedback de code review",
727
- version: "0.9.5",
718
+ version: "0.9.6",
728
719
  sha256: "d761e884e71d8d3476ac734d287cae403a4024506a7d12e7361a448217c0a831"
729
720
  },
730
721
  {
731
722
  name: "openspec-propose",
732
723
  file: "assets/skills/openspec-propose/SKILL.md",
733
724
  description: "Skill de generación de proposal (OpenSpec)",
734
- version: "0.9.5",
725
+ version: "0.9.6",
735
726
  sha256: "6a517f750f24c008208156a2d653e97ed30b1e53878aeac5ce394e573db0678f"
736
727
  },
737
728
  {
738
729
  name: "openspec-apply-change",
739
730
  file: "assets/skills/openspec-apply-change/SKILL.md",
740
731
  description: "Skill de aplicación de change (OpenSpec)",
741
- version: "0.9.5",
732
+ version: "0.9.6",
742
733
  sha256: "dfc823bf89fc7505e91ab6dee9c1f004be38a410bd3d88fb67b211b1b6cbb1d0"
743
734
  },
744
735
  {
745
736
  name: "openspec-archive-change",
746
737
  file: "assets/skills/openspec-archive-change/SKILL.md",
747
738
  description: "Skill de archivo de change (OpenSpec)",
748
- version: "0.9.5",
739
+ version: "0.9.6",
749
740
  sha256: "16e4b561de7747283663fed602e506abf502452c49a8d4b86d7a5539c40f0195"
750
741
  },
751
742
  {
752
743
  name: "openspec-explore",
753
744
  file: "assets/skills/openspec-explore/SKILL.md",
754
745
  description: "Modo explore para OpenSpec — thinking partner para explorar ideas, investigar problemas y clarificar requisitos antes/durante un cambio",
755
- version: "0.9.5",
746
+ version: "0.9.6",
756
747
  sha256: "9eafc3a8c693b8d9916867ef764d49e5222da717fde501c957bb3f6c312d2415"
757
748
  },
758
749
  {
759
750
  name: "using-git-worktrees",
760
751
  file: "assets/skills/using-git-worktrees/SKILL.md",
761
752
  description: "Skill de uso de git worktrees para aislamiento de trabajo",
762
- version: "0.9.5",
753
+ version: "0.9.6",
763
754
  sha256: "93341bc1b7c053618a8b6dc07e3615b77990d7b549a0201f5835d95fef67ce13"
764
755
  },
765
756
  {
766
757
  name: "using-superpowers",
767
758
  file: "assets/skills/using-superpowers/SKILL.md",
768
759
  description: "Skill de orquestación de Superpowers skills",
769
- version: "0.9.5",
760
+ version: "0.9.6",
770
761
  sha256: "7e54536f96d2a379185a10bfc1e970850caa2561b6d8aca7080f0defea0381a4"
771
762
  },
772
763
  {
773
764
  name: "writing-skills",
774
765
  file: "assets/skills/writing-skills/SKILL.md",
775
766
  description: "Skill de creación y edición de skills",
776
- version: "0.9.5",
767
+ version: "0.9.6",
777
768
  sha256: "3d76b906cee518a2b809febb70db95697a35b9f368986bb504b4120c3bfb437a"
778
769
  },
779
770
  {
780
771
  name: "graceful-degradation",
781
772
  file: "assets/skills/graceful-degradation/SKILL.md",
782
773
  description: "Skill de degradación graceful cuando múltiples tools están indisponibles",
783
- version: "0.9.5",
774
+ version: "0.9.6",
784
775
  sha256: "363449bd9e6f800a0a3168667cf78f767fb105d86e4a4adadcc649d418139303"
785
776
  }
786
777
  ]
@@ -1130,10 +1121,10 @@ var init_config = __esm(() => {
1130
1121
 
1131
1122
  // src/stack.ts
1132
1123
  import { chmodSync, copyFileSync as copyFileSync3, existsSync as existsSync6, mkdirSync as mkdirSync4, rmSync as rmSync4, unlinkSync as unlinkSync3 } from "fs";
1133
- import { basename as basename2, dirname as dirname5, join as join7, resolve as resolve2 } from "path";
1124
+ import { basename as basename2, dirname as dirname5, join as join7, resolve as resolve3 } from "path";
1134
1125
  import { execFileSync as execFileSync3 } from "child_process";
1135
1126
  function resolveToolInstallLocation(toolsDir) {
1136
- const resolvedToolsDir = resolve2(toolsDir ?? join7(findProjectRoot(), ".opencode", "tools"));
1127
+ const resolvedToolsDir = resolve3(toolsDir ?? join7(findProjectRoot(), ".opencode", "tools"));
1137
1128
  const possibleOpenCodeDir = dirname5(resolvedToolsDir);
1138
1129
  return {
1139
1130
  projectRoot: basename2(possibleOpenCodeDir) === ".opencode" ? dirname5(possibleOpenCodeDir) : findProjectRoot(),
@@ -1690,7 +1681,7 @@ var init_doctor_v2 = __esm(() => {
1690
1681
  // package.json
1691
1682
  var package_default = {
1692
1683
  name: "ostacky",
1693
- version: "0.9.5",
1684
+ version: "0.9.6",
1694
1685
  description: "Instalador interactivo de agentes y comandos para OpenCode",
1695
1686
  type: "module",
1696
1687
  bin: {
@@ -1701,7 +1692,8 @@ var package_default = {
1701
1692
  dev: "bun run src/cli.ts",
1702
1693
  build: "bun build src/cli.ts --target=node --format=esm --outfile dist/cli.js && bun scripts/add-shebang.ts",
1703
1694
  start: "node dist/cli.js",
1704
- test: "bun test",
1695
+ test: "bun test --isolate",
1696
+ "test:safe": "bun run scripts/run-tests-isolated.ts",
1705
1697
  "check:skills": "bun run scripts/check-skill-sync.ts",
1706
1698
  "hash:check": "bun run scripts/update-manifest-hashes.ts --check",
1707
1699
  "hash:update": "bun run scripts/update-manifest-hashes.ts",
@@ -2690,6 +2682,7 @@ import { dirname as dirname7 } from "path";
2690
2682
  init_github();
2691
2683
  init_fs();
2692
2684
  init_lockfile();
2685
+ import { resolve as resolve2 } from "path";
2693
2686
 
2694
2687
  // src/installer.ts
2695
2688
  init_github();
@@ -2867,7 +2860,7 @@ async function probeMcpServer(nodeExecutable, serverPath, cwd, statePath, option
2867
2860
  params: {
2868
2861
  protocolVersion: "2025-03-26",
2869
2862
  capabilities: {},
2870
- clientInfo: { name: "ostacky-installer", version: "0.9.5" }
2863
+ clientInfo: { name: "ostacky-installer", version: "0.9.6" }
2871
2864
  }
2872
2865
  });
2873
2866
  });
@@ -3224,6 +3217,28 @@ function onCancel(value) {
3224
3217
  process.exit(0);
3225
3218
  }
3226
3219
  }
3220
+ async function runGitPreflight(cwd = process.cwd(), opts) {
3221
+ if (isGitRepo(cwd))
3222
+ return { projectRoot: findProjectRoot(cwd), gitReady: true };
3223
+ const interactive = opts?.interactive ?? process.stdin.isTTY === true;
3224
+ if (interactive) {
3225
+ const ask = opts?.confirm ?? (() => me({ message: `No hay repo Git en ${cwd}. ¿Inicializar uno? (recomendado para aislamiento por worktree)` }));
3226
+ let answer = false;
3227
+ try {
3228
+ answer = await ask();
3229
+ } catch {
3230
+ answer = false;
3231
+ }
3232
+ if (answer === true) {
3233
+ try {
3234
+ initGitRepo(cwd);
3235
+ return { projectRoot: findProjectRoot(cwd), gitReady: true };
3236
+ } catch {}
3237
+ }
3238
+ }
3239
+ v2.warn("Sin repo Git: aislamiento por worktree no disponible; se instala en el directorio actual.");
3240
+ return { projectRoot: resolve2(cwd), gitReady: false };
3241
+ }
3227
3242
  async function loadManifest() {
3228
3243
  const spin = L2();
3229
3244
  spin.start("Obteniendo recursos disponibles...");
@@ -3253,9 +3268,10 @@ function printPostInstallSteps() {
3253
3268
  ].join(`
3254
3269
  `), "Próximos pasos");
3255
3270
  }
3256
- async function resolveOpenCodePaths(scope) {
3271
+ async function resolveOpenCodePaths(scope, opts) {
3257
3272
  const cwd = process.cwd();
3258
- const dir = scope === "local" || !scope ? getOpenCodeDirForScope("local", cwd) : getOpenCodeDirForScope("local", cwd);
3273
+ const base = opts?.gitPreflight ? (await runGitPreflight(cwd)).projectRoot : cwd;
3274
+ const dir = getOpenCodeDirForScope("local", base);
3259
3275
  if (scope && scope !== "local") {
3260
3276
  v2.warn(`Scope ${scope} removido; usando local en ${dir}`);
3261
3277
  }
@@ -4161,7 +4177,7 @@ async function runInteractiveMenu(scope) {
4161
4177
  we(" OpenCode Installer ");
4162
4178
  await ensureOpencodeInstalled();
4163
4179
  const manifest = await loadManifest();
4164
- const paths = await resolveOpenCodePaths(scope ?? null);
4180
+ const paths = await resolveOpenCodePaths(scope ?? null, { gitPreflight: true });
4165
4181
  if (!paths) {
4166
4182
  fe("Instalación cancelada.");
4167
4183
  return;
@@ -4235,7 +4251,7 @@ async function runInstallCommand(scope, opts) {
4235
4251
  we(" OpenCode Installer ");
4236
4252
  await ensureOpencodeInstalled();
4237
4253
  const manifest = await loadManifest();
4238
- const paths = await resolveOpenCodePaths(scope ?? null);
4254
+ const paths = await resolveOpenCodePaths(scope ?? null, { gitPreflight: true });
4239
4255
  if (!paths) {
4240
4256
  fe("Cancelado.");
4241
4257
  return;
@@ -4300,7 +4316,7 @@ async function runAddMcpCommand(scope) {
4300
4316
  async function runInstallStackCommand(scope) {
4301
4317
  await ensureOpencodeInstalled();
4302
4318
  we(" OpenCode Installer — Stack ");
4303
- const paths = await resolveOpenCodePaths(scope ?? null);
4319
+ const paths = await resolveOpenCodePaths(scope ?? null, { gitPreflight: true });
4304
4320
  if (!paths) {
4305
4321
  fe("Cancelado.");
4306
4322
  return;
package/manifest.json CHANGED
@@ -1,29 +1,29 @@
1
1
  {
2
- "version": "0.9.5",
2
+ "version": "0.9.6",
3
3
  "repo": "JaimeHoracio/Ostacky",
4
- "tag": "v0.9.5",
4
+ "tag": "v0.9.6",
5
5
  "agents": [
6
6
  {
7
7
  "name": "ostacky",
8
8
  "file": "assets/agents/ostacky.md",
9
- "description": "Orquestador con recuperación automática (nunca se congela), ruteo por nivel de impacto, controller MCP con SDK oficial, edición segura con fallback inline, y delegación en OpenSpec + Superpowers. v0.9.5: prune de skills obsoletas, lastHandoff, getAvailableTransitions, consecutiveFailures real, mem_session_summary automático al cierre.",
10
- "version": "0.9.5",
11
- "sha256": "986c41356dcdea8d74fea6a17127a45e78e16a5cda43152efb5c7ffd11593b8c"
9
+ "description": "Orquestador con recuperación automática (nunca se congela), ruteo por nivel de impacto, controller MCP con SDK oficial, edición segura con fallback inline, y delegación en OpenSpec + Superpowers. v0.9.6: prune de skills obsoletas, lastHandoff, getAvailableTransitions, consecutiveFailures real, mem_session_summary automático al cierre.",
10
+ "version": "0.9.6",
11
+ "sha256": "29e435104f6915905a85e15ca768a339c3e5b0898fc923ae147afb7c4f20a716"
12
12
  }
13
13
  ],
14
14
  "commands": [
15
15
  {
16
16
  "name": "install-stack",
17
17
  "file": "assets/commands/install-stack.md",
18
- "description": "Instala el stack tecnológico del proyecto (CodeGraph, skills, OpenSpec, Engram, controller plugin). v0.9.5: controller plugin como alma hard-gate, Context7 removido del stack.",
19
- "version": "0.9.5",
20
- "sha256": "e218ec7db404fc8bd5fa1d92312eef5ea517bb0940af054f8665048ec2e9da5f"
18
+ "description": "Instala el stack tecnológico del proyecto (CodeGraph, skills, OpenSpec, Engram, controller plugin). v0.9.6: controller plugin como alma hard-gate, Context7 removido del stack.",
19
+ "version": "0.9.6",
20
+ "sha256": "88da074ab02bef60bcaebd1fed9592ea13f95d245850ec9f2467cf69a7f2fc4c"
21
21
  },
22
22
  {
23
23
  "name": "opsx-sync",
24
24
  "file": "assets/commands/opsx-sync.md",
25
25
  "description": "Sincroniza delta specs del change activo sin inicializar CodeGraph si ya existe índice",
26
- "version": "0.9.5",
26
+ "version": "0.9.6",
27
27
  "sha256": "fe0158478f2ca63b315037a85fc1632b77868532e319af6c7384285441767d64"
28
28
  }
29
29
  ],
@@ -31,16 +31,16 @@
31
31
  {
32
32
  "name": "ostacky-controller",
33
33
  "file": "assets/mcp/ostacky-controller/",
34
- "description": "Máquina de estados persistida con @modelcontextprotocol/server SDK. v0.9.5: 22 tools (incluye set_handoff, get_handoff, clear_handoff, get_available_transitions funcional). Bugfixes: consecutiveFailures real, lastHandoff state, defaultChoice persistido. Robustez: degraded mode automático tras 3 fallos, persistence condicional para Nivel 0, prune de skills obsoletas.",
35
- "version": "0.9.5",
36
- "sha256": "775f4b8b28a315e97f9192d71a9433fa28235fe84c29401451ace628829c7076"
34
+ "description": "Máquina de estados persistida con @modelcontextprotocol/server SDK. v0.9.6: 22 tools (incluye set_handoff, get_handoff, clear_handoff, get_available_transitions funcional). Bugfixes: consecutiveFailures real, lastHandoff state, defaultChoice persistido. Robustez: degraded mode automático tras 3 fallos, persistence condicional para Nivel 0, prune de skills obsoletas.",
35
+ "version": "0.9.6",
36
+ "sha256": "6669c464c47a285a21f3eea6456487c92b725a40e7938ade5ecfff97e2537427"
37
37
  },
38
38
  {
39
39
  "name": "openspec",
40
40
  "file": "assets/mcp/openspec/",
41
41
  "description": "MCP server local para OpenSpec - proposal, apply, archive, sync de cambios",
42
- "version": "0.9.5",
43
- "sha256": "fa4be28bfc1e75db8f1a037e2580f04a60066c80e8e5934e90e1041020d04609"
42
+ "version": "0.9.6",
43
+ "sha256": "bdb283fe8ec2dfcba2ec4f38191f4039e58cd7ae12e44e66310783b42c827638"
44
44
  }
45
45
  ],
46
46
  "skills": [
@@ -48,105 +48,105 @@
48
48
  "name": "brainstorming",
49
49
  "file": "assets/skills/brainstorming/SKILL.md",
50
50
  "description": "Skill unificado de pensamiento con dos modos: creative-design (producción de diseño → transición a implementación directa o openspec-propose) y open-exploration (exploración libre)",
51
- "version": "0.9.5",
51
+ "version": "0.9.6",
52
52
  "sha256": "f1013a86a8f27914d85a716e23c7fd32db1786d93615e8b0834b13d184308549"
53
53
  },
54
54
  {
55
55
  "name": "execution-mode-evaluation",
56
56
  "file": "assets/skills/execution-mode-evaluation/SKILL.md",
57
57
  "description": "Skill de análisis de modo de ejecución — output reconciliado con controller snapshot contract (recommendation field)",
58
- "version": "0.9.5",
58
+ "version": "0.9.6",
59
59
  "sha256": "2158a6864c0912e868a9d720db7fd79441e6cc298e3320833d2527c9727c852e"
60
60
  },
61
61
  {
62
62
  "name": "tdd",
63
63
  "file": "assets/skills/tdd/SKILL.md",
64
64
  "description": "Skill de test-driven development (Superpowers)",
65
- "version": "0.9.5",
65
+ "version": "0.9.6",
66
66
  "sha256": "f0ebfbbc43a8868d31a3fd2df37ae7f60fe8add09c6475862395a68269e5ff7f"
67
67
  },
68
68
  {
69
69
  "name": "subagent-driven-development",
70
70
  "file": "assets/skills/subagent-driven-development/SKILL.md",
71
71
  "description": "Skill de ejecución con subagentes (Superpowers) — ejecuta solo después de confirmación del coordinador Ostacky",
72
- "version": "0.9.5",
72
+ "version": "0.9.6",
73
73
  "sha256": "1a42d714a9a13faf05f0bf7b580e8d837c2e77a5633839542ccce603023419e8"
74
74
  },
75
75
  {
76
76
  "name": "dispatching-parallel-agents",
77
77
  "file": "assets/skills/dispatching-parallel-agents/SKILL.md",
78
78
  "description": "Skill de dispatch paralelo de agentes (Superpowers)",
79
- "version": "0.9.5",
79
+ "version": "0.9.6",
80
80
  "sha256": "7e7b712ef742d5631e302e6a71583e2bbbd33094da9281abfb84b43505fc3ef1"
81
81
  },
82
82
  {
83
83
  "name": "review",
84
84
  "file": "assets/skills/review/SKILL.md",
85
85
  "description": "Skill de revisión de código (Superpowers)",
86
- "version": "0.9.5",
86
+ "version": "0.9.6",
87
87
  "sha256": "b19650ed4d1d4d9857a4dd5b7e08e91328a1a1fc9c45bcc2fb600fa9d0213279"
88
88
  },
89
89
  {
90
90
  "name": "receiving-code-review",
91
91
  "file": "assets/skills/receiving-code-review/SKILL.md",
92
92
  "description": "Skill de recibir y procesar feedback de code review",
93
- "version": "0.9.5",
93
+ "version": "0.9.6",
94
94
  "sha256": "d761e884e71d8d3476ac734d287cae403a4024506a7d12e7361a448217c0a831"
95
95
  },
96
96
  {
97
97
  "name": "openspec-propose",
98
98
  "file": "assets/skills/openspec-propose/SKILL.md",
99
99
  "description": "Skill de generación de proposal (OpenSpec)",
100
- "version": "0.9.5",
100
+ "version": "0.9.6",
101
101
  "sha256": "6a517f750f24c008208156a2d653e97ed30b1e53878aeac5ce394e573db0678f"
102
102
  },
103
103
  {
104
104
  "name": "openspec-apply-change",
105
105
  "file": "assets/skills/openspec-apply-change/SKILL.md",
106
106
  "description": "Skill de aplicación de change (OpenSpec)",
107
- "version": "0.9.5",
107
+ "version": "0.9.6",
108
108
  "sha256": "dfc823bf89fc7505e91ab6dee9c1f004be38a410bd3d88fb67b211b1b6cbb1d0"
109
109
  },
110
110
  {
111
111
  "name": "openspec-archive-change",
112
112
  "file": "assets/skills/openspec-archive-change/SKILL.md",
113
113
  "description": "Skill de archivo de change (OpenSpec)",
114
- "version": "0.9.5",
114
+ "version": "0.9.6",
115
115
  "sha256": "16e4b561de7747283663fed602e506abf502452c49a8d4b86d7a5539c40f0195"
116
116
  },
117
117
  {
118
118
  "name": "openspec-explore",
119
119
  "file": "assets/skills/openspec-explore/SKILL.md",
120
120
  "description": "Modo explore para OpenSpec — thinking partner para explorar ideas, investigar problemas y clarificar requisitos antes/durante un cambio",
121
- "version": "0.9.5",
121
+ "version": "0.9.6",
122
122
  "sha256": "9eafc3a8c693b8d9916867ef764d49e5222da717fde501c957bb3f6c312d2415"
123
123
  },
124
124
  {
125
125
  "name": "using-git-worktrees",
126
126
  "file": "assets/skills/using-git-worktrees/SKILL.md",
127
127
  "description": "Skill de uso de git worktrees para aislamiento de trabajo",
128
- "version": "0.9.5",
128
+ "version": "0.9.6",
129
129
  "sha256": "93341bc1b7c053618a8b6dc07e3615b77990d7b549a0201f5835d95fef67ce13"
130
130
  },
131
131
  {
132
132
  "name": "using-superpowers",
133
133
  "file": "assets/skills/using-superpowers/SKILL.md",
134
134
  "description": "Skill de orquestación de Superpowers skills",
135
- "version": "0.9.5",
135
+ "version": "0.9.6",
136
136
  "sha256": "7e54536f96d2a379185a10bfc1e970850caa2561b6d8aca7080f0defea0381a4"
137
137
  },
138
138
  {
139
139
  "name": "writing-skills",
140
140
  "file": "assets/skills/writing-skills/SKILL.md",
141
141
  "description": "Skill de creación y edición de skills",
142
- "version": "0.9.5",
142
+ "version": "0.9.6",
143
143
  "sha256": "3d76b906cee518a2b809febb70db95697a35b9f368986bb504b4120c3bfb437a"
144
144
  },
145
145
  {
146
146
  "name": "graceful-degradation",
147
147
  "file": "assets/skills/graceful-degradation/SKILL.md",
148
148
  "description": "Skill de degradación graceful cuando múltiples tools están indisponibles",
149
- "version": "0.9.5",
149
+ "version": "0.9.6",
150
150
  "sha256": "363449bd9e6f800a0a3168667cf78f767fb105d86e4a4adadcc649d418139303"
151
151
  }
152
152
  ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ostacky",
3
- "version": "0.9.5",
3
+ "version": "0.9.6",
4
4
  "description": "Instalador interactivo de agentes y comandos para OpenCode",
5
5
  "type": "module",
6
6
  "bin": {
@@ -11,7 +11,8 @@
11
11
  "dev": "bun run src/cli.ts",
12
12
  "build": "bun build src/cli.ts --target=node --format=esm --outfile dist/cli.js && bun scripts/add-shebang.ts",
13
13
  "start": "node dist/cli.js",
14
- "test": "bun test",
14
+ "test": "bun test --isolate",
15
+ "test:safe": "bun run scripts/run-tests-isolated.ts",
15
16
  "check:skills": "bun run scripts/check-skill-sync.ts",
16
17
  "hash:check": "bun run scripts/update-manifest-hashes.ts --check",
17
18
  "hash:update": "bun run scripts/update-manifest-hashes.ts",
@@ -1,20 +0,0 @@
1
- {
2
- "lockfileVersion": 1,
3
- "configVersion": 1,
4
- "workspaces": {
5
- "": {
6
- "name": "openspec-mcp",
7
- "dependencies": {
8
- "@modelcontextprotocol/server": "^2.0.0-beta.5",
9
- "zod": "^4.0.0",
10
- },
11
- },
12
- },
13
- "packages": {
14
- "@modelcontextprotocol/core": ["@modelcontextprotocol/core@2.0.0-beta.5", "", { "dependencies": { "zod": "^4.2.0" } }, "sha512-HKbY9XTbsDy1Y6r2I55TGE3JEapM0vg96e1MUmBIF9LGjos5gjhcIrTz1yvBPLg2aFKHjwhUAQfRdrCEnPxNew=="],
15
-
16
- "@modelcontextprotocol/server": ["@modelcontextprotocol/server@2.0.0-beta.5", "", { "dependencies": { "@modelcontextprotocol/core": "2.0.0-beta.5", "zod": "^4.2.0" } }, "sha512-i1E5l75rQKsgY/AKAIspgMBH1vEL7dqiK7tHr0L+raYcb0SWOziqNGJXGIG6NY4AlXDWIKGJQGB7Nqfs3oUi5g=="],
17
-
18
- "zod": ["zod@4.4.3", "", {}, "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ=="],
19
- }
20
- }
@@ -1,20 +0,0 @@
1
- {
2
- "lockfileVersion": 2,
3
- "configVersion": 0,
4
- "workspaces": {
5
- "": {
6
- "name": "ostacky-controller",
7
- "dependencies": {
8
- "@modelcontextprotocol/server": "^2.0.0",
9
- "zod": "^4.0.0",
10
- },
11
- },
12
- },
13
- "packages": {
14
- "@modelcontextprotocol/core": ["@modelcontextprotocol/core@2.1.0", "", { "dependencies": { "zod": "^4.2.0" } }, "sha512-YdFj5gMRHr0gYNAhTbQDgjLHiEJdIAUYxomhKseUNye7ZGlISQmUoLh2sveFFCiQ7j2YMffT1kgSND0FSfIFjQ=="],
15
-
16
- "@modelcontextprotocol/server": ["@modelcontextprotocol/server@2.1.0", "", { "dependencies": { "@modelcontextprotocol/core": "2.1.0", "zod": "^4.2.0" } }, "sha512-FdvwZU5N03O77Suh35JqjAqq5R1ZTEPFtwu6N4BgBq28qrQtrCnpbLL5U2pwYCuE194jAw0xnlOVmIqhfoYuUQ=="],
17
-
18
- "zod": ["zod@4.4.3", "", {}, "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ=="],
19
- }
20
- }