ostacky 0.6.0 → 0.6.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 +9 -9
- package/assets/agents/ostacky.md +311 -310
- package/assets/commands/install-stack.md +510 -536
- package/assets/commands/opsx-sync.md +26 -26
- package/assets/mcp/openspec/index.js +1 -1
- package/assets/mcp/openspec/package.json +1 -1
- package/assets/mcp/ostacky-controller/index.js +989 -994
- package/assets/mcp/ostacky-controller/package.json +10 -10
- package/assets/plugins/engram.ts +537 -537
- package/assets/skills/brainstorming/SKILL.md +197 -197
- package/assets/skills/dispatching-parallel-agents/SKILL.md +182 -182
- package/assets/skills/execution-mode-evaluation/SKILL.md +189 -189
- package/assets/skills/graceful-degradation/SKILL.md +235 -235
- package/assets/skills/openspec-apply-change/SKILL.md +167 -167
- package/assets/skills/openspec-archive-change/SKILL.md +114 -114
- package/assets/skills/openspec-explore/SKILL.md +288 -288
- package/assets/skills/openspec-propose/SKILL.md +114 -114
- package/assets/skills/receiving-code-review/SKILL.md +213 -213
- package/assets/skills/review/SKILL.md +216 -216
- package/assets/skills/subagent-driven-development/SKILL.md +302 -302
- package/assets/skills/tdd/SKILL.md +371 -371
- package/assets/skills/using-git-worktrees/SKILL.md +212 -212
- package/assets/skills/using-superpowers/SKILL.md +111 -111
- package/assets/skills/writing-plans/SKILL.md +149 -149
- package/assets/skills/writing-skills/SKILL.md +655 -655
- package/dist/cli.js +2363 -2001
- package/manifest.json +158 -158
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -173,2099 +173,2267 @@ var require_picocolors = __commonJS((exports, module) => {
|
|
|
173
173
|
module.exports.createColors = createColors;
|
|
174
174
|
});
|
|
175
175
|
|
|
176
|
-
//
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
176
|
+
// src/security.ts
|
|
177
|
+
var exports_security = {};
|
|
178
|
+
__export(exports_security, {
|
|
179
|
+
verifyChecksum: () => verifyChecksum,
|
|
180
|
+
validateFilePath: () => validateFilePath,
|
|
181
|
+
sha256: () => sha256
|
|
182
|
+
});
|
|
183
|
+
import { createHash } from "crypto";
|
|
184
|
+
function validateFilePath(filePath) {
|
|
185
|
+
if (filePath.includes("..") || filePath.startsWith("/") || filePath.startsWith("\\") || /^[a-zA-Z]:/.test(filePath)) {
|
|
186
|
+
throw new Error(`Ruta de archivo inválida: "${filePath}"`);
|
|
187
|
+
}
|
|
184
188
|
}
|
|
185
|
-
function
|
|
186
|
-
|
|
187
|
-
throw new TypeError(`Expected a \`string\`, got \`${typeof t}\``);
|
|
188
|
-
return t.replace(Q, "");
|
|
189
|
+
function sha256(content) {
|
|
190
|
+
return createHash("sha256").update(content, "utf-8").digest("hex");
|
|
189
191
|
}
|
|
190
|
-
function
|
|
191
|
-
|
|
192
|
+
function verifyChecksum(content, expectedHash, label) {
|
|
193
|
+
if (!expectedHash)
|
|
194
|
+
return;
|
|
195
|
+
const actual = sha256(content);
|
|
196
|
+
if (actual !== expectedHash) {
|
|
197
|
+
throw new Error(`Checksum inválido para "${label}"
|
|
198
|
+
esperado: ${expectedHash}
|
|
199
|
+
recibido: ${actual}`);
|
|
200
|
+
}
|
|
192
201
|
}
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
202
|
+
var init_security = () => {};
|
|
203
|
+
|
|
204
|
+
// src/fs.ts
|
|
205
|
+
import {
|
|
206
|
+
existsSync,
|
|
207
|
+
mkdirSync,
|
|
208
|
+
unlinkSync,
|
|
209
|
+
readdirSync,
|
|
210
|
+
statSync,
|
|
211
|
+
copyFileSync,
|
|
212
|
+
readFileSync,
|
|
213
|
+
rmSync,
|
|
214
|
+
createWriteStream,
|
|
215
|
+
renameSync
|
|
216
|
+
} from "fs";
|
|
217
|
+
import { createHash as createHash2 } from "crypto";
|
|
218
|
+
import { join, resolve, dirname, relative, basename } from "path";
|
|
219
|
+
import { execFileSync } from "child_process";
|
|
220
|
+
function findOpenCodeDir(startDir = process.cwd()) {
|
|
221
|
+
let current = resolve(startDir);
|
|
222
|
+
while (true) {
|
|
223
|
+
const opencodeDir = join(current, ".opencode");
|
|
224
|
+
if (existsSync(opencodeDir))
|
|
225
|
+
return opencodeDir;
|
|
226
|
+
if (existsSync(join(current, ".git")))
|
|
227
|
+
return null;
|
|
228
|
+
const parent = dirname(current);
|
|
229
|
+
if (parent === current)
|
|
230
|
+
return null;
|
|
231
|
+
current = parent;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
function findProjectRoot(startDir = process.cwd()) {
|
|
235
|
+
let current = resolve(startDir);
|
|
236
|
+
while (true) {
|
|
237
|
+
if (existsSync(join(current, ".opencode")) || existsSync(join(current, ".git"))) {
|
|
238
|
+
return current;
|
|
213
239
|
}
|
|
240
|
+
const parent = dirname(current);
|
|
241
|
+
if (parent === current)
|
|
242
|
+
return resolve(startDir);
|
|
243
|
+
current = parent;
|
|
214
244
|
}
|
|
215
|
-
return e;
|
|
216
245
|
}
|
|
217
|
-
function
|
|
218
|
-
const
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
246
|
+
function ensureOpenCodePaths(opencodeDir) {
|
|
247
|
+
const paths = {
|
|
248
|
+
root: opencodeDir,
|
|
249
|
+
agents: join(opencodeDir, "agents"),
|
|
250
|
+
commands: join(opencodeDir, "commands"),
|
|
251
|
+
plugins: join(opencodeDir, "plugins"),
|
|
252
|
+
skills: join(opencodeDir, "skills"),
|
|
253
|
+
mcp: join(opencodeDir, "mcp"),
|
|
254
|
+
tools: join(opencodeDir, "tools")
|
|
255
|
+
};
|
|
256
|
+
for (const dir of [paths.root, paths.agents, paths.commands, paths.plugins, paths.skills, paths.mcp, paths.tools]) {
|
|
257
|
+
if (!existsSync(dir))
|
|
258
|
+
mkdirSync(dir, { recursive: true });
|
|
223
259
|
}
|
|
224
|
-
return
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
260
|
+
return paths;
|
|
261
|
+
}
|
|
262
|
+
function ensureToolDirs(toolsDir, toolNames) {
|
|
263
|
+
for (const name of toolNames) {
|
|
264
|
+
const dir = join(toolsDir, name);
|
|
265
|
+
if (!existsSync(dir))
|
|
266
|
+
mkdirSync(dir, { recursive: true });
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
function createOpenCodeDir(baseDir) {
|
|
270
|
+
return ensureOpenCodePaths(join(baseDir, ".opencode"));
|
|
271
|
+
}
|
|
272
|
+
function copyDirRecursive(src, dest, skipGenerated = false) {
|
|
273
|
+
if (!existsSync(dest))
|
|
274
|
+
mkdirSync(dest, { recursive: true });
|
|
275
|
+
for (const entry of readdirSync(src)) {
|
|
276
|
+
if (skipGenerated && (entry === "node_modules" || entry === "package-lock.json"))
|
|
277
|
+
continue;
|
|
278
|
+
const srcPath = join(src, entry);
|
|
279
|
+
const destPath = join(dest, entry);
|
|
280
|
+
const stat = statSync(srcPath);
|
|
281
|
+
if (stat.isDirectory()) {
|
|
282
|
+
copyDirRecursive(srcPath, destPath, skipGenerated);
|
|
283
|
+
} else {
|
|
284
|
+
copyFileSync(srcPath, destPath);
|
|
244
285
|
}
|
|
245
|
-
|
|
246
|
-
if (i === 0)
|
|
247
|
-
return 30;
|
|
248
|
-
let D = 30 + (Math.round(s) << 2 | Math.round(e) << 1 | Math.round(F));
|
|
249
|
-
return i === 2 && (D += 60), D;
|
|
250
|
-
}, enumerable: false }, rgbToAnsi: { value: (u, F, e) => r.ansi256ToAnsi(r.rgbToAnsi256(u, F, e)), enumerable: false }, hexToAnsi: { value: (u) => r.ansi256ToAnsi(r.hexToAnsi256(u)), enumerable: false } }), r;
|
|
286
|
+
}
|
|
251
287
|
}
|
|
252
|
-
function
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
288
|
+
function computeTreeHash(dir) {
|
|
289
|
+
const lines = [];
|
|
290
|
+
walkForHash(dir, dir, lines);
|
|
291
|
+
const combined = lines.sort().join(`
|
|
256
292
|
`);
|
|
293
|
+
return createHash2("sha256").update(combined, "utf-8").digest("hex");
|
|
257
294
|
}
|
|
258
|
-
function
|
|
259
|
-
for (const
|
|
260
|
-
|
|
261
|
-
if (!Object.hasOwn(t, F))
|
|
295
|
+
function walkForHash(root, current, lines) {
|
|
296
|
+
for (const entry of readdirSync(current)) {
|
|
297
|
+
if (entry === "node_modules" || entry === "package-lock.json")
|
|
262
298
|
continue;
|
|
263
|
-
const
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
299
|
+
const full = join(current, entry);
|
|
300
|
+
const stat = statSync(full);
|
|
301
|
+
if (stat.isDirectory()) {
|
|
302
|
+
walkForHash(root, full, lines);
|
|
303
|
+
} else {
|
|
304
|
+
const rel = relative(root, full);
|
|
305
|
+
const content = readFileSync(full, "utf-8");
|
|
306
|
+
lines.push(`${rel}:${sha256(content)}`);
|
|
270
307
|
}
|
|
271
308
|
}
|
|
272
309
|
}
|
|
273
|
-
function
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
310
|
+
function isCommandAvailable(cmd) {
|
|
311
|
+
try {
|
|
312
|
+
execFileSync(process.platform === "win32" ? "where" : "which", [cmd], {
|
|
313
|
+
stdio: "ignore"
|
|
314
|
+
});
|
|
315
|
+
return true;
|
|
316
|
+
} catch {
|
|
317
|
+
return false;
|
|
318
|
+
}
|
|
280
319
|
}
|
|
281
|
-
function
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
320
|
+
function findExecutablePath(cmd) {
|
|
321
|
+
try {
|
|
322
|
+
const command = process.platform === "win32" ? "where" : "which";
|
|
323
|
+
const result = execFileSync(command, [cmd], {
|
|
324
|
+
encoding: "utf-8",
|
|
325
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
326
|
+
});
|
|
327
|
+
return result.split(/\r?\n/).map((entry) => entry.trim()).find(Boolean) ?? null;
|
|
328
|
+
} catch {
|
|
329
|
+
return null;
|
|
330
|
+
}
|
|
290
331
|
}
|
|
291
|
-
function
|
|
292
|
-
|
|
332
|
+
function detectPlatformTarget(platform = process.platform, arch = process.arch) {
|
|
333
|
+
let os;
|
|
334
|
+
let cpu;
|
|
335
|
+
if (platform === "darwin")
|
|
336
|
+
os = "darwin";
|
|
337
|
+
else if (platform === "linux")
|
|
338
|
+
os = "linux";
|
|
339
|
+
else if (platform === "win32")
|
|
340
|
+
os = "win32";
|
|
341
|
+
else
|
|
342
|
+
return null;
|
|
343
|
+
if (arch === "arm64")
|
|
344
|
+
cpu = "arm64";
|
|
345
|
+
else if (arch === "x64")
|
|
346
|
+
cpu = "x64";
|
|
347
|
+
else
|
|
348
|
+
return null;
|
|
349
|
+
return `${os}-${cpu}`;
|
|
293
350
|
}
|
|
294
|
-
function
|
|
295
|
-
|
|
296
|
-
F.isTTY && F.setRawMode(u);
|
|
351
|
+
function getExecutableName(name, platform = process.platform) {
|
|
352
|
+
return platform === "win32" ? `${name}.exe` : name;
|
|
297
353
|
}
|
|
298
|
-
function
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
f.moveCursor(u, a, n, () => {
|
|
311
|
-
f.clearLine(u, 1, () => {
|
|
312
|
-
t.once("keypress", i);
|
|
313
|
-
});
|
|
314
|
-
});
|
|
354
|
+
function getExecutableNames(name, platform = process.platform) {
|
|
355
|
+
if (platform !== "win32")
|
|
356
|
+
return [name];
|
|
357
|
+
return name === "codegraph" ? [`${name}.exe`, `${name}.cmd`] : [`${name}.exe`];
|
|
358
|
+
}
|
|
359
|
+
function getCommandInvocation(command, args, platform = process.platform) {
|
|
360
|
+
const requiresCmd = platform === "win32" && (command.toLowerCase().endsWith(".cmd") || command === "npm" || command === "npx");
|
|
361
|
+
if (!requiresCmd)
|
|
362
|
+
return { command, args };
|
|
363
|
+
return {
|
|
364
|
+
command: "cmd.exe",
|
|
365
|
+
args: ["/d", "/c", "call", command, ...args]
|
|
315
366
|
};
|
|
316
|
-
|
|
317
|
-
|
|
367
|
+
}
|
|
368
|
+
function getEngramReleaseTarget(platform = process.platform, arch = process.arch) {
|
|
369
|
+
const os = platform === "win32" ? "windows" : platform === "darwin" || platform === "linux" ? platform : null;
|
|
370
|
+
const cpu = arch === "x64" ? "amd64" : arch === "arm64" ? "arm64" : null;
|
|
371
|
+
return os && cpu ? `${os}-${cpu}` : null;
|
|
372
|
+
}
|
|
373
|
+
function shouldRetryDownload(error) {
|
|
374
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
375
|
+
const status = message.match(/\bHTTP\s+(\d{3})\b/i)?.[1];
|
|
376
|
+
if (status) {
|
|
377
|
+
const code = Number(status);
|
|
378
|
+
return code === 408 || code === 425 || code === 429 || code >= 500;
|
|
379
|
+
}
|
|
380
|
+
return /abort|timeout|timed out|econnreset|econnrefused|eai_again|enotfound|fetch failed|network/i.test(message);
|
|
381
|
+
}
|
|
382
|
+
function promoteStagedDirectory(stagedDir, destinationDir) {
|
|
383
|
+
const backupDir = `${destinationDir}.backup-${process.pid}-${Date.now()}`;
|
|
384
|
+
const hadDestination = existsSync(destinationDir);
|
|
385
|
+
if (hadDestination)
|
|
386
|
+
renameSync(destinationDir, backupDir);
|
|
387
|
+
try {
|
|
388
|
+
mkdirSync(dirname(destinationDir), { recursive: true });
|
|
389
|
+
renameSync(stagedDir, destinationDir);
|
|
390
|
+
} catch (error) {
|
|
391
|
+
if (hadDestination && existsSync(backupDir))
|
|
392
|
+
renameSync(backupDir, destinationDir);
|
|
393
|
+
throw error;
|
|
394
|
+
}
|
|
395
|
+
let settled = false;
|
|
396
|
+
return {
|
|
397
|
+
commit() {
|
|
398
|
+
if (settled)
|
|
399
|
+
return;
|
|
400
|
+
if (hadDestination && existsSync(backupDir))
|
|
401
|
+
rmSync(backupDir, { recursive: true, force: true });
|
|
402
|
+
settled = true;
|
|
403
|
+
},
|
|
404
|
+
rollback() {
|
|
405
|
+
if (settled)
|
|
406
|
+
return;
|
|
407
|
+
if (existsSync(destinationDir))
|
|
408
|
+
rmSync(destinationDir, { recursive: true, force: true });
|
|
409
|
+
if (hadDestination && existsSync(backupDir))
|
|
410
|
+
renameSync(backupDir, destinationDir);
|
|
411
|
+
settled = true;
|
|
412
|
+
}
|
|
318
413
|
};
|
|
319
414
|
}
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
unsubscribe() {
|
|
328
|
-
this._subscribers.clear();
|
|
329
|
-
}
|
|
330
|
-
setSubscriber(u, F) {
|
|
331
|
-
const e = this._subscribers.get(u) ?? [];
|
|
332
|
-
e.push(F), this._subscribers.set(u, e);
|
|
333
|
-
}
|
|
334
|
-
on(u, F) {
|
|
335
|
-
this.setSubscriber(u, { cb: F });
|
|
336
|
-
}
|
|
337
|
-
once(u, F) {
|
|
338
|
-
this.setSubscriber(u, { cb: F, once: true });
|
|
339
|
-
}
|
|
340
|
-
emit(u, ...F) {
|
|
341
|
-
const e = this._subscribers.get(u) ?? [], s = [];
|
|
342
|
-
for (const i of e)
|
|
343
|
-
i.cb(...F), i.once && s.push(() => e.splice(e.indexOf(i), 1));
|
|
344
|
-
for (const i of s)
|
|
345
|
-
i();
|
|
346
|
-
}
|
|
347
|
-
prompt() {
|
|
348
|
-
return new Promise((u, F) => {
|
|
349
|
-
if (this._abortSignal) {
|
|
350
|
-
if (this._abortSignal.aborted)
|
|
351
|
-
return this.state = "cancel", this.close(), u(S);
|
|
352
|
-
this._abortSignal.addEventListener("abort", () => {
|
|
353
|
-
this.state = "cancel", this.close();
|
|
354
|
-
}, { once: true });
|
|
415
|
+
function downloadToFile(url, dest, timeoutMs = 180000) {
|
|
416
|
+
return new Promise((resolve2, reject) => {
|
|
417
|
+
const controller = new AbortController;
|
|
418
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
419
|
+
fetch(url, { signal: controller.signal, headers: { "User-Agent": USER_AGENT } }).then((res) => {
|
|
420
|
+
if (!res.ok || !res.body) {
|
|
421
|
+
throw new Error(`HTTP ${res.status} ${res.statusText} descargando ${url}`);
|
|
355
422
|
}
|
|
356
|
-
const
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
423
|
+
const file = createWriteStream(dest);
|
|
424
|
+
const fail = (error) => {
|
|
425
|
+
file.destroy();
|
|
426
|
+
try {
|
|
427
|
+
unlinkSync(dest);
|
|
428
|
+
} catch {}
|
|
429
|
+
reject(error);
|
|
430
|
+
};
|
|
431
|
+
file.once("error", fail);
|
|
432
|
+
file.once("finish", resolve2);
|
|
433
|
+
const writable = new WritableStream({
|
|
434
|
+
write(chunk) {
|
|
435
|
+
return new Promise((ok, failWrite) => file.write(Buffer.from(chunk), (err) => err ? failWrite(err) : ok()));
|
|
436
|
+
},
|
|
437
|
+
close() {
|
|
438
|
+
file.end();
|
|
439
|
+
}
|
|
363
440
|
});
|
|
441
|
+
return res.body.pipeTo(writable).catch(fail);
|
|
442
|
+
}).then(() => {
|
|
443
|
+
clearTimeout(timer);
|
|
444
|
+
}).catch((err) => {
|
|
445
|
+
clearTimeout(timer);
|
|
446
|
+
try {
|
|
447
|
+
unlinkSync(dest);
|
|
448
|
+
} catch {}
|
|
449
|
+
reject(err);
|
|
364
450
|
});
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
451
|
+
});
|
|
452
|
+
}
|
|
453
|
+
async function downloadAndExtract(url, destDir, stripComponents = 1, timeoutMs = 180000) {
|
|
454
|
+
const tmp = join(dirname(destDir), `.${basename(destDir)}.download-${Date.now()}`);
|
|
455
|
+
if (!existsSync(tmp))
|
|
456
|
+
mkdirSync(tmp, { recursive: true });
|
|
457
|
+
const archivePath = join(tmp, url.endsWith(".zip") ? "archive.zip" : "archive.tar.gz");
|
|
458
|
+
const extractedDir = join(tmp, "extracted");
|
|
459
|
+
try {
|
|
460
|
+
await downloadToFile(url, archivePath, timeoutMs);
|
|
461
|
+
mkdirSync(extractedDir, { recursive: true });
|
|
462
|
+
const args = url.endsWith(".zip") ? ["-xf", archivePath, "-C", extractedDir] : ["-xzf", archivePath, "-C", extractedDir];
|
|
463
|
+
execFileSync("tar", args, { stdio: "pipe", timeout: 60000 });
|
|
464
|
+
let stagedDir = extractedDir;
|
|
465
|
+
for (let component = 0;component < stripComponents; component++) {
|
|
466
|
+
const entries = readdirSync(stagedDir);
|
|
467
|
+
if (entries.length !== 1) {
|
|
468
|
+
throw new Error(`No se puede remover ${stripComponents} componente(s) del archive: estructura inesperada.`);
|
|
371
469
|
}
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
}
|
|
376
|
-
close() {
|
|
377
|
-
this.input.unpipe(), this.input.removeListener("keypress", this.onKeypress), this.output.write(`
|
|
378
|
-
`), d(this.input, false), this.rl?.close(), this.rl = undefined, this.emit(`${this.state}`, this.value), this.unsubscribe();
|
|
379
|
-
}
|
|
380
|
-
restoreCursor() {
|
|
381
|
-
const u = G(this._prevFrame, process.stdout.columns, { hard: true }).split(`
|
|
382
|
-
`).length - 1;
|
|
383
|
-
this.output.write(import_sisteransi.cursor.move(-999, u * -1));
|
|
384
|
-
}
|
|
385
|
-
render() {
|
|
386
|
-
const u = G(this._render(this) ?? "", process.stdout.columns, { hard: true });
|
|
387
|
-
if (u !== this._prevFrame) {
|
|
388
|
-
if (this.state === "initial")
|
|
389
|
-
this.output.write(import_sisteransi.cursor.hide);
|
|
390
|
-
else {
|
|
391
|
-
const F = lD(this._prevFrame, u);
|
|
392
|
-
if (this.restoreCursor(), F && F?.length === 1) {
|
|
393
|
-
const e = F[0];
|
|
394
|
-
this.output.write(import_sisteransi.cursor.move(0, e)), this.output.write(import_sisteransi.erase.lines(1));
|
|
395
|
-
const s = u.split(`
|
|
396
|
-
`);
|
|
397
|
-
this.output.write(s[e]), this._prevFrame = u, this.output.write(import_sisteransi.cursor.move(0, s.length - e - 1));
|
|
398
|
-
return;
|
|
399
|
-
}
|
|
400
|
-
if (F && F?.length > 1) {
|
|
401
|
-
const e = F[0];
|
|
402
|
-
this.output.write(import_sisteransi.cursor.move(0, e)), this.output.write(import_sisteransi.erase.down());
|
|
403
|
-
const s = u.split(`
|
|
404
|
-
`).slice(e);
|
|
405
|
-
this.output.write(s.join(`
|
|
406
|
-
`)), this._prevFrame = u;
|
|
407
|
-
return;
|
|
408
|
-
}
|
|
409
|
-
this.output.write(import_sisteransi.erase.down());
|
|
470
|
+
const next = join(stagedDir, entries[0]);
|
|
471
|
+
if (!statSync(next).isDirectory()) {
|
|
472
|
+
throw new Error(`No se puede remover ${stripComponents} componente(s) del archive: falta directorio raíz.`);
|
|
410
473
|
}
|
|
411
|
-
|
|
474
|
+
stagedDir = next;
|
|
412
475
|
}
|
|
476
|
+
return promoteStagedDirectory(stagedDir, destDir);
|
|
477
|
+
} finally {
|
|
478
|
+
try {
|
|
479
|
+
rmSync(tmp, { recursive: true, force: true });
|
|
480
|
+
} catch {}
|
|
413
481
|
}
|
|
414
482
|
}
|
|
415
|
-
|
|
416
|
-
return /\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67)\uDB40\uDC7F|(?:\uD83E\uDDD1\uD83C\uDFFF\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFC-\uDFFF])|\uD83D\uDC68(?:\uD83C\uDFFB(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|[\u2695\u2696\u2708]\uFE0F|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))?|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])\uFE0F|\u200D(?:(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D[\uDC66\uDC67])|\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC)?|(?:\uD83D\uDC69(?:\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69]))|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC69(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83E\uDDD1(?:\u200D(?:\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDE36\u200D\uD83C\uDF2B|\uD83C\uDFF3\uFE0F\u200D\u26A7|\uD83D\uDC3B\u200D\u2744|(?:(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\uD83C\uDFF4\u200D\u2620|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])\u200D[\u2640\u2642]|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u2600-\u2604\u260E\u2611\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26B0\u26B1\u26C8\u26CF\u26D1\u26D3\u26E9\u26F0\u26F1\u26F4\u26F7\u26F8\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u3030\u303D\u3297\u3299]|\uD83C[\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]|\uD83D[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3])\uFE0F|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDE35\u200D\uD83D\uDCAB|\uD83D\uDE2E\u200D\uD83D\uDCA8|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83E\uDDD1(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83D\uDC69(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF6\uD83C\uDDE6|\uD83C\uDDF4\uD83C\uDDF2|\uD83D\uDC08\u200D\u2B1B|\u2764\uFE0F\u200D(?:\uD83D\uDD25|\uD83E\uDE79)|\uD83D\uDC41\uFE0F|\uD83C\uDFF3\uFE0F|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|[#\*0-9]\uFE0F\u20E3|\u2764\uFE0F|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|\uD83C\uDFF4|(?:[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270C\u270D]|\uD83D[\uDD74\uDD90])(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC08\uDC15\uDC3B\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE2E\uDE35\uDE36\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5]|\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD]|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF]|[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0D\uDD0E\uDD10-\uDD17\uDD1D\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78\uDD7A-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCB\uDDD0\uDDE0-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6]|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26A7\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5-\uDED7\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])\uFE0F|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDC8F\uDC91\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDD77\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g;
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
D += E, D === F && C < e.length - 1 && (t.push(""), D = 0);
|
|
427
|
-
}
|
|
428
|
-
!D && t[t.length - 1].length > 0 && t.length > 1 && (t[t.length - 2] += t.pop());
|
|
429
|
-
}, nD = (t) => {
|
|
430
|
-
const u = t.split(" ");
|
|
431
|
-
let F = u.length;
|
|
432
|
-
for (;F > 0 && !(A(u[F - 1]) > 0); )
|
|
433
|
-
F--;
|
|
434
|
-
return F === u.length ? t : u.slice(0, F).join(" ") + u.slice(F).join("");
|
|
435
|
-
}, oD = (t, u, F = {}) => {
|
|
436
|
-
if (F.trim !== false && t.trim() === "")
|
|
437
|
-
return "";
|
|
438
|
-
let e = "", s, i;
|
|
439
|
-
const D = ED(t);
|
|
440
|
-
let C = [""];
|
|
441
|
-
for (const [E, a] of t.split(" ").entries()) {
|
|
442
|
-
F.trim !== false && (C[C.length - 1] = C[C.length - 1].trimStart());
|
|
443
|
-
let n = A(C[C.length - 1]);
|
|
444
|
-
if (E !== 0 && (n >= u && (F.wordWrap === false || F.trim === false) && (C.push(""), n = 0), (n > 0 || F.trim === false) && (C[C.length - 1] += " ", n++)), F.hard && D[E] > u) {
|
|
445
|
-
const B = u - n, p = 1 + Math.floor((D[E] - B - 1) / u);
|
|
446
|
-
Math.floor((D[E] - 1) / u) < p && C.push(""), _(C, a, u);
|
|
447
|
-
continue;
|
|
448
|
-
}
|
|
449
|
-
if (n + D[E] > u && n > 0 && D[E] > 0) {
|
|
450
|
-
if (F.wordWrap === false && n < u) {
|
|
451
|
-
_(C, a, u);
|
|
452
|
-
continue;
|
|
483
|
+
async function downloadAndExtractWithRetry(url, destDir, stripComponents = 1, timeoutMs = 180000, maxRetries = 2) {
|
|
484
|
+
let lastError = null;
|
|
485
|
+
for (let attempt = 0;attempt <= maxRetries; attempt++) {
|
|
486
|
+
try {
|
|
487
|
+
return await downloadAndExtract(url, destDir, stripComponents, timeoutMs);
|
|
488
|
+
} catch (err) {
|
|
489
|
+
lastError = err;
|
|
490
|
+
if (attempt < maxRetries && shouldRetryDownload(lastError)) {
|
|
491
|
+
const delay = 1000 * Math.pow(2, attempt);
|
|
492
|
+
console.error(`[download] Intento ${attempt + 1} falló: ${lastError.message}. Reintentando en ${delay}ms...`);
|
|
493
|
+
await new Promise((r2) => setTimeout(r2, delay));
|
|
453
494
|
}
|
|
454
|
-
C.push("");
|
|
455
|
-
}
|
|
456
|
-
if (n + D[E] > u && F.wordWrap === false) {
|
|
457
|
-
_(C, a, u);
|
|
458
|
-
continue;
|
|
459
495
|
}
|
|
460
|
-
C[C.length - 1] += a;
|
|
461
496
|
}
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
497
|
+
throw lastError;
|
|
498
|
+
}
|
|
499
|
+
function findBinaryInDir(dir, name) {
|
|
500
|
+
const entries = readdirSync(dir);
|
|
501
|
+
for (const entry of entries) {
|
|
502
|
+
const full = join(dir, entry);
|
|
503
|
+
const stat = statSync(full);
|
|
504
|
+
if (stat.isDirectory()) {
|
|
505
|
+
const found = findBinaryInDir(full, name);
|
|
506
|
+
if (found)
|
|
507
|
+
return found;
|
|
508
|
+
} else if (getExecutableNames(name).includes(entry)) {
|
|
509
|
+
return full;
|
|
473
510
|
}
|
|
474
|
-
const n = iD.codes.get(Number(s));
|
|
475
|
-
o[E + 1] === `
|
|
476
|
-
` ? (i && (e += z("")), s && n && (e += V(n))) : a === `
|
|
477
|
-
` && (s && n && (e += V(s)), i && (e += z(i)));
|
|
478
511
|
}
|
|
479
|
-
return
|
|
480
|
-
}
|
|
481
|
-
var
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
i = i + this.characterLength(s[D]);
|
|
501
|
-
return i;
|
|
502
|
-
}, u.slice = function(e, s, i) {
|
|
503
|
-
textLen = u.length(e), s = s || 0, i = i || 1, s < 0 && (s = textLen + s), i < 0 && (i = textLen + i);
|
|
504
|
-
for (var D = "", C = 0, o = F(e), E = 0;E < o.length; E++) {
|
|
505
|
-
var a = o[E], n = u.length(a);
|
|
506
|
-
if (C >= s - (n == 2 ? 1 : 0))
|
|
507
|
-
if (C + n <= i)
|
|
508
|
-
D += a;
|
|
509
|
-
else
|
|
510
|
-
break;
|
|
511
|
-
C += n;
|
|
512
|
-
}
|
|
513
|
-
return D;
|
|
514
|
-
};
|
|
515
|
-
})(P);
|
|
516
|
-
X = P.exports;
|
|
517
|
-
DD = O(X);
|
|
518
|
-
FD = O(uD);
|
|
519
|
-
r = { modifier: { reset: [0, 0], bold: [1, 22], dim: [2, 22], italic: [3, 23], underline: [4, 24], overline: [53, 55], inverse: [7, 27], hidden: [8, 28], strikethrough: [9, 29] }, color: { black: [30, 39], red: [31, 39], green: [32, 39], yellow: [33, 39], blue: [34, 39], magenta: [35, 39], cyan: [36, 39], white: [37, 39], blackBright: [90, 39], gray: [90, 39], grey: [90, 39], redBright: [91, 39], greenBright: [92, 39], yellowBright: [93, 39], blueBright: [94, 39], magentaBright: [95, 39], cyanBright: [96, 39], whiteBright: [97, 39] }, bgColor: { bgBlack: [40, 49], bgRed: [41, 49], bgGreen: [42, 49], bgYellow: [43, 49], bgBlue: [44, 49], bgMagenta: [45, 49], bgCyan: [46, 49], bgWhite: [47, 49], bgBlackBright: [100, 49], bgGray: [100, 49], bgGrey: [100, 49], bgRedBright: [101, 49], bgGreenBright: [102, 49], bgYellowBright: [103, 49], bgBlueBright: [104, 49], bgMagentaBright: [105, 49], bgCyanBright: [106, 49], bgWhiteBright: [107, 49] } };
|
|
520
|
-
Object.keys(r.modifier);
|
|
521
|
-
tD = Object.keys(r.color);
|
|
522
|
-
eD = Object.keys(r.bgColor);
|
|
523
|
-
[...tD, ...eD];
|
|
524
|
-
iD = sD();
|
|
525
|
-
v = new Set(["\x1B", ""]);
|
|
526
|
-
y = `${rD}8;;`;
|
|
527
|
-
aD = ["up", "down", "left", "right", "space", "enter", "cancel"];
|
|
528
|
-
c = { actions: new Set(aD), aliases: new Map([["k", "up"], ["j", "down"], ["h", "left"], ["l", "right"], ["\x03", "cancel"], ["escape", "cancel"]]) };
|
|
529
|
-
xD = globalThis.process.platform.startsWith("win");
|
|
530
|
-
S = Symbol("clack:cancel");
|
|
531
|
-
AD = Object.defineProperty;
|
|
532
|
-
fD = class fD extends x {
|
|
533
|
-
get cursor() {
|
|
534
|
-
return this.value ? 0 : 1;
|
|
535
|
-
}
|
|
536
|
-
get _value() {
|
|
537
|
-
return this.cursor === 0;
|
|
538
|
-
}
|
|
539
|
-
constructor(u) {
|
|
540
|
-
super(u, false), this.value = !!u.initialValue, this.on("value", () => {
|
|
541
|
-
this.value = this._value;
|
|
542
|
-
}), this.on("confirm", (F) => {
|
|
543
|
-
this.output.write(import_sisteransi.cursor.move(0, -1)), this.value = F, this.state = "submit", this.close();
|
|
544
|
-
}), this.on("cursor", () => {
|
|
545
|
-
this.value = !this.value;
|
|
546
|
-
});
|
|
547
|
-
}
|
|
548
|
-
};
|
|
549
|
-
gD = Object.defineProperty;
|
|
550
|
-
dD = class extends x {
|
|
551
|
-
constructor(u) {
|
|
552
|
-
super(u, false), K(this, "options"), K(this, "cursor", 0);
|
|
553
|
-
const { options: F } = u;
|
|
554
|
-
this.options = Object.entries(F).flatMap(([e, s]) => [{ value: e, group: true, label: e }, ...s.map((i) => ({ ...i, group: e }))]), this.value = [...u.initialValues ?? []], this.cursor = Math.max(this.options.findIndex(({ value: e }) => e === u.cursorAt), 0), this.on("cursor", (e) => {
|
|
555
|
-
switch (e) {
|
|
556
|
-
case "left":
|
|
557
|
-
case "up":
|
|
558
|
-
this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
|
|
559
|
-
break;
|
|
560
|
-
case "down":
|
|
561
|
-
case "right":
|
|
562
|
-
this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
|
|
563
|
-
break;
|
|
564
|
-
case "space":
|
|
565
|
-
this.toggleValue();
|
|
566
|
-
break;
|
|
567
|
-
}
|
|
568
|
-
});
|
|
569
|
-
}
|
|
570
|
-
getGroupItems(u) {
|
|
571
|
-
return this.options.filter((F) => F.group === u);
|
|
572
|
-
}
|
|
573
|
-
isGroupSelected(u) {
|
|
574
|
-
return this.getGroupItems(u).every((F) => this.value.includes(F.value));
|
|
575
|
-
}
|
|
576
|
-
toggleValue() {
|
|
577
|
-
const u = this.options[this.cursor];
|
|
578
|
-
if (u.group === true) {
|
|
579
|
-
const F = u.value, e = this.getGroupItems(F);
|
|
580
|
-
this.isGroupSelected(F) ? this.value = this.value.filter((s) => e.findIndex((i) => i.value === s) === -1) : this.value = [...this.value, ...e.map((s) => s.value)], this.value = Array.from(new Set(this.value));
|
|
581
|
-
} else {
|
|
582
|
-
const F = this.value.includes(u.value);
|
|
583
|
-
this.value = F ? this.value.filter((e) => e !== u.value) : [...this.value, u.value];
|
|
512
|
+
return null;
|
|
513
|
+
}
|
|
514
|
+
var USER_AGENT = "ostacky-installer";
|
|
515
|
+
var init_fs = __esm(() => {
|
|
516
|
+
init_security();
|
|
517
|
+
});
|
|
518
|
+
|
|
519
|
+
// manifest.json
|
|
520
|
+
var manifest_default;
|
|
521
|
+
var init_manifest = __esm(() => {
|
|
522
|
+
manifest_default = {
|
|
523
|
+
version: "0.6.2",
|
|
524
|
+
repo: "JaimeHoracio/Ostacky",
|
|
525
|
+
tag: "v0.6.2",
|
|
526
|
+
agents: [
|
|
527
|
+
{
|
|
528
|
+
name: "ostacky",
|
|
529
|
+
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",
|
|
531
|
+
version: "0.6.2",
|
|
532
|
+
sha256: "9cd6f45339b897fe002775a3a54f570e47dedd1784fa474d6cd5113594d1bd85"
|
|
584
533
|
}
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
}
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
}
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
534
|
+
],
|
|
535
|
+
commands: [
|
|
536
|
+
{
|
|
537
|
+
name: "install-stack",
|
|
538
|
+
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)",
|
|
540
|
+
version: "0.6.2",
|
|
541
|
+
sha256: "00dd0562f38aaa8d3d255332a21f190a516f82fb3ce00151fc33f2a7e5f8146b"
|
|
542
|
+
},
|
|
543
|
+
{
|
|
544
|
+
name: "opsx-sync",
|
|
545
|
+
file: "assets/commands/opsx-sync.md",
|
|
546
|
+
description: "Sincroniza delta specs del change activo sin inicializar CodeGraph si ya existe índice",
|
|
547
|
+
version: "0.6.2",
|
|
548
|
+
sha256: "fe0158478f2ca63b315037a85fc1632b77868532e319af6c7384285441767d64"
|
|
549
|
+
}
|
|
550
|
+
],
|
|
551
|
+
mcpServers: [
|
|
552
|
+
{
|
|
553
|
+
name: "ostacky-controller",
|
|
554
|
+
file: "assets/mcp/ostacky-controller/",
|
|
555
|
+
description: "Máquina de estados persistida con @modelcontextprotocol/server SDK. 20 tools: start_request → discovery → route → execution → sync → done + validate_edit + complete_task + ping + proceed_to_route + abandon integrado",
|
|
556
|
+
version: "0.6.2",
|
|
557
|
+
sha256: "9ee05fa1dd80de42c1b210d9ba85ef4aa34e5b652e2ed5753519b66eca399776"
|
|
558
|
+
},
|
|
559
|
+
{
|
|
560
|
+
name: "openspec",
|
|
561
|
+
file: "assets/mcp/openspec/",
|
|
562
|
+
description: "MCP server local para OpenSpec - proposal, apply, archive, sync de cambios",
|
|
563
|
+
version: "0.6.2",
|
|
564
|
+
sha256: "fa4be28bfc1e75db8f1a037e2580f04a60066c80e8e5934e90e1041020d04609"
|
|
565
|
+
}
|
|
566
|
+
],
|
|
567
|
+
skills: [
|
|
568
|
+
{
|
|
569
|
+
name: "brainstorming",
|
|
570
|
+
file: "assets/skills/brainstorming/SKILL.md",
|
|
571
|
+
description: "Skill unificado de pensamiento con dos modos: creative-design (producción de diseño → transición a writing-plans o openspec-propose) y open-exploration (exploración libre)",
|
|
572
|
+
version: "0.6.2",
|
|
573
|
+
sha256: "ad474c324aaf78c495dff508268b55274048f272f00501d66eaa3aa5e0483862"
|
|
574
|
+
},
|
|
575
|
+
{
|
|
576
|
+
name: "execution-mode-evaluation",
|
|
577
|
+
file: "assets/skills/execution-mode-evaluation/SKILL.md",
|
|
578
|
+
description: "Skill de análisis de modo de ejecución — output reconciliado con controller snapshot contract (recommendation field)",
|
|
579
|
+
version: "0.6.2",
|
|
580
|
+
sha256: "ae4064dedd3d40ffd3bc7d8d49dab970397555c6f7c1b2c8054e3bda9d4eb73b"
|
|
581
|
+
},
|
|
582
|
+
{
|
|
583
|
+
name: "writing-plans",
|
|
584
|
+
file: "assets/skills/writing-plans/SKILL.md",
|
|
585
|
+
description: "Skill de planificación de implementación (Superpowers) — execution handoff removido, Ostacky decide modo de ejecución",
|
|
586
|
+
version: "0.6.2",
|
|
587
|
+
sha256: "92a3f40dc215cee7b587c2df52ac3a88a129dec0c176059014a5e070ea344c23"
|
|
588
|
+
},
|
|
589
|
+
{
|
|
590
|
+
name: "tdd",
|
|
591
|
+
file: "assets/skills/tdd/SKILL.md",
|
|
592
|
+
description: "Skill de test-driven development (Superpowers)",
|
|
593
|
+
version: "0.6.2",
|
|
594
|
+
sha256: "2932bb3c38b2e41305ec8aa375a7800259eda1bba6bbecfa5b6c4de850b2be43"
|
|
595
|
+
},
|
|
596
|
+
{
|
|
597
|
+
name: "subagent-driven-development",
|
|
598
|
+
file: "assets/skills/subagent-driven-development/SKILL.md",
|
|
599
|
+
description: "Skill de ejecución con subagentes (Superpowers) — ejecuta solo después de confirmación del coordinador Ostacky",
|
|
600
|
+
version: "0.6.2",
|
|
601
|
+
sha256: "cf0f4cc6f5301bfd26784ab91f3b6bb30ed30527fb1658e6caab82ac7cee9ca1"
|
|
602
|
+
},
|
|
603
|
+
{
|
|
604
|
+
name: "dispatching-parallel-agents",
|
|
605
|
+
file: "assets/skills/dispatching-parallel-agents/SKILL.md",
|
|
606
|
+
description: "Skill de dispatch paralelo de agentes (Superpowers)",
|
|
607
|
+
version: "0.6.2",
|
|
608
|
+
sha256: "57e3829cc1217e46e693049eaf910f8fad58c27f6d1ec3e37ab7534993123ab6"
|
|
609
|
+
},
|
|
610
|
+
{
|
|
611
|
+
name: "review",
|
|
612
|
+
file: "assets/skills/review/SKILL.md",
|
|
613
|
+
description: "Skill de revisión de código (Superpowers)",
|
|
614
|
+
version: "0.6.2",
|
|
615
|
+
sha256: "c4a5ecbbaa834ade627a86cebb382c75a9ddab83efedf8f8a3ae1ba24bd7a216"
|
|
616
|
+
},
|
|
617
|
+
{
|
|
618
|
+
name: "receiving-code-review",
|
|
619
|
+
file: "assets/skills/receiving-code-review/SKILL.md",
|
|
620
|
+
description: "Skill de recibir y procesar feedback de code review",
|
|
621
|
+
version: "0.6.2",
|
|
622
|
+
sha256: "8cccf2b6234be4dfbfd426d0ba4b3e26d3ed8f416adaf1d78e8e3b8ef39067df"
|
|
623
|
+
},
|
|
624
|
+
{
|
|
625
|
+
name: "openspec-propose",
|
|
626
|
+
file: "assets/skills/openspec-propose/SKILL.md",
|
|
627
|
+
description: "Skill de generación de proposal (OpenSpec)",
|
|
628
|
+
version: "0.6.2",
|
|
629
|
+
sha256: "f8d38be8e9432d69c43e28c2a2c6ddc860e94e844c79a5b3f78a5c4f8fcf8ce0"
|
|
630
|
+
},
|
|
631
|
+
{
|
|
632
|
+
name: "openspec-apply-change",
|
|
633
|
+
file: "assets/skills/openspec-apply-change/SKILL.md",
|
|
634
|
+
description: "Skill de aplicación de change (OpenSpec)",
|
|
635
|
+
version: "0.6.2",
|
|
636
|
+
sha256: "6c7779ed0dca40d70845dbcbcd5294867cab20eca98c6883a0207c4d10c29518"
|
|
637
|
+
},
|
|
638
|
+
{
|
|
639
|
+
name: "openspec-archive-change",
|
|
640
|
+
file: "assets/skills/openspec-archive-change/SKILL.md",
|
|
641
|
+
description: "Skill de archivo de change (OpenSpec)",
|
|
642
|
+
version: "0.6.2",
|
|
643
|
+
sha256: "0e566b7cd752784a58ef96bec28b0a85c933d72a8c93a5601ca1cd01669a5620"
|
|
644
|
+
},
|
|
645
|
+
{
|
|
646
|
+
name: "openspec-explore",
|
|
647
|
+
file: "assets/skills/openspec-explore/SKILL.md",
|
|
648
|
+
description: "Modo explore para OpenSpec — thinking partner para explorar ideas, investigar problemas y clarificar requisitos antes/durante un cambio",
|
|
649
|
+
version: "0.6.2",
|
|
650
|
+
sha256: "52746b6c51d5ed5026774391d55edac6558f488d68a5b84f9c7064a10e2333bb"
|
|
651
|
+
},
|
|
652
|
+
{
|
|
653
|
+
name: "using-git-worktrees",
|
|
654
|
+
file: "assets/skills/using-git-worktrees/SKILL.md",
|
|
655
|
+
description: "Skill de uso de git worktrees para aislamiento de trabajo",
|
|
656
|
+
version: "0.6.2",
|
|
657
|
+
sha256: "47dfb8b8f35520d3a516c1ac17083eabb0e7458904ef066ce219c48fd0c01037"
|
|
658
|
+
},
|
|
659
|
+
{
|
|
660
|
+
name: "using-superpowers",
|
|
661
|
+
file: "assets/skills/using-superpowers/SKILL.md",
|
|
662
|
+
description: "Skill de orquestación de Superpowers skills",
|
|
663
|
+
version: "0.6.2",
|
|
664
|
+
sha256: "f66cb61561a7fa23df40d9450459f4109ffc2f7a6f07efa74a8c1fcb96f105bd"
|
|
665
|
+
},
|
|
666
|
+
{
|
|
667
|
+
name: "writing-skills",
|
|
668
|
+
file: "assets/skills/writing-skills/SKILL.md",
|
|
669
|
+
description: "Skill de creación y edición de skills",
|
|
670
|
+
version: "0.6.2",
|
|
671
|
+
sha256: "397725e389ce4a80ef6864ec793d1b6f1ae158d1e33db56b8f5ff5167b3938fa"
|
|
672
|
+
},
|
|
673
|
+
{
|
|
674
|
+
name: "graceful-degradation",
|
|
675
|
+
file: "assets/skills/graceful-degradation/SKILL.md",
|
|
676
|
+
description: "Skill de degradación graceful cuando múltiples tools están indisponibles",
|
|
677
|
+
version: "0.6.2",
|
|
678
|
+
sha256: "e32b136c5dfce5b4e7eeddabd3d60866203f700002705ff65ccdec7826f01d71"
|
|
679
|
+
}
|
|
680
|
+
]
|
|
695
681
|
};
|
|
696
682
|
});
|
|
697
683
|
|
|
698
|
-
//
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
tasks: () => xe,
|
|
704
|
-
spinner: () => L2,
|
|
705
|
-
selectKey: () => he,
|
|
706
|
-
select: () => de,
|
|
707
|
-
password: () => $e,
|
|
708
|
-
outro: () => fe,
|
|
709
|
-
note: () => ye,
|
|
710
|
-
multiselect: () => pe,
|
|
711
|
-
log: () => v2,
|
|
712
|
-
isCancel: () => BD,
|
|
713
|
-
intro: () => we,
|
|
714
|
-
groupMultiselect: () => ge,
|
|
715
|
-
group: () => be,
|
|
716
|
-
confirm: () => me,
|
|
717
|
-
cancel: () => ve
|
|
718
|
-
});
|
|
719
|
-
import { stripVTControlCharacters as T2 } from "node:util";
|
|
720
|
-
import p from "node:process";
|
|
721
|
-
function X2() {
|
|
722
|
-
return p.platform !== "win32" ? p.env.TERM !== "linux" : !!p.env.CI || !!p.env.WT_SESSION || !!p.env.TERMINUS_SUBLIME || p.env.ConEmuTask === "{cmd::Cmder}" || p.env.TERM_PROGRAM === "Terminus-Sublime" || p.env.TERM_PROGRAM === "vscode" || p.env.TERM === "xterm-256color" || p.env.TERM === "alacritty" || p.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
|
|
684
|
+
// src/cache.ts
|
|
685
|
+
import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
686
|
+
import { join as join2, dirname as dirname2 } from "path";
|
|
687
|
+
function getCacheRoot(projectRoot) {
|
|
688
|
+
return join2(projectRoot, ".opencode", "cache");
|
|
723
689
|
}
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
n >= l2 + o - 3 ? l2 = Math.max(Math.min(n - o + 3, t.length - o), 0) : n < l2 + 2 && (l2 = Math.max(n - 2, 0));
|
|
740
|
-
const $2 = o < t.length && l2 > 0, d2 = o < t.length && l2 + o < t.length;
|
|
741
|
-
return t.slice(l2, l2 + o).map((w2, b2, C) => {
|
|
742
|
-
const I2 = b2 === 0 && $2, x2 = b2 === C.length - 1 && d2;
|
|
743
|
-
return I2 || x2 ? import_picocolors2.default.dim("...") : i(w2, b2 + l2 === n);
|
|
744
|
-
});
|
|
745
|
-
}, ue = (s) => new PD({ validate: s.validate, placeholder: s.placeholder, defaultValue: s.defaultValue, initialValue: s.initialValue, render() {
|
|
746
|
-
const n = `${import_picocolors2.default.gray(a)}
|
|
747
|
-
${y2(this.state)} ${s.message}
|
|
748
|
-
`, t = s.placeholder ? import_picocolors2.default.inverse(s.placeholder[0]) + import_picocolors2.default.dim(s.placeholder.slice(1)) : import_picocolors2.default.inverse(import_picocolors2.default.hidden("_")), i = this.value ? this.valueWithCursor : t;
|
|
749
|
-
switch (this.state) {
|
|
750
|
-
case "error":
|
|
751
|
-
return `${n.trim()}
|
|
752
|
-
${import_picocolors2.default.yellow(a)} ${i}
|
|
753
|
-
${import_picocolors2.default.yellow(m2)} ${import_picocolors2.default.yellow(this.error)}
|
|
754
|
-
`;
|
|
755
|
-
case "submit":
|
|
756
|
-
return `${n}${import_picocolors2.default.gray(a)} ${import_picocolors2.default.dim(this.value || s.placeholder)}`;
|
|
757
|
-
case "cancel":
|
|
758
|
-
return `${n}${import_picocolors2.default.gray(a)} ${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(this.value ?? ""))}${this.value?.trim() ? `
|
|
759
|
-
${import_picocolors2.default.gray(a)}` : ""}`;
|
|
760
|
-
default:
|
|
761
|
-
return `${n}${import_picocolors2.default.cyan(a)} ${i}
|
|
762
|
-
${import_picocolors2.default.cyan(m2)}
|
|
763
|
-
`;
|
|
764
|
-
}
|
|
765
|
-
} }).prompt(), $e = (s) => new kD({ validate: s.validate, mask: s.mask ?? se, render() {
|
|
766
|
-
const n = `${import_picocolors2.default.gray(a)}
|
|
767
|
-
${y2(this.state)} ${s.message}
|
|
768
|
-
`, t = this.valueWithCursor, i = this.masked;
|
|
769
|
-
switch (this.state) {
|
|
770
|
-
case "error":
|
|
771
|
-
return `${n.trim()}
|
|
772
|
-
${import_picocolors2.default.yellow(a)} ${i}
|
|
773
|
-
${import_picocolors2.default.yellow(m2)} ${import_picocolors2.default.yellow(this.error)}
|
|
774
|
-
`;
|
|
775
|
-
case "submit":
|
|
776
|
-
return `${n}${import_picocolors2.default.gray(a)} ${import_picocolors2.default.dim(i)}`;
|
|
777
|
-
case "cancel":
|
|
778
|
-
return `${n}${import_picocolors2.default.gray(a)} ${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(i ?? ""))}${i ? `
|
|
779
|
-
${import_picocolors2.default.gray(a)}` : ""}`;
|
|
780
|
-
default:
|
|
781
|
-
return `${n}${import_picocolors2.default.cyan(a)} ${t}
|
|
782
|
-
${import_picocolors2.default.cyan(m2)}
|
|
783
|
-
`;
|
|
690
|
+
function cacheKey(projectRoot, repo, tag, filePath) {
|
|
691
|
+
const repoSlug = repo.replace("/", "__");
|
|
692
|
+
return join2(getCacheRoot(projectRoot), repoSlug, tag, filePath);
|
|
693
|
+
}
|
|
694
|
+
function getCached(projectRoot, repo, tag, filePath, expectedHash) {
|
|
695
|
+
const cachePath = cacheKey(projectRoot, repo, tag, filePath);
|
|
696
|
+
if (!existsSync2(cachePath))
|
|
697
|
+
return null;
|
|
698
|
+
try {
|
|
699
|
+
const content = readFileSync2(cachePath, "utf-8");
|
|
700
|
+
if (expectedHash && sha256(content) !== expectedHash)
|
|
701
|
+
return null;
|
|
702
|
+
return content;
|
|
703
|
+
} catch {
|
|
704
|
+
return null;
|
|
784
705
|
}
|
|
785
|
-
}
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
}
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
`;
|
|
821
|
-
switch (this.state) {
|
|
822
|
-
case "submit":
|
|
823
|
-
return `${t}${import_picocolors2.default.gray(a)} ${n(this.options[this.cursor], "selected")}`;
|
|
824
|
-
case "cancel":
|
|
825
|
-
return `${t}${import_picocolors2.default.gray(a)} ${n(this.options[this.cursor], "cancelled")}
|
|
826
|
-
${import_picocolors2.default.gray(a)}`;
|
|
827
|
-
default:
|
|
828
|
-
return `${t}${import_picocolors2.default.cyan(a)} ${k2({ cursor: this.cursor, options: this.options, maxItems: s.maxItems, style: (i, r2) => n(i, r2 ? "active" : "inactive") }).join(`
|
|
829
|
-
${import_picocolors2.default.cyan(a)} `)}
|
|
830
|
-
${import_picocolors2.default.cyan(m2)}
|
|
831
|
-
`;
|
|
832
|
-
}
|
|
833
|
-
} }).prompt();
|
|
834
|
-
}, he = (s) => {
|
|
835
|
-
const n = (t, i = "inactive") => {
|
|
836
|
-
const r2 = t.label ?? String(t.value);
|
|
837
|
-
return i === "selected" ? `${import_picocolors2.default.dim(r2)}` : i === "cancelled" ? `${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(r2))}` : i === "active" ? `${import_picocolors2.default.bgCyan(import_picocolors2.default.gray(` ${t.value} `))} ${r2} ${t.hint ? import_picocolors2.default.dim(`(${t.hint})`) : ""}` : `${import_picocolors2.default.gray(import_picocolors2.default.bgWhite(import_picocolors2.default.inverse(` ${t.value} `)))} ${r2} ${t.hint ? import_picocolors2.default.dim(`(${t.hint})`) : ""}`;
|
|
838
|
-
};
|
|
839
|
-
return new OD({ options: s.options, initialValue: s.initialValue, render() {
|
|
840
|
-
const t = `${import_picocolors2.default.gray(a)}
|
|
841
|
-
${y2(this.state)} ${s.message}
|
|
842
|
-
`;
|
|
843
|
-
switch (this.state) {
|
|
844
|
-
case "submit":
|
|
845
|
-
return `${t}${import_picocolors2.default.gray(a)} ${n(this.options.find((i) => i.value === this.value) ?? s.options[0], "selected")}`;
|
|
846
|
-
case "cancel":
|
|
847
|
-
return `${t}${import_picocolors2.default.gray(a)} ${n(this.options[0], "cancelled")}
|
|
848
|
-
${import_picocolors2.default.gray(a)}`;
|
|
849
|
-
default:
|
|
850
|
-
return `${t}${import_picocolors2.default.cyan(a)} ${this.options.map((i, r2) => n(i, r2 === this.cursor ? "active" : "inactive")).join(`
|
|
851
|
-
${import_picocolors2.default.cyan(a)} `)}
|
|
852
|
-
${import_picocolors2.default.cyan(m2)}
|
|
853
|
-
`;
|
|
854
|
-
}
|
|
855
|
-
} }).prompt();
|
|
856
|
-
}, pe = (s) => {
|
|
857
|
-
const n = (t, i) => {
|
|
858
|
-
const r2 = t.label ?? String(t.value);
|
|
859
|
-
return i === "active" ? `${import_picocolors2.default.cyan(V2)} ${r2} ${t.hint ? import_picocolors2.default.dim(`(${t.hint})`) : ""}` : i === "selected" ? `${import_picocolors2.default.green(M2)} ${import_picocolors2.default.dim(r2)}` : i === "cancelled" ? `${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(r2))}` : i === "active-selected" ? `${import_picocolors2.default.green(M2)} ${r2} ${t.hint ? import_picocolors2.default.dim(`(${t.hint})`) : ""}` : i === "submitted" ? `${import_picocolors2.default.dim(r2)}` : `${import_picocolors2.default.dim(G2)} ${import_picocolors2.default.dim(r2)}`;
|
|
860
|
-
};
|
|
861
|
-
return new wD({ options: s.options, initialValues: s.initialValues, required: s.required ?? true, cursorAt: s.cursorAt, validate(t) {
|
|
862
|
-
if (this.required && t.length === 0)
|
|
863
|
-
return `Please select at least one option.
|
|
864
|
-
${import_picocolors2.default.reset(import_picocolors2.default.dim(`Press ${import_picocolors2.default.gray(import_picocolors2.default.bgWhite(import_picocolors2.default.inverse(" space ")))} to select, ${import_picocolors2.default.gray(import_picocolors2.default.bgWhite(import_picocolors2.default.inverse(" enter ")))} to submit`))}`;
|
|
865
|
-
}, render() {
|
|
866
|
-
const t = `${import_picocolors2.default.gray(a)}
|
|
867
|
-
${y2(this.state)} ${s.message}
|
|
868
|
-
`, i = (r2, c2) => {
|
|
869
|
-
const o = this.value.includes(r2.value);
|
|
870
|
-
return c2 && o ? n(r2, "active-selected") : o ? n(r2, "selected") : n(r2, c2 ? "active" : "inactive");
|
|
871
|
-
};
|
|
872
|
-
switch (this.state) {
|
|
873
|
-
case "submit":
|
|
874
|
-
return `${t}${import_picocolors2.default.gray(a)} ${this.options.filter(({ value: r2 }) => this.value.includes(r2)).map((r2) => n(r2, "submitted")).join(import_picocolors2.default.dim(", ")) || import_picocolors2.default.dim("none")}`;
|
|
875
|
-
case "cancel": {
|
|
876
|
-
const r2 = this.options.filter(({ value: c2 }) => this.value.includes(c2)).map((c2) => n(c2, "cancelled")).join(import_picocolors2.default.dim(", "));
|
|
877
|
-
return `${t}${import_picocolors2.default.gray(a)} ${r2.trim() ? `${r2}
|
|
878
|
-
${import_picocolors2.default.gray(a)}` : ""}`;
|
|
879
|
-
}
|
|
880
|
-
case "error": {
|
|
881
|
-
const r2 = this.error.split(`
|
|
882
|
-
`).map((c2, o) => o === 0 ? `${import_picocolors2.default.yellow(m2)} ${import_picocolors2.default.yellow(c2)}` : ` ${c2}`).join(`
|
|
883
|
-
`);
|
|
884
|
-
return `${t + import_picocolors2.default.yellow(a)} ${k2({ options: this.options, cursor: this.cursor, maxItems: s.maxItems, style: i }).join(`
|
|
885
|
-
${import_picocolors2.default.yellow(a)} `)}
|
|
886
|
-
${r2}
|
|
887
|
-
`;
|
|
888
|
-
}
|
|
889
|
-
default:
|
|
890
|
-
return `${t}${import_picocolors2.default.cyan(a)} ${k2({ options: this.options, cursor: this.cursor, maxItems: s.maxItems, style: i }).join(`
|
|
891
|
-
${import_picocolors2.default.cyan(a)} `)}
|
|
892
|
-
${import_picocolors2.default.cyan(m2)}
|
|
893
|
-
`;
|
|
706
|
+
}
|
|
707
|
+
function putCache(projectRoot, repo, tag, filePath, content) {
|
|
708
|
+
const cachePath = cacheKey(projectRoot, repo, tag, filePath);
|
|
709
|
+
const dir = dirname2(cachePath);
|
|
710
|
+
if (!existsSync2(dir))
|
|
711
|
+
mkdirSync2(dir, { recursive: true });
|
|
712
|
+
writeFileSync2(cachePath, content, "utf-8");
|
|
713
|
+
}
|
|
714
|
+
var init_cache = __esm(() => {
|
|
715
|
+
init_security();
|
|
716
|
+
});
|
|
717
|
+
|
|
718
|
+
// src/github.ts
|
|
719
|
+
import { fileURLToPath } from "url";
|
|
720
|
+
import { dirname as dirname3, join as join3 } from "path";
|
|
721
|
+
function getBundledSkillPath(name) {
|
|
722
|
+
validateFilePath(name);
|
|
723
|
+
return join3(BUNDLED_SKILLS_DIR, name);
|
|
724
|
+
}
|
|
725
|
+
function getBundledMcpPath(name) {
|
|
726
|
+
validateFilePath(name);
|
|
727
|
+
return join3(BUNDLED_MCP_DIR, name);
|
|
728
|
+
}
|
|
729
|
+
function getRawUrl(repo, tag, path) {
|
|
730
|
+
return `${GITHUB_RAW}/${repo}/${tag}/${path}`;
|
|
731
|
+
}
|
|
732
|
+
async function fetchLatestReleaseTag(repo) {
|
|
733
|
+
try {
|
|
734
|
+
const res = await fetch(`https://api.github.com/repos/${repo}/releases/latest`, {
|
|
735
|
+
signal: AbortSignal.timeout(5000),
|
|
736
|
+
headers: { "User-Agent": USER_AGENT }
|
|
737
|
+
});
|
|
738
|
+
if (res.ok) {
|
|
739
|
+
const data = await res.json();
|
|
740
|
+
return data.tag_name ?? null;
|
|
894
741
|
}
|
|
895
|
-
} }
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
`).map((r2, c2) => c2 === 0 ? `${import_picocolors2.default.yellow(m2)} ${import_picocolors2.default.yellow(r2)}` : ` ${r2}`).join(`
|
|
920
|
-
`);
|
|
921
|
-
return `${t}${import_picocolors2.default.yellow(a)} ${this.options.map((r2, c2, o) => {
|
|
922
|
-
const l2 = this.value.includes(r2.value) || r2.group === true && this.isGroupSelected(`${r2.value}`), $2 = c2 === this.cursor;
|
|
923
|
-
return !$2 && typeof r2.group == "string" && this.options[this.cursor].value === r2.group ? n(r2, l2 ? "group-active-selected" : "group-active", o) : $2 && l2 ? n(r2, "active-selected", o) : l2 ? n(r2, "selected", o) : n(r2, $2 ? "active" : "inactive", o);
|
|
924
|
-
}).join(`
|
|
925
|
-
${import_picocolors2.default.yellow(a)} `)}
|
|
926
|
-
${i}
|
|
927
|
-
`;
|
|
928
|
-
}
|
|
929
|
-
default:
|
|
930
|
-
return `${t}${import_picocolors2.default.cyan(a)} ${this.options.map((i, r2, c2) => {
|
|
931
|
-
const o = this.value.includes(i.value) || i.group === true && this.isGroupSelected(`${i.value}`), l2 = r2 === this.cursor;
|
|
932
|
-
return !l2 && typeof i.group == "string" && this.options[this.cursor].value === i.group ? n(i, o ? "group-active-selected" : "group-active", c2) : l2 && o ? n(i, "active-selected", c2) : o ? n(i, "selected", c2) : n(i, l2 ? "active" : "inactive", c2);
|
|
933
|
-
}).join(`
|
|
934
|
-
${import_picocolors2.default.cyan(a)} `)}
|
|
935
|
-
${import_picocolors2.default.cyan(m2)}
|
|
936
|
-
`;
|
|
742
|
+
} catch {}
|
|
743
|
+
try {
|
|
744
|
+
const res = await fetch(`https://github.com/${repo}/releases/latest`, {
|
|
745
|
+
redirect: "manual",
|
|
746
|
+
signal: AbortSignal.timeout(5000),
|
|
747
|
+
headers: { "User-Agent": USER_AGENT }
|
|
748
|
+
});
|
|
749
|
+
const loc = res.headers.get("location") ?? "";
|
|
750
|
+
const m3 = loc.match(/releases\/tag\/(v[^/]+)$/);
|
|
751
|
+
if (m3)
|
|
752
|
+
return m3[1];
|
|
753
|
+
} catch {}
|
|
754
|
+
return null;
|
|
755
|
+
}
|
|
756
|
+
async function fetchManifest(tag) {
|
|
757
|
+
const resolvedTag = tag ?? manifest_default.tag;
|
|
758
|
+
try {
|
|
759
|
+
const url = getRawUrl(manifest_default.repo, resolvedTag, "manifest.json");
|
|
760
|
+
const response = await fetch(url, {
|
|
761
|
+
signal: AbortSignal.timeout(5000),
|
|
762
|
+
headers: { "User-Agent": USER_AGENT }
|
|
763
|
+
});
|
|
764
|
+
if (response.ok) {
|
|
765
|
+
return await response.json();
|
|
937
766
|
}
|
|
938
|
-
} }
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
767
|
+
} catch {}
|
|
768
|
+
return manifest_default;
|
|
769
|
+
}
|
|
770
|
+
async function fetchLatestManifest() {
|
|
771
|
+
const latestTag = await fetchLatestReleaseTag(manifest_default.repo);
|
|
772
|
+
const currentTag = manifest_default.tag;
|
|
773
|
+
const isNew = latestTag !== null && latestTag !== currentTag;
|
|
774
|
+
const manifest = await fetchManifest(latestTag ?? currentTag);
|
|
775
|
+
return { manifest, isNew, latestTag };
|
|
776
|
+
}
|
|
777
|
+
async function downloadFile(manifest, filePath) {
|
|
778
|
+
validateFilePath(filePath);
|
|
779
|
+
const item = [
|
|
780
|
+
...manifest.agents,
|
|
781
|
+
...manifest.commands,
|
|
782
|
+
...manifest.skills ?? [],
|
|
783
|
+
...manifest.mcpServers ?? []
|
|
784
|
+
].find((i) => i.file === filePath);
|
|
785
|
+
const expectedHash = item?.sha256 ?? null;
|
|
786
|
+
const projectRoot = findProjectRoot();
|
|
787
|
+
const cached = getCached(projectRoot, manifest.repo, manifest.tag, filePath, expectedHash);
|
|
788
|
+
if (cached !== null)
|
|
789
|
+
return cached;
|
|
790
|
+
const url = getRawUrl(manifest.repo, manifest.tag, filePath);
|
|
791
|
+
const response = await fetch(url, {
|
|
792
|
+
headers: { "User-Agent": USER_AGENT },
|
|
793
|
+
signal: AbortSignal.timeout(30000)
|
|
794
|
+
});
|
|
795
|
+
if (!response.ok) {
|
|
796
|
+
throw new Error(`Error descargando ${url}: ${response.status} ${response.statusText}`);
|
|
797
|
+
}
|
|
798
|
+
const content = await response.text();
|
|
799
|
+
verifyChecksum(content, expectedHash, filePath);
|
|
800
|
+
putCache(projectRoot, manifest.repo, manifest.tag, filePath, content);
|
|
801
|
+
return content;
|
|
802
|
+
}
|
|
803
|
+
var GITHUB_RAW = "https://raw.githubusercontent.com", __filename2, __dirname2, PACKAGE_ROOT, BUNDLED_SKILLS_DIR, BUNDLED_MCP_DIR;
|
|
804
|
+
var init_github = __esm(() => {
|
|
805
|
+
init_manifest();
|
|
806
|
+
init_cache();
|
|
807
|
+
init_security();
|
|
808
|
+
init_fs();
|
|
809
|
+
__filename2 = fileURLToPath(import.meta.url);
|
|
810
|
+
__dirname2 = dirname3(__filename2);
|
|
811
|
+
PACKAGE_ROOT = join3(__dirname2, "..");
|
|
812
|
+
BUNDLED_SKILLS_DIR = join3(PACKAGE_ROOT, "assets", "skills");
|
|
813
|
+
BUNDLED_MCP_DIR = join3(PACKAGE_ROOT, "assets", "mcp");
|
|
814
|
+
});
|
|
963
815
|
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
816
|
+
// src/lockfile.ts
|
|
817
|
+
var exports_lockfile = {};
|
|
818
|
+
__export(exports_lockfile, {
|
|
819
|
+
writeLockfile: () => writeLockfile,
|
|
820
|
+
removeFromLockfile: () => removeFromLockfile,
|
|
821
|
+
readLockfile: () => readLockfile,
|
|
822
|
+
getLockfilePath: () => getLockfilePath,
|
|
823
|
+
getInstalledVersion: () => getInstalledVersion,
|
|
824
|
+
clearLockfile: () => clearLockfile
|
|
825
|
+
});
|
|
826
|
+
import { existsSync as existsSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
827
|
+
import { join as join4 } from "path";
|
|
828
|
+
function getLockfilePath(opencodeRoot) {
|
|
829
|
+
return join4(opencodeRoot, LOCKFILE_NAME);
|
|
830
|
+
}
|
|
831
|
+
function readLockfile(opencodeRoot) {
|
|
832
|
+
const lockPath = getLockfilePath(opencodeRoot);
|
|
833
|
+
if (!existsSync3(lockPath))
|
|
834
|
+
return null;
|
|
835
|
+
try {
|
|
836
|
+
return JSON.parse(readFileSync3(lockPath, "utf-8"));
|
|
837
|
+
} catch {
|
|
838
|
+
return null;
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
function writeLockfile(opencodeRoot, lockfile) {
|
|
842
|
+
writeFileSync3(getLockfilePath(opencodeRoot), JSON.stringify(lockfile, null, 2), "utf-8");
|
|
843
|
+
}
|
|
844
|
+
function getInstalledVersion(lockfile, type, name) {
|
|
845
|
+
return lockfile?.[type]?.[name]?.version ?? null;
|
|
846
|
+
}
|
|
847
|
+
function removeFromLockfile(opencodeRoot, type, name) {
|
|
848
|
+
const lockfile = readLockfile(opencodeRoot);
|
|
849
|
+
if (!lockfile)
|
|
850
|
+
return;
|
|
851
|
+
if (!lockfile[type])
|
|
852
|
+
return;
|
|
853
|
+
if (!(name in lockfile[type]))
|
|
854
|
+
return;
|
|
855
|
+
delete lockfile[type][name];
|
|
856
|
+
writeLockfile(opencodeRoot, lockfile);
|
|
857
|
+
}
|
|
858
|
+
function clearLockfile(opencodeRoot) {
|
|
859
|
+
const lockfile = readLockfile(opencodeRoot);
|
|
860
|
+
if (!lockfile) {
|
|
861
|
+
writeLockfile(opencodeRoot, {
|
|
862
|
+
version: LOCKFILE_VERSION,
|
|
863
|
+
lockedAt: new Date().toISOString(),
|
|
864
|
+
repo: "",
|
|
865
|
+
tag: "",
|
|
866
|
+
agents: {},
|
|
867
|
+
commands: {},
|
|
868
|
+
skills: {},
|
|
869
|
+
mcpServers: {}
|
|
1008
870
|
});
|
|
1009
|
-
|
|
1010
|
-
|
|
871
|
+
return;
|
|
872
|
+
}
|
|
873
|
+
lockfile.agents = {};
|
|
874
|
+
lockfile.commands = {};
|
|
875
|
+
lockfile.skills = {};
|
|
876
|
+
lockfile.mcpServers = {};
|
|
877
|
+
lockfile.lockedAt = new Date().toISOString();
|
|
878
|
+
writeLockfile(opencodeRoot, lockfile);
|
|
879
|
+
}
|
|
880
|
+
var LOCKFILE_NAME = "ostacky-lock.json", LOCKFILE_VERSION;
|
|
881
|
+
var init_lockfile = __esm(() => {
|
|
882
|
+
init_manifest();
|
|
883
|
+
LOCKFILE_VERSION = manifest_default.version;
|
|
884
|
+
});
|
|
885
|
+
|
|
886
|
+
// src/config.ts
|
|
887
|
+
var exports_config = {};
|
|
888
|
+
__export(exports_config, {
|
|
889
|
+
writeOpenCodeConfig: () => writeOpenCodeConfig,
|
|
890
|
+
stripJsoncComments: () => stripJsoncComments,
|
|
891
|
+
setMcpEntryAtProjectRoot: () => setMcpEntryAtProjectRoot,
|
|
892
|
+
setMcpEntry: () => setMcpEntry,
|
|
893
|
+
readOpenCodeConfig: () => readOpenCodeConfig,
|
|
894
|
+
patchOpenCodeConfig: () => patchOpenCodeConfig,
|
|
895
|
+
findOpenCodeConfig: () => findOpenCodeConfig,
|
|
896
|
+
ensureOpenCodeConfig: () => ensureOpenCodeConfig,
|
|
897
|
+
ensureMcpEntryAtProjectRoot: () => ensureMcpEntryAtProjectRoot,
|
|
898
|
+
ensureMcpEntry: () => ensureMcpEntry
|
|
899
|
+
});
|
|
900
|
+
import { existsSync as existsSync4, readFileSync as readFileSync4, renameSync as renameSync2, rmSync as rmSync2, writeFileSync as writeFileSync4 } from "fs";
|
|
901
|
+
import { join as join5 } from "path";
|
|
902
|
+
function stripJsoncComments(text) {
|
|
903
|
+
let result = "";
|
|
904
|
+
let i = 0;
|
|
905
|
+
let inString = false;
|
|
906
|
+
while (i < text.length) {
|
|
907
|
+
const char = text[i];
|
|
908
|
+
const next = text[i + 1];
|
|
909
|
+
if (inString) {
|
|
910
|
+
if (char === "\\") {
|
|
911
|
+
result += char + (next ?? "");
|
|
912
|
+
i += 2;
|
|
913
|
+
continue;
|
|
914
|
+
}
|
|
915
|
+
if (char === '"')
|
|
916
|
+
inString = false;
|
|
917
|
+
result += char;
|
|
918
|
+
i++;
|
|
1011
919
|
continue;
|
|
1012
920
|
}
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
for (const n of s) {
|
|
1018
|
-
if (n.enabled === false)
|
|
921
|
+
if (char === '"') {
|
|
922
|
+
inString = true;
|
|
923
|
+
result += char;
|
|
924
|
+
i++;
|
|
1019
925
|
continue;
|
|
1020
|
-
const t = L2();
|
|
1021
|
-
t.start(n.title);
|
|
1022
|
-
const i = await n.task(t.message);
|
|
1023
|
-
t.stop(i || n.title);
|
|
1024
|
-
}
|
|
1025
|
-
};
|
|
1026
|
-
var init_dist2 = __esm(() => {
|
|
1027
|
-
init_dist();
|
|
1028
|
-
init_dist();
|
|
1029
|
-
import_picocolors2 = __toESM(require_picocolors(), 1);
|
|
1030
|
-
import_sisteransi2 = __toESM(require_src(), 1);
|
|
1031
|
-
E = X2();
|
|
1032
|
-
ee = u("◆", "*");
|
|
1033
|
-
A2 = u("■", "x");
|
|
1034
|
-
B = u("▲", "x");
|
|
1035
|
-
S2 = u("◇", "o");
|
|
1036
|
-
te = u("┌", "T");
|
|
1037
|
-
a = u("│", "|");
|
|
1038
|
-
m2 = u("└", "—");
|
|
1039
|
-
j2 = u("●", ">");
|
|
1040
|
-
R2 = u("○", " ");
|
|
1041
|
-
V2 = u("◻", "[•]");
|
|
1042
|
-
M2 = u("◼", "[+]");
|
|
1043
|
-
G2 = u("◻", "[ ]");
|
|
1044
|
-
se = u("▪", "•");
|
|
1045
|
-
N2 = u("─", "-");
|
|
1046
|
-
re = u("╮", "+");
|
|
1047
|
-
ie = u("├", "+");
|
|
1048
|
-
ne = u("╯", "+");
|
|
1049
|
-
ae = u("●", "•");
|
|
1050
|
-
oe = u("◆", "*");
|
|
1051
|
-
ce = u("▲", "!");
|
|
1052
|
-
le = u("■", "x");
|
|
1053
|
-
v2 = { message: (s = "", { symbol: n = import_picocolors2.default.gray(a) } = {}) => {
|
|
1054
|
-
const t = [`${import_picocolors2.default.gray(a)}`];
|
|
1055
|
-
if (s) {
|
|
1056
|
-
const [i, ...r2] = s.split(`
|
|
1057
|
-
`);
|
|
1058
|
-
t.push(`${n} ${i}`, ...r2.map((c2) => `${import_picocolors2.default.gray(a)} ${c2}`));
|
|
1059
926
|
}
|
|
1060
|
-
|
|
1061
|
-
`
|
|
1062
|
-
`)
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
}
|
|
927
|
+
if (char === "/" && next === "/") {
|
|
928
|
+
while (i < text.length && text[i] !== `
|
|
929
|
+
`)
|
|
930
|
+
i++;
|
|
931
|
+
continue;
|
|
932
|
+
}
|
|
933
|
+
if (char === "/" && next === "*") {
|
|
934
|
+
i += 2;
|
|
935
|
+
while (i < text.length && !(text[i] === "*" && text[i + 1] === "/"))
|
|
936
|
+
i++;
|
|
937
|
+
i += 2;
|
|
938
|
+
continue;
|
|
939
|
+
}
|
|
940
|
+
result += char;
|
|
941
|
+
i++;
|
|
942
|
+
}
|
|
943
|
+
return result.replace(/,\s*([}\]])/g, "$1");
|
|
944
|
+
}
|
|
945
|
+
function readOpenCodeConfig(configPath) {
|
|
946
|
+
const raw = readFileSync4(configPath, "utf-8");
|
|
947
|
+
try {
|
|
948
|
+
return JSON.parse(stripJsoncComments(raw));
|
|
949
|
+
} catch {
|
|
950
|
+
return null;
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
function writeOpenCodeConfig(configPath, config) {
|
|
954
|
+
const tmpPath = `${configPath}.tmp.${process.pid}.${Date.now()}`;
|
|
955
|
+
try {
|
|
956
|
+
writeFileSync4(tmpPath, JSON.stringify(config, null, 2) + `
|
|
957
|
+
`, "utf-8");
|
|
958
|
+
renameSync2(tmpPath, configPath);
|
|
959
|
+
} finally {
|
|
960
|
+
if (existsSync4(tmpPath))
|
|
961
|
+
rmSync2(tmpPath, { force: true });
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
function ensureOpenCodeConfig(projectRoot) {
|
|
965
|
+
const existing = findOpenCodeConfig(projectRoot);
|
|
966
|
+
if (existing)
|
|
967
|
+
return existing;
|
|
968
|
+
const configPath = join5(projectRoot, "opencode.json");
|
|
969
|
+
writeOpenCodeConfig(configPath, {
|
|
970
|
+
$schema: "https://opencode.ai/config.json",
|
|
971
|
+
mcp: {}
|
|
972
|
+
});
|
|
973
|
+
return configPath;
|
|
974
|
+
}
|
|
975
|
+
function findOpenCodeConfig(projectRoot) {
|
|
976
|
+
const candidates = ["opencode.json", "opencode.jsonc"];
|
|
977
|
+
for (const name of candidates) {
|
|
978
|
+
const full = join5(projectRoot, name);
|
|
979
|
+
if (existsSync4(full))
|
|
980
|
+
return full;
|
|
981
|
+
}
|
|
982
|
+
return null;
|
|
983
|
+
}
|
|
984
|
+
function setMcpEntry(name, entry) {
|
|
985
|
+
setMcpEntryAtProjectRoot(findProjectRoot(), name, entry);
|
|
986
|
+
}
|
|
987
|
+
function setMcpEntryAtProjectRoot(projectRoot, name, entry) {
|
|
988
|
+
const configPath = ensureOpenCodeConfig(projectRoot);
|
|
989
|
+
const config = readOpenCodeConfig(configPath);
|
|
990
|
+
if (!config)
|
|
991
|
+
throw new Error(`Error parseando ${configPath}`);
|
|
992
|
+
if (!config.mcp)
|
|
993
|
+
config.mcp = {};
|
|
994
|
+
config.mcp[name] = entry;
|
|
995
|
+
writeOpenCodeConfig(configPath, config);
|
|
996
|
+
}
|
|
997
|
+
function ensureMcpEntry(name, entry) {
|
|
998
|
+
ensureMcpEntryAtProjectRoot(findProjectRoot(), name, entry);
|
|
999
|
+
}
|
|
1000
|
+
function ensureMcpEntryAtProjectRoot(projectRoot, name, entry) {
|
|
1001
|
+
const configPath = ensureOpenCodeConfig(projectRoot);
|
|
1002
|
+
const config = readOpenCodeConfig(configPath);
|
|
1003
|
+
if (!config)
|
|
1004
|
+
throw new Error(`Error parseando ${configPath}`);
|
|
1005
|
+
if (!config.mcp)
|
|
1006
|
+
config.mcp = {};
|
|
1007
|
+
const mcp = config.mcp;
|
|
1008
|
+
if (!mcp[name]) {
|
|
1009
|
+
mcp[name] = entry;
|
|
1010
|
+
writeOpenCodeConfig(configPath, config);
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
function patchOpenCodeConfig(projectRoot = findProjectRoot()) {
|
|
1014
|
+
const configPath = findOpenCodeConfig(projectRoot);
|
|
1015
|
+
if (!configPath) {
|
|
1016
|
+
return {
|
|
1017
|
+
success: false,
|
|
1018
|
+
message: "No se encontró opencode.json ni opencode.jsonc"
|
|
1019
|
+
};
|
|
1020
|
+
}
|
|
1021
|
+
const config = readOpenCodeConfig(configPath);
|
|
1022
|
+
if (!config) {
|
|
1023
|
+
return {
|
|
1024
|
+
success: false,
|
|
1025
|
+
message: `Error parseando ${configPath}`
|
|
1026
|
+
};
|
|
1027
|
+
}
|
|
1028
|
+
let changed = false;
|
|
1029
|
+
if ("plugin" in config) {
|
|
1030
|
+
delete config.plugin;
|
|
1031
|
+
changed = true;
|
|
1032
|
+
}
|
|
1033
|
+
if (changed) {
|
|
1034
|
+
writeOpenCodeConfig(configPath, config);
|
|
1035
|
+
return { success: true, message: "Config actualizada (plugin legacy eliminado)" };
|
|
1036
|
+
}
|
|
1037
|
+
return { success: true, message: "Config de OpenCode ya está limpia" };
|
|
1038
|
+
}
|
|
1039
|
+
var init_config = __esm(() => {
|
|
1040
|
+
init_fs();
|
|
1076
1041
|
});
|
|
1077
1042
|
|
|
1078
|
-
// src/
|
|
1079
|
-
var
|
|
1080
|
-
__export(
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1043
|
+
// src/stack.ts
|
|
1044
|
+
var exports_stack = {};
|
|
1045
|
+
__export(exports_stack, {
|
|
1046
|
+
verifyMcpServers: () => verifyMcpServers,
|
|
1047
|
+
uninstallStackConfig: () => uninstallStackConfig,
|
|
1048
|
+
uninstallEngramConfig: () => uninstallEngramConfig,
|
|
1049
|
+
setupOpenSpec: () => setupOpenSpec,
|
|
1050
|
+
setupContext7: () => setupContext7,
|
|
1051
|
+
installStack: () => installStack,
|
|
1052
|
+
installEngram: () => installEngram,
|
|
1053
|
+
installCodeGraph: () => installCodeGraph,
|
|
1054
|
+
buildLocalMcpCommand: () => buildLocalMcpCommand,
|
|
1055
|
+
buildEngramDownloadUrl: () => buildEngramDownloadUrl
|
|
1084
1056
|
});
|
|
1085
|
-
import {
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1057
|
+
import { chmodSync, copyFileSync as copyFileSync3, existsSync as existsSync6, mkdirSync as mkdirSync4, rmSync as rmSync4, unlinkSync as unlinkSync3 } from "fs";
|
|
1058
|
+
import { basename as basename2, dirname as dirname5, join as join7, resolve as resolve2 } from "path";
|
|
1059
|
+
import { execFileSync as execFileSync3 } from "child_process";
|
|
1060
|
+
function resolveToolInstallLocation(toolsDir) {
|
|
1061
|
+
const resolvedToolsDir = resolve2(toolsDir ?? join7(findProjectRoot(), ".opencode", "tools"));
|
|
1062
|
+
const possibleOpenCodeDir = dirname5(resolvedToolsDir);
|
|
1063
|
+
return {
|
|
1064
|
+
projectRoot: basename2(possibleOpenCodeDir) === ".opencode" ? dirname5(possibleOpenCodeDir) : findProjectRoot(),
|
|
1065
|
+
toolsDir: resolvedToolsDir
|
|
1066
|
+
};
|
|
1090
1067
|
}
|
|
1091
|
-
function
|
|
1092
|
-
|
|
1068
|
+
function runTool(binary, args, cwd, timeout = 30000) {
|
|
1069
|
+
const invocation = getCommandInvocation(binary, args);
|
|
1070
|
+
execFileSync3(invocation.command, invocation.args, {
|
|
1071
|
+
cwd,
|
|
1072
|
+
stdio: "pipe",
|
|
1073
|
+
timeout
|
|
1074
|
+
});
|
|
1093
1075
|
}
|
|
1094
|
-
function
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
esperado: ${expectedHash}
|
|
1101
|
-
recibido: ${actual}`);
|
|
1076
|
+
function findToolBinary(toolDir, name) {
|
|
1077
|
+
const binDir = join7(toolDir, "bin");
|
|
1078
|
+
for (const executable of getExecutableNames(name)) {
|
|
1079
|
+
const candidate = join7(binDir, executable);
|
|
1080
|
+
if (existsSync6(candidate))
|
|
1081
|
+
return candidate;
|
|
1102
1082
|
}
|
|
1083
|
+
return findBinaryInDir(toolDir, name);
|
|
1103
1084
|
}
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
import { execSync } from "child_process";
|
|
1121
|
-
function findOpenCodeDir(startDir = process.cwd()) {
|
|
1122
|
-
let current = resolve(startDir);
|
|
1123
|
-
while (true) {
|
|
1124
|
-
const opencodeDir = join(current, ".opencode");
|
|
1125
|
-
if (existsSync(opencodeDir))
|
|
1126
|
-
return opencodeDir;
|
|
1127
|
-
if (existsSync(join(current, ".git")))
|
|
1128
|
-
return null;
|
|
1129
|
-
const parent = dirname(current);
|
|
1130
|
-
if (parent === current)
|
|
1131
|
-
return null;
|
|
1132
|
-
current = parent;
|
|
1085
|
+
function configureLocalTool(projectRoot, name, command) {
|
|
1086
|
+
setMcpEntryAtProjectRoot(projectRoot, name, {
|
|
1087
|
+
type: "local",
|
|
1088
|
+
command,
|
|
1089
|
+
enabled: true
|
|
1090
|
+
});
|
|
1091
|
+
}
|
|
1092
|
+
function buildLocalMcpCommand(executable, args, platform = process.platform) {
|
|
1093
|
+
const invocation = getCommandInvocation(executable, args, platform);
|
|
1094
|
+
return [invocation.command, ...invocation.args];
|
|
1095
|
+
}
|
|
1096
|
+
function copyEngramPlugin(projectRoot) {
|
|
1097
|
+
const pluginSource = join7(PACKAGE_ROOT, "assets", "plugins", "engram.ts");
|
|
1098
|
+
const pluginsDir = join7(projectRoot, ".opencode", "plugins");
|
|
1099
|
+
if (!existsSync6(pluginSource)) {
|
|
1100
|
+
throw new Error(`Plugin bundleado de Engram no encontrado: ${pluginSource}`);
|
|
1133
1101
|
}
|
|
1102
|
+
mkdirSync4(pluginsDir, { recursive: true });
|
|
1103
|
+
copyFileSync3(pluginSource, join7(pluginsDir, "engram.ts"));
|
|
1134
1104
|
}
|
|
1135
|
-
function
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1105
|
+
function buildEngramDownloadUrl(tag, platform = process.platform, arch = process.arch) {
|
|
1106
|
+
const target = getEngramReleaseTarget(platform, arch);
|
|
1107
|
+
if (!target)
|
|
1108
|
+
return null;
|
|
1109
|
+
const extension = platform === "win32" ? "zip" : "tar.gz";
|
|
1110
|
+
return `https://github.com/Gentleman-Programming/engram/releases/download/${tag}/engram_${tag.replace(/^v/, "")}_${target.replace("-", "_")}.${extension}`;
|
|
1111
|
+
}
|
|
1112
|
+
async function installCodeGraph(toolsDir) {
|
|
1113
|
+
const location = resolveToolInstallLocation(toolsDir);
|
|
1114
|
+
const { projectRoot } = location;
|
|
1115
|
+
const cgToolDir = join7(location.toolsDir, "codegraph");
|
|
1116
|
+
if (!existsSync6(cgToolDir))
|
|
1117
|
+
mkdirSync4(cgToolDir, { recursive: true });
|
|
1118
|
+
const target = detectPlatformTarget();
|
|
1119
|
+
if (!target) {
|
|
1120
|
+
return {
|
|
1121
|
+
success: false,
|
|
1122
|
+
message: `Plataforma no soportada para descarga local: ${process.platform}/${process.arch}. Instalá CodeGraph manualmente.`
|
|
1123
|
+
};
|
|
1124
|
+
}
|
|
1125
|
+
let localBin = findToolBinary(cgToolDir, "codegraph");
|
|
1126
|
+
let archivePromotion = null;
|
|
1127
|
+
const failAfterExtraction = (message) => {
|
|
1128
|
+
try {
|
|
1129
|
+
archivePromotion?.rollback();
|
|
1130
|
+
} catch {}
|
|
1131
|
+
return { success: false, message };
|
|
1132
|
+
};
|
|
1133
|
+
if (localBin) {
|
|
1134
|
+
try {
|
|
1135
|
+
runTool(localBin, ["--version"], projectRoot, 1e4);
|
|
1136
|
+
} catch {
|
|
1137
|
+
try {
|
|
1138
|
+
rmSync4(cgToolDir, { recursive: true, force: true });
|
|
1139
|
+
} catch {}
|
|
1140
|
+
localBin = null;
|
|
1141
|
+
}
|
|
1142
|
+
}
|
|
1143
|
+
if (!localBin) {
|
|
1144
|
+
const tag = await fetchLatestReleaseTag("colbymchenry/codegraph");
|
|
1145
|
+
if (!tag) {
|
|
1146
|
+
return {
|
|
1147
|
+
success: false,
|
|
1148
|
+
message: "No se pudo obtener la última versión de CodeGraph desde GitHub."
|
|
1149
|
+
};
|
|
1150
|
+
}
|
|
1151
|
+
const ext = process.platform === "win32" ? "zip" : "tar.gz";
|
|
1152
|
+
const url = `https://github.com/colbymchenry/codegraph/releases/download/${tag}/codegraph-${target}.${ext}`;
|
|
1153
|
+
try {
|
|
1154
|
+
archivePromotion = await downloadAndExtractWithRetry(url, cgToolDir, 1, 180000, 2);
|
|
1155
|
+
} catch (e2) {
|
|
1156
|
+
return {
|
|
1157
|
+
success: false,
|
|
1158
|
+
message: `Error descargando CodeGraph ${tag}: ${e2.message}`
|
|
1159
|
+
};
|
|
1160
|
+
}
|
|
1161
|
+
localBin = findToolBinary(cgToolDir, "codegraph");
|
|
1162
|
+
if (!localBin) {
|
|
1163
|
+
return failAfterExtraction(`Descarga de CodeGraph ${tag} completada pero no se encontró el binario en ${join7(cgToolDir, "bin")}.`);
|
|
1164
|
+
}
|
|
1165
|
+
if (process.platform !== "win32") {
|
|
1166
|
+
try {
|
|
1167
|
+
chmodSync(localBin, 493);
|
|
1168
|
+
} catch {}
|
|
1140
1169
|
}
|
|
1141
|
-
const parent = dirname(current);
|
|
1142
|
-
if (parent === current)
|
|
1143
|
-
return resolve(startDir);
|
|
1144
|
-
current = parent;
|
|
1145
1170
|
}
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
agents: join(opencodeDir, "agents"),
|
|
1151
|
-
commands: join(opencodeDir, "commands"),
|
|
1152
|
-
plugins: join(opencodeDir, "plugins"),
|
|
1153
|
-
skills: join(opencodeDir, "skills"),
|
|
1154
|
-
mcp: join(opencodeDir, "mcp"),
|
|
1155
|
-
tools: join(opencodeDir, "tools")
|
|
1156
|
-
};
|
|
1157
|
-
for (const dir of [paths.root, paths.agents, paths.commands, paths.plugins, paths.skills, paths.mcp, paths.tools]) {
|
|
1158
|
-
if (!existsSync(dir))
|
|
1159
|
-
mkdirSync(dir, { recursive: true });
|
|
1171
|
+
try {
|
|
1172
|
+
runTool(localBin, ["--version"], projectRoot, 1e4);
|
|
1173
|
+
} catch (error) {
|
|
1174
|
+
return failAfterExtraction(`CodeGraph fue extraído pero no se puede ejecutar: ${error.message}`);
|
|
1160
1175
|
}
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
if (!existsSync(dir))
|
|
1167
|
-
mkdirSync(dir, { recursive: true });
|
|
1176
|
+
let indexWarning = null;
|
|
1177
|
+
try {
|
|
1178
|
+
runTool(localBin, ["init", "-i"], projectRoot, 120000);
|
|
1179
|
+
} catch (error) {
|
|
1180
|
+
indexWarning = `El índice no se pudo inicializar todavía: ${error.message}`;
|
|
1168
1181
|
}
|
|
1182
|
+
try {
|
|
1183
|
+
configureLocalTool(projectRoot, "codegraph", buildLocalMcpCommand(localBin, ["serve", "--mcp"]));
|
|
1184
|
+
} catch (error) {
|
|
1185
|
+
return failAfterExtraction(`CodeGraph fue instalado pero no se pudo configurar el MCP: ${error.message}`);
|
|
1186
|
+
}
|
|
1187
|
+
archivePromotion?.commit();
|
|
1188
|
+
return {
|
|
1189
|
+
success: true,
|
|
1190
|
+
message: indexWarning ? `CodeGraph instalado y configurado para OpenCode. ${indexWarning}` : "CodeGraph instalado localmente y configurado para OpenCode"
|
|
1191
|
+
};
|
|
1169
1192
|
}
|
|
1170
|
-
function
|
|
1171
|
-
|
|
1193
|
+
function setupOpenSpec(projectRoot = findProjectRoot()) {
|
|
1194
|
+
const useBun = isCommandAvailable("bun");
|
|
1195
|
+
try {
|
|
1196
|
+
const invocation = getCommandInvocation(useBun ? "bunx" : "npx", useBun ? ["openspec", "init", "--tools", "opencode", "--force"] : ["--yes", "openspec", "init", "--tools", "opencode", "--force"]);
|
|
1197
|
+
execFileSync3(invocation.command, invocation.args, {
|
|
1198
|
+
stdio: "pipe",
|
|
1199
|
+
timeout: 120000,
|
|
1200
|
+
cwd: projectRoot
|
|
1201
|
+
});
|
|
1202
|
+
return { success: true, message: "OpenSpec configurado para OpenCode" };
|
|
1203
|
+
} catch (e2) {
|
|
1204
|
+
return {
|
|
1205
|
+
success: false,
|
|
1206
|
+
message: `Error configurando OpenSpec: ${e2.message}`
|
|
1207
|
+
};
|
|
1208
|
+
}
|
|
1172
1209
|
}
|
|
1173
|
-
function
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1210
|
+
async function installEngram(toolsDir) {
|
|
1211
|
+
const location = resolveToolInstallLocation(toolsDir);
|
|
1212
|
+
const { projectRoot } = location;
|
|
1213
|
+
const engramToolDir = join7(location.toolsDir, "engram");
|
|
1214
|
+
const engramBinDir = join7(engramToolDir, "bin");
|
|
1215
|
+
if (!existsSync6(engramBinDir))
|
|
1216
|
+
mkdirSync4(engramBinDir, { recursive: true });
|
|
1217
|
+
const localBin = join7(engramBinDir, getExecutableName("engram"));
|
|
1218
|
+
let archivePromotion = null;
|
|
1219
|
+
const failAfterExtraction = (message) => {
|
|
1220
|
+
try {
|
|
1221
|
+
archivePromotion?.rollback();
|
|
1222
|
+
} catch {}
|
|
1223
|
+
return { success: false, message };
|
|
1224
|
+
};
|
|
1225
|
+
if (existsSync6(localBin)) {
|
|
1226
|
+
try {
|
|
1227
|
+
runTool(localBin, ["--version"], projectRoot, 1e4);
|
|
1228
|
+
} catch {
|
|
1229
|
+
try {
|
|
1230
|
+
unlinkSync3(localBin);
|
|
1231
|
+
} catch {}
|
|
1186
1232
|
}
|
|
1187
1233
|
}
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1234
|
+
if (!existsSync6(localBin)) {
|
|
1235
|
+
const globalBin = findExecutablePath("engram");
|
|
1236
|
+
const useGlobalBinary = globalBin && (process.platform !== "win32" || globalBin.toLowerCase().endsWith(".exe"));
|
|
1237
|
+
if (useGlobalBinary) {
|
|
1238
|
+
try {
|
|
1239
|
+
runTool(globalBin, ["--version"], projectRoot, 1e4);
|
|
1240
|
+
mkdirSync4(engramBinDir, { recursive: true });
|
|
1241
|
+
copyFileSync3(globalBin, localBin);
|
|
1242
|
+
} catch {
|
|
1243
|
+
try {
|
|
1244
|
+
unlinkSync3(localBin);
|
|
1245
|
+
} catch {}
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1249
|
+
if (!existsSync6(localBin)) {
|
|
1250
|
+
const tag = await fetchLatestReleaseTag("Gentleman-Programming/engram");
|
|
1251
|
+
if (!tag) {
|
|
1252
|
+
return {
|
|
1253
|
+
success: false,
|
|
1254
|
+
message: "No se pudo obtener la última versión de Engram desde GitHub."
|
|
1255
|
+
};
|
|
1256
|
+
}
|
|
1257
|
+
const url = buildEngramDownloadUrl(tag);
|
|
1258
|
+
if (!url) {
|
|
1259
|
+
return {
|
|
1260
|
+
success: false,
|
|
1261
|
+
message: `Plataforma no soportada para descargar Engram: ${process.platform}/${process.arch}.`
|
|
1262
|
+
};
|
|
1263
|
+
}
|
|
1264
|
+
try {
|
|
1265
|
+
archivePromotion = await downloadAndExtractWithRetry(url, engramToolDir, 0, 120000, 2);
|
|
1266
|
+
} catch (e2) {
|
|
1267
|
+
return {
|
|
1268
|
+
success: false,
|
|
1269
|
+
message: `Error descargando Engram ${tag}: ${e2.message}`
|
|
1270
|
+
};
|
|
1271
|
+
}
|
|
1272
|
+
mkdirSync4(engramBinDir, { recursive: true });
|
|
1273
|
+
const found = findBinaryInDir(engramToolDir, "engram");
|
|
1274
|
+
if (!found) {
|
|
1275
|
+
return failAfterExtraction(`Descarga de Engram ${tag} completada pero no se encontró el binario en ${localBin}.`);
|
|
1276
|
+
}
|
|
1277
|
+
try {
|
|
1278
|
+
if (found !== localBin)
|
|
1279
|
+
copyFileSync3(found, localBin);
|
|
1280
|
+
} catch (error) {
|
|
1281
|
+
return failAfterExtraction(`Engram fue descargado pero no se pudo materializar el binario local: ${error.message}`);
|
|
1282
|
+
}
|
|
1283
|
+
if (process.platform !== "win32") {
|
|
1284
|
+
try {
|
|
1285
|
+
chmodSync(localBin, 493);
|
|
1286
|
+
} catch {}
|
|
1208
1287
|
}
|
|
1209
1288
|
}
|
|
1289
|
+
try {
|
|
1290
|
+
runTool(localBin, ["--version"], projectRoot, 1e4);
|
|
1291
|
+
copyEngramPlugin(projectRoot);
|
|
1292
|
+
configureLocalTool(projectRoot, "engram", buildLocalMcpCommand(localBin, ["mcp"]));
|
|
1293
|
+
} catch (error) {
|
|
1294
|
+
return failAfterExtraction(`Engram fue instalado pero no se pudo verificar o configurar: ${error.message}`);
|
|
1295
|
+
}
|
|
1296
|
+
archivePromotion?.commit();
|
|
1297
|
+
return { success: true, message: "Engram instalado localmente y configurado para OpenCode (MCP + plugin)" };
|
|
1210
1298
|
}
|
|
1211
|
-
function
|
|
1299
|
+
function setupContext7(toolsDir) {
|
|
1300
|
+
const location = resolveToolInstallLocation(toolsDir);
|
|
1301
|
+
const { projectRoot } = location;
|
|
1302
|
+
const ctx7ToolDir = join7(location.toolsDir, "context7");
|
|
1303
|
+
if (!existsSync6(ctx7ToolDir))
|
|
1304
|
+
mkdirSync4(ctx7ToolDir, { recursive: true });
|
|
1212
1305
|
try {
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
}
|
|
1218
|
-
|
|
1306
|
+
ensureMcpEntryAtProjectRoot(projectRoot, "context7", {
|
|
1307
|
+
type: "remote",
|
|
1308
|
+
url: "https://mcp.context7.com/mcp",
|
|
1309
|
+
enabled: true
|
|
1310
|
+
});
|
|
1311
|
+
} catch (error) {
|
|
1312
|
+
return { success: false, message: `No se pudo registrar Context7: ${error.message}` };
|
|
1313
|
+
}
|
|
1314
|
+
const useBun = isCommandAvailable("bun");
|
|
1315
|
+
try {
|
|
1316
|
+
const invocation = getCommandInvocation(useBun ? "bunx" : "npx", useBun ? ["ctx7", "setup", "--opencode"] : ["--yes", "ctx7", "setup", "--opencode"]);
|
|
1317
|
+
execFileSync3(invocation.command, invocation.args, {
|
|
1318
|
+
stdio: "pipe",
|
|
1319
|
+
timeout: 60000,
|
|
1320
|
+
cwd: projectRoot
|
|
1321
|
+
});
|
|
1322
|
+
return { success: true, message: "Context7 configurado (MCP + skill instalado)" };
|
|
1219
1323
|
} catch {
|
|
1220
|
-
return
|
|
1324
|
+
return {
|
|
1325
|
+
success: true,
|
|
1326
|
+
message: "Context7 MCP registrado (skill opcional no instalada — corrí `npx ctx7 setup --opencode` manualmente si la querés)"
|
|
1327
|
+
};
|
|
1221
1328
|
}
|
|
1222
1329
|
}
|
|
1223
|
-
function
|
|
1224
|
-
const
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
else if (platform === "win32")
|
|
1233
|
-
os = "win32";
|
|
1234
|
-
else
|
|
1235
|
-
return null;
|
|
1236
|
-
if (arch === "arm64")
|
|
1237
|
-
cpu = "arm64";
|
|
1238
|
-
else if (arch === "x64")
|
|
1239
|
-
cpu = "x64";
|
|
1240
|
-
else
|
|
1241
|
-
return null;
|
|
1242
|
-
return `${os}-${cpu}`;
|
|
1330
|
+
async function installStack(toolsDir) {
|
|
1331
|
+
const { projectRoot } = resolveToolInstallLocation(toolsDir);
|
|
1332
|
+
return {
|
|
1333
|
+
codegraph: await installCodeGraph(toolsDir),
|
|
1334
|
+
openspec: setupOpenSpec(projectRoot),
|
|
1335
|
+
engram: await installEngram(toolsDir),
|
|
1336
|
+
context7: setupContext7(toolsDir),
|
|
1337
|
+
config: patchOpenCodeConfig(projectRoot)
|
|
1338
|
+
};
|
|
1243
1339
|
}
|
|
1244
|
-
function
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
return res.body.pipeTo(writable);
|
|
1265
|
-
}).then(() => {
|
|
1266
|
-
clearTimeout(timer);
|
|
1267
|
-
}).catch((err) => {
|
|
1268
|
-
clearTimeout(timer);
|
|
1269
|
-
file.destroy();
|
|
1270
|
-
try {
|
|
1271
|
-
unlinkSync(dest);
|
|
1272
|
-
} catch {}
|
|
1273
|
-
reject(err);
|
|
1274
|
-
});
|
|
1275
|
-
});
|
|
1340
|
+
function uninstallEngramConfig() {
|
|
1341
|
+
const projectRoot = findProjectRoot();
|
|
1342
|
+
const configPath = findOpenCodeConfig(projectRoot);
|
|
1343
|
+
if (!configPath) {
|
|
1344
|
+
return { success: false, message: "No se encontró opencode.json ni opencode.jsonc" };
|
|
1345
|
+
}
|
|
1346
|
+
const config = readOpenCodeConfig(configPath);
|
|
1347
|
+
if (!config) {
|
|
1348
|
+
return { success: false, message: `Error parseando ${configPath}` };
|
|
1349
|
+
}
|
|
1350
|
+
const mcp = config.mcp;
|
|
1351
|
+
if (mcp && "engram" in mcp) {
|
|
1352
|
+
delete mcp.engram;
|
|
1353
|
+
if (Object.keys(mcp).length === 0) {
|
|
1354
|
+
delete config.mcp;
|
|
1355
|
+
}
|
|
1356
|
+
writeOpenCodeConfig(configPath, config);
|
|
1357
|
+
return { success: true, message: "Config de Engram eliminada de opencode.json" };
|
|
1358
|
+
}
|
|
1359
|
+
return { success: true, message: "Engram no estaba configurado en este proyecto" };
|
|
1276
1360
|
}
|
|
1277
|
-
|
|
1278
|
-
const
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1361
|
+
function uninstallStackConfig(paths) {
|
|
1362
|
+
const projectRoot = dirname5(paths.root);
|
|
1363
|
+
const removed = [];
|
|
1364
|
+
const configPath = findOpenCodeConfig(projectRoot);
|
|
1365
|
+
if (configPath) {
|
|
1366
|
+
const config = readOpenCodeConfig(configPath);
|
|
1367
|
+
if (config) {
|
|
1368
|
+
const mcp = config.mcp;
|
|
1369
|
+
let changed = false;
|
|
1370
|
+
if (mcp) {
|
|
1371
|
+
for (const name of ["codegraph", "context7", "engram"]) {
|
|
1372
|
+
if (name in mcp) {
|
|
1373
|
+
delete mcp[name];
|
|
1374
|
+
removed.push(`mcp.${name}`);
|
|
1375
|
+
changed = true;
|
|
1376
|
+
}
|
|
1377
|
+
}
|
|
1378
|
+
if (Object.keys(mcp).length === 0) {
|
|
1379
|
+
delete config.mcp;
|
|
1380
|
+
changed = true;
|
|
1381
|
+
}
|
|
1382
|
+
}
|
|
1383
|
+
if (changed) {
|
|
1384
|
+
writeOpenCodeConfig(configPath, config);
|
|
1385
|
+
}
|
|
1294
1386
|
}
|
|
1295
|
-
}
|
|
1387
|
+
}
|
|
1388
|
+
const codegraphDir = join7(projectRoot, ".codegraph");
|
|
1389
|
+
if (existsSync6(codegraphDir)) {
|
|
1296
1390
|
try {
|
|
1297
|
-
|
|
1391
|
+
rmSync4(codegraphDir, { recursive: true, force: true });
|
|
1392
|
+
removed.push(".codegraph/");
|
|
1298
1393
|
} catch {}
|
|
1299
1394
|
}
|
|
1300
|
-
|
|
1301
|
-
async function downloadAndExtractWithRetry(url, destDir, stripComponents = 1, timeoutMs = 180000, maxRetries = 2) {
|
|
1302
|
-
let lastError = null;
|
|
1303
|
-
for (let attempt = 0;attempt <= maxRetries; attempt++) {
|
|
1395
|
+
if (existsSync6(paths.tools)) {
|
|
1304
1396
|
try {
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
} catch
|
|
1308
|
-
lastError = err;
|
|
1309
|
-
if (attempt < maxRetries) {
|
|
1310
|
-
const delay = 1000 * Math.pow(2, attempt);
|
|
1311
|
-
console.error(`[download] Intento ${attempt + 1} falló: ${lastError.message}. Reintentando en ${delay}ms...`);
|
|
1312
|
-
await new Promise((r2) => setTimeout(r2, delay));
|
|
1313
|
-
}
|
|
1314
|
-
}
|
|
1397
|
+
rmSync4(paths.tools, { recursive: true, force: true });
|
|
1398
|
+
removed.push(".opencode/tools/");
|
|
1399
|
+
} catch {}
|
|
1315
1400
|
}
|
|
1316
|
-
|
|
1401
|
+
if (removed.length === 0) {
|
|
1402
|
+
return { success: true, message: "No había configuración del stack para remover" };
|
|
1403
|
+
}
|
|
1404
|
+
return {
|
|
1405
|
+
success: true,
|
|
1406
|
+
message: `Removido: ${removed.join(", ")}. Los binarios globales (codegraph, engram) no se tocaron.`
|
|
1407
|
+
};
|
|
1317
1408
|
}
|
|
1318
|
-
function
|
|
1319
|
-
const
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
}
|
|
1328
|
-
|
|
1409
|
+
function verifyMcpServers(projectRoot) {
|
|
1410
|
+
const opencodeDir = findOpenCodeDir(projectRoot);
|
|
1411
|
+
const mcpBase = opencodeDir ? join7(opencodeDir, "mcp") : join7(projectRoot, ".opencode", "mcp");
|
|
1412
|
+
const controllerPath = join7(mcpBase, "ostacky-controller", "index.js");
|
|
1413
|
+
const openspecPath = join7(mcpBase, "openspec", "index.js");
|
|
1414
|
+
const result = {
|
|
1415
|
+
ostackyController: {
|
|
1416
|
+
exists: existsSync6(controllerPath),
|
|
1417
|
+
path: controllerPath
|
|
1418
|
+
},
|
|
1419
|
+
openspec: {
|
|
1420
|
+
exists: existsSync6(openspecPath),
|
|
1421
|
+
path: openspecPath
|
|
1329
1422
|
}
|
|
1423
|
+
};
|
|
1424
|
+
if (!result.ostackyController.exists) {
|
|
1425
|
+
result.ostackyController.error = "ostacky-controller MCP server not found";
|
|
1330
1426
|
}
|
|
1331
|
-
|
|
1427
|
+
if (!result.openspec.exists) {
|
|
1428
|
+
result.openspec.error = "openspec MCP server not found";
|
|
1429
|
+
}
|
|
1430
|
+
return result;
|
|
1332
1431
|
}
|
|
1333
|
-
var
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
// manifest.json
|
|
1339
|
-
var manifest_default;
|
|
1340
|
-
var init_manifest = __esm(() => {
|
|
1341
|
-
manifest_default = {
|
|
1342
|
-
version: "0.6.0",
|
|
1343
|
-
repo: "JaimeHoracio/Ostacky",
|
|
1344
|
-
tag: "v0.6.0",
|
|
1345
|
-
agents: [
|
|
1346
|
-
{
|
|
1347
|
-
name: "ostacky",
|
|
1348
|
-
file: "assets/agents/ostacky.md",
|
|
1349
|
-
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",
|
|
1350
|
-
version: "0.6.0",
|
|
1351
|
-
sha256: "206963fd98b0af4580338407d1df11c30ecd0c18b984f73eb4b624555c263f55"
|
|
1352
|
-
}
|
|
1353
|
-
],
|
|
1354
|
-
commands: [
|
|
1355
|
-
{
|
|
1356
|
-
name: "install-stack",
|
|
1357
|
-
file: "assets/commands/install-stack.md",
|
|
1358
|
-
description: "Instala el stack tecnológico del proyecto (CodeGraph, skills, OpenSpec, Engram, Context7, controller MCP con SDK oficial)",
|
|
1359
|
-
version: "0.6.0",
|
|
1360
|
-
sha256: "9fb5a6ab01506c62c3a844fdac3940773c4aa2c22aa4f1effcf9048dafa28673"
|
|
1361
|
-
},
|
|
1362
|
-
{
|
|
1363
|
-
name: "opsx-sync",
|
|
1364
|
-
file: "assets/commands/opsx-sync.md",
|
|
1365
|
-
description: "Sincroniza delta specs del change activo sin inicializar CodeGraph si ya existe índice",
|
|
1366
|
-
version: "0.6.0",
|
|
1367
|
-
sha256: "ed9948f1910743b672e1dfad496bc96972a224a98b063232be39290d43068c50"
|
|
1368
|
-
}
|
|
1369
|
-
],
|
|
1370
|
-
mcpServers: [
|
|
1371
|
-
{
|
|
1372
|
-
name: "ostacky-controller",
|
|
1373
|
-
file: "assets/mcp/ostacky-controller/",
|
|
1374
|
-
description: "Máquina de estados persistida con @modelcontextprotocol/server SDK. 20 tools: start_request → discovery → route → execution → sync → done + validate_edit + complete_task + ping + proceed_to_route + abandon integrado",
|
|
1375
|
-
version: "0.6.0",
|
|
1376
|
-
sha256: "b9637c3c78f4da059868e5af4d1e99af8280a9d3e3f1a6eafc6e74362c93a75b"
|
|
1377
|
-
},
|
|
1378
|
-
{
|
|
1379
|
-
name: "openspec",
|
|
1380
|
-
file: "assets/mcp/openspec/",
|
|
1381
|
-
description: "MCP server local para OpenSpec - proposal, apply, archive, sync de cambios",
|
|
1382
|
-
version: "0.6.0",
|
|
1383
|
-
sha256: "db49c5ddbf1c2b3a9b65598b9a0ac1409694cd54444d1d1bd74eb12e6b39be01"
|
|
1384
|
-
}
|
|
1385
|
-
],
|
|
1386
|
-
skills: [
|
|
1387
|
-
{
|
|
1388
|
-
name: "brainstorming",
|
|
1389
|
-
file: "assets/skills/brainstorming/SKILL.md",
|
|
1390
|
-
description: "Skill unificado de pensamiento con dos modos: creative-design (producción de diseño → transición a writing-plans o openspec-propose) y open-exploration (exploración libre)",
|
|
1391
|
-
version: "0.6.0",
|
|
1392
|
-
sha256: "d1051ded927d57dcf72c33fa0d6116c7d0103ef36f5a7f9e22f7b3da78f9c74e"
|
|
1393
|
-
},
|
|
1394
|
-
{
|
|
1395
|
-
name: "execution-mode-evaluation",
|
|
1396
|
-
file: "assets/skills/execution-mode-evaluation/SKILL.md",
|
|
1397
|
-
description: "Skill de análisis de modo de ejecución — output reconciliado con controller snapshot contract (recommendation field)",
|
|
1398
|
-
version: "0.6.0",
|
|
1399
|
-
sha256: "5c37f6f4132378f863c99102bbde8bab478160ced82a2ea1025f958275d8e881"
|
|
1400
|
-
},
|
|
1401
|
-
{
|
|
1402
|
-
name: "writing-plans",
|
|
1403
|
-
file: "assets/skills/writing-plans/SKILL.md",
|
|
1404
|
-
description: "Skill de planificación de implementación (Superpowers) — execution handoff removido, Ostacky decide modo de ejecución",
|
|
1405
|
-
version: "0.6.0",
|
|
1406
|
-
sha256: "e681af5e607e7ae4b6a1c0760a4f1d1d292a028d2b6989df3afb9be8dcc81c61"
|
|
1407
|
-
},
|
|
1408
|
-
{
|
|
1409
|
-
name: "tdd",
|
|
1410
|
-
file: "assets/skills/tdd/SKILL.md",
|
|
1411
|
-
description: "Skill de test-driven development (Superpowers)",
|
|
1412
|
-
version: "0.6.0",
|
|
1413
|
-
sha256: "9f5a25e61e049d473a854a5401cec947329e830aa902db7c31f91a160ac19890"
|
|
1414
|
-
},
|
|
1415
|
-
{
|
|
1416
|
-
name: "subagent-driven-development",
|
|
1417
|
-
file: "assets/skills/subagent-driven-development/SKILL.md",
|
|
1418
|
-
description: "Skill de ejecución con subagentes (Superpowers) — ejecuta solo después de confirmación del coordinador Ostacky",
|
|
1419
|
-
version: "0.6.0",
|
|
1420
|
-
sha256: "65d87f2b3ae1da5d08b6760938ab7009e0e226182ec1d88d322a230754ac9d8e"
|
|
1421
|
-
},
|
|
1422
|
-
{
|
|
1423
|
-
name: "dispatching-parallel-agents",
|
|
1424
|
-
file: "assets/skills/dispatching-parallel-agents/SKILL.md",
|
|
1425
|
-
description: "Skill de dispatch paralelo de agentes (Superpowers)",
|
|
1426
|
-
version: "0.6.0",
|
|
1427
|
-
sha256: "2d93480e4b9c0f516861a765977ae08b6e02dc113dc456068ef8026bcb950fcb"
|
|
1428
|
-
},
|
|
1429
|
-
{
|
|
1430
|
-
name: "review",
|
|
1431
|
-
file: "assets/skills/review/SKILL.md",
|
|
1432
|
-
description: "Skill de revisión de código (Superpowers)",
|
|
1433
|
-
version: "0.6.0",
|
|
1434
|
-
sha256: "14831d9ef3746ef6e2e6047c868fe7aa296d01f0644227ce776fe99436357b1a"
|
|
1435
|
-
},
|
|
1436
|
-
{
|
|
1437
|
-
name: "receiving-code-review",
|
|
1438
|
-
file: "assets/skills/receiving-code-review/SKILL.md",
|
|
1439
|
-
description: "Skill de recibir y procesar feedback de code review",
|
|
1440
|
-
version: "0.6.0",
|
|
1441
|
-
sha256: "0a5780e8a41539d15428114b7c46f36670acc16aba0db3348d36be1175433872"
|
|
1442
|
-
},
|
|
1443
|
-
{
|
|
1444
|
-
name: "openspec-propose",
|
|
1445
|
-
file: "assets/skills/openspec-propose/SKILL.md",
|
|
1446
|
-
description: "Skill de generación de proposal (OpenSpec)",
|
|
1447
|
-
version: "0.6.0",
|
|
1448
|
-
sha256: "c50d478fd96ec5a60080012d5d87a09b54787884b4b0fa7d8631e7bee6c8c80d"
|
|
1449
|
-
},
|
|
1450
|
-
{
|
|
1451
|
-
name: "openspec-apply-change",
|
|
1452
|
-
file: "assets/skills/openspec-apply-change/SKILL.md",
|
|
1453
|
-
description: "Skill de aplicación de change (OpenSpec)",
|
|
1454
|
-
version: "0.6.0",
|
|
1455
|
-
sha256: "723a492f2ef2df3337e8e841ae84f4f5d0f8621e534c8ea76540ee3a796ff527"
|
|
1456
|
-
},
|
|
1457
|
-
{
|
|
1458
|
-
name: "openspec-archive-change",
|
|
1459
|
-
file: "assets/skills/openspec-archive-change/SKILL.md",
|
|
1460
|
-
description: "Skill de archivo de change (OpenSpec)",
|
|
1461
|
-
version: "0.6.0",
|
|
1462
|
-
sha256: "dc2422d0ff9a54e3ed9b016df2bad0dfa6cca9adaee02bb4563ce7525cc56f40"
|
|
1463
|
-
},
|
|
1464
|
-
{
|
|
1465
|
-
name: "openspec-explore",
|
|
1466
|
-
file: "assets/skills/openspec-explore/SKILL.md",
|
|
1467
|
-
description: "Modo explore para OpenSpec — thinking partner para explorar ideas, investigar problemas y clarificar requisitos antes/durante un cambio",
|
|
1468
|
-
version: "0.6.0",
|
|
1469
|
-
sha256: "6e162c0b38dedd2ee70d0be9179af1a9716e78ac786511d5b49ebeb0fffc14a0"
|
|
1470
|
-
},
|
|
1471
|
-
{
|
|
1472
|
-
name: "using-git-worktrees",
|
|
1473
|
-
file: "assets/skills/using-git-worktrees/SKILL.md",
|
|
1474
|
-
description: "Skill de uso de git worktrees para aislamiento de trabajo",
|
|
1475
|
-
version: "0.6.0",
|
|
1476
|
-
sha256: "3829b79c1d36b1bc9d148153b07f66265599a19494f648731273e3e6d1a0d65c"
|
|
1477
|
-
},
|
|
1478
|
-
{
|
|
1479
|
-
name: "using-superpowers",
|
|
1480
|
-
file: "assets/skills/using-superpowers/SKILL.md",
|
|
1481
|
-
description: "Skill de orquestación de Superpowers skills",
|
|
1482
|
-
version: "0.6.0",
|
|
1483
|
-
sha256: "d0153c2bdac88c5a409d439d137b8f04fecda005cc7722f1ca83b2211bfda115"
|
|
1484
|
-
},
|
|
1485
|
-
{
|
|
1486
|
-
name: "writing-skills",
|
|
1487
|
-
file: "assets/skills/writing-skills/SKILL.md",
|
|
1488
|
-
description: "Skill de creación y edición de skills",
|
|
1489
|
-
version: "0.6.0",
|
|
1490
|
-
sha256: "371da06aad8a546389785140248698b6401730f34c2ab00b4b9304e5a51e1eb4"
|
|
1491
|
-
},
|
|
1492
|
-
{
|
|
1493
|
-
name: "graceful-degradation",
|
|
1494
|
-
file: "assets/skills/graceful-degradation/SKILL.md",
|
|
1495
|
-
description: "Skill de degradación graceful cuando múltiples tools están indisponibles",
|
|
1496
|
-
version: "0.6.0",
|
|
1497
|
-
sha256: "92ea3381b5610d9041797868a5887fb358d185d80ebb753bdae3f9f9abb4d790"
|
|
1498
|
-
}
|
|
1499
|
-
]
|
|
1500
|
-
};
|
|
1432
|
+
var init_stack = __esm(() => {
|
|
1433
|
+
init_fs();
|
|
1434
|
+
init_config();
|
|
1435
|
+
init_github();
|
|
1501
1436
|
});
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
}
|
|
1523
|
-
|
|
1437
|
+
// package.json
|
|
1438
|
+
var package_default = {
|
|
1439
|
+
name: "ostacky",
|
|
1440
|
+
version: "0.6.2",
|
|
1441
|
+
description: "Instalador interactivo de agentes y comandos para OpenCode",
|
|
1442
|
+
type: "module",
|
|
1443
|
+
bin: {
|
|
1444
|
+
ostacky: "./dist/cli.js"
|
|
1445
|
+
},
|
|
1446
|
+
scripts: {
|
|
1447
|
+
prebuild: "bun run scripts/sync-version.ts",
|
|
1448
|
+
dev: "bun run src/cli.ts",
|
|
1449
|
+
build: "bun build src/cli.ts --target=node --format=esm --outfile dist/cli.js && bun scripts/add-shebang.ts",
|
|
1450
|
+
start: "node dist/cli.js",
|
|
1451
|
+
test: "bun test",
|
|
1452
|
+
"check:skills": "bun run scripts/check-skill-sync.ts",
|
|
1453
|
+
"check:skills:fix": "bun run scripts/check-skill-sync.ts --fix",
|
|
1454
|
+
"hash:check": "bun run scripts/update-manifest-hashes.ts --check",
|
|
1455
|
+
"hash:update": "bun run scripts/update-manifest-hashes.ts",
|
|
1456
|
+
prepublishOnly: "bun run build"
|
|
1457
|
+
},
|
|
1458
|
+
files: [
|
|
1459
|
+
"dist/",
|
|
1460
|
+
"assets/",
|
|
1461
|
+
"manifest.json",
|
|
1462
|
+
"LICENSE"
|
|
1463
|
+
],
|
|
1464
|
+
keywords: [
|
|
1465
|
+
"opencode",
|
|
1466
|
+
"installer",
|
|
1467
|
+
"cli",
|
|
1468
|
+
"agent"
|
|
1469
|
+
],
|
|
1470
|
+
license: "MIT",
|
|
1471
|
+
dependencies: {
|
|
1472
|
+
"@clack/prompts": "^0.9.0"
|
|
1473
|
+
},
|
|
1474
|
+
devDependencies: {
|
|
1475
|
+
"@types/bun": "latest",
|
|
1476
|
+
typescript: "^5.0.0"
|
|
1477
|
+
},
|
|
1478
|
+
publishConfig: {
|
|
1479
|
+
access: "public"
|
|
1480
|
+
},
|
|
1481
|
+
engines: {
|
|
1482
|
+
node: ">=20.0.0"
|
|
1524
1483
|
}
|
|
1525
|
-
}
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1484
|
+
};
|
|
1485
|
+
|
|
1486
|
+
// node_modules/@clack/prompts/dist/index.mjs
|
|
1487
|
+
var exports_dist = {};
|
|
1488
|
+
__export(exports_dist, {
|
|
1489
|
+
updateSettings: () => hD,
|
|
1490
|
+
text: () => ue,
|
|
1491
|
+
tasks: () => xe,
|
|
1492
|
+
spinner: () => L2,
|
|
1493
|
+
selectKey: () => he,
|
|
1494
|
+
select: () => de,
|
|
1495
|
+
password: () => $e,
|
|
1496
|
+
outro: () => fe,
|
|
1497
|
+
note: () => ye,
|
|
1498
|
+
multiselect: () => pe,
|
|
1499
|
+
log: () => v2,
|
|
1500
|
+
isCancel: () => BD,
|
|
1501
|
+
intro: () => we,
|
|
1502
|
+
groupMultiselect: () => ge,
|
|
1503
|
+
group: () => be,
|
|
1504
|
+
confirm: () => me,
|
|
1505
|
+
cancel: () => ve
|
|
1535
1506
|
});
|
|
1507
|
+
import { stripVTControlCharacters as T2 } from "node:util";
|
|
1536
1508
|
|
|
1537
|
-
//
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1509
|
+
// node_modules/@clack/core/dist/index.mjs
|
|
1510
|
+
var import_sisteransi = __toESM(require_src(), 1);
|
|
1511
|
+
var import_picocolors = __toESM(require_picocolors(), 1);
|
|
1512
|
+
import { stdin as $, stdout as j } from "node:process";
|
|
1513
|
+
import * as f from "node:readline";
|
|
1514
|
+
import M from "node:readline";
|
|
1515
|
+
import { WriteStream as U } from "node:tty";
|
|
1516
|
+
function J({ onlyFirst: t = false } = {}) {
|
|
1517
|
+
const F = ["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?(?:\\u0007|\\u001B\\u005C|\\u009C))", "(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))"].join("|");
|
|
1518
|
+
return new RegExp(F, t ? undefined : "g");
|
|
1543
1519
|
}
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1520
|
+
var Q = J();
|
|
1521
|
+
function T(t) {
|
|
1522
|
+
if (typeof t != "string")
|
|
1523
|
+
throw new TypeError(`Expected a \`string\`, got \`${typeof t}\``);
|
|
1524
|
+
return t.replace(Q, "");
|
|
1547
1525
|
}
|
|
1548
|
-
function
|
|
1549
|
-
return
|
|
1526
|
+
function O(t) {
|
|
1527
|
+
return t && t.__esModule && Object.prototype.hasOwnProperty.call(t, "default") ? t.default : t;
|
|
1550
1528
|
}
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1529
|
+
var P = { exports: {} };
|
|
1530
|
+
(function(t) {
|
|
1531
|
+
var u = {};
|
|
1532
|
+
t.exports = u, u.eastAsianWidth = function(e) {
|
|
1533
|
+
var s = e.charCodeAt(0), i = e.length == 2 ? e.charCodeAt(1) : 0, D = s;
|
|
1534
|
+
return 55296 <= s && s <= 56319 && 56320 <= i && i <= 57343 && (s &= 1023, i &= 1023, D = s << 10 | i, D += 65536), D == 12288 || 65281 <= D && D <= 65376 || 65504 <= D && D <= 65510 ? "F" : D == 8361 || 65377 <= D && D <= 65470 || 65474 <= D && D <= 65479 || 65482 <= D && D <= 65487 || 65490 <= D && D <= 65495 || 65498 <= D && D <= 65500 || 65512 <= D && D <= 65518 ? "H" : 4352 <= D && D <= 4447 || 4515 <= D && D <= 4519 || 4602 <= D && D <= 4607 || 9001 <= D && D <= 9002 || 11904 <= D && D <= 11929 || 11931 <= D && D <= 12019 || 12032 <= D && D <= 12245 || 12272 <= D && D <= 12283 || 12289 <= D && D <= 12350 || 12353 <= D && D <= 12438 || 12441 <= D && D <= 12543 || 12549 <= D && D <= 12589 || 12593 <= D && D <= 12686 || 12688 <= D && D <= 12730 || 12736 <= D && D <= 12771 || 12784 <= D && D <= 12830 || 12832 <= D && D <= 12871 || 12880 <= D && D <= 13054 || 13056 <= D && D <= 19903 || 19968 <= D && D <= 42124 || 42128 <= D && D <= 42182 || 43360 <= D && D <= 43388 || 44032 <= D && D <= 55203 || 55216 <= D && D <= 55238 || 55243 <= D && D <= 55291 || 63744 <= D && D <= 64255 || 65040 <= D && D <= 65049 || 65072 <= D && D <= 65106 || 65108 <= D && D <= 65126 || 65128 <= D && D <= 65131 || 110592 <= D && D <= 110593 || 127488 <= D && D <= 127490 || 127504 <= D && D <= 127546 || 127552 <= D && D <= 127560 || 127568 <= D && D <= 127569 || 131072 <= D && D <= 194367 || 177984 <= D && D <= 196605 || 196608 <= D && D <= 262141 ? "W" : 32 <= D && D <= 126 || 162 <= D && D <= 163 || 165 <= D && D <= 166 || D == 172 || D == 175 || 10214 <= D && D <= 10221 || 10629 <= D && D <= 10630 ? "Na" : D == 161 || D == 164 || 167 <= D && D <= 168 || D == 170 || 173 <= D && D <= 174 || 176 <= D && D <= 180 || 182 <= D && D <= 186 || 188 <= D && D <= 191 || D == 198 || D == 208 || 215 <= D && D <= 216 || 222 <= D && D <= 225 || D == 230 || 232 <= D && D <= 234 || 236 <= D && D <= 237 || D == 240 || 242 <= D && D <= 243 || 247 <= D && D <= 250 || D == 252 || D == 254 || D == 257 || D == 273 || D == 275 || D == 283 || 294 <= D && D <= 295 || D == 299 || 305 <= D && D <= 307 || D == 312 || 319 <= D && D <= 322 || D == 324 || 328 <= D && D <= 331 || D == 333 || 338 <= D && D <= 339 || 358 <= D && D <= 359 || D == 363 || D == 462 || D == 464 || D == 466 || D == 468 || D == 470 || D == 472 || D == 474 || D == 476 || D == 593 || D == 609 || D == 708 || D == 711 || 713 <= D && D <= 715 || D == 717 || D == 720 || 728 <= D && D <= 731 || D == 733 || D == 735 || 768 <= D && D <= 879 || 913 <= D && D <= 929 || 931 <= D && D <= 937 || 945 <= D && D <= 961 || 963 <= D && D <= 969 || D == 1025 || 1040 <= D && D <= 1103 || D == 1105 || D == 8208 || 8211 <= D && D <= 8214 || 8216 <= D && D <= 8217 || 8220 <= D && D <= 8221 || 8224 <= D && D <= 8226 || 8228 <= D && D <= 8231 || D == 8240 || 8242 <= D && D <= 8243 || D == 8245 || D == 8251 || D == 8254 || D == 8308 || D == 8319 || 8321 <= D && D <= 8324 || D == 8364 || D == 8451 || D == 8453 || D == 8457 || D == 8467 || D == 8470 || 8481 <= D && D <= 8482 || D == 8486 || D == 8491 || 8531 <= D && D <= 8532 || 8539 <= D && D <= 8542 || 8544 <= D && D <= 8555 || 8560 <= D && D <= 8569 || D == 8585 || 8592 <= D && D <= 8601 || 8632 <= D && D <= 8633 || D == 8658 || D == 8660 || D == 8679 || D == 8704 || 8706 <= D && D <= 8707 || 8711 <= D && D <= 8712 || D == 8715 || D == 8719 || D == 8721 || D == 8725 || D == 8730 || 8733 <= D && D <= 8736 || D == 8739 || D == 8741 || 8743 <= D && D <= 8748 || D == 8750 || 8756 <= D && D <= 8759 || 8764 <= D && D <= 8765 || D == 8776 || D == 8780 || D == 8786 || 8800 <= D && D <= 8801 || 8804 <= D && D <= 8807 || 8810 <= D && D <= 8811 || 8814 <= D && D <= 8815 || 8834 <= D && D <= 8835 || 8838 <= D && D <= 8839 || D == 8853 || D == 8857 || D == 8869 || D == 8895 || D == 8978 || 9312 <= D && D <= 9449 || 9451 <= D && D <= 9547 || 9552 <= D && D <= 9587 || 9600 <= D && D <= 9615 || 9618 <= D && D <= 9621 || 9632 <= D && D <= 9633 || 9635 <= D && D <= 9641 || 9650 <= D && D <= 9651 || 9654 <= D && D <= 9655 || 9660 <= D && D <= 9661 || 9664 <= D && D <= 9665 || 9670 <= D && D <= 9672 || D == 9675 || 9678 <= D && D <= 9681 || 9698 <= D && D <= 9701 || D == 9711 || 9733 <= D && D <= 9734 || D == 9737 || 9742 <= D && D <= 9743 || 9748 <= D && D <= 9749 || D == 9756 || D == 9758 || D == 9792 || D == 9794 || 9824 <= D && D <= 9825 || 9827 <= D && D <= 9829 || 9831 <= D && D <= 9834 || 9836 <= D && D <= 9837 || D == 9839 || 9886 <= D && D <= 9887 || 9918 <= D && D <= 9919 || 9924 <= D && D <= 9933 || 9935 <= D && D <= 9953 || D == 9955 || 9960 <= D && D <= 9983 || D == 10045 || D == 10071 || 10102 <= D && D <= 10111 || 11093 <= D && D <= 11097 || 12872 <= D && D <= 12879 || 57344 <= D && D <= 63743 || 65024 <= D && D <= 65039 || D == 65533 || 127232 <= D && D <= 127242 || 127248 <= D && D <= 127277 || 127280 <= D && D <= 127337 || 127344 <= D && D <= 127386 || 917760 <= D && D <= 917999 || 983040 <= D && D <= 1048573 || 1048576 <= D && D <= 1114109 ? "A" : "N";
|
|
1535
|
+
}, u.characterLength = function(e) {
|
|
1536
|
+
var s = this.eastAsianWidth(e);
|
|
1537
|
+
return s == "F" || s == "W" || s == "A" ? 2 : 1;
|
|
1538
|
+
};
|
|
1539
|
+
function F(e) {
|
|
1540
|
+
return e.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]|[^\uD800-\uDFFF]/g) || [];
|
|
1541
|
+
}
|
|
1542
|
+
u.length = function(e) {
|
|
1543
|
+
for (var s = F(e), i = 0, D = 0;D < s.length; D++)
|
|
1544
|
+
i = i + this.characterLength(s[D]);
|
|
1545
|
+
return i;
|
|
1546
|
+
}, u.slice = function(e, s, i) {
|
|
1547
|
+
textLen = u.length(e), s = s || 0, i = i || 1, s < 0 && (s = textLen + s), i < 0 && (i = textLen + i);
|
|
1548
|
+
for (var D = "", C = 0, o = F(e), E = 0;E < o.length; E++) {
|
|
1549
|
+
var a = o[E], n = u.length(a);
|
|
1550
|
+
if (C >= s - (n == 2 ? 1 : 0))
|
|
1551
|
+
if (C + n <= i)
|
|
1552
|
+
D += a;
|
|
1553
|
+
else
|
|
1554
|
+
break;
|
|
1555
|
+
C += n;
|
|
1556
|
+
}
|
|
1557
|
+
return D;
|
|
1558
|
+
};
|
|
1559
|
+
})(P);
|
|
1560
|
+
var X = P.exports;
|
|
1561
|
+
var DD = O(X);
|
|
1562
|
+
var uD = function() {
|
|
1563
|
+
return /\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67)\uDB40\uDC7F|(?:\uD83E\uDDD1\uD83C\uDFFF\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFC-\uDFFF])|\uD83D\uDC68(?:\uD83C\uDFFB(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|[\u2695\u2696\u2708]\uFE0F|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))?|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])\uFE0F|\u200D(?:(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D[\uDC66\uDC67])|\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC)?|(?:\uD83D\uDC69(?:\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69]))|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC69(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83E\uDDD1(?:\u200D(?:\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDE36\u200D\uD83C\uDF2B|\uD83C\uDFF3\uFE0F\u200D\u26A7|\uD83D\uDC3B\u200D\u2744|(?:(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\uD83C\uDFF4\u200D\u2620|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])\u200D[\u2640\u2642]|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u2600-\u2604\u260E\u2611\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26B0\u26B1\u26C8\u26CF\u26D1\u26D3\u26E9\u26F0\u26F1\u26F4\u26F7\u26F8\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u3030\u303D\u3297\u3299]|\uD83C[\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]|\uD83D[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3])\uFE0F|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDE35\u200D\uD83D\uDCAB|\uD83D\uDE2E\u200D\uD83D\uDCA8|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83E\uDDD1(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83D\uDC69(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF6\uD83C\uDDE6|\uD83C\uDDF4\uD83C\uDDF2|\uD83D\uDC08\u200D\u2B1B|\u2764\uFE0F\u200D(?:\uD83D\uDD25|\uD83E\uDE79)|\uD83D\uDC41\uFE0F|\uD83C\uDFF3\uFE0F|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|[#\*0-9]\uFE0F\u20E3|\u2764\uFE0F|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|\uD83C\uDFF4|(?:[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270C\u270D]|\uD83D[\uDD74\uDD90])(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC08\uDC15\uDC3B\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE2E\uDE35\uDE36\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5]|\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD]|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF]|[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0D\uDD0E\uDD10-\uDD17\uDD1D\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78\uDD7A-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCB\uDDD0\uDDE0-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6]|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26A7\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5-\uDED7\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])\uFE0F|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDC8F\uDC91\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDD77\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g;
|
|
1564
|
+
};
|
|
1565
|
+
var FD = O(uD);
|
|
1566
|
+
function A(t, u = {}) {
|
|
1567
|
+
if (typeof t != "string" || t.length === 0 || (u = { ambiguousIsNarrow: true, ...u }, t = T(t), t.length === 0))
|
|
1568
|
+
return 0;
|
|
1569
|
+
t = t.replace(FD(), " ");
|
|
1570
|
+
const F = u.ambiguousIsNarrow ? 1 : 2;
|
|
1571
|
+
let e = 0;
|
|
1572
|
+
for (const s of t) {
|
|
1573
|
+
const i = s.codePointAt(0);
|
|
1574
|
+
if (i <= 31 || i >= 127 && i <= 159 || i >= 768 && i <= 879)
|
|
1575
|
+
continue;
|
|
1576
|
+
switch (DD.eastAsianWidth(s)) {
|
|
1577
|
+
case "F":
|
|
1578
|
+
case "W":
|
|
1579
|
+
e += 2;
|
|
1580
|
+
break;
|
|
1581
|
+
case "A":
|
|
1582
|
+
e += F;
|
|
1583
|
+
break;
|
|
1584
|
+
default:
|
|
1585
|
+
e += 1;
|
|
1560
1586
|
}
|
|
1561
|
-
}
|
|
1562
|
-
|
|
1563
|
-
const res = await fetch(`https://github.com/${repo}/releases/latest`, {
|
|
1564
|
-
redirect: "manual",
|
|
1565
|
-
signal: AbortSignal.timeout(5000),
|
|
1566
|
-
headers: { "User-Agent": USER_AGENT }
|
|
1567
|
-
});
|
|
1568
|
-
const loc = res.headers.get("location") ?? "";
|
|
1569
|
-
const m3 = loc.match(/releases\/tag\/(v[^/]+)$/);
|
|
1570
|
-
if (m3)
|
|
1571
|
-
return m3[1];
|
|
1572
|
-
} catch {}
|
|
1573
|
-
return null;
|
|
1587
|
+
}
|
|
1588
|
+
return e;
|
|
1574
1589
|
}
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1590
|
+
var m = 10;
|
|
1591
|
+
var L = (t = 0) => (u) => `\x1B[${u + t}m`;
|
|
1592
|
+
var N = (t = 0) => (u) => `\x1B[${38 + t};5;${u}m`;
|
|
1593
|
+
var I = (t = 0) => (u, F, e) => `\x1B[${38 + t};2;${u};${F};${e}m`;
|
|
1594
|
+
var r = { modifier: { reset: [0, 0], bold: [1, 22], dim: [2, 22], italic: [3, 23], underline: [4, 24], overline: [53, 55], inverse: [7, 27], hidden: [8, 28], strikethrough: [9, 29] }, color: { black: [30, 39], red: [31, 39], green: [32, 39], yellow: [33, 39], blue: [34, 39], magenta: [35, 39], cyan: [36, 39], white: [37, 39], blackBright: [90, 39], gray: [90, 39], grey: [90, 39], redBright: [91, 39], greenBright: [92, 39], yellowBright: [93, 39], blueBright: [94, 39], magentaBright: [95, 39], cyanBright: [96, 39], whiteBright: [97, 39] }, bgColor: { bgBlack: [40, 49], bgRed: [41, 49], bgGreen: [42, 49], bgYellow: [43, 49], bgBlue: [44, 49], bgMagenta: [45, 49], bgCyan: [46, 49], bgWhite: [47, 49], bgBlackBright: [100, 49], bgGray: [100, 49], bgGrey: [100, 49], bgRedBright: [101, 49], bgGreenBright: [102, 49], bgYellowBright: [103, 49], bgBlueBright: [104, 49], bgMagentaBright: [105, 49], bgCyanBright: [106, 49], bgWhiteBright: [107, 49] } };
|
|
1595
|
+
Object.keys(r.modifier);
|
|
1596
|
+
var tD = Object.keys(r.color);
|
|
1597
|
+
var eD = Object.keys(r.bgColor);
|
|
1598
|
+
[...tD, ...eD];
|
|
1599
|
+
function sD() {
|
|
1600
|
+
const t = new Map;
|
|
1601
|
+
for (const [u, F] of Object.entries(r)) {
|
|
1602
|
+
for (const [e, s] of Object.entries(F))
|
|
1603
|
+
r[e] = { open: `\x1B[${s[0]}m`, close: `\x1B[${s[1]}m` }, F[e] = r[e], t.set(s[0], s[1]);
|
|
1604
|
+
Object.defineProperty(r, u, { value: F, enumerable: false });
|
|
1605
|
+
}
|
|
1606
|
+
return Object.defineProperty(r, "codes", { value: t, enumerable: false }), r.color.close = "\x1B[39m", r.bgColor.close = "\x1B[49m", r.color.ansi = L(), r.color.ansi256 = N(), r.color.ansi16m = I(), r.bgColor.ansi = L(m), r.bgColor.ansi256 = N(m), r.bgColor.ansi16m = I(m), Object.defineProperties(r, { rgbToAnsi256: { value: (u, F, e) => u === F && F === e ? u < 8 ? 16 : u > 248 ? 231 : Math.round((u - 8) / 247 * 24) + 232 : 16 + 36 * Math.round(u / 255 * 5) + 6 * Math.round(F / 255 * 5) + Math.round(e / 255 * 5), enumerable: false }, hexToRgb: { value: (u) => {
|
|
1607
|
+
const F = /[a-f\d]{6}|[a-f\d]{3}/i.exec(u.toString(16));
|
|
1608
|
+
if (!F)
|
|
1609
|
+
return [0, 0, 0];
|
|
1610
|
+
let [e] = F;
|
|
1611
|
+
e.length === 3 && (e = [...e].map((i) => i + i).join(""));
|
|
1612
|
+
const s = Number.parseInt(e, 16);
|
|
1613
|
+
return [s >> 16 & 255, s >> 8 & 255, s & 255];
|
|
1614
|
+
}, enumerable: false }, hexToAnsi256: { value: (u) => r.rgbToAnsi256(...r.hexToRgb(u)), enumerable: false }, ansi256ToAnsi: { value: (u) => {
|
|
1615
|
+
if (u < 8)
|
|
1616
|
+
return 30 + u;
|
|
1617
|
+
if (u < 16)
|
|
1618
|
+
return 90 + (u - 8);
|
|
1619
|
+
let F, e, s;
|
|
1620
|
+
if (u >= 232)
|
|
1621
|
+
F = ((u - 232) * 10 + 8) / 255, e = F, s = F;
|
|
1622
|
+
else {
|
|
1623
|
+
u -= 16;
|
|
1624
|
+
const C = u % 36;
|
|
1625
|
+
F = Math.floor(u / 36) / 5, e = Math.floor(C / 6) / 5, s = C % 6 / 5;
|
|
1585
1626
|
}
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
const isNew = latestTag !== null && latestTag !== currentTag;
|
|
1593
|
-
const manifest = await fetchManifest(latestTag ?? currentTag);
|
|
1594
|
-
return { manifest, isNew, latestTag };
|
|
1627
|
+
const i = Math.max(F, e, s) * 2;
|
|
1628
|
+
if (i === 0)
|
|
1629
|
+
return 30;
|
|
1630
|
+
let D = 30 + (Math.round(s) << 2 | Math.round(e) << 1 | Math.round(F));
|
|
1631
|
+
return i === 2 && (D += 60), D;
|
|
1632
|
+
}, enumerable: false }, rgbToAnsi: { value: (u, F, e) => r.ansi256ToAnsi(r.rgbToAnsi256(u, F, e)), enumerable: false }, hexToAnsi: { value: (u) => r.ansi256ToAnsi(r.hexToAnsi256(u)), enumerable: false } }), r;
|
|
1595
1633
|
}
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
const
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1634
|
+
var iD = sD();
|
|
1635
|
+
var v = new Set(["\x1B", ""]);
|
|
1636
|
+
var CD = 39;
|
|
1637
|
+
var w = "\x07";
|
|
1638
|
+
var W = "[";
|
|
1639
|
+
var rD = "]";
|
|
1640
|
+
var R = "m";
|
|
1641
|
+
var y = `${rD}8;;`;
|
|
1642
|
+
var V = (t) => `${v.values().next().value}${W}${t}${R}`;
|
|
1643
|
+
var z = (t) => `${v.values().next().value}${y}${t}${w}`;
|
|
1644
|
+
var ED = (t) => t.split(" ").map((u) => A(u));
|
|
1645
|
+
var _ = (t, u, F) => {
|
|
1646
|
+
const e = [...u];
|
|
1647
|
+
let s = false, i = false, D = A(T(t[t.length - 1]));
|
|
1648
|
+
for (const [C, o] of e.entries()) {
|
|
1649
|
+
const E = A(o);
|
|
1650
|
+
if (D + E <= F ? t[t.length - 1] += o : (t.push(o), D = 0), v.has(o) && (s = true, i = e.slice(C + 1).join("").startsWith(y)), s) {
|
|
1651
|
+
i ? o === w && (s = false, i = false) : o === R && (s = false);
|
|
1652
|
+
continue;
|
|
1653
|
+
}
|
|
1654
|
+
D += E, D === F && C < e.length - 1 && (t.push(""), D = 0);
|
|
1616
1655
|
}
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
}
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1656
|
+
!D && t[t.length - 1].length > 0 && t.length > 1 && (t[t.length - 2] += t.pop());
|
|
1657
|
+
};
|
|
1658
|
+
var nD = (t) => {
|
|
1659
|
+
const u = t.split(" ");
|
|
1660
|
+
let F = u.length;
|
|
1661
|
+
for (;F > 0 && !(A(u[F - 1]) > 0); )
|
|
1662
|
+
F--;
|
|
1663
|
+
return F === u.length ? t : u.slice(0, F).join(" ") + u.slice(F).join("");
|
|
1664
|
+
};
|
|
1665
|
+
var oD = (t, u, F = {}) => {
|
|
1666
|
+
if (F.trim !== false && t.trim() === "")
|
|
1667
|
+
return "";
|
|
1668
|
+
let e = "", s, i;
|
|
1669
|
+
const D = ED(t);
|
|
1670
|
+
let C = [""];
|
|
1671
|
+
for (const [E, a] of t.split(" ").entries()) {
|
|
1672
|
+
F.trim !== false && (C[C.length - 1] = C[C.length - 1].trimStart());
|
|
1673
|
+
let n = A(C[C.length - 1]);
|
|
1674
|
+
if (E !== 0 && (n >= u && (F.wordWrap === false || F.trim === false) && (C.push(""), n = 0), (n > 0 || F.trim === false) && (C[C.length - 1] += " ", n++)), F.hard && D[E] > u) {
|
|
1675
|
+
const B = u - n, p = 1 + Math.floor((D[E] - B - 1) / u);
|
|
1676
|
+
Math.floor((D[E] - 1) / u) < p && C.push(""), _(C, a, u);
|
|
1677
|
+
continue;
|
|
1678
|
+
}
|
|
1679
|
+
if (n + D[E] > u && n > 0 && D[E] > 0) {
|
|
1680
|
+
if (F.wordWrap === false && n < u) {
|
|
1681
|
+
_(C, a, u);
|
|
1682
|
+
continue;
|
|
1683
|
+
}
|
|
1684
|
+
C.push("");
|
|
1685
|
+
}
|
|
1686
|
+
if (n + D[E] > u && F.wordWrap === false) {
|
|
1687
|
+
_(C, a, u);
|
|
1688
|
+
continue;
|
|
1689
|
+
}
|
|
1690
|
+
C[C.length - 1] += a;
|
|
1691
|
+
}
|
|
1692
|
+
F.trim !== false && (C = C.map((E) => nD(E)));
|
|
1693
|
+
const o = [...C.join(`
|
|
1694
|
+
`)];
|
|
1695
|
+
for (const [E, a] of o.entries()) {
|
|
1696
|
+
if (e += a, v.has(a)) {
|
|
1697
|
+
const { groups: B } = new RegExp(`(?:\\${W}(?<code>\\d+)m|\\${y}(?<uri>.*)${w})`).exec(o.slice(E).join("")) || { groups: {} };
|
|
1698
|
+
if (B.code !== undefined) {
|
|
1699
|
+
const p = Number.parseFloat(B.code);
|
|
1700
|
+
s = p === CD ? undefined : p;
|
|
1701
|
+
} else
|
|
1702
|
+
B.uri !== undefined && (i = B.uri.length === 0 ? undefined : B.uri);
|
|
1703
|
+
}
|
|
1704
|
+
const n = iD.codes.get(Number(s));
|
|
1705
|
+
o[E + 1] === `
|
|
1706
|
+
` ? (i && (e += z("")), s && n && (e += V(n))) : a === `
|
|
1707
|
+
` && (s && n && (e += V(s)), i && (e += z(i)));
|
|
1658
1708
|
}
|
|
1709
|
+
return e;
|
|
1710
|
+
};
|
|
1711
|
+
function G(t, u, F) {
|
|
1712
|
+
return String(t).normalize().replace(/\r\n/g, `
|
|
1713
|
+
`).split(`
|
|
1714
|
+
`).map((e) => oD(e, u, F)).join(`
|
|
1715
|
+
`);
|
|
1659
1716
|
}
|
|
1660
|
-
|
|
1661
|
-
|
|
1717
|
+
var aD = ["up", "down", "left", "right", "space", "enter", "cancel"];
|
|
1718
|
+
var c = { actions: new Set(aD), aliases: new Map([["k", "up"], ["j", "down"], ["h", "left"], ["l", "right"], ["\x03", "cancel"], ["escape", "cancel"]]) };
|
|
1719
|
+
function hD(t) {
|
|
1720
|
+
for (const u in t) {
|
|
1721
|
+
const F = u;
|
|
1722
|
+
if (!Object.hasOwn(t, F))
|
|
1723
|
+
continue;
|
|
1724
|
+
const e = t[F];
|
|
1725
|
+
switch (F) {
|
|
1726
|
+
case "aliases": {
|
|
1727
|
+
for (const s in e)
|
|
1728
|
+
Object.hasOwn(e, s) && (c.aliases.has(s) || c.aliases.set(s, e[s]));
|
|
1729
|
+
break;
|
|
1730
|
+
}
|
|
1731
|
+
}
|
|
1732
|
+
}
|
|
1662
1733
|
}
|
|
1663
|
-
function
|
|
1664
|
-
|
|
1734
|
+
function k(t, u) {
|
|
1735
|
+
if (typeof t == "string")
|
|
1736
|
+
return c.aliases.get(t) === u;
|
|
1737
|
+
for (const F of t)
|
|
1738
|
+
if (F !== undefined && k(F, u))
|
|
1739
|
+
return true;
|
|
1740
|
+
return false;
|
|
1665
1741
|
}
|
|
1666
|
-
function
|
|
1667
|
-
|
|
1668
|
-
if (!lockfile)
|
|
1669
|
-
return;
|
|
1670
|
-
if (!lockfile[type])
|
|
1671
|
-
return;
|
|
1672
|
-
if (!(name in lockfile[type]))
|
|
1742
|
+
function lD(t, u) {
|
|
1743
|
+
if (t === u)
|
|
1673
1744
|
return;
|
|
1674
|
-
|
|
1675
|
-
|
|
1745
|
+
const F = t.split(`
|
|
1746
|
+
`), e = u.split(`
|
|
1747
|
+
`), s = [];
|
|
1748
|
+
for (let i = 0;i < Math.max(F.length, e.length); i++)
|
|
1749
|
+
F[i] !== e[i] && s.push(i);
|
|
1750
|
+
return s;
|
|
1676
1751
|
}
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1752
|
+
var xD = globalThis.process.platform.startsWith("win");
|
|
1753
|
+
var S = Symbol("clack:cancel");
|
|
1754
|
+
function BD(t) {
|
|
1755
|
+
return t === S;
|
|
1756
|
+
}
|
|
1757
|
+
function d(t, u) {
|
|
1758
|
+
const F = t;
|
|
1759
|
+
F.isTTY && F.setRawMode(u);
|
|
1760
|
+
}
|
|
1761
|
+
function cD({ input: t = $, output: u = j, overwrite: F = true, hideCursor: e = true } = {}) {
|
|
1762
|
+
const s = f.createInterface({ input: t, output: u, prompt: "", tabSize: 1 });
|
|
1763
|
+
f.emitKeypressEvents(t, s), t.isTTY && t.setRawMode(true);
|
|
1764
|
+
const i = (D, { name: C, sequence: o }) => {
|
|
1765
|
+
const E = String(D);
|
|
1766
|
+
if (k([E, C, o], "cancel")) {
|
|
1767
|
+
e && u.write(import_sisteransi.cursor.show), process.exit(0);
|
|
1768
|
+
return;
|
|
1769
|
+
}
|
|
1770
|
+
if (!F)
|
|
1771
|
+
return;
|
|
1772
|
+
const a = C === "return" ? 0 : -1, n = C === "return" ? -1 : 0;
|
|
1773
|
+
f.moveCursor(u, a, n, () => {
|
|
1774
|
+
f.clearLine(u, 1, () => {
|
|
1775
|
+
t.once("keypress", i);
|
|
1776
|
+
});
|
|
1689
1777
|
});
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
lockfile.skills = {};
|
|
1695
|
-
lockfile.mcpServers = {};
|
|
1696
|
-
lockfile.lockedAt = new Date().toISOString();
|
|
1697
|
-
writeLockfile(opencodeRoot, lockfile);
|
|
1778
|
+
};
|
|
1779
|
+
return e && u.write(import_sisteransi.cursor.hide), t.once("keypress", i), () => {
|
|
1780
|
+
t.off("keypress", i), e && u.write(import_sisteransi.cursor.show), t.isTTY && !xD && t.setRawMode(false), s.terminal = false, s.close();
|
|
1781
|
+
};
|
|
1698
1782
|
}
|
|
1699
|
-
var
|
|
1700
|
-
var
|
|
1701
|
-
|
|
1702
|
-
LOCKFILE_VERSION = manifest_default.version;
|
|
1703
|
-
});
|
|
1783
|
+
var AD = Object.defineProperty;
|
|
1784
|
+
var pD = (t, u, F) => (u in t) ? AD(t, u, { enumerable: true, configurable: true, writable: true, value: F }) : t[u] = F;
|
|
1785
|
+
var h = (t, u, F) => (pD(t, typeof u != "symbol" ? u + "" : u, F), F);
|
|
1704
1786
|
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
const
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1787
|
+
class x {
|
|
1788
|
+
constructor(u, F = true) {
|
|
1789
|
+
h(this, "input"), h(this, "output"), h(this, "_abortSignal"), h(this, "rl"), h(this, "opts"), h(this, "_render"), h(this, "_track", false), h(this, "_prevFrame", ""), h(this, "_subscribers", new Map), h(this, "_cursor", 0), h(this, "state", "initial"), h(this, "error", ""), h(this, "value");
|
|
1790
|
+
const { input: e = $, output: s = j, render: i, signal: D, ...C } = u;
|
|
1791
|
+
this.opts = C, this.onKeypress = this.onKeypress.bind(this), this.close = this.close.bind(this), this.render = this.render.bind(this), this._render = i.bind(this), this._track = F, this._abortSignal = D, this.input = e, this.output = s;
|
|
1792
|
+
}
|
|
1793
|
+
unsubscribe() {
|
|
1794
|
+
this._subscribers.clear();
|
|
1795
|
+
}
|
|
1796
|
+
setSubscriber(u, F) {
|
|
1797
|
+
const e = this._subscribers.get(u) ?? [];
|
|
1798
|
+
e.push(F), this._subscribers.set(u, e);
|
|
1799
|
+
}
|
|
1800
|
+
on(u, F) {
|
|
1801
|
+
this.setSubscriber(u, { cb: F });
|
|
1802
|
+
}
|
|
1803
|
+
once(u, F) {
|
|
1804
|
+
this.setSubscriber(u, { cb: F, once: true });
|
|
1805
|
+
}
|
|
1806
|
+
emit(u, ...F) {
|
|
1807
|
+
const e = this._subscribers.get(u) ?? [], s = [];
|
|
1808
|
+
for (const i of e)
|
|
1809
|
+
i.cb(...F), i.once && s.push(() => e.splice(e.indexOf(i), 1));
|
|
1810
|
+
for (const i of s)
|
|
1811
|
+
i();
|
|
1812
|
+
}
|
|
1813
|
+
prompt() {
|
|
1814
|
+
return new Promise((u, F) => {
|
|
1815
|
+
if (this._abortSignal) {
|
|
1816
|
+
if (this._abortSignal.aborted)
|
|
1817
|
+
return this.state = "cancel", this.close(), u(S);
|
|
1818
|
+
this._abortSignal.addEventListener("abort", () => {
|
|
1819
|
+
this.state = "cancel", this.close();
|
|
1820
|
+
}, { once: true });
|
|
1731
1821
|
}
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1822
|
+
const e = new U(0);
|
|
1823
|
+
e._write = (s, i, D) => {
|
|
1824
|
+
this._track && (this.value = this.rl?.line.replace(/\t/g, ""), this._cursor = this.rl?.cursor ?? 0, this.emit("value", this.value)), D();
|
|
1825
|
+
}, this.input.pipe(e), this.rl = M.createInterface({ input: this.input, output: e, tabSize: 2, prompt: "", escapeCodeTimeout: 50 }), M.emitKeypressEvents(this.input, this.rl), this.rl.prompt(), this.opts.initialValue !== undefined && this._track && this.rl.write(this.opts.initialValue), this.input.on("keypress", this.onKeypress), d(this.input, true), this.output.on("resize", this.render), this.render(), this.once("submit", () => {
|
|
1826
|
+
this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), d(this.input, false), u(this.value);
|
|
1827
|
+
}), this.once("cancel", () => {
|
|
1828
|
+
this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), d(this.input, false), u(S);
|
|
1829
|
+
});
|
|
1830
|
+
});
|
|
1831
|
+
}
|
|
1832
|
+
onKeypress(u, F) {
|
|
1833
|
+
if (this.state === "error" && (this.state = "active"), F?.name && (!this._track && c.aliases.has(F.name) && this.emit("cursor", c.aliases.get(F.name)), c.actions.has(F.name) && this.emit("cursor", F.name)), u && (u.toLowerCase() === "y" || u.toLowerCase() === "n") && this.emit("confirm", u.toLowerCase() === "y"), u === "\t" && this.opts.placeholder && (this.value || (this.rl?.write(this.opts.placeholder), this.emit("value", this.opts.placeholder))), u && this.emit("key", u.toLowerCase()), F?.name === "return") {
|
|
1834
|
+
if (this.opts.validate) {
|
|
1835
|
+
const e = this.opts.validate(this.value);
|
|
1836
|
+
e && (this.error = e instanceof Error ? e.message : e, this.state = "error", this.rl?.write(this.value));
|
|
1837
|
+
}
|
|
1838
|
+
this.state !== "error" && (this.state = "submit");
|
|
1749
1839
|
}
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1840
|
+
k([u, F?.name, F?.sequence], "cancel") && (this.state = "cancel"), (this.state === "submit" || this.state === "cancel") && this.emit("finalize"), this.render(), (this.state === "submit" || this.state === "cancel") && this.close();
|
|
1841
|
+
}
|
|
1842
|
+
close() {
|
|
1843
|
+
this.input.unpipe(), this.input.removeListener("keypress", this.onKeypress), this.output.write(`
|
|
1844
|
+
`), d(this.input, false), this.rl?.close(), this.rl = undefined, this.emit(`${this.state}`, this.value), this.unsubscribe();
|
|
1845
|
+
}
|
|
1846
|
+
restoreCursor() {
|
|
1847
|
+
const u = G(this._prevFrame, process.stdout.columns, { hard: true }).split(`
|
|
1848
|
+
`).length - 1;
|
|
1849
|
+
this.output.write(import_sisteransi.cursor.move(-999, u * -1));
|
|
1850
|
+
}
|
|
1851
|
+
render() {
|
|
1852
|
+
const u = G(this._render(this) ?? "", process.stdout.columns, { hard: true });
|
|
1853
|
+
if (u !== this._prevFrame) {
|
|
1854
|
+
if (this.state === "initial")
|
|
1855
|
+
this.output.write(import_sisteransi.cursor.hide);
|
|
1856
|
+
else {
|
|
1857
|
+
const F = lD(this._prevFrame, u);
|
|
1858
|
+
if (this.restoreCursor(), F && F?.length === 1) {
|
|
1859
|
+
const e = F[0];
|
|
1860
|
+
this.output.write(import_sisteransi.cursor.move(0, e)), this.output.write(import_sisteransi.erase.lines(1));
|
|
1861
|
+
const s = u.split(`
|
|
1862
|
+
`);
|
|
1863
|
+
this.output.write(s[e]), this._prevFrame = u, this.output.write(import_sisteransi.cursor.move(0, s.length - e - 1));
|
|
1864
|
+
return;
|
|
1865
|
+
}
|
|
1866
|
+
if (F && F?.length > 1) {
|
|
1867
|
+
const e = F[0];
|
|
1868
|
+
this.output.write(import_sisteransi.cursor.move(0, e)), this.output.write(import_sisteransi.erase.down());
|
|
1869
|
+
const s = u.split(`
|
|
1870
|
+
`).slice(e);
|
|
1871
|
+
this.output.write(s.join(`
|
|
1872
|
+
`)), this._prevFrame = u;
|
|
1873
|
+
return;
|
|
1874
|
+
}
|
|
1875
|
+
this.output.write(import_sisteransi.erase.down());
|
|
1876
|
+
}
|
|
1877
|
+
this.output.write(u), this.state === "initial" && (this.state = "active"), this._prevFrame = u;
|
|
1756
1878
|
}
|
|
1757
|
-
result += char;
|
|
1758
|
-
i++;
|
|
1759
1879
|
}
|
|
1760
|
-
return result.replace(/,\s*([}\]])/g, "$1");
|
|
1761
1880
|
}
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
return
|
|
1766
|
-
}
|
|
1767
|
-
|
|
1881
|
+
|
|
1882
|
+
class fD extends x {
|
|
1883
|
+
get cursor() {
|
|
1884
|
+
return this.value ? 0 : 1;
|
|
1885
|
+
}
|
|
1886
|
+
get _value() {
|
|
1887
|
+
return this.cursor === 0;
|
|
1888
|
+
}
|
|
1889
|
+
constructor(u) {
|
|
1890
|
+
super(u, false), this.value = !!u.initialValue, this.on("value", () => {
|
|
1891
|
+
this.value = this._value;
|
|
1892
|
+
}), this.on("confirm", (F) => {
|
|
1893
|
+
this.output.write(import_sisteransi.cursor.move(0, -1)), this.value = F, this.state = "submit", this.close();
|
|
1894
|
+
}), this.on("cursor", () => {
|
|
1895
|
+
this.value = !this.value;
|
|
1896
|
+
});
|
|
1768
1897
|
}
|
|
1769
1898
|
}
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1899
|
+
var gD = Object.defineProperty;
|
|
1900
|
+
var vD = (t, u, F) => (u in t) ? gD(t, u, { enumerable: true, configurable: true, writable: true, value: F }) : t[u] = F;
|
|
1901
|
+
var K = (t, u, F) => (vD(t, typeof u != "symbol" ? u + "" : u, F), F);
|
|
1902
|
+
var dD = class extends x {
|
|
1903
|
+
constructor(u) {
|
|
1904
|
+
super(u, false), K(this, "options"), K(this, "cursor", 0);
|
|
1905
|
+
const { options: F } = u;
|
|
1906
|
+
this.options = Object.entries(F).flatMap(([e, s]) => [{ value: e, group: true, label: e }, ...s.map((i) => ({ ...i, group: e }))]), this.value = [...u.initialValues ?? []], this.cursor = Math.max(this.options.findIndex(({ value: e }) => e === u.cursorAt), 0), this.on("cursor", (e) => {
|
|
1907
|
+
switch (e) {
|
|
1908
|
+
case "left":
|
|
1909
|
+
case "up":
|
|
1910
|
+
this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
|
|
1911
|
+
break;
|
|
1912
|
+
case "down":
|
|
1913
|
+
case "right":
|
|
1914
|
+
this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
|
|
1915
|
+
break;
|
|
1916
|
+
case "space":
|
|
1917
|
+
this.toggleValue();
|
|
1918
|
+
break;
|
|
1919
|
+
}
|
|
1920
|
+
});
|
|
1791
1921
|
}
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
function setMcpEntry(name, entry) {
|
|
1795
|
-
const projectRoot = findProjectRoot();
|
|
1796
|
-
const configPath = ensureOpenCodeConfig(projectRoot);
|
|
1797
|
-
const config = readOpenCodeConfig(configPath);
|
|
1798
|
-
if (!config)
|
|
1799
|
-
return;
|
|
1800
|
-
if (!config.mcp)
|
|
1801
|
-
config.mcp = {};
|
|
1802
|
-
config.mcp[name] = entry;
|
|
1803
|
-
writeOpenCodeConfig(configPath, config);
|
|
1804
|
-
}
|
|
1805
|
-
function ensureMcpEntry(name, entry) {
|
|
1806
|
-
const projectRoot = findProjectRoot();
|
|
1807
|
-
const configPath = ensureOpenCodeConfig(projectRoot);
|
|
1808
|
-
const config = readOpenCodeConfig(configPath);
|
|
1809
|
-
if (!config)
|
|
1810
|
-
return;
|
|
1811
|
-
if (!config.mcp)
|
|
1812
|
-
config.mcp = {};
|
|
1813
|
-
const mcp = config.mcp;
|
|
1814
|
-
if (!mcp[name]) {
|
|
1815
|
-
mcp[name] = entry;
|
|
1816
|
-
writeOpenCodeConfig(configPath, config);
|
|
1922
|
+
getGroupItems(u) {
|
|
1923
|
+
return this.options.filter((F) => F.group === u);
|
|
1817
1924
|
}
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
const projectRoot = findProjectRoot();
|
|
1821
|
-
const configPath = findOpenCodeConfig(projectRoot);
|
|
1822
|
-
if (!configPath) {
|
|
1823
|
-
return {
|
|
1824
|
-
success: false,
|
|
1825
|
-
message: "No se encontró opencode.json ni opencode.jsonc"
|
|
1826
|
-
};
|
|
1925
|
+
isGroupSelected(u) {
|
|
1926
|
+
return this.getGroupItems(u).every((F) => this.value.includes(F.value));
|
|
1827
1927
|
}
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
}
|
|
1928
|
+
toggleValue() {
|
|
1929
|
+
const u = this.options[this.cursor];
|
|
1930
|
+
if (u.group === true) {
|
|
1931
|
+
const F = u.value, e = this.getGroupItems(F);
|
|
1932
|
+
this.isGroupSelected(F) ? this.value = this.value.filter((s) => e.findIndex((i) => i.value === s) === -1) : this.value = [...this.value, ...e.map((s) => s.value)], this.value = Array.from(new Set(this.value));
|
|
1933
|
+
} else {
|
|
1934
|
+
const F = this.value.includes(u.value);
|
|
1935
|
+
this.value = F ? this.value.filter((e) => e !== u.value) : [...this.value, u.value];
|
|
1936
|
+
}
|
|
1834
1937
|
}
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1938
|
+
};
|
|
1939
|
+
var bD = Object.defineProperty;
|
|
1940
|
+
var mD = (t, u, F) => (u in t) ? bD(t, u, { enumerable: true, configurable: true, writable: true, value: F }) : t[u] = F;
|
|
1941
|
+
var Y = (t, u, F) => (mD(t, typeof u != "symbol" ? u + "" : u, F), F);
|
|
1942
|
+
var wD = class extends x {
|
|
1943
|
+
constructor(u) {
|
|
1944
|
+
super(u, false), Y(this, "options"), Y(this, "cursor", 0), this.options = u.options, this.value = [...u.initialValues ?? []], this.cursor = Math.max(this.options.findIndex(({ value: F }) => F === u.cursorAt), 0), this.on("key", (F) => {
|
|
1945
|
+
F === "a" && this.toggleAll();
|
|
1946
|
+
}), this.on("cursor", (F) => {
|
|
1947
|
+
switch (F) {
|
|
1948
|
+
case "left":
|
|
1949
|
+
case "up":
|
|
1950
|
+
this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
|
|
1951
|
+
break;
|
|
1952
|
+
case "down":
|
|
1953
|
+
case "right":
|
|
1954
|
+
this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
|
|
1955
|
+
break;
|
|
1956
|
+
case "space":
|
|
1957
|
+
this.toggleValue();
|
|
1958
|
+
break;
|
|
1959
|
+
}
|
|
1960
|
+
});
|
|
1839
1961
|
}
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
return { success: true, message: "Config actualizada (plugin legacy eliminado)" };
|
|
1962
|
+
get _value() {
|
|
1963
|
+
return this.options[this.cursor].value;
|
|
1843
1964
|
}
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1965
|
+
toggleAll() {
|
|
1966
|
+
const u = this.value.length === this.options.length;
|
|
1967
|
+
this.value = u ? [] : this.options.map((F) => F.value);
|
|
1968
|
+
}
|
|
1969
|
+
toggleValue() {
|
|
1970
|
+
const u = this.value.includes(this._value);
|
|
1971
|
+
this.value = u ? this.value.filter((F) => F !== this._value) : [...this.value, this._value];
|
|
1972
|
+
}
|
|
1973
|
+
};
|
|
1974
|
+
var yD = Object.defineProperty;
|
|
1975
|
+
var _D = (t, u, F) => (u in t) ? yD(t, u, { enumerable: true, configurable: true, writable: true, value: F }) : t[u] = F;
|
|
1976
|
+
var Z = (t, u, F) => (_D(t, typeof u != "symbol" ? u + "" : u, F), F);
|
|
1849
1977
|
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
});
|
|
1862
|
-
import { existsSync as existsSync6, mkdirSync as mkdirSync4, copyFileSync as copyFileSync3, unlinkSync as unlinkSync3, rmSync as rmSync3 } from "fs";
|
|
1863
|
-
import { join as join7 } from "path";
|
|
1864
|
-
import { execSync as execSync3 } from "child_process";
|
|
1865
|
-
async function installCodeGraph(toolsDir) {
|
|
1866
|
-
const projectRoot = findProjectRoot();
|
|
1867
|
-
const cgToolDir = join7(toolsDir ?? join7(projectRoot, ".opencode", "tools"), "codegraph");
|
|
1868
|
-
if (!existsSync6(cgToolDir))
|
|
1869
|
-
mkdirSync4(cgToolDir, { recursive: true });
|
|
1870
|
-
const target = detectPlatformTarget();
|
|
1871
|
-
if (!target) {
|
|
1872
|
-
return {
|
|
1873
|
-
success: false,
|
|
1874
|
-
message: `Plataforma no soportada para descarga local: ${process.platform}/${process.arch}. Instalá CodeGraph manualmente.`
|
|
1875
|
-
};
|
|
1978
|
+
class kD extends x {
|
|
1979
|
+
constructor({ mask: u, ...F }) {
|
|
1980
|
+
super(F), Z(this, "valueWithCursor", ""), Z(this, "_mask", "•"), this._mask = u ?? "•", this.on("finalize", () => {
|
|
1981
|
+
this.valueWithCursor = this.masked;
|
|
1982
|
+
}), this.on("value", () => {
|
|
1983
|
+
if (this.cursor >= this.value.length)
|
|
1984
|
+
this.valueWithCursor = `${this.masked}${import_picocolors.default.inverse(import_picocolors.default.hidden("_"))}`;
|
|
1985
|
+
else {
|
|
1986
|
+
const e = this.masked.slice(0, this.cursor), s = this.masked.slice(this.cursor);
|
|
1987
|
+
this.valueWithCursor = `${e}${import_picocolors.default.inverse(s[0])}${s.slice(1)}`;
|
|
1988
|
+
}
|
|
1989
|
+
});
|
|
1876
1990
|
}
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
if (existsSync6(localBinExe)) {
|
|
1880
|
-
try {
|
|
1881
|
-
execSync3(`"${localBinExe}" --version`, { stdio: "pipe", timeout: 1e4 });
|
|
1882
|
-
} catch {
|
|
1883
|
-
try {
|
|
1884
|
-
rmSync3(join7(cgToolDir, "bin"), { recursive: true, force: true });
|
|
1885
|
-
} catch {}
|
|
1886
|
-
}
|
|
1991
|
+
get cursor() {
|
|
1992
|
+
return this._cursor;
|
|
1887
1993
|
}
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
if (!tag) {
|
|
1891
|
-
return {
|
|
1892
|
-
success: false,
|
|
1893
|
-
message: "No se pudo obtener la última versión de CodeGraph desde GitHub."
|
|
1894
|
-
};
|
|
1895
|
-
}
|
|
1896
|
-
const ext = process.platform === "win32" ? "zip" : "tar.gz";
|
|
1897
|
-
const url = `https://github.com/colbymchenry/codegraph/releases/download/${tag}/codegraph-${target}.${ext}`;
|
|
1898
|
-
try {
|
|
1899
|
-
await downloadAndExtractWithRetry(url, cgToolDir, 1, 180000, 2);
|
|
1900
|
-
} catch (e2) {
|
|
1901
|
-
return {
|
|
1902
|
-
success: false,
|
|
1903
|
-
message: `Error descargando CodeGraph ${tag}: ${e2.message}`
|
|
1904
|
-
};
|
|
1905
|
-
}
|
|
1906
|
-
if (!existsSync6(localBinExe)) {
|
|
1907
|
-
return {
|
|
1908
|
-
success: false,
|
|
1909
|
-
message: `Descarga de CodeGraph ${tag} completada pero no se encontró el binario en ${localBinExe}.`
|
|
1910
|
-
};
|
|
1911
|
-
}
|
|
1912
|
-
if (process.platform !== "win32") {
|
|
1913
|
-
try {
|
|
1914
|
-
execSync3(`chmod +x "${localBinExe}"`, { stdio: "pipe" });
|
|
1915
|
-
} catch {}
|
|
1916
|
-
}
|
|
1994
|
+
get masked() {
|
|
1995
|
+
return this.value.replaceAll(/./g, this._mask);
|
|
1917
1996
|
}
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1997
|
+
}
|
|
1998
|
+
var SD = Object.defineProperty;
|
|
1999
|
+
var $D = (t, u, F) => (u in t) ? SD(t, u, { enumerable: true, configurable: true, writable: true, value: F }) : t[u] = F;
|
|
2000
|
+
var q = (t, u, F) => ($D(t, typeof u != "symbol" ? u + "" : u, F), F);
|
|
2001
|
+
|
|
2002
|
+
class jD extends x {
|
|
2003
|
+
constructor(u) {
|
|
2004
|
+
super(u, false), q(this, "options"), q(this, "cursor", 0), this.options = u.options, this.cursor = this.options.findIndex(({ value: F }) => F === u.initialValue), this.cursor === -1 && (this.cursor = 0), this.changeValue(), this.on("cursor", (F) => {
|
|
2005
|
+
switch (F) {
|
|
2006
|
+
case "left":
|
|
2007
|
+
case "up":
|
|
2008
|
+
this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
|
|
2009
|
+
break;
|
|
2010
|
+
case "down":
|
|
2011
|
+
case "right":
|
|
2012
|
+
this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
|
|
2013
|
+
break;
|
|
2014
|
+
}
|
|
2015
|
+
this.changeValue();
|
|
1926
2016
|
});
|
|
1927
|
-
} catch {}
|
|
1928
|
-
const rootAgentsMd = join7(projectRoot, "AGENTS.md");
|
|
1929
|
-
if (existsSync6(rootAgentsMd)) {
|
|
1930
|
-
const dest = join7(cgToolDir, "AGENTS.md");
|
|
1931
|
-
try {
|
|
1932
|
-
copyFileSync3(rootAgentsMd, dest);
|
|
1933
|
-
unlinkSync3(rootAgentsMd);
|
|
1934
|
-
} catch {}
|
|
1935
2017
|
}
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
2018
|
+
get _value() {
|
|
2019
|
+
return this.options[this.cursor];
|
|
2020
|
+
}
|
|
2021
|
+
changeValue() {
|
|
2022
|
+
this.value = this._value.value;
|
|
2023
|
+
}
|
|
1942
2024
|
}
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
2025
|
+
var MD = Object.defineProperty;
|
|
2026
|
+
var TD = (t, u, F) => (u in t) ? MD(t, u, { enumerable: true, configurable: true, writable: true, value: F }) : t[u] = F;
|
|
2027
|
+
var H = (t, u, F) => (TD(t, typeof u != "symbol" ? u + "" : u, F), F);
|
|
2028
|
+
|
|
2029
|
+
class OD extends x {
|
|
2030
|
+
constructor(u) {
|
|
2031
|
+
super(u, false), H(this, "options"), H(this, "cursor", 0), this.options = u.options;
|
|
2032
|
+
const F = this.options.map(({ value: [e] }) => e?.toLowerCase());
|
|
2033
|
+
this.cursor = Math.max(F.indexOf(u.initialValue), 0), this.on("key", (e) => {
|
|
2034
|
+
if (!F.includes(e))
|
|
2035
|
+
return;
|
|
2036
|
+
const s = this.options.find(({ value: [i] }) => i?.toLowerCase() === e);
|
|
2037
|
+
s && (this.value = s.value, this.state = "submit", this.emit("submit"));
|
|
1949
2038
|
});
|
|
1950
|
-
return { success: true, message: "OpenSpec configurado para OpenCode" };
|
|
1951
|
-
} catch (e2) {
|
|
1952
|
-
return {
|
|
1953
|
-
success: false,
|
|
1954
|
-
message: `Error configurando OpenSpec: ${e2.message}`
|
|
1955
|
-
};
|
|
1956
2039
|
}
|
|
1957
2040
|
}
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
} else {
|
|
1975
|
-
copyFileSync3(globalBin, localBin2);
|
|
1976
|
-
}
|
|
1977
|
-
} catch {}
|
|
1978
|
-
}
|
|
1979
|
-
setMcpEntry("engram", {
|
|
1980
|
-
type: "local",
|
|
1981
|
-
command: [`.opencode/tools/engram/bin/engram`, "mcp"],
|
|
1982
|
-
enabled: true
|
|
2041
|
+
|
|
2042
|
+
class PD extends x {
|
|
2043
|
+
get valueWithCursor() {
|
|
2044
|
+
if (this.state === "submit")
|
|
2045
|
+
return this.value;
|
|
2046
|
+
if (this.cursor >= this.value.length)
|
|
2047
|
+
return `${this.value}█`;
|
|
2048
|
+
const u = this.value.slice(0, this.cursor), [F, ...e] = this.value.slice(this.cursor);
|
|
2049
|
+
return `${u}${import_picocolors.default.inverse(F)}${e.join("")}`;
|
|
2050
|
+
}
|
|
2051
|
+
get cursor() {
|
|
2052
|
+
return this._cursor;
|
|
2053
|
+
}
|
|
2054
|
+
constructor(u) {
|
|
2055
|
+
super(u), this.on("finalize", () => {
|
|
2056
|
+
this.value || (this.value = u.defaultValue);
|
|
1983
2057
|
});
|
|
1984
|
-
const pluginSource2 = join7(projectRoot, "assets", "plugins", "engram.ts");
|
|
1985
|
-
const pluginsDir2 = join7(projectRoot, ".opencode", "plugins");
|
|
1986
|
-
const pluginTarget2 = join7(pluginsDir2, "engram.ts");
|
|
1987
|
-
if (existsSync6(pluginSource2)) {
|
|
1988
|
-
if (!existsSync6(pluginsDir2))
|
|
1989
|
-
mkdirSync4(pluginsDir2, { recursive: true });
|
|
1990
|
-
try {
|
|
1991
|
-
copyFileSync3(pluginSource2, pluginTarget2);
|
|
1992
|
-
} catch {}
|
|
1993
|
-
}
|
|
1994
|
-
return { success: true, message: `Engram global detectado en ${globalBin} — usando binario global. Plugin copiado a .opencode/plugins/` };
|
|
1995
2058
|
}
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2059
|
+
}
|
|
2060
|
+
|
|
2061
|
+
// node_modules/@clack/prompts/dist/index.mjs
|
|
2062
|
+
var import_picocolors2 = __toESM(require_picocolors(), 1);
|
|
2063
|
+
var import_sisteransi2 = __toESM(require_src(), 1);
|
|
2064
|
+
import p from "node:process";
|
|
2065
|
+
function X2() {
|
|
2066
|
+
return p.platform !== "win32" ? p.env.TERM !== "linux" : !!p.env.CI || !!p.env.WT_SESSION || !!p.env.TERMINUS_SUBLIME || p.env.ConEmuTask === "{cmd::Cmder}" || p.env.TERM_PROGRAM === "Terminus-Sublime" || p.env.TERM_PROGRAM === "vscode" || p.env.TERM === "xterm-256color" || p.env.TERM === "alacritty" || p.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
|
|
2067
|
+
}
|
|
2068
|
+
var E = X2();
|
|
2069
|
+
var u = (s, n) => E ? s : n;
|
|
2070
|
+
var ee = u("◆", "*");
|
|
2071
|
+
var A2 = u("■", "x");
|
|
2072
|
+
var B = u("▲", "x");
|
|
2073
|
+
var S2 = u("◇", "o");
|
|
2074
|
+
var te = u("┌", "T");
|
|
2075
|
+
var a = u("│", "|");
|
|
2076
|
+
var m2 = u("└", "—");
|
|
2077
|
+
var j2 = u("●", ">");
|
|
2078
|
+
var R2 = u("○", " ");
|
|
2079
|
+
var V2 = u("◻", "[•]");
|
|
2080
|
+
var M2 = u("◼", "[+]");
|
|
2081
|
+
var G2 = u("◻", "[ ]");
|
|
2082
|
+
var se = u("▪", "•");
|
|
2083
|
+
var N2 = u("─", "-");
|
|
2084
|
+
var re = u("╮", "+");
|
|
2085
|
+
var ie = u("├", "+");
|
|
2086
|
+
var ne = u("╯", "+");
|
|
2087
|
+
var ae = u("●", "•");
|
|
2088
|
+
var oe = u("◆", "*");
|
|
2089
|
+
var ce = u("▲", "!");
|
|
2090
|
+
var le = u("■", "x");
|
|
2091
|
+
var y2 = (s) => {
|
|
2092
|
+
switch (s) {
|
|
2093
|
+
case "initial":
|
|
2094
|
+
case "active":
|
|
2095
|
+
return import_picocolors2.default.cyan(ee);
|
|
2096
|
+
case "cancel":
|
|
2097
|
+
return import_picocolors2.default.red(A2);
|
|
2098
|
+
case "error":
|
|
2099
|
+
return import_picocolors2.default.yellow(B);
|
|
2100
|
+
case "submit":
|
|
2101
|
+
return import_picocolors2.default.green(S2);
|
|
2102
|
+
}
|
|
2103
|
+
};
|
|
2104
|
+
var k2 = (s) => {
|
|
2105
|
+
const { cursor: n, options: t, style: i } = s, r2 = s.maxItems ?? Number.POSITIVE_INFINITY, c2 = Math.max(process.stdout.rows - 4, 0), o = Math.min(c2, Math.max(r2, 5));
|
|
2106
|
+
let l2 = 0;
|
|
2107
|
+
n >= l2 + o - 3 ? l2 = Math.max(Math.min(n - o + 3, t.length - o), 0) : n < l2 + 2 && (l2 = Math.max(n - 2, 0));
|
|
2108
|
+
const $2 = o < t.length && l2 > 0, d2 = o < t.length && l2 + o < t.length;
|
|
2109
|
+
return t.slice(l2, l2 + o).map((w2, b2, C) => {
|
|
2110
|
+
const I2 = b2 === 0 && $2, x2 = b2 === C.length - 1 && d2;
|
|
2111
|
+
return I2 || x2 ? import_picocolors2.default.dim("...") : i(w2, b2 + l2 === n);
|
|
2112
|
+
});
|
|
2113
|
+
};
|
|
2114
|
+
var ue = (s) => new PD({ validate: s.validate, placeholder: s.placeholder, defaultValue: s.defaultValue, initialValue: s.initialValue, render() {
|
|
2115
|
+
const n = `${import_picocolors2.default.gray(a)}
|
|
2116
|
+
${y2(this.state)} ${s.message}
|
|
2117
|
+
`, t = s.placeholder ? import_picocolors2.default.inverse(s.placeholder[0]) + import_picocolors2.default.dim(s.placeholder.slice(1)) : import_picocolors2.default.inverse(import_picocolors2.default.hidden("_")), i = this.value ? this.valueWithCursor : t;
|
|
2118
|
+
switch (this.state) {
|
|
2119
|
+
case "error":
|
|
2120
|
+
return `${n.trim()}
|
|
2121
|
+
${import_picocolors2.default.yellow(a)} ${i}
|
|
2122
|
+
${import_picocolors2.default.yellow(m2)} ${import_picocolors2.default.yellow(this.error)}
|
|
2123
|
+
`;
|
|
2124
|
+
case "submit":
|
|
2125
|
+
return `${n}${import_picocolors2.default.gray(a)} ${import_picocolors2.default.dim(this.value || s.placeholder)}`;
|
|
2126
|
+
case "cancel":
|
|
2127
|
+
return `${n}${import_picocolors2.default.gray(a)} ${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(this.value ?? ""))}${this.value?.trim() ? `
|
|
2128
|
+
${import_picocolors2.default.gray(a)}` : ""}`;
|
|
2129
|
+
default:
|
|
2130
|
+
return `${n}${import_picocolors2.default.cyan(a)} ${i}
|
|
2131
|
+
${import_picocolors2.default.cyan(m2)}
|
|
2132
|
+
`;
|
|
2133
|
+
}
|
|
2134
|
+
} }).prompt();
|
|
2135
|
+
var $e = (s) => new kD({ validate: s.validate, mask: s.mask ?? se, render() {
|
|
2136
|
+
const n = `${import_picocolors2.default.gray(a)}
|
|
2137
|
+
${y2(this.state)} ${s.message}
|
|
2138
|
+
`, t = this.valueWithCursor, i = this.masked;
|
|
2139
|
+
switch (this.state) {
|
|
2140
|
+
case "error":
|
|
2141
|
+
return `${n.trim()}
|
|
2142
|
+
${import_picocolors2.default.yellow(a)} ${i}
|
|
2143
|
+
${import_picocolors2.default.yellow(m2)} ${import_picocolors2.default.yellow(this.error)}
|
|
2144
|
+
`;
|
|
2145
|
+
case "submit":
|
|
2146
|
+
return `${n}${import_picocolors2.default.gray(a)} ${import_picocolors2.default.dim(i)}`;
|
|
2147
|
+
case "cancel":
|
|
2148
|
+
return `${n}${import_picocolors2.default.gray(a)} ${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(i ?? ""))}${i ? `
|
|
2149
|
+
${import_picocolors2.default.gray(a)}` : ""}`;
|
|
2150
|
+
default:
|
|
2151
|
+
return `${n}${import_picocolors2.default.cyan(a)} ${t}
|
|
2152
|
+
${import_picocolors2.default.cyan(m2)}
|
|
2153
|
+
`;
|
|
2006
2154
|
}
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2155
|
+
} }).prompt();
|
|
2156
|
+
var me = (s) => {
|
|
2157
|
+
const n = s.active ?? "Yes", t = s.inactive ?? "No";
|
|
2158
|
+
return new fD({ active: n, inactive: t, initialValue: s.initialValue ?? true, render() {
|
|
2159
|
+
const i = `${import_picocolors2.default.gray(a)}
|
|
2160
|
+
${y2(this.state)} ${s.message}
|
|
2161
|
+
`, r2 = this.value ? n : t;
|
|
2162
|
+
switch (this.state) {
|
|
2163
|
+
case "submit":
|
|
2164
|
+
return `${i}${import_picocolors2.default.gray(a)} ${import_picocolors2.default.dim(r2)}`;
|
|
2165
|
+
case "cancel":
|
|
2166
|
+
return `${i}${import_picocolors2.default.gray(a)} ${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(r2))}
|
|
2167
|
+
${import_picocolors2.default.gray(a)}`;
|
|
2168
|
+
default:
|
|
2169
|
+
return `${i}${import_picocolors2.default.cyan(a)} ${this.value ? `${import_picocolors2.default.green(j2)} ${n}` : `${import_picocolors2.default.dim(R2)} ${import_picocolors2.default.dim(n)}`} ${import_picocolors2.default.dim("/")} ${this.value ? `${import_picocolors2.default.dim(R2)} ${import_picocolors2.default.dim(t)}` : `${import_picocolors2.default.green(j2)} ${t}`}
|
|
2170
|
+
${import_picocolors2.default.cyan(m2)}
|
|
2171
|
+
`;
|
|
2015
2172
|
}
|
|
2016
|
-
}
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2173
|
+
} }).prompt();
|
|
2174
|
+
};
|
|
2175
|
+
var de = (s) => {
|
|
2176
|
+
const n = (t, i) => {
|
|
2177
|
+
const r2 = t.label ?? String(t.value);
|
|
2178
|
+
switch (i) {
|
|
2179
|
+
case "selected":
|
|
2180
|
+
return `${import_picocolors2.default.dim(r2)}`;
|
|
2181
|
+
case "active":
|
|
2182
|
+
return `${import_picocolors2.default.green(j2)} ${r2} ${t.hint ? import_picocolors2.default.dim(`(${t.hint})`) : ""}`;
|
|
2183
|
+
case "cancelled":
|
|
2184
|
+
return `${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(r2))}`;
|
|
2185
|
+
default:
|
|
2186
|
+
return `${import_picocolors2.default.dim(R2)} ${import_picocolors2.default.dim(r2)}`;
|
|
2024
2187
|
}
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
const
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2188
|
+
};
|
|
2189
|
+
return new jD({ options: s.options, initialValue: s.initialValue, render() {
|
|
2190
|
+
const t = `${import_picocolors2.default.gray(a)}
|
|
2191
|
+
${y2(this.state)} ${s.message}
|
|
2192
|
+
`;
|
|
2193
|
+
switch (this.state) {
|
|
2194
|
+
case "submit":
|
|
2195
|
+
return `${t}${import_picocolors2.default.gray(a)} ${n(this.options[this.cursor], "selected")}`;
|
|
2196
|
+
case "cancel":
|
|
2197
|
+
return `${t}${import_picocolors2.default.gray(a)} ${n(this.options[this.cursor], "cancelled")}
|
|
2198
|
+
${import_picocolors2.default.gray(a)}`;
|
|
2199
|
+
default:
|
|
2200
|
+
return `${t}${import_picocolors2.default.cyan(a)} ${k2({ cursor: this.cursor, options: this.options, maxItems: s.maxItems, style: (i, r2) => n(i, r2 ? "active" : "inactive") }).join(`
|
|
2201
|
+
${import_picocolors2.default.cyan(a)} `)}
|
|
2202
|
+
${import_picocolors2.default.cyan(m2)}
|
|
2203
|
+
`;
|
|
2037
2204
|
}
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2205
|
+
} }).prompt();
|
|
2206
|
+
};
|
|
2207
|
+
var he = (s) => {
|
|
2208
|
+
const n = (t, i = "inactive") => {
|
|
2209
|
+
const r2 = t.label ?? String(t.value);
|
|
2210
|
+
return i === "selected" ? `${import_picocolors2.default.dim(r2)}` : i === "cancelled" ? `${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(r2))}` : i === "active" ? `${import_picocolors2.default.bgCyan(import_picocolors2.default.gray(` ${t.value} `))} ${r2} ${t.hint ? import_picocolors2.default.dim(`(${t.hint})`) : ""}` : `${import_picocolors2.default.gray(import_picocolors2.default.bgWhite(import_picocolors2.default.inverse(` ${t.value} `)))} ${r2} ${t.hint ? import_picocolors2.default.dim(`(${t.hint})`) : ""}`;
|
|
2211
|
+
};
|
|
2212
|
+
return new OD({ options: s.options, initialValue: s.initialValue, render() {
|
|
2213
|
+
const t = `${import_picocolors2.default.gray(a)}
|
|
2214
|
+
${y2(this.state)} ${s.message}
|
|
2215
|
+
`;
|
|
2216
|
+
switch (this.state) {
|
|
2217
|
+
case "submit":
|
|
2218
|
+
return `${t}${import_picocolors2.default.gray(a)} ${n(this.options.find((i) => i.value === this.value) ?? s.options[0], "selected")}`;
|
|
2219
|
+
case "cancel":
|
|
2220
|
+
return `${t}${import_picocolors2.default.gray(a)} ${n(this.options[0], "cancelled")}
|
|
2221
|
+
${import_picocolors2.default.gray(a)}`;
|
|
2222
|
+
default:
|
|
2223
|
+
return `${t}${import_picocolors2.default.cyan(a)} ${this.options.map((i, r2) => n(i, r2 === this.cursor ? "active" : "inactive")).join(`
|
|
2224
|
+
${import_picocolors2.default.cyan(a)} `)}
|
|
2225
|
+
${import_picocolors2.default.cyan(m2)}
|
|
2226
|
+
`;
|
|
2044
2227
|
}
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2228
|
+
} }).prompt();
|
|
2229
|
+
};
|
|
2230
|
+
var pe = (s) => {
|
|
2231
|
+
const n = (t, i) => {
|
|
2232
|
+
const r2 = t.label ?? String(t.value);
|
|
2233
|
+
return i === "active" ? `${import_picocolors2.default.cyan(V2)} ${r2} ${t.hint ? import_picocolors2.default.dim(`(${t.hint})`) : ""}` : i === "selected" ? `${import_picocolors2.default.green(M2)} ${import_picocolors2.default.dim(r2)}` : i === "cancelled" ? `${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(r2))}` : i === "active-selected" ? `${import_picocolors2.default.green(M2)} ${r2} ${t.hint ? import_picocolors2.default.dim(`(${t.hint})`) : ""}` : i === "submitted" ? `${import_picocolors2.default.dim(r2)}` : `${import_picocolors2.default.dim(G2)} ${import_picocolors2.default.dim(r2)}`;
|
|
2234
|
+
};
|
|
2235
|
+
return new wD({ options: s.options, initialValues: s.initialValues, required: s.required ?? true, cursorAt: s.cursorAt, validate(t) {
|
|
2236
|
+
if (this.required && t.length === 0)
|
|
2237
|
+
return `Please select at least one option.
|
|
2238
|
+
${import_picocolors2.default.reset(import_picocolors2.default.dim(`Press ${import_picocolors2.default.gray(import_picocolors2.default.bgWhite(import_picocolors2.default.inverse(" space ")))} to select, ${import_picocolors2.default.gray(import_picocolors2.default.bgWhite(import_picocolors2.default.inverse(" enter ")))} to submit`))}`;
|
|
2239
|
+
}, render() {
|
|
2240
|
+
const t = `${import_picocolors2.default.gray(a)}
|
|
2241
|
+
${y2(this.state)} ${s.message}
|
|
2242
|
+
`, i = (r2, c2) => {
|
|
2243
|
+
const o = this.value.includes(r2.value);
|
|
2244
|
+
return c2 && o ? n(r2, "active-selected") : o ? n(r2, "selected") : n(r2, c2 ? "active" : "inactive");
|
|
2245
|
+
};
|
|
2246
|
+
switch (this.state) {
|
|
2247
|
+
case "submit":
|
|
2248
|
+
return `${t}${import_picocolors2.default.gray(a)} ${this.options.filter(({ value: r2 }) => this.value.includes(r2)).map((r2) => n(r2, "submitted")).join(import_picocolors2.default.dim(", ")) || import_picocolors2.default.dim("none")}`;
|
|
2249
|
+
case "cancel": {
|
|
2250
|
+
const r2 = this.options.filter(({ value: c2 }) => this.value.includes(c2)).map((c2) => n(c2, "cancelled")).join(import_picocolors2.default.dim(", "));
|
|
2251
|
+
return `${t}${import_picocolors2.default.gray(a)} ${r2.trim() ? `${r2}
|
|
2252
|
+
${import_picocolors2.default.gray(a)}` : ""}`;
|
|
2053
2253
|
}
|
|
2254
|
+
case "error": {
|
|
2255
|
+
const r2 = this.error.split(`
|
|
2256
|
+
`).map((c2, o) => o === 0 ? `${import_picocolors2.default.yellow(m2)} ${import_picocolors2.default.yellow(c2)}` : ` ${c2}`).join(`
|
|
2257
|
+
`);
|
|
2258
|
+
return `${t + import_picocolors2.default.yellow(a)} ${k2({ options: this.options, cursor: this.cursor, maxItems: s.maxItems, style: i }).join(`
|
|
2259
|
+
${import_picocolors2.default.yellow(a)} `)}
|
|
2260
|
+
${r2}
|
|
2261
|
+
`;
|
|
2262
|
+
}
|
|
2263
|
+
default:
|
|
2264
|
+
return `${t}${import_picocolors2.default.cyan(a)} ${k2({ options: this.options, cursor: this.cursor, maxItems: s.maxItems, style: i }).join(`
|
|
2265
|
+
${import_picocolors2.default.cyan(a)} `)}
|
|
2266
|
+
${import_picocolors2.default.cyan(m2)}
|
|
2267
|
+
`;
|
|
2054
2268
|
}
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
}
|
|
2061
|
-
if (process.platform !== "win32") {
|
|
2062
|
-
try {
|
|
2063
|
-
execSync3(`chmod +x "${localBin}"`, { stdio: "pipe" });
|
|
2064
|
-
} catch {}
|
|
2065
|
-
}
|
|
2066
|
-
}
|
|
2067
|
-
setMcpEntry("engram", {
|
|
2068
|
-
type: "local",
|
|
2069
|
-
command: [`.opencode/tools/engram/bin/engram`, "mcp"],
|
|
2070
|
-
enabled: true
|
|
2071
|
-
});
|
|
2072
|
-
const pluginSource = join7(projectRoot, "assets", "plugins", "engram.ts");
|
|
2073
|
-
const pluginsDir = join7(projectRoot, ".opencode", "plugins");
|
|
2074
|
-
const pluginTarget = join7(pluginsDir, "engram.ts");
|
|
2075
|
-
if (existsSync6(pluginSource)) {
|
|
2076
|
-
if (!existsSync6(pluginsDir))
|
|
2077
|
-
mkdirSync4(pluginsDir, { recursive: true });
|
|
2078
|
-
try {
|
|
2079
|
-
copyFileSync3(pluginSource, pluginTarget);
|
|
2080
|
-
} catch {}
|
|
2081
|
-
}
|
|
2082
|
-
return { success: true, message: "Engram instalado localmente en .opencode/tools/engram/bin/ y configurado para OpenCode (MCP + plugin)" };
|
|
2083
|
-
}
|
|
2084
|
-
function setupContext7(toolsDir) {
|
|
2085
|
-
const projectRoot = findProjectRoot();
|
|
2086
|
-
const ctx7ToolDir = join7(toolsDir ?? join7(projectRoot, ".opencode", "tools"), "context7");
|
|
2087
|
-
if (!existsSync6(ctx7ToolDir))
|
|
2088
|
-
mkdirSync4(ctx7ToolDir, { recursive: true });
|
|
2089
|
-
ensureMcpEntry("context7", {
|
|
2090
|
-
type: "remote",
|
|
2091
|
-
url: "https://mcp.context7.com/mcp",
|
|
2092
|
-
enabled: true
|
|
2093
|
-
});
|
|
2094
|
-
const npxCmd = isCommandAvailable("bun") ? "bunx" : "npx --yes";
|
|
2095
|
-
try {
|
|
2096
|
-
execSync3(`${npxCmd} ctx7 setup --opencode`, {
|
|
2097
|
-
stdio: "pipe",
|
|
2098
|
-
timeout: 60000
|
|
2099
|
-
});
|
|
2100
|
-
return { success: true, message: "Context7 configurado (MCP + skill instalado)" };
|
|
2101
|
-
} catch {
|
|
2102
|
-
return {
|
|
2103
|
-
success: true,
|
|
2104
|
-
message: "Context7 MCP registrado (skill opcional no instalada — corrí `npx ctx7 setup --opencode` manualmente si la querés)"
|
|
2105
|
-
};
|
|
2106
|
-
}
|
|
2107
|
-
}
|
|
2108
|
-
async function installStack(toolsDir) {
|
|
2109
|
-
return {
|
|
2110
|
-
codegraph: await installCodeGraph(toolsDir),
|
|
2111
|
-
openspec: setupOpenSpec(),
|
|
2112
|
-
engram: await installEngram(toolsDir),
|
|
2113
|
-
context7: setupContext7(toolsDir),
|
|
2114
|
-
config: patchOpenCodeConfig()
|
|
2269
|
+
} }).prompt();
|
|
2270
|
+
};
|
|
2271
|
+
var ge = (s) => {
|
|
2272
|
+
const n = (t, i, r2 = []) => {
|
|
2273
|
+
const c2 = t.label ?? String(t.value), o = typeof t.group == "string", l2 = o && (r2[r2.indexOf(t) + 1] ?? { group: true }), $2 = o && l2.group === true, d2 = o ? `${$2 ? m2 : a} ` : "";
|
|
2274
|
+
return i === "active" ? `${import_picocolors2.default.dim(d2)}${import_picocolors2.default.cyan(V2)} ${c2} ${t.hint ? import_picocolors2.default.dim(`(${t.hint})`) : ""}` : i === "group-active" ? `${d2}${import_picocolors2.default.cyan(V2)} ${import_picocolors2.default.dim(c2)}` : i === "group-active-selected" ? `${d2}${import_picocolors2.default.green(M2)} ${import_picocolors2.default.dim(c2)}` : i === "selected" ? `${import_picocolors2.default.dim(d2)}${import_picocolors2.default.green(M2)} ${import_picocolors2.default.dim(c2)}` : i === "cancelled" ? `${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(c2))}` : i === "active-selected" ? `${import_picocolors2.default.dim(d2)}${import_picocolors2.default.green(M2)} ${c2} ${t.hint ? import_picocolors2.default.dim(`(${t.hint})`) : ""}` : i === "submitted" ? `${import_picocolors2.default.dim(c2)}` : `${import_picocolors2.default.dim(d2)}${import_picocolors2.default.dim(G2)} ${import_picocolors2.default.dim(c2)}`;
|
|
2115
2275
|
};
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
}
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
}
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
delete config.mcp;
|
|
2132
|
-
}
|
|
2133
|
-
writeOpenCodeConfig(configPath, config);
|
|
2134
|
-
return { success: true, message: "Config de Engram eliminada de opencode.json" };
|
|
2135
|
-
}
|
|
2136
|
-
return { success: true, message: "Engram no estaba configurado en este proyecto" };
|
|
2137
|
-
}
|
|
2138
|
-
function uninstallStackConfig(paths) {
|
|
2139
|
-
const projectRoot = findProjectRoot();
|
|
2140
|
-
const removed = [];
|
|
2141
|
-
const configPath = findOpenCodeConfig(projectRoot);
|
|
2142
|
-
if (configPath) {
|
|
2143
|
-
const config = readOpenCodeConfig(configPath);
|
|
2144
|
-
if (config) {
|
|
2145
|
-
const mcp = config.mcp;
|
|
2146
|
-
let changed = false;
|
|
2147
|
-
if (mcp) {
|
|
2148
|
-
for (const name of ["codegraph", "context7", "engram"]) {
|
|
2149
|
-
if (name in mcp) {
|
|
2150
|
-
delete mcp[name];
|
|
2151
|
-
removed.push(`mcp.${name}`);
|
|
2152
|
-
changed = true;
|
|
2153
|
-
}
|
|
2154
|
-
}
|
|
2155
|
-
if (Object.keys(mcp).length === 0) {
|
|
2156
|
-
delete config.mcp;
|
|
2157
|
-
changed = true;
|
|
2158
|
-
}
|
|
2276
|
+
return new dD({ options: s.options, initialValues: s.initialValues, required: s.required ?? true, cursorAt: s.cursorAt, validate(t) {
|
|
2277
|
+
if (this.required && t.length === 0)
|
|
2278
|
+
return `Please select at least one option.
|
|
2279
|
+
${import_picocolors2.default.reset(import_picocolors2.default.dim(`Press ${import_picocolors2.default.gray(import_picocolors2.default.bgWhite(import_picocolors2.default.inverse(" space ")))} to select, ${import_picocolors2.default.gray(import_picocolors2.default.bgWhite(import_picocolors2.default.inverse(" enter ")))} to submit`))}`;
|
|
2280
|
+
}, render() {
|
|
2281
|
+
const t = `${import_picocolors2.default.gray(a)}
|
|
2282
|
+
${y2(this.state)} ${s.message}
|
|
2283
|
+
`;
|
|
2284
|
+
switch (this.state) {
|
|
2285
|
+
case "submit":
|
|
2286
|
+
return `${t}${import_picocolors2.default.gray(a)} ${this.options.filter(({ value: i }) => this.value.includes(i)).map((i) => n(i, "submitted")).join(import_picocolors2.default.dim(", "))}`;
|
|
2287
|
+
case "cancel": {
|
|
2288
|
+
const i = this.options.filter(({ value: r2 }) => this.value.includes(r2)).map((r2) => n(r2, "cancelled")).join(import_picocolors2.default.dim(", "));
|
|
2289
|
+
return `${t}${import_picocolors2.default.gray(a)} ${i.trim() ? `${i}
|
|
2290
|
+
${import_picocolors2.default.gray(a)}` : ""}`;
|
|
2159
2291
|
}
|
|
2160
|
-
|
|
2161
|
-
|
|
2292
|
+
case "error": {
|
|
2293
|
+
const i = this.error.split(`
|
|
2294
|
+
`).map((r2, c2) => c2 === 0 ? `${import_picocolors2.default.yellow(m2)} ${import_picocolors2.default.yellow(r2)}` : ` ${r2}`).join(`
|
|
2295
|
+
`);
|
|
2296
|
+
return `${t}${import_picocolors2.default.yellow(a)} ${this.options.map((r2, c2, o) => {
|
|
2297
|
+
const l2 = this.value.includes(r2.value) || r2.group === true && this.isGroupSelected(`${r2.value}`), $2 = c2 === this.cursor;
|
|
2298
|
+
return !$2 && typeof r2.group == "string" && this.options[this.cursor].value === r2.group ? n(r2, l2 ? "group-active-selected" : "group-active", o) : $2 && l2 ? n(r2, "active-selected", o) : l2 ? n(r2, "selected", o) : n(r2, $2 ? "active" : "inactive", o);
|
|
2299
|
+
}).join(`
|
|
2300
|
+
${import_picocolors2.default.yellow(a)} `)}
|
|
2301
|
+
${i}
|
|
2302
|
+
`;
|
|
2162
2303
|
}
|
|
2304
|
+
default:
|
|
2305
|
+
return `${t}${import_picocolors2.default.cyan(a)} ${this.options.map((i, r2, c2) => {
|
|
2306
|
+
const o = this.value.includes(i.value) || i.group === true && this.isGroupSelected(`${i.value}`), l2 = r2 === this.cursor;
|
|
2307
|
+
return !l2 && typeof i.group == "string" && this.options[this.cursor].value === i.group ? n(i, o ? "group-active-selected" : "group-active", c2) : l2 && o ? n(i, "active-selected", c2) : o ? n(i, "selected", c2) : n(i, l2 ? "active" : "inactive", c2);
|
|
2308
|
+
}).join(`
|
|
2309
|
+
${import_picocolors2.default.cyan(a)} `)}
|
|
2310
|
+
${import_picocolors2.default.cyan(m2)}
|
|
2311
|
+
`;
|
|
2163
2312
|
}
|
|
2313
|
+
} }).prompt();
|
|
2314
|
+
};
|
|
2315
|
+
var ye = (s = "", n = "") => {
|
|
2316
|
+
const t = `
|
|
2317
|
+
${s}
|
|
2318
|
+
`.split(`
|
|
2319
|
+
`), i = T2(n).length, r2 = Math.max(t.reduce((o, l2) => {
|
|
2320
|
+
const $2 = T2(l2);
|
|
2321
|
+
return $2.length > o ? $2.length : o;
|
|
2322
|
+
}, 0), i) + 2, c2 = t.map((o) => `${import_picocolors2.default.gray(a)} ${import_picocolors2.default.dim(o)}${" ".repeat(r2 - T2(o).length)}${import_picocolors2.default.gray(a)}`).join(`
|
|
2323
|
+
`);
|
|
2324
|
+
process.stdout.write(`${import_picocolors2.default.gray(a)}
|
|
2325
|
+
${import_picocolors2.default.green(S2)} ${import_picocolors2.default.reset(n)} ${import_picocolors2.default.gray(N2.repeat(Math.max(r2 - i - 1, 1)) + re)}
|
|
2326
|
+
${c2}
|
|
2327
|
+
${import_picocolors2.default.gray(ie + N2.repeat(r2 + 2) + ne)}
|
|
2328
|
+
`);
|
|
2329
|
+
};
|
|
2330
|
+
var ve = (s = "") => {
|
|
2331
|
+
process.stdout.write(`${import_picocolors2.default.gray(m2)} ${import_picocolors2.default.red(s)}
|
|
2332
|
+
|
|
2333
|
+
`);
|
|
2334
|
+
};
|
|
2335
|
+
var we = (s = "") => {
|
|
2336
|
+
process.stdout.write(`${import_picocolors2.default.gray(te)} ${s}
|
|
2337
|
+
`);
|
|
2338
|
+
};
|
|
2339
|
+
var fe = (s = "") => {
|
|
2340
|
+
process.stdout.write(`${import_picocolors2.default.gray(a)}
|
|
2341
|
+
${import_picocolors2.default.gray(m2)} ${s}
|
|
2342
|
+
|
|
2343
|
+
`);
|
|
2344
|
+
};
|
|
2345
|
+
var v2 = { message: (s = "", { symbol: n = import_picocolors2.default.gray(a) } = {}) => {
|
|
2346
|
+
const t = [`${import_picocolors2.default.gray(a)}`];
|
|
2347
|
+
if (s) {
|
|
2348
|
+
const [i, ...r2] = s.split(`
|
|
2349
|
+
`);
|
|
2350
|
+
t.push(`${n} ${i}`, ...r2.map((c2) => `${import_picocolors2.default.gray(a)} ${c2}`));
|
|
2164
2351
|
}
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
}
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2352
|
+
process.stdout.write(`${t.join(`
|
|
2353
|
+
`)}
|
|
2354
|
+
`);
|
|
2355
|
+
}, info: (s) => {
|
|
2356
|
+
v2.message(s, { symbol: import_picocolors2.default.blue(ae) });
|
|
2357
|
+
}, success: (s) => {
|
|
2358
|
+
v2.message(s, { symbol: import_picocolors2.default.green(oe) });
|
|
2359
|
+
}, step: (s) => {
|
|
2360
|
+
v2.message(s, { symbol: import_picocolors2.default.green(S2) });
|
|
2361
|
+
}, warn: (s) => {
|
|
2362
|
+
v2.message(s, { symbol: import_picocolors2.default.yellow(ce) });
|
|
2363
|
+
}, warning: (s) => {
|
|
2364
|
+
v2.warn(s);
|
|
2365
|
+
}, error: (s) => {
|
|
2366
|
+
v2.message(s, { symbol: import_picocolors2.default.red(le) });
|
|
2367
|
+
} };
|
|
2368
|
+
var L2 = () => {
|
|
2369
|
+
const s = E ? ["◒", "◐", "◓", "◑"] : ["•", "o", "O", "0"], n = E ? 80 : 120, t = process.env.CI === "true";
|
|
2370
|
+
let i, r2, c2 = false, o = "", l2;
|
|
2371
|
+
const $2 = (h2) => {
|
|
2372
|
+
const g2 = h2 > 1 ? "Something went wrong" : "Canceled";
|
|
2373
|
+
c2 && P2(g2, h2);
|
|
2374
|
+
}, d2 = () => $2(2), w2 = () => $2(1), b2 = () => {
|
|
2375
|
+
process.on("uncaughtExceptionMonitor", d2), process.on("unhandledRejection", d2), process.on("SIGINT", w2), process.on("SIGTERM", w2), process.on("exit", $2);
|
|
2376
|
+
}, C = () => {
|
|
2377
|
+
process.removeListener("uncaughtExceptionMonitor", d2), process.removeListener("unhandledRejection", d2), process.removeListener("SIGINT", w2), process.removeListener("SIGTERM", w2), process.removeListener("exit", $2);
|
|
2378
|
+
}, I2 = () => {
|
|
2379
|
+
if (l2 === undefined)
|
|
2380
|
+
return;
|
|
2381
|
+
t && process.stdout.write(`
|
|
2382
|
+
`);
|
|
2383
|
+
const h2 = l2.split(`
|
|
2384
|
+
`);
|
|
2385
|
+
process.stdout.write(import_sisteransi2.cursor.move(-999, h2.length - 1)), process.stdout.write(import_sisteransi2.erase.down(h2.length));
|
|
2386
|
+
}, x2 = (h2) => h2.replace(/\.+$/, ""), O2 = (h2 = "") => {
|
|
2387
|
+
c2 = true, i = cD(), o = x2(h2), process.stdout.write(`${import_picocolors2.default.gray(a)}
|
|
2388
|
+
`);
|
|
2389
|
+
let g2 = 0, f2 = 0;
|
|
2390
|
+
b2(), r2 = setInterval(() => {
|
|
2391
|
+
if (t && o === l2)
|
|
2392
|
+
return;
|
|
2393
|
+
I2(), l2 = o;
|
|
2394
|
+
const W2 = import_picocolors2.default.magenta(s[g2]), _2 = t ? "..." : ".".repeat(Math.floor(f2)).slice(0, 3);
|
|
2395
|
+
process.stdout.write(`${W2} ${o}${_2}`), g2 = g2 + 1 < s.length ? g2 + 1 : 0, f2 = f2 < s.length ? f2 + 0.125 : 0;
|
|
2396
|
+
}, n);
|
|
2397
|
+
}, P2 = (h2 = "", g2 = 0) => {
|
|
2398
|
+
c2 = false, clearInterval(r2), I2();
|
|
2399
|
+
const f2 = g2 === 0 ? import_picocolors2.default.green(S2) : g2 === 1 ? import_picocolors2.default.red(A2) : import_picocolors2.default.red(B);
|
|
2400
|
+
o = x2(h2 ?? o), process.stdout.write(`${f2} ${o}
|
|
2401
|
+
`), C(), i();
|
|
2184
2402
|
};
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
const
|
|
2191
|
-
const
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
path: openspecPath
|
|
2403
|
+
return { start: O2, stop: P2, message: (h2 = "") => {
|
|
2404
|
+
o = x2(h2 ?? o);
|
|
2405
|
+
} };
|
|
2406
|
+
};
|
|
2407
|
+
var be = async (s, n) => {
|
|
2408
|
+
const t = {}, i = Object.keys(s);
|
|
2409
|
+
for (const r2 of i) {
|
|
2410
|
+
const c2 = s[r2], o = await c2({ results: t })?.catch((l2) => {
|
|
2411
|
+
throw l2;
|
|
2412
|
+
});
|
|
2413
|
+
if (typeof n?.onCancel == "function" && BD(o)) {
|
|
2414
|
+
t[r2] = "canceled", n.onCancel({ results: t });
|
|
2415
|
+
continue;
|
|
2199
2416
|
}
|
|
2200
|
-
|
|
2201
|
-
if (!result.ostackyController.exists) {
|
|
2202
|
-
result.ostackyController.error = "ostacky-controller MCP server not found";
|
|
2203
|
-
}
|
|
2204
|
-
if (!result.openspec.exists) {
|
|
2205
|
-
result.openspec.error = "openspec MCP server not found";
|
|
2417
|
+
t[r2] = o;
|
|
2206
2418
|
}
|
|
2207
|
-
return
|
|
2208
|
-
}
|
|
2209
|
-
var
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
version: "0.6.0",
|
|
2218
|
-
description: "Instalador interactivo de agentes y comandos para OpenCode",
|
|
2219
|
-
type: "module",
|
|
2220
|
-
bin: {
|
|
2221
|
-
ostacky: "./dist/cli.js"
|
|
2222
|
-
},
|
|
2223
|
-
scripts: {
|
|
2224
|
-
prebuild: "bun run scripts/sync-version.ts",
|
|
2225
|
-
dev: "bun run src/cli.ts",
|
|
2226
|
-
build: "bun build src/cli.ts --target=node --format=esm --outfile dist/cli.js && bun scripts/add-shebang.ts",
|
|
2227
|
-
start: "node dist/cli.js",
|
|
2228
|
-
test: "bun test",
|
|
2229
|
-
"check:skills": "bun run scripts/check-skill-sync.ts",
|
|
2230
|
-
"check:skills:fix": "bun run scripts/check-skill-sync.ts --fix",
|
|
2231
|
-
"hash:check": "bun run scripts/update-manifest-hashes.ts --check",
|
|
2232
|
-
"hash:update": "bun run scripts/update-manifest-hashes.ts",
|
|
2233
|
-
prepublishOnly: "bun run build"
|
|
2234
|
-
},
|
|
2235
|
-
files: [
|
|
2236
|
-
"dist/",
|
|
2237
|
-
"assets/",
|
|
2238
|
-
"manifest.json",
|
|
2239
|
-
"LICENSE"
|
|
2240
|
-
],
|
|
2241
|
-
keywords: [
|
|
2242
|
-
"opencode",
|
|
2243
|
-
"installer",
|
|
2244
|
-
"cli",
|
|
2245
|
-
"agent"
|
|
2246
|
-
],
|
|
2247
|
-
license: "MIT",
|
|
2248
|
-
dependencies: {
|
|
2249
|
-
"@clack/prompts": "^0.9.0"
|
|
2250
|
-
},
|
|
2251
|
-
devDependencies: {
|
|
2252
|
-
"@types/bun": "latest",
|
|
2253
|
-
typescript: "^5.0.0"
|
|
2254
|
-
},
|
|
2255
|
-
publishConfig: {
|
|
2256
|
-
access: "public"
|
|
2257
|
-
},
|
|
2258
|
-
engines: {
|
|
2259
|
-
node: ">=20.0.0"
|
|
2419
|
+
return t;
|
|
2420
|
+
};
|
|
2421
|
+
var xe = async (s) => {
|
|
2422
|
+
for (const n of s) {
|
|
2423
|
+
if (n.enabled === false)
|
|
2424
|
+
continue;
|
|
2425
|
+
const t = L2();
|
|
2426
|
+
t.start(n.title);
|
|
2427
|
+
const i = await n.task(t.message);
|
|
2428
|
+
t.stop(i || n.title);
|
|
2260
2429
|
}
|
|
2261
2430
|
};
|
|
2262
2431
|
|
|
2263
2432
|
// src/prompts/index.ts
|
|
2264
|
-
init_dist2();
|
|
2265
2433
|
init_fs();
|
|
2434
|
+
import { dirname as dirname7 } from "path";
|
|
2266
2435
|
|
|
2267
2436
|
// src/prompts/helpers.ts
|
|
2268
|
-
init_dist2();
|
|
2269
2437
|
init_github();
|
|
2270
2438
|
init_fs();
|
|
2271
2439
|
init_lockfile();
|
|
@@ -2285,10 +2453,166 @@ import {
|
|
|
2285
2453
|
statSync as statSync2,
|
|
2286
2454
|
copyFileSync as copyFileSync2,
|
|
2287
2455
|
readFileSync as readFileSync5,
|
|
2288
|
-
rmSync as
|
|
2456
|
+
rmSync as rmSync3
|
|
2289
2457
|
} from "fs";
|
|
2290
|
-
import {
|
|
2291
|
-
import { join as join6 } from "path";
|
|
2458
|
+
import { execFileSync as execFileSync2, spawn } from "child_process";
|
|
2459
|
+
import { dirname as dirname4, join as join6 } from "path";
|
|
2460
|
+
import { pathToFileURL } from "url";
|
|
2461
|
+
function createMcpConfigEntry(name, nodeExecutable, serverPath, statePath) {
|
|
2462
|
+
const entry = {
|
|
2463
|
+
type: "local",
|
|
2464
|
+
command: [nodeExecutable, serverPath],
|
|
2465
|
+
enabled: true
|
|
2466
|
+
};
|
|
2467
|
+
if (name === "ostacky-controller" && statePath) {
|
|
2468
|
+
entry.environment = { OSTACKY_STATE_PATH: statePath };
|
|
2469
|
+
}
|
|
2470
|
+
return entry;
|
|
2471
|
+
}
|
|
2472
|
+
function getVerifiedNodeExecutable() {
|
|
2473
|
+
const nodeExecutable = findExecutablePath("node");
|
|
2474
|
+
if (!nodeExecutable) {
|
|
2475
|
+
throw new Error("No se encontró Node.js en PATH; no se puede iniciar un MCP local.");
|
|
2476
|
+
}
|
|
2477
|
+
try {
|
|
2478
|
+
execFileSync2(nodeExecutable, ["--version"], { stdio: "pipe", timeout: 1e4 });
|
|
2479
|
+
} catch (error) {
|
|
2480
|
+
throw new Error(`Node.js no se puede ejecutar desde ${nodeExecutable}: ${error.message}`);
|
|
2481
|
+
}
|
|
2482
|
+
return nodeExecutable;
|
|
2483
|
+
}
|
|
2484
|
+
function validateMcpModule(nodeExecutable, serverPath, cwd) {
|
|
2485
|
+
try {
|
|
2486
|
+
execFileSync2(nodeExecutable, ["--input-type=module", "--eval", "await import(process.env.OSTACKY_MCP_PROBE)"], {
|
|
2487
|
+
cwd,
|
|
2488
|
+
env: { ...process.env, OSTACKY_MCP_PROBE: pathToFileURL(serverPath).href },
|
|
2489
|
+
stdio: "pipe",
|
|
2490
|
+
timeout: 15000
|
|
2491
|
+
});
|
|
2492
|
+
} catch (error) {
|
|
2493
|
+
throw new Error(`El MCP no pasó la validación de carga: ${error.message}`);
|
|
2494
|
+
}
|
|
2495
|
+
}
|
|
2496
|
+
async function probeMcpServer(nodeExecutable, serverPath, cwd, statePath) {
|
|
2497
|
+
try {
|
|
2498
|
+
await new Promise((resolve2, reject) => {
|
|
2499
|
+
const child = spawn(nodeExecutable, [serverPath], {
|
|
2500
|
+
cwd,
|
|
2501
|
+
env: {
|
|
2502
|
+
...process.env,
|
|
2503
|
+
...statePath ? { OSTACKY_STATE_PATH: statePath } : {}
|
|
2504
|
+
},
|
|
2505
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
2506
|
+
windowsHide: true
|
|
2507
|
+
});
|
|
2508
|
+
let settled = false;
|
|
2509
|
+
let stderr = "";
|
|
2510
|
+
let stdoutBuffer = "";
|
|
2511
|
+
const requestTimeout = 1e4;
|
|
2512
|
+
const finish = (error) => {
|
|
2513
|
+
if (settled)
|
|
2514
|
+
return;
|
|
2515
|
+
settled = true;
|
|
2516
|
+
clearTimeout(timer);
|
|
2517
|
+
try {
|
|
2518
|
+
child.stdin?.end();
|
|
2519
|
+
} catch {}
|
|
2520
|
+
if (child.exitCode === null)
|
|
2521
|
+
child.kill();
|
|
2522
|
+
error ? reject(error) : resolve2();
|
|
2523
|
+
};
|
|
2524
|
+
const fail = (message) => finish(new Error(`${message}${stderr ? `: ${stderr.trim()}` : ""}`));
|
|
2525
|
+
const send = (message) => {
|
|
2526
|
+
try {
|
|
2527
|
+
child.stdin?.write(JSON.stringify(message) + `
|
|
2528
|
+
`);
|
|
2529
|
+
} catch (error) {
|
|
2530
|
+
finish(error);
|
|
2531
|
+
}
|
|
2532
|
+
};
|
|
2533
|
+
const timer = setTimeout(() => fail("El MCP no completó el health check a tiempo"), requestTimeout);
|
|
2534
|
+
child.once("error", (error) => finish(error));
|
|
2535
|
+
child.stderr?.on("data", (chunk) => {
|
|
2536
|
+
stderr += chunk.toString();
|
|
2537
|
+
});
|
|
2538
|
+
child.once("exit", (code, signal) => {
|
|
2539
|
+
fail(`El MCP terminó durante el health check (código ${code ?? "null"}, señal ${signal ?? "ninguna"})`);
|
|
2540
|
+
});
|
|
2541
|
+
child.stdout?.on("data", (chunk) => {
|
|
2542
|
+
stdoutBuffer += chunk.toString();
|
|
2543
|
+
const lines = stdoutBuffer.split(/\r?\n/);
|
|
2544
|
+
stdoutBuffer = lines.pop() ?? "";
|
|
2545
|
+
for (const line of lines) {
|
|
2546
|
+
if (!line.trim())
|
|
2547
|
+
continue;
|
|
2548
|
+
let message;
|
|
2549
|
+
try {
|
|
2550
|
+
message = JSON.parse(line);
|
|
2551
|
+
} catch {
|
|
2552
|
+
continue;
|
|
2553
|
+
}
|
|
2554
|
+
if (message.error) {
|
|
2555
|
+
fail(`El MCP respondió un error: ${message.error.message ?? "desconocido"}`);
|
|
2556
|
+
return;
|
|
2557
|
+
}
|
|
2558
|
+
if (message.id === 1) {
|
|
2559
|
+
send({ jsonrpc: "2.0", method: "notifications/initialized" });
|
|
2560
|
+
send({ jsonrpc: "2.0", id: 2, method: "tools/list", params: {} });
|
|
2561
|
+
continue;
|
|
2562
|
+
}
|
|
2563
|
+
if (message.id === 2) {
|
|
2564
|
+
const tools = message.result?.tools ?? [];
|
|
2565
|
+
if (!tools.some((tool) => tool.name === "ping") || !tools.some((tool) => tool.name === "start_request")) {
|
|
2566
|
+
fail("El MCP inició pero no expuso las tools requeridas");
|
|
2567
|
+
return;
|
|
2568
|
+
}
|
|
2569
|
+
send({
|
|
2570
|
+
jsonrpc: "2.0",
|
|
2571
|
+
id: 3,
|
|
2572
|
+
method: "tools/call",
|
|
2573
|
+
params: { name: "start_request", arguments: { requestId: "installer-probe" } }
|
|
2574
|
+
});
|
|
2575
|
+
continue;
|
|
2576
|
+
}
|
|
2577
|
+
if (message.id === 3) {
|
|
2578
|
+
const result = message.result;
|
|
2579
|
+
if (result?.isError) {
|
|
2580
|
+
fail("La tool start_request falló durante el health check");
|
|
2581
|
+
return;
|
|
2582
|
+
}
|
|
2583
|
+
finish();
|
|
2584
|
+
}
|
|
2585
|
+
}
|
|
2586
|
+
});
|
|
2587
|
+
send({
|
|
2588
|
+
jsonrpc: "2.0",
|
|
2589
|
+
id: 1,
|
|
2590
|
+
method: "initialize",
|
|
2591
|
+
params: {
|
|
2592
|
+
protocolVersion: "2025-03-26",
|
|
2593
|
+
capabilities: {},
|
|
2594
|
+
clientInfo: { name: "ostacky-installer", version: "0.6.2" }
|
|
2595
|
+
}
|
|
2596
|
+
});
|
|
2597
|
+
});
|
|
2598
|
+
} finally {
|
|
2599
|
+
if (statePath && existsSync5(statePath))
|
|
2600
|
+
rmSync3(statePath, { force: true });
|
|
2601
|
+
if (statePath && existsSync5(statePath + ".backup"))
|
|
2602
|
+
rmSync3(statePath + ".backup", { force: true });
|
|
2603
|
+
}
|
|
2604
|
+
}
|
|
2605
|
+
function takeFileSnapshot(path) {
|
|
2606
|
+
return { path, content: existsSync5(path) ? readFileSync5(path, "utf-8") : null };
|
|
2607
|
+
}
|
|
2608
|
+
function restoreFileSnapshot(snapshot) {
|
|
2609
|
+
if (snapshot.content === null) {
|
|
2610
|
+
if (existsSync5(snapshot.path))
|
|
2611
|
+
rmSync3(snapshot.path, { force: true });
|
|
2612
|
+
return;
|
|
2613
|
+
}
|
|
2614
|
+
writeFileSync5(snapshot.path, snapshot.content, "utf-8");
|
|
2615
|
+
}
|
|
2292
2616
|
function upsertLockfile(paths, type, item, manifest, contentHash) {
|
|
2293
2617
|
const existing = readLockfile(paths.root) ?? {
|
|
2294
2618
|
version: manifest.version,
|
|
@@ -2362,7 +2686,7 @@ async function installSkill(item, manifest, paths) {
|
|
|
2362
2686
|
}
|
|
2363
2687
|
const dest = join6(paths.skills, item.name);
|
|
2364
2688
|
if (existsSync5(dest)) {
|
|
2365
|
-
|
|
2689
|
+
rmSync3(dest, { recursive: true, force: true });
|
|
2366
2690
|
}
|
|
2367
2691
|
copyDirRecursive(src, dest);
|
|
2368
2692
|
upsertLockfile(paths, "skills", item, manifest, treeHash);
|
|
@@ -2378,36 +2702,67 @@ async function installMcpServer(item, manifest, paths) {
|
|
|
2378
2702
|
` + ` esperado: ${item.sha256}
|
|
2379
2703
|
` + ` recibido: ${treeHash}`);
|
|
2380
2704
|
}
|
|
2705
|
+
const nodeExecutable = getVerifiedNodeExecutable();
|
|
2706
|
+
const projectRoot = dirname4(paths.root);
|
|
2381
2707
|
const dest = join6(paths.mcp, item.name);
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2708
|
+
const staging = `${dest}.staging-${process.pid}-${Date.now()}`;
|
|
2709
|
+
const statePath = item.name === "ostacky-controller" ? join6(paths.root, "ostacky-state.json") : undefined;
|
|
2710
|
+
try {
|
|
2711
|
+
mkdirSync3(staging, { recursive: true });
|
|
2712
|
+
const bundledPath = join6(PACKAGE_ROOT, "dist", "mcp", item.name, "index.js");
|
|
2713
|
+
if (existsSync5(bundledPath)) {
|
|
2714
|
+
copyFileSync2(bundledPath, join6(staging, "index.js"));
|
|
2715
|
+
writeFileSync5(join6(staging, "package.json"), JSON.stringify({ type: "module" }) + `
|
|
2716
|
+
`, "utf-8");
|
|
2717
|
+
} else {
|
|
2718
|
+
copyDirRecursive(src, staging, true);
|
|
2719
|
+
const useBun = isCommandAvailable("bun");
|
|
2720
|
+
const packageManager = useBun ? "bun" : "npm";
|
|
2721
|
+
if (!useBun && !isCommandAvailable("npm")) {
|
|
2722
|
+
throw new Error(`No se encontró Bun ni npm para instalar dependencias de ${item.name}.`);
|
|
2723
|
+
}
|
|
2724
|
+
const args = useBun ? ["install", "--no-save"] : ["install", "--no-audit", "--no-fund"];
|
|
2725
|
+
try {
|
|
2726
|
+
const invocation = getCommandInvocation(packageManager, args);
|
|
2727
|
+
execFileSync2(invocation.command, invocation.args, {
|
|
2728
|
+
cwd: staging,
|
|
2729
|
+
stdio: "pipe",
|
|
2730
|
+
timeout: 60000
|
|
2731
|
+
});
|
|
2732
|
+
} catch (error) {
|
|
2733
|
+
throw new Error(`No se pudieron instalar dependencias de ${item.name} con ${packageManager}: ${error.message}`);
|
|
2734
|
+
}
|
|
2735
|
+
}
|
|
2736
|
+
const stagedServerPath = join6(staging, "index.js");
|
|
2737
|
+
if (!existsSync5(stagedServerPath)) {
|
|
2738
|
+
throw new Error(`El MCP ${item.name} no contiene index.js después de instalarse.`);
|
|
2739
|
+
}
|
|
2740
|
+
validateMcpModule(nodeExecutable, stagedServerPath, staging);
|
|
2741
|
+
await probeMcpServer(nodeExecutable, stagedServerPath, staging, item.name === "ostacky-controller" ? join6(staging, ".probe-state.json") : undefined);
|
|
2742
|
+
const configPath = findOpenCodeConfig(projectRoot) ?? join6(projectRoot, "opencode.json");
|
|
2743
|
+
const configSnapshot = takeFileSnapshot(configPath);
|
|
2744
|
+
const lockfileSnapshot = takeFileSnapshot(getLockfilePath(paths.root));
|
|
2745
|
+
const promotion = promoteStagedDirectory(staging, dest);
|
|
2392
2746
|
try {
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2747
|
+
setMcpEntryAtProjectRoot(projectRoot, item.name, createMcpConfigEntry(item.name, nodeExecutable, join6(dest, "index.js"), statePath));
|
|
2748
|
+
upsertLockfile(paths, "mcpServers", item, manifest, treeHash);
|
|
2749
|
+
promotion.commit();
|
|
2750
|
+
} catch (error) {
|
|
2751
|
+
try {
|
|
2752
|
+
restoreFileSnapshot(configSnapshot);
|
|
2753
|
+
} catch {}
|
|
2754
|
+
try {
|
|
2755
|
+
restoreFileSnapshot(lockfileSnapshot);
|
|
2756
|
+
} catch {}
|
|
2757
|
+
try {
|
|
2758
|
+
promotion.rollback();
|
|
2759
|
+
} catch {}
|
|
2760
|
+
throw error;
|
|
2403
2761
|
}
|
|
2762
|
+
} finally {
|
|
2763
|
+
if (existsSync5(staging))
|
|
2764
|
+
rmSync3(staging, { recursive: true, force: true });
|
|
2404
2765
|
}
|
|
2405
|
-
upsertLockfile(paths, "mcpServers", item, manifest, treeHash);
|
|
2406
|
-
ensureMcpEntry(item.name, {
|
|
2407
|
-
type: "local",
|
|
2408
|
-
command: ["node", `.opencode/mcp/${item.name}/index.js`],
|
|
2409
|
-
enabled: true
|
|
2410
|
-
});
|
|
2411
2766
|
}
|
|
2412
2767
|
function isMcpServerInstalled(name, paths) {
|
|
2413
2768
|
return existsSync5(join6(paths.mcp, name, "index.js"));
|
|
@@ -2449,7 +2804,7 @@ function uninstallSkill(name, paths) {
|
|
|
2449
2804
|
const dirPath = join6(paths.skills, name);
|
|
2450
2805
|
try {
|
|
2451
2806
|
if (existsSync5(dirPath)) {
|
|
2452
|
-
|
|
2807
|
+
rmSync3(dirPath, { recursive: true, force: true });
|
|
2453
2808
|
}
|
|
2454
2809
|
} catch {
|
|
2455
2810
|
return false;
|
|
@@ -2461,12 +2816,12 @@ function uninstallMcpServer(name, paths) {
|
|
|
2461
2816
|
const dirPath = join6(paths.mcp, name);
|
|
2462
2817
|
try {
|
|
2463
2818
|
if (existsSync5(dirPath)) {
|
|
2464
|
-
|
|
2819
|
+
rmSync3(dirPath, { recursive: true, force: true });
|
|
2465
2820
|
}
|
|
2466
2821
|
} catch {
|
|
2467
2822
|
return false;
|
|
2468
2823
|
}
|
|
2469
|
-
const projectRoot =
|
|
2824
|
+
const projectRoot = dirname4(paths.root);
|
|
2470
2825
|
const configPath = findOpenCodeConfig(projectRoot);
|
|
2471
2826
|
if (configPath) {
|
|
2472
2827
|
const config = readOpenCodeConfig(configPath);
|
|
@@ -2538,7 +2893,7 @@ async function loadLatestManifest() {
|
|
|
2538
2893
|
}
|
|
2539
2894
|
function printPostInstallSteps() {
|
|
2540
2895
|
ye([
|
|
2541
|
-
"
|
|
2896
|
+
"Cerrá y reiniciá OpenCode si ya estaba corriendo (los MCP no recargan su config en caliente):",
|
|
2542
2897
|
" TUI → opencode",
|
|
2543
2898
|
" Web → opencode web --port 4096",
|
|
2544
2899
|
"Escribí @Ostacky en el chat (TUI o web) para invocar al agente",
|
|
@@ -2641,21 +2996,21 @@ function kindLabel(type) {
|
|
|
2641
2996
|
}
|
|
2642
2997
|
|
|
2643
2998
|
// src/prompts/install.ts
|
|
2644
|
-
|
|
2645
|
-
import { join as join8 } from "path";
|
|
2999
|
+
import { dirname as dirname6, join as join8 } from "path";
|
|
2646
3000
|
import { existsSync as existsSync7 } from "fs";
|
|
2647
3001
|
init_stack();
|
|
2648
3002
|
init_fs();
|
|
2649
|
-
async function doInstallStack(toolsDir) {
|
|
3003
|
+
async function doInstallStack(toolsDir, projectRoot) {
|
|
2650
3004
|
const spin = L2();
|
|
2651
3005
|
let allOk = true;
|
|
3006
|
+
const resolvedProjectRoot = projectRoot ?? dirname6(dirname6(toolsDir ?? join8(process.cwd(), ".opencode", "tools")));
|
|
2652
3007
|
spin.start("Instalando CodeGraph...");
|
|
2653
3008
|
const cg = await installCodeGraph(toolsDir);
|
|
2654
3009
|
spin.stop(cg.success ? `✓ ${cg.message}` : `✗ ${cg.message}`);
|
|
2655
3010
|
if (!cg.success)
|
|
2656
3011
|
allOk = false;
|
|
2657
3012
|
spin.start("Configurando OpenSpec...");
|
|
2658
|
-
const os = setupOpenSpec();
|
|
3013
|
+
const os = setupOpenSpec(resolvedProjectRoot);
|
|
2659
3014
|
spin.stop(os.success ? `✓ ${os.message}` : `✗ ${os.message}`);
|
|
2660
3015
|
if (!os.success)
|
|
2661
3016
|
allOk = false;
|
|
@@ -2671,13 +3026,14 @@ async function doInstallStack(toolsDir) {
|
|
|
2671
3026
|
allOk = false;
|
|
2672
3027
|
spin.start("Verificando configuración...");
|
|
2673
3028
|
const { patchOpenCodeConfig: patchOpenCodeConfig2 } = await Promise.resolve().then(() => (init_config(), exports_config));
|
|
2674
|
-
const cfg = patchOpenCodeConfig2();
|
|
3029
|
+
const cfg = patchOpenCodeConfig2(resolvedProjectRoot);
|
|
2675
3030
|
spin.stop(cfg.success ? `✓ ${cfg.message}` : `✗ ${cfg.message}`);
|
|
2676
3031
|
if (!cfg.success)
|
|
2677
3032
|
allOk = false;
|
|
2678
3033
|
if (!allOk) {
|
|
2679
3034
|
v2.warn("Algunos componentes requieren atención. Revisá los mensajes de error arriba.");
|
|
2680
3035
|
}
|
|
3036
|
+
return allOk;
|
|
2681
3037
|
}
|
|
2682
3038
|
async function doInstallAll(manifest, paths) {
|
|
2683
3039
|
const spin = L2();
|
|
@@ -2724,27 +3080,29 @@ async function doInstallAll(manifest, paths) {
|
|
|
2724
3080
|
}
|
|
2725
3081
|
}
|
|
2726
3082
|
v2.info("Instalando stack de herramientas...");
|
|
2727
|
-
await doInstallStack(paths.tools);
|
|
3083
|
+
const stackOk = await doInstallStack(paths.tools, dirname6(paths.root));
|
|
3084
|
+
if (!stackOk)
|
|
3085
|
+
errors++;
|
|
2728
3086
|
const missingTools = [];
|
|
2729
|
-
const
|
|
2730
|
-
const
|
|
2731
|
-
if (!existsSync7(
|
|
3087
|
+
const codegraphDir = join8(paths.tools, "codegraph");
|
|
3088
|
+
const engramDir = join8(paths.tools, "engram");
|
|
3089
|
+
if (!existsSync7(codegraphDir) || !findBinaryInDir(codegraphDir, "codegraph"))
|
|
2732
3090
|
missingTools.push("CodeGraph");
|
|
2733
|
-
if (!existsSync7(
|
|
3091
|
+
if (!existsSync7(engramDir) || !findBinaryInDir(engramDir, "engram"))
|
|
2734
3092
|
missingTools.push("Engram");
|
|
2735
3093
|
if (missingTools.length > 0) {
|
|
2736
3094
|
v2.warn(`Faltan herramientas del stack: ${missingTools.join(", ")}.
|
|
2737
3095
|
` + "Ejecutá `/install-stack` desde el agente para instalarlas manualmente.");
|
|
2738
3096
|
}
|
|
2739
|
-
if (errors === 0) {
|
|
3097
|
+
if (errors === 0 && stackOk && missingTools.length === 0) {
|
|
2740
3098
|
v2.success("Todo instalado correctamente.");
|
|
2741
3099
|
} else {
|
|
2742
|
-
v2.warn(`
|
|
3100
|
+
v2.warn(`Instalación parcial: ${errors} componente(s) requieren atención.`);
|
|
2743
3101
|
}
|
|
3102
|
+
return errors === 0 && stackOk && missingTools.length === 0;
|
|
2744
3103
|
}
|
|
2745
3104
|
|
|
2746
3105
|
// src/prompts/add.ts
|
|
2747
|
-
init_dist2();
|
|
2748
3106
|
init_lockfile();
|
|
2749
3107
|
async function doAddAgent(manifest, paths) {
|
|
2750
3108
|
const lockfile = readLockfile(paths.root);
|
|
@@ -2858,7 +3216,6 @@ async function doAddMcp(manifest, paths) {
|
|
|
2858
3216
|
}
|
|
2859
3217
|
|
|
2860
3218
|
// src/prompts/update.ts
|
|
2861
|
-
init_dist2();
|
|
2862
3219
|
init_lockfile();
|
|
2863
3220
|
async function doUpdate(manifest, paths) {
|
|
2864
3221
|
const candidates = getUpdateCandidates(manifest, paths);
|
|
@@ -2928,7 +3285,6 @@ async function doUpdate(manifest, paths) {
|
|
|
2928
3285
|
}
|
|
2929
3286
|
|
|
2930
3287
|
// src/prompts/uninstall.ts
|
|
2931
|
-
init_dist2();
|
|
2932
3288
|
import { join as join9 } from "path";
|
|
2933
3289
|
init_stack();
|
|
2934
3290
|
init_lockfile();
|
|
@@ -3269,9 +3625,10 @@ async function runInteractiveMenu() {
|
|
|
3269
3625
|
onCancel(action);
|
|
3270
3626
|
switch (action) {
|
|
3271
3627
|
case "all":
|
|
3272
|
-
await doInstallAll(manifest, paths)
|
|
3628
|
+
if (!await doInstallAll(manifest, paths))
|
|
3629
|
+
process.exitCode = 1;
|
|
3273
3630
|
printPostInstallSteps();
|
|
3274
|
-
fe("Listo.");
|
|
3631
|
+
fe(process.exitCode ? "Instalación parcial." : "Listo.");
|
|
3275
3632
|
break;
|
|
3276
3633
|
case "agent":
|
|
3277
3634
|
await doAddAgent(manifest, paths);
|
|
@@ -3295,8 +3652,10 @@ async function runInteractiveMenu() {
|
|
|
3295
3652
|
break;
|
|
3296
3653
|
case "stack": {
|
|
3297
3654
|
ensureToolDirs(paths.tools, ["codegraph", "engram", "context7"]);
|
|
3298
|
-
await doInstallStack(paths.tools);
|
|
3299
|
-
|
|
3655
|
+
const stackOk = await doInstallStack(paths.tools, dirname7(paths.root));
|
|
3656
|
+
if (!stackOk)
|
|
3657
|
+
process.exitCode = 1;
|
|
3658
|
+
fe(stackOk ? "Listo." : "Instalación parcial.");
|
|
3300
3659
|
break;
|
|
3301
3660
|
}
|
|
3302
3661
|
case "update": {
|
|
@@ -3322,9 +3681,10 @@ async function runInstallCommand() {
|
|
|
3322
3681
|
fe("Cancelado.");
|
|
3323
3682
|
return;
|
|
3324
3683
|
}
|
|
3325
|
-
await doInstallAll(manifest, paths)
|
|
3684
|
+
if (!await doInstallAll(manifest, paths))
|
|
3685
|
+
process.exitCode = 1;
|
|
3326
3686
|
printPostInstallSteps();
|
|
3327
|
-
fe("Instalación completada.");
|
|
3687
|
+
fe(process.exitCode ? "Instalación parcial." : "Instalación completada.");
|
|
3328
3688
|
}
|
|
3329
3689
|
async function runAddAgentCommand() {
|
|
3330
3690
|
we(" OpenCode Installer ");
|
|
@@ -3382,8 +3742,10 @@ async function runInstallStackCommand() {
|
|
|
3382
3742
|
return;
|
|
3383
3743
|
}
|
|
3384
3744
|
ensureToolDirs(paths.tools, ["codegraph", "engram", "context7"]);
|
|
3385
|
-
await doInstallStack(paths.tools);
|
|
3386
|
-
|
|
3745
|
+
const stackOk = await doInstallStack(paths.tools, dirname7(paths.root));
|
|
3746
|
+
if (!stackOk)
|
|
3747
|
+
process.exitCode = 1;
|
|
3748
|
+
fe(stackOk ? "Stack instalado." : "Stack instalado parcialmente.");
|
|
3387
3749
|
}
|
|
3388
3750
|
async function runUninstallStackCommand() {
|
|
3389
3751
|
we(" OpenCode Installer — Stack ");
|
|
@@ -3443,7 +3805,7 @@ async function runUninstallAgentCommand(name) {
|
|
|
3443
3805
|
const { readLockfile: readLockfile2 } = await Promise.resolve().then(() => (init_lockfile(), exports_lockfile));
|
|
3444
3806
|
const lockfile = readLockfile2(paths.root);
|
|
3445
3807
|
if (lockfile && Object.keys(lockfile.agents).length > 0) {
|
|
3446
|
-
const
|
|
3808
|
+
const prompts = exports_dist;
|
|
3447
3809
|
const installed = Object.keys(lockfile.agents);
|
|
3448
3810
|
const options = installed.map((n) => ({
|
|
3449
3811
|
value: n,
|
|
@@ -3478,7 +3840,7 @@ async function runUninstallCommandCommand(name) {
|
|
|
3478
3840
|
const { readLockfile: readLockfile2 } = await Promise.resolve().then(() => (init_lockfile(), exports_lockfile));
|
|
3479
3841
|
const lockfile = readLockfile2(paths.root);
|
|
3480
3842
|
if (lockfile && Object.keys(lockfile.commands).length > 0) {
|
|
3481
|
-
const
|
|
3843
|
+
const prompts = exports_dist;
|
|
3482
3844
|
const installed = Object.keys(lockfile.commands);
|
|
3483
3845
|
const options = installed.map((n) => ({
|
|
3484
3846
|
value: n,
|
|
@@ -3513,7 +3875,7 @@ async function runUninstallSkillCommand(name) {
|
|
|
3513
3875
|
const { readLockfile: readLockfile2 } = await Promise.resolve().then(() => (init_lockfile(), exports_lockfile));
|
|
3514
3876
|
const lockfile = readLockfile2(paths.root);
|
|
3515
3877
|
if (lockfile && lockfile.skills && Object.keys(lockfile.skills).length > 0) {
|
|
3516
|
-
const
|
|
3878
|
+
const prompts = exports_dist;
|
|
3517
3879
|
const installed = Object.keys(lockfile.skills);
|
|
3518
3880
|
const options = installed.map((n) => ({
|
|
3519
3881
|
value: n,
|
|
@@ -3548,7 +3910,7 @@ async function runUninstallMcpCommand(name) {
|
|
|
3548
3910
|
const { readLockfile: readLockfile2 } = await Promise.resolve().then(() => (init_lockfile(), exports_lockfile));
|
|
3549
3911
|
const lockfile = readLockfile2(paths.root);
|
|
3550
3912
|
if (lockfile && lockfile.mcpServers && Object.keys(lockfile.mcpServers).length > 0) {
|
|
3551
|
-
const
|
|
3913
|
+
const prompts = exports_dist;
|
|
3552
3914
|
const installed = Object.keys(lockfile.mcpServers);
|
|
3553
3915
|
const options = installed.map((n) => ({
|
|
3554
3916
|
value: n,
|