ostacky 0.7.1 → 0.7.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 +14 -11
- package/assets/agents/ostacky.md +18 -11
- package/assets/commands/install-stack.md +20 -1
- package/assets/mcp/ostacky-controller/index.js +471 -104
- package/assets/mcp/ostacky-controller/package.json +1 -1
- package/assets/plugins/engram.ts +82 -8
- package/assets/skills/graceful-degradation/SKILL.md +4 -0
- package/dist/cli.js +297 -136
- package/manifest.json +29 -29
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { createRequire } from "node:module";
|
|
2
3
|
var __create = Object.create;
|
|
3
4
|
var __getProtoOf = Object.getPrototypeOf;
|
|
4
5
|
var __defProp = Object.defineProperty;
|
|
@@ -44,6 +45,7 @@ var __export = (target, all) => {
|
|
|
44
45
|
});
|
|
45
46
|
};
|
|
46
47
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
48
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
47
49
|
|
|
48
50
|
// node_modules/sisteransi/src/index.js
|
|
49
51
|
var require_src = __commonJS((exports, module) => {
|
|
@@ -215,8 +217,9 @@ import {
|
|
|
215
217
|
renameSync
|
|
216
218
|
} from "fs";
|
|
217
219
|
import { createHash as createHash2 } from "crypto";
|
|
218
|
-
import { join, resolve, dirname, relative, basename } from "path";
|
|
220
|
+
import { join, resolve, dirname, relative, basename, win32 } from "path";
|
|
219
221
|
import { execFileSync } from "child_process";
|
|
222
|
+
import { homedir } from "os";
|
|
220
223
|
function findOpenCodeDir(startDir = process.cwd()) {
|
|
221
224
|
let current = resolve(startDir);
|
|
222
225
|
while (true) {
|
|
@@ -243,6 +246,32 @@ function findProjectRoot(startDir = process.cwd()) {
|
|
|
243
246
|
current = parent;
|
|
244
247
|
}
|
|
245
248
|
}
|
|
249
|
+
function getGlobalOpenCodeDir(platform = process.platform, home = homedir()) {
|
|
250
|
+
if (platform === "win32") {
|
|
251
|
+
const appData = process.env.APPDATA ?? win32.join(home, "AppData", "Roaming");
|
|
252
|
+
return win32.join(appData, "opencode");
|
|
253
|
+
}
|
|
254
|
+
const xdg = process.env.XDG_CONFIG_HOME ?? join(home, ".config");
|
|
255
|
+
return join(xdg, "opencode");
|
|
256
|
+
}
|
|
257
|
+
function getOpenCodeDirForScope(scope, cwd = process.cwd()) {
|
|
258
|
+
if (scope === "global")
|
|
259
|
+
return getGlobalOpenCodeDir();
|
|
260
|
+
if (scope === "local") {
|
|
261
|
+
const existing2 = findOpenCodeDir(cwd);
|
|
262
|
+
if (existing2)
|
|
263
|
+
return existing2;
|
|
264
|
+
return join(findProjectRoot(cwd), ".opencode");
|
|
265
|
+
}
|
|
266
|
+
const existing = findOpenCodeDir(cwd);
|
|
267
|
+
if (existing)
|
|
268
|
+
return existing;
|
|
269
|
+
const root = findProjectRoot(cwd);
|
|
270
|
+
if (existsSync(join(root, ".opencode")) || existsSync(join(root, ".git"))) {
|
|
271
|
+
return join(root, ".opencode");
|
|
272
|
+
}
|
|
273
|
+
return getGlobalOpenCodeDir();
|
|
274
|
+
}
|
|
246
275
|
function ensureOpenCodePaths(opencodeDir) {
|
|
247
276
|
const paths = {
|
|
248
277
|
root: opencodeDir,
|
|
@@ -266,9 +295,6 @@ function ensureToolDirs(toolsDir, toolNames) {
|
|
|
266
295
|
mkdirSync(dir, { recursive: true });
|
|
267
296
|
}
|
|
268
297
|
}
|
|
269
|
-
function createOpenCodeDir(baseDir) {
|
|
270
|
-
return ensureOpenCodePaths(join(baseDir, ".opencode"));
|
|
271
|
-
}
|
|
272
298
|
function copyDirRecursive(src, dest, skipGenerated = false) {
|
|
273
299
|
if (!existsSync(dest))
|
|
274
300
|
mkdirSync(dest, { recursive: true });
|
|
@@ -451,7 +477,7 @@ function downloadToFile(url, dest, timeoutMs = 180000) {
|
|
|
451
477
|
});
|
|
452
478
|
}
|
|
453
479
|
async function downloadAndExtract(url, destDir, stripComponents = 1, timeoutMs = 180000) {
|
|
454
|
-
const tmp = join(dirname(destDir), `.${basename(destDir)}.download-${Date.now()}`);
|
|
480
|
+
const tmp = join(dirname(destDir), `.${basename(destDir)}.download-${Date.now()}-${process.pid}`);
|
|
455
481
|
if (!existsSync(tmp))
|
|
456
482
|
mkdirSync(tmp, { recursive: true });
|
|
457
483
|
const archivePath = join(tmp, url.endsWith(".zip") ? "archive.zip" : "archive.tar.gz");
|
|
@@ -520,31 +546,31 @@ var init_fs = __esm(() => {
|
|
|
520
546
|
var manifest_default;
|
|
521
547
|
var init_manifest = __esm(() => {
|
|
522
548
|
manifest_default = {
|
|
523
|
-
version: "0.7.
|
|
549
|
+
version: "0.7.2",
|
|
524
550
|
repo: "JaimeHoracio/Ostacky",
|
|
525
|
-
tag: "v0.7.
|
|
551
|
+
tag: "v0.7.2",
|
|
526
552
|
agents: [
|
|
527
553
|
{
|
|
528
554
|
name: "ostacky",
|
|
529
555
|
file: "assets/agents/ostacky.md",
|
|
530
|
-
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.7.
|
|
531
|
-
version: "0.7.
|
|
532
|
-
sha256: "
|
|
556
|
+
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.7.2: prune de skills obsoletas, lastHandoff, getAvailableTransitions, consecutiveFailures real, mem_session_summary automático al cierre.",
|
|
557
|
+
version: "0.7.2",
|
|
558
|
+
sha256: "1b6a5cbb49f1c6e977241f8ab86d1a045fdb8a04111bbc75633429a131c71acd"
|
|
533
559
|
}
|
|
534
560
|
],
|
|
535
561
|
commands: [
|
|
536
562
|
{
|
|
537
563
|
name: "install-stack",
|
|
538
564
|
file: "assets/commands/install-stack.md",
|
|
539
|
-
description: "Instala el stack tecnológico del proyecto (CodeGraph, skills, OpenSpec, Engram, Context7, controller MCP con SDK oficial). v0.7.
|
|
540
|
-
version: "0.7.
|
|
541
|
-
sha256: "
|
|
565
|
+
description: "Instala el stack tecnológico del proyecto (CodeGraph, skills, OpenSpec, Engram, Context7, controller MCP con SDK oficial). v0.7.2: Paso 1.5 controller expandido con verificación post-instalación y troubleshooting.",
|
|
566
|
+
version: "0.7.2",
|
|
567
|
+
sha256: "7277d333bfe65e674b9696fa5f887854e35824eb5b88420dd0f5bbde3bca7add"
|
|
542
568
|
},
|
|
543
569
|
{
|
|
544
570
|
name: "opsx-sync",
|
|
545
571
|
file: "assets/commands/opsx-sync.md",
|
|
546
572
|
description: "Sincroniza delta specs del change activo sin inicializar CodeGraph si ya existe índice",
|
|
547
|
-
version: "0.7.
|
|
573
|
+
version: "0.7.2",
|
|
548
574
|
sha256: "fe0158478f2ca63b315037a85fc1632b77868532e319af6c7384285441767d64"
|
|
549
575
|
}
|
|
550
576
|
],
|
|
@@ -552,15 +578,15 @@ var init_manifest = __esm(() => {
|
|
|
552
578
|
{
|
|
553
579
|
name: "ostacky-controller",
|
|
554
580
|
file: "assets/mcp/ostacky-controller/",
|
|
555
|
-
description: "Máquina de estados persistida con @modelcontextprotocol/server SDK. v0.7.
|
|
556
|
-
version: "0.7.
|
|
557
|
-
sha256: "
|
|
581
|
+
description: "Máquina de estados persistida con @modelcontextprotocol/server SDK. v0.7.2: 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.",
|
|
582
|
+
version: "0.7.2",
|
|
583
|
+
sha256: "34048819b8905dff24c731e02d813deb4fb7fbbb65e8b8df66e5c8db201492a0"
|
|
558
584
|
},
|
|
559
585
|
{
|
|
560
586
|
name: "openspec",
|
|
561
587
|
file: "assets/mcp/openspec/",
|
|
562
588
|
description: "MCP server local para OpenSpec - proposal, apply, archive, sync de cambios",
|
|
563
|
-
version: "0.7.
|
|
589
|
+
version: "0.7.2",
|
|
564
590
|
sha256: "fa4be28bfc1e75db8f1a037e2580f04a60066c80e8e5934e90e1041020d04609"
|
|
565
591
|
}
|
|
566
592
|
],
|
|
@@ -569,106 +595,106 @@ var init_manifest = __esm(() => {
|
|
|
569
595
|
name: "brainstorming",
|
|
570
596
|
file: "assets/skills/brainstorming/SKILL.md",
|
|
571
597
|
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)",
|
|
572
|
-
version: "0.7.
|
|
598
|
+
version: "0.7.2",
|
|
573
599
|
sha256: "333810ca63450e8ab795e8c5a58e645101e788d79210ca8ac36e10d11be39585"
|
|
574
600
|
},
|
|
575
601
|
{
|
|
576
602
|
name: "execution-mode-evaluation",
|
|
577
603
|
file: "assets/skills/execution-mode-evaluation/SKILL.md",
|
|
578
604
|
description: "Skill de análisis de modo de ejecución — output reconciliado con controller snapshot contract (recommendation field)",
|
|
579
|
-
version: "0.7.
|
|
605
|
+
version: "0.7.2",
|
|
580
606
|
sha256: "edf6fca0af52cce83f8fd08e7db9b3d79cc130b53fca505e90d3fbaf4909338b"
|
|
581
607
|
},
|
|
582
608
|
{
|
|
583
609
|
name: "tdd",
|
|
584
610
|
file: "assets/skills/tdd/SKILL.md",
|
|
585
611
|
description: "Skill de test-driven development (Superpowers)",
|
|
586
|
-
version: "0.7.
|
|
612
|
+
version: "0.7.2",
|
|
587
613
|
sha256: "aa412298980b7826165c211145c1b8e9135f68f36247bb3cb96d0a0eae274486"
|
|
588
614
|
},
|
|
589
615
|
{
|
|
590
616
|
name: "subagent-driven-development",
|
|
591
617
|
file: "assets/skills/subagent-driven-development/SKILL.md",
|
|
592
618
|
description: "Skill de ejecución con subagentes (Superpowers) — ejecuta solo después de confirmación del coordinador Ostacky",
|
|
593
|
-
version: "0.7.
|
|
619
|
+
version: "0.7.2",
|
|
594
620
|
sha256: "1a42d714a9a13faf05f0bf7b580e8d837c2e77a5633839542ccce603023419e8"
|
|
595
621
|
},
|
|
596
622
|
{
|
|
597
623
|
name: "dispatching-parallel-agents",
|
|
598
624
|
file: "assets/skills/dispatching-parallel-agents/SKILL.md",
|
|
599
625
|
description: "Skill de dispatch paralelo de agentes (Superpowers)",
|
|
600
|
-
version: "0.7.
|
|
626
|
+
version: "0.7.2",
|
|
601
627
|
sha256: "3c8a66d51ae2e719e877d02c3dac32bd804722c3bb9227c258ecae78252a20ab"
|
|
602
628
|
},
|
|
603
629
|
{
|
|
604
630
|
name: "review",
|
|
605
631
|
file: "assets/skills/review/SKILL.md",
|
|
606
632
|
description: "Skill de revisión de código (Superpowers)",
|
|
607
|
-
version: "0.7.
|
|
633
|
+
version: "0.7.2",
|
|
608
634
|
sha256: "b19650ed4d1d4d9857a4dd5b7e08e91328a1a1fc9c45bcc2fb600fa9d0213279"
|
|
609
635
|
},
|
|
610
636
|
{
|
|
611
637
|
name: "receiving-code-review",
|
|
612
638
|
file: "assets/skills/receiving-code-review/SKILL.md",
|
|
613
639
|
description: "Skill de recibir y procesar feedback de code review",
|
|
614
|
-
version: "0.7.
|
|
640
|
+
version: "0.7.2",
|
|
615
641
|
sha256: "d761e884e71d8d3476ac734d287cae403a4024506a7d12e7361a448217c0a831"
|
|
616
642
|
},
|
|
617
643
|
{
|
|
618
644
|
name: "openspec-propose",
|
|
619
645
|
file: "assets/skills/openspec-propose/SKILL.md",
|
|
620
646
|
description: "Skill de generación de proposal (OpenSpec)",
|
|
621
|
-
version: "0.7.
|
|
647
|
+
version: "0.7.2",
|
|
622
648
|
sha256: "bb59100b9fd3c9f9a1ec6509fa975ec55bf7fc737df4fe73bb3e9bbc217b83f7"
|
|
623
649
|
},
|
|
624
650
|
{
|
|
625
651
|
name: "openspec-apply-change",
|
|
626
652
|
file: "assets/skills/openspec-apply-change/SKILL.md",
|
|
627
653
|
description: "Skill de aplicación de change (OpenSpec)",
|
|
628
|
-
version: "0.7.
|
|
654
|
+
version: "0.7.2",
|
|
629
655
|
sha256: "dfc823bf89fc7505e91ab6dee9c1f004be38a410bd3d88fb67b211b1b6cbb1d0"
|
|
630
656
|
},
|
|
631
657
|
{
|
|
632
658
|
name: "openspec-archive-change",
|
|
633
659
|
file: "assets/skills/openspec-archive-change/SKILL.md",
|
|
634
660
|
description: "Skill de archivo de change (OpenSpec)",
|
|
635
|
-
version: "0.7.
|
|
661
|
+
version: "0.7.2",
|
|
636
662
|
sha256: "16e4b561de7747283663fed602e506abf502452c49a8d4b86d7a5539c40f0195"
|
|
637
663
|
},
|
|
638
664
|
{
|
|
639
665
|
name: "openspec-explore",
|
|
640
666
|
file: "assets/skills/openspec-explore/SKILL.md",
|
|
641
667
|
description: "Modo explore para OpenSpec — thinking partner para explorar ideas, investigar problemas y clarificar requisitos antes/durante un cambio",
|
|
642
|
-
version: "0.7.
|
|
668
|
+
version: "0.7.2",
|
|
643
669
|
sha256: "37ae4aaf17ea71a395bab6dc4d9d61b9a49d7910f6692535ae8553244c46880b"
|
|
644
670
|
},
|
|
645
671
|
{
|
|
646
672
|
name: "using-git-worktrees",
|
|
647
673
|
file: "assets/skills/using-git-worktrees/SKILL.md",
|
|
648
674
|
description: "Skill de uso de git worktrees para aislamiento de trabajo",
|
|
649
|
-
version: "0.7.
|
|
675
|
+
version: "0.7.2",
|
|
650
676
|
sha256: "11afa9123828fc5caa22137aff907cd99c751e99027fbd4c020751110a949281"
|
|
651
677
|
},
|
|
652
678
|
{
|
|
653
679
|
name: "using-superpowers",
|
|
654
680
|
file: "assets/skills/using-superpowers/SKILL.md",
|
|
655
681
|
description: "Skill de orquestación de Superpowers skills",
|
|
656
|
-
version: "0.7.
|
|
682
|
+
version: "0.7.2",
|
|
657
683
|
sha256: "7e54536f96d2a379185a10bfc1e970850caa2561b6d8aca7080f0defea0381a4"
|
|
658
684
|
},
|
|
659
685
|
{
|
|
660
686
|
name: "writing-skills",
|
|
661
687
|
file: "assets/skills/writing-skills/SKILL.md",
|
|
662
688
|
description: "Skill de creación y edición de skills",
|
|
663
|
-
version: "0.7.
|
|
689
|
+
version: "0.7.2",
|
|
664
690
|
sha256: "3d76b906cee518a2b809febb70db95697a35b9f368986bb504b4120c3bfb437a"
|
|
665
691
|
},
|
|
666
692
|
{
|
|
667
693
|
name: "graceful-degradation",
|
|
668
694
|
file: "assets/skills/graceful-degradation/SKILL.md",
|
|
669
695
|
description: "Skill de degradación graceful cuando múltiples tools están indisponibles",
|
|
670
|
-
version: "0.7.
|
|
671
|
-
sha256: "
|
|
696
|
+
version: "0.7.2",
|
|
697
|
+
sha256: "376dc90fa27ab7e5947747f20ccf2cc76f9326c77b567fda388252a60d25c431"
|
|
672
698
|
}
|
|
673
699
|
]
|
|
674
700
|
};
|
|
@@ -1468,7 +1494,7 @@ var init_stack = __esm(() => {
|
|
|
1468
1494
|
// package.json
|
|
1469
1495
|
var package_default = {
|
|
1470
1496
|
name: "ostacky",
|
|
1471
|
-
version: "0.7.
|
|
1497
|
+
version: "0.7.2",
|
|
1472
1498
|
description: "Instalador interactivo de agentes y comandos para OpenCode",
|
|
1473
1499
|
type: "module",
|
|
1474
1500
|
bin: {
|
|
@@ -2468,6 +2494,7 @@ import { dirname as dirname7 } from "path";
|
|
|
2468
2494
|
init_github();
|
|
2469
2495
|
init_fs();
|
|
2470
2496
|
init_lockfile();
|
|
2497
|
+
import { homedir as homedir2 } from "os";
|
|
2471
2498
|
|
|
2472
2499
|
// src/installer.ts
|
|
2473
2500
|
init_github();
|
|
@@ -2546,6 +2573,7 @@ async function probeMcpServer(nodeExecutable, serverPath, cwd, statePath, option
|
|
|
2546
2573
|
let stderr = "";
|
|
2547
2574
|
let stdoutBuffer = "";
|
|
2548
2575
|
const requestTimeout = 1e4;
|
|
2576
|
+
let exitTimeout;
|
|
2549
2577
|
const finish = (error) => {
|
|
2550
2578
|
if (settled)
|
|
2551
2579
|
return;
|
|
@@ -2554,9 +2582,18 @@ async function probeMcpServer(nodeExecutable, serverPath, cwd, statePath, option
|
|
|
2554
2582
|
try {
|
|
2555
2583
|
child.stdin?.end();
|
|
2556
2584
|
} catch {}
|
|
2557
|
-
if (child.exitCode === null)
|
|
2585
|
+
if (child.exitCode === null) {
|
|
2586
|
+
const onExit = () => {
|
|
2587
|
+
if (exitTimeout)
|
|
2588
|
+
clearTimeout(exitTimeout);
|
|
2589
|
+
error ? reject(error) : resolve2();
|
|
2590
|
+
};
|
|
2591
|
+
child.once("exit", onExit);
|
|
2558
2592
|
child.kill();
|
|
2559
|
-
|
|
2593
|
+
exitTimeout = setTimeout(onExit, 500);
|
|
2594
|
+
} else {
|
|
2595
|
+
error ? reject(error) : resolve2();
|
|
2596
|
+
}
|
|
2560
2597
|
};
|
|
2561
2598
|
const fail = (message) => finish(new Error(`${message}${stderr ? `: ${stderr.trim()}` : ""}`));
|
|
2562
2599
|
const send = (message) => {
|
|
@@ -2633,15 +2670,35 @@ async function probeMcpServer(nodeExecutable, serverPath, cwd, statePath, option
|
|
|
2633
2670
|
params: {
|
|
2634
2671
|
protocolVersion: "2025-03-26",
|
|
2635
2672
|
capabilities: {},
|
|
2636
|
-
clientInfo: { name: "ostacky-installer", version: "0.7.
|
|
2673
|
+
clientInfo: { name: "ostacky-installer", version: "0.7.2" }
|
|
2637
2674
|
}
|
|
2638
2675
|
});
|
|
2639
2676
|
});
|
|
2640
2677
|
} finally {
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2678
|
+
await new Promise((r2) => setTimeout(r2, 200));
|
|
2679
|
+
if (statePath) {
|
|
2680
|
+
for (const p2 of [
|
|
2681
|
+
statePath,
|
|
2682
|
+
statePath + ".backup",
|
|
2683
|
+
statePath + ".lock.pid",
|
|
2684
|
+
statePath + ".lock.timestamp",
|
|
2685
|
+
statePath + ".tmp." + process.pid
|
|
2686
|
+
]) {
|
|
2687
|
+
try {
|
|
2688
|
+
if (existsSync5(p2))
|
|
2689
|
+
rmSync3(p2, { force: true });
|
|
2690
|
+
} catch {}
|
|
2691
|
+
}
|
|
2692
|
+
try {
|
|
2693
|
+
const { dirname: dirname5, join: join7 } = await import("path");
|
|
2694
|
+
const handoff = join7(dirname5(statePath), ".ostacky-handoff-compaction.json");
|
|
2695
|
+
if (existsSync5(handoff)) {
|
|
2696
|
+
try {
|
|
2697
|
+
rmSync3(handoff, { force: true });
|
|
2698
|
+
} catch {}
|
|
2699
|
+
}
|
|
2700
|
+
} catch {}
|
|
2701
|
+
}
|
|
2645
2702
|
}
|
|
2646
2703
|
}
|
|
2647
2704
|
function takeFileSnapshot(path) {
|
|
@@ -2723,8 +2780,8 @@ async function installSkill(item, manifest, paths) {
|
|
|
2723
2780
|
const treeHash = computeTreeHash(src);
|
|
2724
2781
|
if (item.sha256 && treeHash !== item.sha256) {
|
|
2725
2782
|
throw new Error(`Tree hash inválido para skill "${item.name}"
|
|
2726
|
-
|
|
2727
|
-
|
|
2783
|
+
esperado: ${item.sha256}
|
|
2784
|
+
recibido: ${treeHash}`);
|
|
2728
2785
|
}
|
|
2729
2786
|
const dest = join6(paths.skills, item.name);
|
|
2730
2787
|
if (existsSync5(dest)) {
|
|
@@ -2764,8 +2821,8 @@ async function installMcpServer(item, manifest, paths) {
|
|
|
2764
2821
|
const treeHash = computeTreeHash(src);
|
|
2765
2822
|
if (item.sha256 && treeHash !== item.sha256) {
|
|
2766
2823
|
throw new Error(`Tree hash inválido para MCP server "${item.name}"
|
|
2767
|
-
|
|
2768
|
-
|
|
2824
|
+
esperado: ${item.sha256}
|
|
2825
|
+
recibido: ${treeHash}`);
|
|
2769
2826
|
}
|
|
2770
2827
|
const nodeExecutable = getVerifiedNodeExecutable();
|
|
2771
2828
|
const projectRoot = dirname4(paths.root);
|
|
@@ -2969,25 +3026,63 @@ function printPostInstallSteps() {
|
|
|
2969
3026
|
].join(`
|
|
2970
3027
|
`), "Próximos pasos");
|
|
2971
3028
|
}
|
|
2972
|
-
async function resolveOpenCodePaths() {
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
3029
|
+
async function resolveOpenCodePaths(scope) {
|
|
3030
|
+
if (scope === "local" || scope === "global" || scope === "auto") {
|
|
3031
|
+
const dir2 = getOpenCodeDirForScope(scope);
|
|
3032
|
+
try {
|
|
3033
|
+
const paths = ensureOpenCodePaths(dir2);
|
|
3034
|
+
if (scope === "global")
|
|
3035
|
+
ye(dir2, "Instalación global");
|
|
3036
|
+
else if (scope === "auto")
|
|
3037
|
+
ye(dir2, `Scope auto → ${dir2.includes(homedir2()) && dir2.includes(".config") ? "global" : "local"}`);
|
|
3038
|
+
else
|
|
3039
|
+
ye(dir2, "Instalación local");
|
|
3040
|
+
return paths;
|
|
3041
|
+
} catch (e2) {
|
|
3042
|
+
const msg = e2.message ?? "";
|
|
3043
|
+
if (scope === "global" && (msg.includes("EACCES") || msg.includes("permission"))) {
|
|
3044
|
+
v2.warn(`No se pudo escribir en global (${dir2}): ${msg}. ¿Instalar local?`);
|
|
3045
|
+
const retry = await me({ message: "¿Reintentar como instalación local?" });
|
|
3046
|
+
onCancel(retry);
|
|
3047
|
+
if (retry) {
|
|
3048
|
+
const localDir2 = getOpenCodeDirForScope("local");
|
|
3049
|
+
return ensureOpenCodePaths(localDir2);
|
|
3050
|
+
}
|
|
3051
|
+
}
|
|
3052
|
+
throw e2;
|
|
3053
|
+
}
|
|
2978
3054
|
}
|
|
2979
|
-
const
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
const
|
|
2983
|
-
|
|
3055
|
+
const cwd = process.cwd();
|
|
3056
|
+
const localDir = getOpenCodeDirForScope("local", cwd);
|
|
3057
|
+
const globalDir = getGlobalOpenCodeDir();
|
|
3058
|
+
const hasLocal = !!findOpenCodeDir(cwd);
|
|
3059
|
+
const scopeChoice = await de({
|
|
3060
|
+
message: `¿Instalar en proyecto local (${localDir}) o global (${globalDir})?`,
|
|
3061
|
+
options: [
|
|
3062
|
+
{ value: "local", label: "Local", hint: `${localDir} (recomendado)` },
|
|
3063
|
+
{ value: "global", label: "Global", hint: globalDir }
|
|
3064
|
+
],
|
|
3065
|
+
initialValue: "local"
|
|
2984
3066
|
});
|
|
2985
|
-
onCancel(
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
3067
|
+
onCancel(scopeChoice);
|
|
3068
|
+
const chosen = scopeChoice;
|
|
3069
|
+
const dir = getOpenCodeDirForScope(chosen, cwd);
|
|
3070
|
+
try {
|
|
3071
|
+
return ensureOpenCodePaths(dir);
|
|
3072
|
+
} catch (e2) {
|
|
3073
|
+
const msg = e2.message ?? "";
|
|
3074
|
+
if (chosen === "global" && (msg.includes("EACCES") || msg.includes("permission"))) {
|
|
3075
|
+
v2.warn(`No se pudo escribir en global (${dir}): ${msg}.`);
|
|
3076
|
+
const retry = await me({ message: "¿Instalar local en su lugar?" });
|
|
3077
|
+
onCancel(retry);
|
|
3078
|
+
if (retry)
|
|
3079
|
+
return ensureOpenCodePaths(getOpenCodeDirForScope("local", cwd));
|
|
3080
|
+
}
|
|
3081
|
+
throw e2;
|
|
3082
|
+
}
|
|
3083
|
+
}
|
|
3084
|
+
function isGlobalScope(paths) {
|
|
3085
|
+
return paths.root === getGlobalOpenCodeDir() || paths.root.startsWith(getGlobalOpenCodeDir() + "/");
|
|
2991
3086
|
}
|
|
2992
3087
|
function getOrphanedItems(manifest, paths) {
|
|
2993
3088
|
const lockfile = readLockfile(paths.root);
|
|
@@ -3105,7 +3200,13 @@ async function doInstallStack(toolsDir, projectRoot) {
|
|
|
3105
3200
|
async function doInstallAll(manifest, paths) {
|
|
3106
3201
|
const spin = L2();
|
|
3107
3202
|
let errors = 0;
|
|
3108
|
-
|
|
3203
|
+
const isGlobal = paths.root === getGlobalOpenCodeDir() || paths.root.startsWith(getGlobalOpenCodeDir() + "/");
|
|
3204
|
+
if (!isGlobal) {
|
|
3205
|
+
ensureToolDirs(paths.tools, ["codegraph", "engram", "context7"]);
|
|
3206
|
+
} else {
|
|
3207
|
+
v2.info("Scope global detectado: el stack (CodeGraph/Engram) permanece siempre en <proyecto>/.opencode/tools — se omite instalación de stack global.");
|
|
3208
|
+
v2.info("Para instalar el stack, ejecutá 'npx ostacky install-stack --scope local' dentro de cada proyecto.");
|
|
3209
|
+
}
|
|
3109
3210
|
for (const agent of manifest.agents) {
|
|
3110
3211
|
spin.start(`Descargando agente: ${agent.name} (${agent.version})`);
|
|
3111
3212
|
try {
|
|
@@ -3150,17 +3251,22 @@ async function doInstallAll(manifest, paths) {
|
|
|
3150
3251
|
errors++;
|
|
3151
3252
|
}
|
|
3152
3253
|
}
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
if (
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
|
|
3254
|
+
let stackOk = true;
|
|
3255
|
+
let missingTools = [];
|
|
3256
|
+
if (isGlobal) {
|
|
3257
|
+
stackOk = true;
|
|
3258
|
+
} else {
|
|
3259
|
+
v2.info("Instalando stack de herramientas...");
|
|
3260
|
+
stackOk = await doInstallStack(paths.tools, dirname6(paths.root));
|
|
3261
|
+
if (!stackOk)
|
|
3262
|
+
errors++;
|
|
3263
|
+
const codegraphDir = join8(paths.tools, "codegraph");
|
|
3264
|
+
const engramDir = join8(paths.tools, "engram");
|
|
3265
|
+
if (!existsSync7(codegraphDir) || !findBinaryInDir(codegraphDir, "codegraph"))
|
|
3266
|
+
missingTools.push("CodeGraph");
|
|
3267
|
+
if (!existsSync7(engramDir) || !findBinaryInDir(engramDir, "engram"))
|
|
3268
|
+
missingTools.push("Engram");
|
|
3269
|
+
}
|
|
3164
3270
|
if (missingTools.length > 0) {
|
|
3165
3271
|
v2.warn(`Faltan herramientas del stack: ${missingTools.join(", ")}.
|
|
3166
3272
|
` + "Ejecutá `/install-stack` desde el agente para instalarlas manualmente.");
|
|
@@ -3675,10 +3781,10 @@ async function doUninstallMcpByName(name, paths) {
|
|
|
3675
3781
|
}
|
|
3676
3782
|
|
|
3677
3783
|
// src/prompts/index.ts
|
|
3678
|
-
async function runInteractiveMenu() {
|
|
3784
|
+
async function runInteractiveMenu(scope) {
|
|
3679
3785
|
we(" OpenCode Installer ");
|
|
3680
3786
|
const manifest = await loadManifest();
|
|
3681
|
-
const paths = await resolveOpenCodePaths();
|
|
3787
|
+
const paths = await resolveOpenCodePaths(scope ?? null);
|
|
3682
3788
|
if (!paths) {
|
|
3683
3789
|
fe("Instalación cancelada.");
|
|
3684
3790
|
return;
|
|
@@ -3726,6 +3832,12 @@ async function runInteractiveMenu() {
|
|
|
3726
3832
|
fe("Listo.");
|
|
3727
3833
|
break;
|
|
3728
3834
|
case "stack": {
|
|
3835
|
+
if (isGlobalScope(paths)) {
|
|
3836
|
+
v2.error("install-stack requiere scope local; el stack vive en <proyecto>/.opencode/tools");
|
|
3837
|
+
v2.info(`Elegiste global (${paths.root}) — el stack debe instalarse por proyecto local.`);
|
|
3838
|
+
fe("Cancelado.");
|
|
3839
|
+
break;
|
|
3840
|
+
}
|
|
3729
3841
|
ensureToolDirs(paths.tools, ["codegraph", "engram", "context7"]);
|
|
3730
3842
|
const stackOk = await doInstallStack(paths.tools, dirname7(paths.root));
|
|
3731
3843
|
if (!stackOk)
|
|
@@ -3748,10 +3860,10 @@ async function runInteractiveMenu() {
|
|
|
3748
3860
|
break;
|
|
3749
3861
|
}
|
|
3750
3862
|
}
|
|
3751
|
-
async function runInstallCommand() {
|
|
3863
|
+
async function runInstallCommand(scope) {
|
|
3752
3864
|
we(" OpenCode Installer ");
|
|
3753
3865
|
const manifest = await loadManifest();
|
|
3754
|
-
const paths = await resolveOpenCodePaths();
|
|
3866
|
+
const paths = await resolveOpenCodePaths(scope ?? null);
|
|
3755
3867
|
if (!paths) {
|
|
3756
3868
|
fe("Cancelado.");
|
|
3757
3869
|
return;
|
|
@@ -3761,10 +3873,10 @@ async function runInstallCommand() {
|
|
|
3761
3873
|
printPostInstallSteps();
|
|
3762
3874
|
fe(process.exitCode ? "Instalación parcial." : "Instalación completada.");
|
|
3763
3875
|
}
|
|
3764
|
-
async function runAddAgentCommand() {
|
|
3876
|
+
async function runAddAgentCommand(scope) {
|
|
3765
3877
|
we(" OpenCode Installer ");
|
|
3766
3878
|
const manifest = await loadManifest();
|
|
3767
|
-
const paths = await resolveOpenCodePaths();
|
|
3879
|
+
const paths = await resolveOpenCodePaths(scope ?? null);
|
|
3768
3880
|
if (!paths) {
|
|
3769
3881
|
fe("Cancelado.");
|
|
3770
3882
|
return;
|
|
@@ -3773,10 +3885,10 @@ async function runAddAgentCommand() {
|
|
|
3773
3885
|
printPostInstallSteps();
|
|
3774
3886
|
fe("Listo.");
|
|
3775
3887
|
}
|
|
3776
|
-
async function runAddCommandCommand() {
|
|
3888
|
+
async function runAddCommandCommand(scope) {
|
|
3777
3889
|
we(" OpenCode Installer ");
|
|
3778
3890
|
const manifest = await loadManifest();
|
|
3779
|
-
const paths = await resolveOpenCodePaths();
|
|
3891
|
+
const paths = await resolveOpenCodePaths(scope ?? null);
|
|
3780
3892
|
if (!paths) {
|
|
3781
3893
|
fe("Cancelado.");
|
|
3782
3894
|
return;
|
|
@@ -3785,10 +3897,10 @@ async function runAddCommandCommand() {
|
|
|
3785
3897
|
printPostInstallSteps();
|
|
3786
3898
|
fe("Listo.");
|
|
3787
3899
|
}
|
|
3788
|
-
async function runAddSkillCommand() {
|
|
3900
|
+
async function runAddSkillCommand(scope) {
|
|
3789
3901
|
we(" OpenCode Installer ");
|
|
3790
3902
|
const manifest = await loadManifest();
|
|
3791
|
-
const paths = await resolveOpenCodePaths();
|
|
3903
|
+
const paths = await resolveOpenCodePaths(scope ?? null);
|
|
3792
3904
|
if (!paths) {
|
|
3793
3905
|
fe("Cancelado.");
|
|
3794
3906
|
return;
|
|
@@ -3797,10 +3909,10 @@ async function runAddSkillCommand() {
|
|
|
3797
3909
|
printPostInstallSteps();
|
|
3798
3910
|
fe("Listo.");
|
|
3799
3911
|
}
|
|
3800
|
-
async function runAddMcpCommand() {
|
|
3912
|
+
async function runAddMcpCommand(scope) {
|
|
3801
3913
|
we(" OpenCode Installer ");
|
|
3802
3914
|
const manifest = await loadManifest();
|
|
3803
|
-
const paths = await resolveOpenCodePaths();
|
|
3915
|
+
const paths = await resolveOpenCodePaths(scope ?? null);
|
|
3804
3916
|
if (!paths) {
|
|
3805
3917
|
fe("Cancelado.");
|
|
3806
3918
|
return;
|
|
@@ -3809,9 +3921,15 @@ async function runAddMcpCommand() {
|
|
|
3809
3921
|
printPostInstallSteps();
|
|
3810
3922
|
fe("Listo.");
|
|
3811
3923
|
}
|
|
3812
|
-
async function runInstallStackCommand() {
|
|
3924
|
+
async function runInstallStackCommand(scope) {
|
|
3925
|
+
if (scope === "global") {
|
|
3926
|
+
v2.error("install-stack requiere scope local; el stack vive en <proyecto>/.opencode/tools");
|
|
3927
|
+
fe("Usá: npx ostacky install-stack --scope local");
|
|
3928
|
+
process.exitCode = 1;
|
|
3929
|
+
return;
|
|
3930
|
+
}
|
|
3813
3931
|
we(" OpenCode Installer — Stack ");
|
|
3814
|
-
const paths = await resolveOpenCodePaths();
|
|
3932
|
+
const paths = await resolveOpenCodePaths(scope ?? null);
|
|
3815
3933
|
if (!paths) {
|
|
3816
3934
|
fe("Cancelado.");
|
|
3817
3935
|
return;
|
|
@@ -3822,9 +3940,9 @@ async function runInstallStackCommand() {
|
|
|
3822
3940
|
process.exitCode = 1;
|
|
3823
3941
|
fe(stackOk ? "Stack instalado." : "Stack instalado parcialmente.");
|
|
3824
3942
|
}
|
|
3825
|
-
async function runUninstallStackCommand() {
|
|
3943
|
+
async function runUninstallStackCommand(scope) {
|
|
3826
3944
|
we(" OpenCode Installer — Stack ");
|
|
3827
|
-
const paths = await resolveOpenCodePaths();
|
|
3945
|
+
const paths = await resolveOpenCodePaths(scope ?? null);
|
|
3828
3946
|
if (!paths) {
|
|
3829
3947
|
fe("Cancelado.");
|
|
3830
3948
|
return;
|
|
@@ -3846,10 +3964,10 @@ async function runUninstallStackCommand() {
|
|
|
3846
3964
|
}
|
|
3847
3965
|
fe("Stack desinstalado.");
|
|
3848
3966
|
}
|
|
3849
|
-
async function runUpdateCommand() {
|
|
3967
|
+
async function runUpdateCommand(scope) {
|
|
3850
3968
|
we(" OpenCode Installer ");
|
|
3851
3969
|
const manifest = await loadLatestManifest();
|
|
3852
|
-
const paths = await resolveOpenCodePaths();
|
|
3970
|
+
const paths = await resolveOpenCodePaths(scope ?? null);
|
|
3853
3971
|
if (!paths) {
|
|
3854
3972
|
fe("Cancelado.");
|
|
3855
3973
|
return;
|
|
@@ -3857,9 +3975,9 @@ async function runUpdateCommand() {
|
|
|
3857
3975
|
await doUpdate(manifest, paths);
|
|
3858
3976
|
fe("Actualización completada.");
|
|
3859
3977
|
}
|
|
3860
|
-
async function runUninstallCommand() {
|
|
3978
|
+
async function runUninstallCommand(scope) {
|
|
3861
3979
|
we(" OpenCode Installer ");
|
|
3862
|
-
const paths = await resolveOpenCodePaths();
|
|
3980
|
+
const paths = await resolveOpenCodePaths(scope ?? null);
|
|
3863
3981
|
if (!paths) {
|
|
3864
3982
|
fe("Cancelado.");
|
|
3865
3983
|
return;
|
|
@@ -3867,9 +3985,9 @@ async function runUninstallCommand() {
|
|
|
3867
3985
|
await doUninstall(paths);
|
|
3868
3986
|
fe("Desinstalación completada.");
|
|
3869
3987
|
}
|
|
3870
|
-
async function runUninstallAgentCommand(name) {
|
|
3988
|
+
async function runUninstallAgentCommand(name, scope) {
|
|
3871
3989
|
we(" OpenCode Installer ");
|
|
3872
|
-
const paths = await resolveOpenCodePaths();
|
|
3990
|
+
const paths = await resolveOpenCodePaths(scope ?? null);
|
|
3873
3991
|
if (!paths) {
|
|
3874
3992
|
fe("Cancelado.");
|
|
3875
3993
|
return;
|
|
@@ -3902,9 +4020,9 @@ async function runUninstallAgentCommand(name) {
|
|
|
3902
4020
|
}
|
|
3903
4021
|
fe("Listo.");
|
|
3904
4022
|
}
|
|
3905
|
-
async function runUninstallCommandCommand(name) {
|
|
4023
|
+
async function runUninstallCommandCommand(name, scope) {
|
|
3906
4024
|
we(" OpenCode Installer ");
|
|
3907
|
-
const paths = await resolveOpenCodePaths();
|
|
4025
|
+
const paths = await resolveOpenCodePaths(scope ?? null);
|
|
3908
4026
|
if (!paths) {
|
|
3909
4027
|
fe("Cancelado.");
|
|
3910
4028
|
return;
|
|
@@ -3937,9 +4055,9 @@ async function runUninstallCommandCommand(name) {
|
|
|
3937
4055
|
}
|
|
3938
4056
|
fe("Listo.");
|
|
3939
4057
|
}
|
|
3940
|
-
async function runUninstallSkillCommand(name) {
|
|
4058
|
+
async function runUninstallSkillCommand(name, scope) {
|
|
3941
4059
|
we(" OpenCode Installer ");
|
|
3942
|
-
const paths = await resolveOpenCodePaths();
|
|
4060
|
+
const paths = await resolveOpenCodePaths(scope ?? null);
|
|
3943
4061
|
if (!paths) {
|
|
3944
4062
|
fe("Cancelado.");
|
|
3945
4063
|
return;
|
|
@@ -3972,9 +4090,9 @@ async function runUninstallSkillCommand(name) {
|
|
|
3972
4090
|
}
|
|
3973
4091
|
fe("Listo.");
|
|
3974
4092
|
}
|
|
3975
|
-
async function runUninstallMcpCommand(name) {
|
|
4093
|
+
async function runUninstallMcpCommand(name, scope) {
|
|
3976
4094
|
we(" OpenCode Installer ");
|
|
3977
|
-
const paths = await resolveOpenCodePaths();
|
|
4095
|
+
const paths = await resolveOpenCodePaths(scope ?? null);
|
|
3978
4096
|
if (!paths) {
|
|
3979
4097
|
fe("Cancelado.");
|
|
3980
4098
|
return;
|
|
@@ -4013,67 +4131,110 @@ var HELP = `
|
|
|
4013
4131
|
ostacky — Instalador de agentes, comandos, skills y MCPs para OpenCode
|
|
4014
4132
|
|
|
4015
4133
|
Uso:
|
|
4016
|
-
npx ostacky Menú interactivo (instalación completa)
|
|
4017
|
-
npx ostacky install Instalar TODO (agente + skills + MCPs + CodeGraph + OpenSpec + Engram + Context7)
|
|
4018
|
-
npx ostacky add agent Agregar agente(s)
|
|
4019
|
-
npx ostacky add command Agregar command(s)
|
|
4020
|
-
npx ostacky add skill Agregar skill(s)
|
|
4021
|
-
npx ostacky add mcp Agregar MCP server(s)
|
|
4022
|
-
npx ostacky install-stack Instalar solo el stack de herramientas (CodeGraph, OpenSpec, Engram, Context7)
|
|
4023
|
-
npx ostacky uninstall-stack Remover la configuración del stack del proyecto
|
|
4024
|
-
npx ostacky update Actualizar instalación
|
|
4025
|
-
npx ostacky uninstall Desinstalar todo
|
|
4026
|
-
npx ostacky uninstall agent Desinstalar agente(s)
|
|
4027
|
-
npx ostacky uninstall command Desinstalar command(s)
|
|
4028
|
-
npx ostacky uninstall skill Desinstalar skill(s)
|
|
4029
|
-
npx ostacky uninstall mcp Desinstalar MCP server(s)
|
|
4134
|
+
npx ostacky [--scope local|global|auto] Menú interactivo (instalación completa, pregunta local vs global, default local)
|
|
4135
|
+
npx ostacky install [--scope local|global|auto] Instalar TODO (agente + skills + MCPs + CodeGraph + OpenSpec + Engram + Context7)
|
|
4136
|
+
npx ostacky add agent [--scope local|global|auto] Agregar agente(s)
|
|
4137
|
+
npx ostacky add command [--scope ...] Agregar command(s)
|
|
4138
|
+
npx ostacky add skill [--scope ...] Agregar skill(s)
|
|
4139
|
+
npx ostacky add mcp [--scope ...] Agregar MCP server(s)
|
|
4140
|
+
npx ostacky install-stack [--scope local|auto] Instalar solo el stack de herramientas (CodeGraph, OpenSpec, Engram, Context7) — global bloquea con error
|
|
4141
|
+
npx ostacky uninstall-stack [--scope local|global|auto] Remover la configuración del stack del proyecto
|
|
4142
|
+
npx ostacky update [--scope ...] Actualizar instalación
|
|
4143
|
+
npx ostacky uninstall [--scope ...] Desinstalar todo
|
|
4144
|
+
npx ostacky uninstall agent [--scope ...] Desinstalar agente(s)
|
|
4145
|
+
npx ostacky uninstall command [--scope ...] Desinstalar command(s)
|
|
4146
|
+
npx ostacky uninstall skill [--scope ...] Desinstalar skill(s)
|
|
4147
|
+
npx ostacky uninstall mcp [--scope ...] Desinstalar MCP server(s)
|
|
4030
4148
|
npx ostacky --help Mostrar esta ayuda
|
|
4031
4149
|
npx ostacky --version Mostrar versión
|
|
4150
|
+
|
|
4151
|
+
Scope:
|
|
4152
|
+
--scope local Escribe en <proyecto>/.opencode (recomendado, default al preguntar)
|
|
4153
|
+
--scope global Escribe en ~/.config/opencode (o %APPDATA%\\opencode en Windows)
|
|
4154
|
+
--scope auto Elige local si existe .opencode o .git, si no global
|
|
4155
|
+
Sin flag Pregunta interactiva local (default) vs global
|
|
4032
4156
|
`.trim();
|
|
4033
|
-
|
|
4157
|
+
function parseScopeArg(argv = process.argv) {
|
|
4158
|
+
for (let i = 0;i < argv.length; i++) {
|
|
4159
|
+
const arg = argv[i];
|
|
4160
|
+
if (arg === "--scope" && i + 1 < argv.length) {
|
|
4161
|
+
const v3 = argv[i + 1];
|
|
4162
|
+
if (v3 === "local" || v3 === "global" || v3 === "auto")
|
|
4163
|
+
return v3;
|
|
4164
|
+
}
|
|
4165
|
+
if (arg.startsWith("--scope=")) {
|
|
4166
|
+
const v3 = arg.split("=")[1];
|
|
4167
|
+
if (v3 === "local" || v3 === "global" || v3 === "auto")
|
|
4168
|
+
return v3;
|
|
4169
|
+
}
|
|
4170
|
+
}
|
|
4171
|
+
return null;
|
|
4172
|
+
}
|
|
4173
|
+
function withoutScopeArgs(argv) {
|
|
4174
|
+
const out = [];
|
|
4175
|
+
for (let i = 0;i < argv.length; i++) {
|
|
4176
|
+
const arg = argv[i];
|
|
4177
|
+
if (arg === "--scope" && i + 1 < argv.length) {
|
|
4178
|
+
i++;
|
|
4179
|
+
continue;
|
|
4180
|
+
}
|
|
4181
|
+
if (arg.startsWith("--scope="))
|
|
4182
|
+
continue;
|
|
4183
|
+
out.push(arg);
|
|
4184
|
+
}
|
|
4185
|
+
return out;
|
|
4186
|
+
}
|
|
4187
|
+
var scope = parseScopeArg();
|
|
4188
|
+
var argvNoScope = withoutScopeArgs(process.argv);
|
|
4189
|
+
var [, , cmd, subcmd] = argvNoScope;
|
|
4034
4190
|
async function main() {
|
|
4035
4191
|
switch (cmd) {
|
|
4036
4192
|
case "install":
|
|
4037
|
-
await runInstallCommand();
|
|
4193
|
+
await runInstallCommand(scope);
|
|
4038
4194
|
break;
|
|
4039
4195
|
case "install-stack":
|
|
4040
|
-
|
|
4196
|
+
if (scope === "global") {
|
|
4197
|
+
console.error("Error: install-stack requiere scope local; el stack vive en <proyecto>/.opencode/tools");
|
|
4198
|
+
console.error("Sugerencia: ejecutá 'npx ostacky install-stack --scope local' dentro de cada proyecto.");
|
|
4199
|
+
process.exit(1);
|
|
4200
|
+
}
|
|
4201
|
+
await runInstallStackCommand(scope);
|
|
4041
4202
|
break;
|
|
4042
4203
|
case "uninstall-stack":
|
|
4043
|
-
await runUninstallStackCommand();
|
|
4204
|
+
await runUninstallStackCommand(scope);
|
|
4044
4205
|
break;
|
|
4045
4206
|
case "add":
|
|
4046
4207
|
if (subcmd === "agent") {
|
|
4047
|
-
await runAddAgentCommand();
|
|
4208
|
+
await runAddAgentCommand(scope);
|
|
4048
4209
|
} else if (subcmd === "command") {
|
|
4049
|
-
await runAddCommandCommand();
|
|
4210
|
+
await runAddCommandCommand(scope);
|
|
4050
4211
|
} else if (subcmd === "skill") {
|
|
4051
|
-
await runAddSkillCommand();
|
|
4212
|
+
await runAddSkillCommand(scope);
|
|
4052
4213
|
} else if (subcmd === "mcp") {
|
|
4053
|
-
await runAddMcpCommand();
|
|
4214
|
+
await runAddMcpCommand(scope);
|
|
4054
4215
|
} else {
|
|
4055
4216
|
console.error(`Tipo desconocido: "${subcmd}". Usa 'agent', 'command', 'skill' o 'mcp'.`);
|
|
4056
4217
|
process.exit(1);
|
|
4057
4218
|
}
|
|
4058
4219
|
break;
|
|
4059
4220
|
case "update":
|
|
4060
|
-
await runUpdateCommand();
|
|
4221
|
+
await runUpdateCommand(scope);
|
|
4061
4222
|
break;
|
|
4062
4223
|
case "uninstall":
|
|
4063
4224
|
if (subcmd === "agent") {
|
|
4064
|
-
const name =
|
|
4065
|
-
await runUninstallAgentCommand(name);
|
|
4225
|
+
const name = argvNoScope[4];
|
|
4226
|
+
await runUninstallAgentCommand(name, scope);
|
|
4066
4227
|
} else if (subcmd === "command") {
|
|
4067
|
-
const name =
|
|
4068
|
-
await runUninstallCommandCommand(name);
|
|
4228
|
+
const name = argvNoScope[4];
|
|
4229
|
+
await runUninstallCommandCommand(name, scope);
|
|
4069
4230
|
} else if (subcmd === "skill") {
|
|
4070
|
-
const name =
|
|
4071
|
-
await runUninstallSkillCommand(name);
|
|
4231
|
+
const name = argvNoScope[4];
|
|
4232
|
+
await runUninstallSkillCommand(name, scope);
|
|
4072
4233
|
} else if (subcmd === "mcp") {
|
|
4073
|
-
const name =
|
|
4074
|
-
await runUninstallMcpCommand(name);
|
|
4234
|
+
const name = argvNoScope[4];
|
|
4235
|
+
await runUninstallMcpCommand(name, scope);
|
|
4075
4236
|
} else if (subcmd === undefined) {
|
|
4076
|
-
await runUninstallCommand();
|
|
4237
|
+
await runUninstallCommand(scope);
|
|
4077
4238
|
} else {
|
|
4078
4239
|
console.error(`Subcomando desconocido: "${subcmd}". Usa 'agent', 'command', 'skill', 'mcp' o nada.`);
|
|
4079
4240
|
process.exit(1);
|
|
@@ -4092,7 +4253,7 @@ async function main() {
|
|
|
4092
4253
|
console.error(`Comando desconocido: "${cmd}". Usá --help para ver los comandos disponibles.`);
|
|
4093
4254
|
process.exit(1);
|
|
4094
4255
|
}
|
|
4095
|
-
await runInteractiveMenu();
|
|
4256
|
+
await runInteractiveMenu(scope);
|
|
4096
4257
|
}
|
|
4097
4258
|
}
|
|
4098
4259
|
main().catch((e2) => {
|