oh-my-opencode 0.1.17 → 0.1.19
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/dist/index.js
CHANGED
|
@@ -803,7 +803,7 @@ function detectErrorType(error) {
|
|
|
803
803
|
if (message.includes("tool_use") && message.includes("tool_result")) {
|
|
804
804
|
return "tool_result_missing";
|
|
805
805
|
}
|
|
806
|
-
if (message.includes("thinking") && message.includes("first block")) {
|
|
806
|
+
if (message.includes("thinking") && (message.includes("first block") || message.includes("must start with") || message.includes("preceeding"))) {
|
|
807
807
|
return "thinking_block_order";
|
|
808
808
|
}
|
|
809
809
|
if (message.includes("thinking is disabled") && message.includes("cannot contain")) {
|
|
@@ -15258,9 +15258,120 @@ var lsp_code_action_resolve = tool({
|
|
|
15258
15258
|
}
|
|
15259
15259
|
});
|
|
15260
15260
|
// src/tools/ast-grep/constants.ts
|
|
15261
|
+
import { createRequire as createRequire4 } from "module";
|
|
15262
|
+
import { dirname as dirname2, join as join5 } from "path";
|
|
15263
|
+
import { existsSync as existsSync7 } from "fs";
|
|
15264
|
+
|
|
15265
|
+
// src/tools/ast-grep/downloader.ts
|
|
15266
|
+
var {spawn: spawn4 } = globalThis.Bun;
|
|
15267
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync2, chmodSync as chmodSync2, unlinkSync as unlinkSync2 } from "fs";
|
|
15268
|
+
import { join as join4 } from "path";
|
|
15269
|
+
import { homedir as homedir3 } from "os";
|
|
15261
15270
|
import { createRequire as createRequire3 } from "module";
|
|
15262
|
-
|
|
15263
|
-
|
|
15271
|
+
var REPO2 = "ast-grep/ast-grep";
|
|
15272
|
+
var DEFAULT_VERSION = "0.40.0";
|
|
15273
|
+
function getAstGrepVersion() {
|
|
15274
|
+
try {
|
|
15275
|
+
const require2 = createRequire3(import.meta.url);
|
|
15276
|
+
const pkg = require2("@ast-grep/cli/package.json");
|
|
15277
|
+
return pkg.version;
|
|
15278
|
+
} catch {
|
|
15279
|
+
return DEFAULT_VERSION;
|
|
15280
|
+
}
|
|
15281
|
+
}
|
|
15282
|
+
var PLATFORM_MAP2 = {
|
|
15283
|
+
"darwin-arm64": { arch: "aarch64", os: "apple-darwin" },
|
|
15284
|
+
"darwin-x64": { arch: "x86_64", os: "apple-darwin" },
|
|
15285
|
+
"linux-arm64": { arch: "aarch64", os: "unknown-linux-gnu" },
|
|
15286
|
+
"linux-x64": { arch: "x86_64", os: "unknown-linux-gnu" },
|
|
15287
|
+
"win32-x64": { arch: "x86_64", os: "pc-windows-msvc" },
|
|
15288
|
+
"win32-arm64": { arch: "aarch64", os: "pc-windows-msvc" },
|
|
15289
|
+
"win32-ia32": { arch: "i686", os: "pc-windows-msvc" }
|
|
15290
|
+
};
|
|
15291
|
+
function getCacheDir2() {
|
|
15292
|
+
if (process.platform === "win32") {
|
|
15293
|
+
const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA;
|
|
15294
|
+
const base2 = localAppData || join4(homedir3(), "AppData", "Local");
|
|
15295
|
+
return join4(base2, "oh-my-opencode", "bin");
|
|
15296
|
+
}
|
|
15297
|
+
const xdgCache = process.env.XDG_CACHE_HOME;
|
|
15298
|
+
const base = xdgCache || join4(homedir3(), ".cache");
|
|
15299
|
+
return join4(base, "oh-my-opencode", "bin");
|
|
15300
|
+
}
|
|
15301
|
+
function getBinaryName3() {
|
|
15302
|
+
return process.platform === "win32" ? "sg.exe" : "sg";
|
|
15303
|
+
}
|
|
15304
|
+
function getCachedBinaryPath2() {
|
|
15305
|
+
const binaryPath = join4(getCacheDir2(), getBinaryName3());
|
|
15306
|
+
return existsSync6(binaryPath) ? binaryPath : null;
|
|
15307
|
+
}
|
|
15308
|
+
async function extractZip2(archivePath, destDir) {
|
|
15309
|
+
const proc = process.platform === "win32" ? spawn4([
|
|
15310
|
+
"powershell",
|
|
15311
|
+
"-command",
|
|
15312
|
+
`Expand-Archive -Path '${archivePath}' -DestinationPath '${destDir}' -Force`
|
|
15313
|
+
], { stdout: "pipe", stderr: "pipe" }) : spawn4(["unzip", "-o", archivePath, "-d", destDir], { stdout: "pipe", stderr: "pipe" });
|
|
15314
|
+
const exitCode = await proc.exited;
|
|
15315
|
+
if (exitCode !== 0) {
|
|
15316
|
+
const stderr = await new Response(proc.stderr).text();
|
|
15317
|
+
const toolHint = process.platform === "win32" ? "Ensure PowerShell is available on your system." : "Please install 'unzip' (e.g., apt install unzip, brew install unzip).";
|
|
15318
|
+
throw new Error(`zip extraction failed (exit ${exitCode}): ${stderr}
|
|
15319
|
+
|
|
15320
|
+
${toolHint}`);
|
|
15321
|
+
}
|
|
15322
|
+
}
|
|
15323
|
+
async function downloadAstGrep(version2 = DEFAULT_VERSION) {
|
|
15324
|
+
const platformKey = `${process.platform}-${process.arch}`;
|
|
15325
|
+
const platformInfo = PLATFORM_MAP2[platformKey];
|
|
15326
|
+
if (!platformInfo) {
|
|
15327
|
+
console.error(`[oh-my-opencode] Unsupported platform for ast-grep: ${platformKey}`);
|
|
15328
|
+
return null;
|
|
15329
|
+
}
|
|
15330
|
+
const cacheDir = getCacheDir2();
|
|
15331
|
+
const binaryName = getBinaryName3();
|
|
15332
|
+
const binaryPath = join4(cacheDir, binaryName);
|
|
15333
|
+
if (existsSync6(binaryPath)) {
|
|
15334
|
+
return binaryPath;
|
|
15335
|
+
}
|
|
15336
|
+
const { arch, os } = platformInfo;
|
|
15337
|
+
const assetName = `app-${arch}-${os}.zip`;
|
|
15338
|
+
const downloadUrl = `https://github.com/${REPO2}/releases/download/${version2}/${assetName}`;
|
|
15339
|
+
console.log(`[oh-my-opencode] Downloading ast-grep binary...`);
|
|
15340
|
+
try {
|
|
15341
|
+
if (!existsSync6(cacheDir)) {
|
|
15342
|
+
mkdirSync2(cacheDir, { recursive: true });
|
|
15343
|
+
}
|
|
15344
|
+
const response = await fetch(downloadUrl, { redirect: "follow" });
|
|
15345
|
+
if (!response.ok) {
|
|
15346
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
15347
|
+
}
|
|
15348
|
+
const archivePath = join4(cacheDir, assetName);
|
|
15349
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
15350
|
+
await Bun.write(archivePath, arrayBuffer);
|
|
15351
|
+
await extractZip2(archivePath, cacheDir);
|
|
15352
|
+
if (existsSync6(archivePath)) {
|
|
15353
|
+
unlinkSync2(archivePath);
|
|
15354
|
+
}
|
|
15355
|
+
if (process.platform !== "win32" && existsSync6(binaryPath)) {
|
|
15356
|
+
chmodSync2(binaryPath, 493);
|
|
15357
|
+
}
|
|
15358
|
+
console.log(`[oh-my-opencode] ast-grep binary ready.`);
|
|
15359
|
+
return binaryPath;
|
|
15360
|
+
} catch (err) {
|
|
15361
|
+
console.error(`[oh-my-opencode] Failed to download ast-grep: ${err instanceof Error ? err.message : err}`);
|
|
15362
|
+
return null;
|
|
15363
|
+
}
|
|
15364
|
+
}
|
|
15365
|
+
async function ensureAstGrepBinary() {
|
|
15366
|
+
const cachedPath = getCachedBinaryPath2();
|
|
15367
|
+
if (cachedPath) {
|
|
15368
|
+
return cachedPath;
|
|
15369
|
+
}
|
|
15370
|
+
const version2 = getAstGrepVersion();
|
|
15371
|
+
return downloadAstGrep(version2);
|
|
15372
|
+
}
|
|
15373
|
+
|
|
15374
|
+
// src/tools/ast-grep/constants.ts
|
|
15264
15375
|
function getPlatformPackageName2() {
|
|
15265
15376
|
const platform = process.platform;
|
|
15266
15377
|
const arch = process.arch;
|
|
@@ -15275,32 +15386,60 @@ function getPlatformPackageName2() {
|
|
|
15275
15386
|
};
|
|
15276
15387
|
return platformMap[`${platform}-${arch}`] ?? null;
|
|
15277
15388
|
}
|
|
15278
|
-
function
|
|
15389
|
+
function findSgCliPathSync() {
|
|
15390
|
+
const binaryName = process.platform === "win32" ? "sg.exe" : "sg";
|
|
15279
15391
|
try {
|
|
15280
|
-
const require2 =
|
|
15392
|
+
const require2 = createRequire4(import.meta.url);
|
|
15281
15393
|
const cliPkgPath = require2.resolve("@ast-grep/cli/package.json");
|
|
15282
15394
|
const cliDir = dirname2(cliPkgPath);
|
|
15283
|
-
const sgPath =
|
|
15284
|
-
if (
|
|
15395
|
+
const sgPath = join5(cliDir, binaryName);
|
|
15396
|
+
if (existsSync7(sgPath)) {
|
|
15285
15397
|
return sgPath;
|
|
15286
15398
|
}
|
|
15287
15399
|
} catch {}
|
|
15288
15400
|
const platformPkg = getPlatformPackageName2();
|
|
15289
15401
|
if (platformPkg) {
|
|
15290
15402
|
try {
|
|
15291
|
-
const require2 =
|
|
15403
|
+
const require2 = createRequire4(import.meta.url);
|
|
15292
15404
|
const pkgPath = require2.resolve(`${platformPkg}/package.json`);
|
|
15293
15405
|
const pkgDir = dirname2(pkgPath);
|
|
15294
|
-
const
|
|
15295
|
-
const binaryPath =
|
|
15296
|
-
if (
|
|
15406
|
+
const astGrepName = process.platform === "win32" ? "ast-grep.exe" : "ast-grep";
|
|
15407
|
+
const binaryPath = join5(pkgDir, astGrepName);
|
|
15408
|
+
if (existsSync7(binaryPath)) {
|
|
15297
15409
|
return binaryPath;
|
|
15298
15410
|
}
|
|
15299
15411
|
} catch {}
|
|
15300
15412
|
}
|
|
15413
|
+
if (process.platform === "darwin") {
|
|
15414
|
+
const homebrewPaths = ["/opt/homebrew/bin/sg", "/usr/local/bin/sg"];
|
|
15415
|
+
for (const path of homebrewPaths) {
|
|
15416
|
+
if (existsSync7(path)) {
|
|
15417
|
+
return path;
|
|
15418
|
+
}
|
|
15419
|
+
}
|
|
15420
|
+
}
|
|
15421
|
+
const cachedPath = getCachedBinaryPath2();
|
|
15422
|
+
if (cachedPath) {
|
|
15423
|
+
return cachedPath;
|
|
15424
|
+
}
|
|
15425
|
+
return null;
|
|
15426
|
+
}
|
|
15427
|
+
var resolvedCliPath2 = null;
|
|
15428
|
+
function getSgCliPath() {
|
|
15429
|
+
if (resolvedCliPath2 !== null) {
|
|
15430
|
+
return resolvedCliPath2;
|
|
15431
|
+
}
|
|
15432
|
+
const syncPath = findSgCliPathSync();
|
|
15433
|
+
if (syncPath) {
|
|
15434
|
+
resolvedCliPath2 = syncPath;
|
|
15435
|
+
return syncPath;
|
|
15436
|
+
}
|
|
15301
15437
|
return "sg";
|
|
15302
15438
|
}
|
|
15303
|
-
|
|
15439
|
+
function setSgCliPath(path) {
|
|
15440
|
+
resolvedCliPath2 = path;
|
|
15441
|
+
}
|
|
15442
|
+
var SG_CLI_PATH = getSgCliPath();
|
|
15304
15443
|
var CLI_LANGUAGES = [
|
|
15305
15444
|
"bash",
|
|
15306
15445
|
"c",
|
|
@@ -15358,7 +15497,44 @@ var LANG_EXTENSIONS = {
|
|
|
15358
15497
|
};
|
|
15359
15498
|
|
|
15360
15499
|
// src/tools/ast-grep/cli.ts
|
|
15361
|
-
var {spawn:
|
|
15500
|
+
var {spawn: spawn5 } = globalThis.Bun;
|
|
15501
|
+
import { existsSync as existsSync8 } from "fs";
|
|
15502
|
+
var resolvedCliPath3 = null;
|
|
15503
|
+
var initPromise2 = null;
|
|
15504
|
+
async function getAstGrepPath() {
|
|
15505
|
+
if (resolvedCliPath3 !== null && existsSync8(resolvedCliPath3)) {
|
|
15506
|
+
return resolvedCliPath3;
|
|
15507
|
+
}
|
|
15508
|
+
if (initPromise2) {
|
|
15509
|
+
return initPromise2;
|
|
15510
|
+
}
|
|
15511
|
+
initPromise2 = (async () => {
|
|
15512
|
+
const syncPath = findSgCliPathSync();
|
|
15513
|
+
if (syncPath && existsSync8(syncPath)) {
|
|
15514
|
+
resolvedCliPath3 = syncPath;
|
|
15515
|
+
setSgCliPath(syncPath);
|
|
15516
|
+
return syncPath;
|
|
15517
|
+
}
|
|
15518
|
+
const downloadedPath = await ensureAstGrepBinary();
|
|
15519
|
+
if (downloadedPath) {
|
|
15520
|
+
resolvedCliPath3 = downloadedPath;
|
|
15521
|
+
setSgCliPath(downloadedPath);
|
|
15522
|
+
return downloadedPath;
|
|
15523
|
+
}
|
|
15524
|
+
return null;
|
|
15525
|
+
})();
|
|
15526
|
+
return initPromise2;
|
|
15527
|
+
}
|
|
15528
|
+
async function spawnSg(cliPath, args) {
|
|
15529
|
+
const proc = spawn5([cliPath, ...args], {
|
|
15530
|
+
stdout: "pipe",
|
|
15531
|
+
stderr: "pipe"
|
|
15532
|
+
});
|
|
15533
|
+
const stdout = await new Response(proc.stdout).text();
|
|
15534
|
+
const stderr = await new Response(proc.stderr).text();
|
|
15535
|
+
const exitCode = await proc.exited;
|
|
15536
|
+
return { stdout, stderr, exitCode };
|
|
15537
|
+
}
|
|
15362
15538
|
async function runSg(options) {
|
|
15363
15539
|
const args = ["run", "-p", options.pattern, "--lang", options.lang, "--json=compact"];
|
|
15364
15540
|
if (options.rewrite) {
|
|
@@ -15377,13 +15553,37 @@ async function runSg(options) {
|
|
|
15377
15553
|
}
|
|
15378
15554
|
const paths = options.paths && options.paths.length > 0 ? options.paths : ["."];
|
|
15379
15555
|
args.push(...paths);
|
|
15380
|
-
|
|
15381
|
-
|
|
15382
|
-
|
|
15383
|
-
|
|
15384
|
-
|
|
15385
|
-
|
|
15386
|
-
|
|
15556
|
+
let cliPath = getSgCliPath();
|
|
15557
|
+
if (!existsSync8(cliPath) && cliPath !== "sg") {
|
|
15558
|
+
const downloadedPath = await getAstGrepPath();
|
|
15559
|
+
if (downloadedPath) {
|
|
15560
|
+
cliPath = downloadedPath;
|
|
15561
|
+
}
|
|
15562
|
+
}
|
|
15563
|
+
let result;
|
|
15564
|
+
try {
|
|
15565
|
+
result = await spawnSg(cliPath, args);
|
|
15566
|
+
} catch (e) {
|
|
15567
|
+
const error45 = e;
|
|
15568
|
+
if (error45.code === "ENOENT" || error45.message?.includes("ENOENT") || error45.message?.includes("not found")) {
|
|
15569
|
+
const downloadedPath = await ensureAstGrepBinary();
|
|
15570
|
+
if (downloadedPath) {
|
|
15571
|
+
resolvedCliPath3 = downloadedPath;
|
|
15572
|
+
setSgCliPath(downloadedPath);
|
|
15573
|
+
result = await spawnSg(downloadedPath, args);
|
|
15574
|
+
} else {
|
|
15575
|
+
throw new Error(`ast-grep CLI binary not found.
|
|
15576
|
+
|
|
15577
|
+
` + `Auto-download failed. Manual install options:
|
|
15578
|
+
` + ` bun add -D @ast-grep/cli
|
|
15579
|
+
` + ` cargo install ast-grep --locked
|
|
15580
|
+
` + ` brew install ast-grep`);
|
|
15581
|
+
}
|
|
15582
|
+
} else {
|
|
15583
|
+
throw new Error(`Failed to spawn ast-grep: ${error45.message}`);
|
|
15584
|
+
}
|
|
15585
|
+
}
|
|
15586
|
+
const { stdout, stderr, exitCode } = result;
|
|
15387
15587
|
if (exitCode !== 0 && stdout.trim() === "") {
|
|
15388
15588
|
if (stderr.includes("No files found")) {
|
|
15389
15589
|
return [];
|
|
@@ -15413,7 +15613,15 @@ var LANG_MAP = {
|
|
|
15413
15613
|
typescript: Lang.TypeScript
|
|
15414
15614
|
};
|
|
15415
15615
|
function parseCode(code, lang) {
|
|
15416
|
-
|
|
15616
|
+
const parseLang = LANG_MAP[lang];
|
|
15617
|
+
if (!parseLang) {
|
|
15618
|
+
const supportedLangs = NAPI_LANGUAGES.join(", ");
|
|
15619
|
+
throw new Error(`Unsupported language for NAPI: "${lang}"
|
|
15620
|
+
` + `Supported languages: ${supportedLangs}
|
|
15621
|
+
|
|
15622
|
+
` + `Use ast_grep_search for other languages (25 supported via CLI).`);
|
|
15623
|
+
}
|
|
15624
|
+
return parse5(parseLang, code);
|
|
15417
15625
|
}
|
|
15418
15626
|
function findPattern(root, pattern) {
|
|
15419
15627
|
return root.root().findAll(pattern);
|
|
@@ -15551,25 +15759,22 @@ function showOutputToUser(context, output) {
|
|
|
15551
15759
|
const ctx = context;
|
|
15552
15760
|
ctx.metadata?.({ metadata: { output } });
|
|
15553
15761
|
}
|
|
15554
|
-
|
|
15555
|
-
function validatePatternForCli(pattern, lang) {
|
|
15556
|
-
if (!JS_TS_LANGUAGES.includes(lang)) {
|
|
15557
|
-
return;
|
|
15558
|
-
}
|
|
15762
|
+
function getEmptyResultHint(pattern, lang) {
|
|
15559
15763
|
const src = pattern.trim();
|
|
15560
|
-
|
|
15561
|
-
|
|
15562
|
-
|
|
15563
|
-
|
|
15564
|
-
|
|
15565
|
-
|
|
15566
|
-
|
|
15567
|
-
` + ` - "export async function $NAME($$$) { $$$ }" (matches export async functions)
|
|
15568
|
-
` + ` - "function $NAME($$$) { $$$ }" (matches all function declarations)
|
|
15569
|
-
` + ` - "async function $NAME($$$) { $$$ }" (matches async functions)
|
|
15570
|
-
|
|
15571
|
-
` + `Your pattern "${pattern}" is missing the parameter list and body.`);
|
|
15764
|
+
if (lang === "python") {
|
|
15765
|
+
if (src.startsWith("class ") && src.endsWith(":")) {
|
|
15766
|
+
return `\uD83D\uDCA1 Hint: Python class patterns need body. Try "class $NAME" or include body with $$$BODY`;
|
|
15767
|
+
}
|
|
15768
|
+
if ((src.startsWith("def ") || src.startsWith("async def ")) && src.endsWith(":")) {
|
|
15769
|
+
return `\uD83D\uDCA1 Hint: Python function patterns need body. Try "def $FUNC($$$):\\n $$$BODY"`;
|
|
15770
|
+
}
|
|
15572
15771
|
}
|
|
15772
|
+
if (["javascript", "typescript", "tsx"].includes(lang)) {
|
|
15773
|
+
if (/^(export\s+)?(async\s+)?function\s+\$[A-Z_]+\s*$/i.test(src)) {
|
|
15774
|
+
return `\uD83D\uDCA1 Hint: Function patterns need params and body. Try "function $NAME($$$) { $$$ }"`;
|
|
15775
|
+
}
|
|
15776
|
+
}
|
|
15777
|
+
return null;
|
|
15573
15778
|
}
|
|
15574
15779
|
var ast_grep_search = tool({
|
|
15575
15780
|
description: "Search code patterns across filesystem using AST-aware matching. Supports 25 languages. " + "Use meta-variables: $VAR (single node), $$$ (multiple nodes). " + "IMPORTANT: Patterns must be complete AST nodes (valid code). " + "For functions, include params and body: 'export async function $NAME($$$) { $$$ }' not 'export async function $NAME'. " + "Examples: 'console.log($MSG)', 'def $FUNC($$$):', 'async function $NAME($$$)'",
|
|
@@ -15582,7 +15787,6 @@ var ast_grep_search = tool({
|
|
|
15582
15787
|
},
|
|
15583
15788
|
execute: async (args, context) => {
|
|
15584
15789
|
try {
|
|
15585
|
-
validatePatternForCli(args.pattern, args.lang);
|
|
15586
15790
|
const matches = await runSg({
|
|
15587
15791
|
pattern: args.pattern,
|
|
15588
15792
|
lang: args.lang,
|
|
@@ -15590,7 +15794,15 @@ var ast_grep_search = tool({
|
|
|
15590
15794
|
globs: args.globs,
|
|
15591
15795
|
context: args.context
|
|
15592
15796
|
});
|
|
15593
|
-
|
|
15797
|
+
let output = formatSearchResult(matches);
|
|
15798
|
+
if (matches.length === 0) {
|
|
15799
|
+
const hint = getEmptyResultHint(args.pattern, args.lang);
|
|
15800
|
+
if (hint) {
|
|
15801
|
+
output += `
|
|
15802
|
+
|
|
15803
|
+
${hint}`;
|
|
15804
|
+
}
|
|
15805
|
+
}
|
|
15594
15806
|
showOutputToUser(context, output);
|
|
15595
15807
|
return output;
|
|
15596
15808
|
} catch (e) {
|
|
@@ -15696,13 +15908,12 @@ var ast_grep_transform = tool({
|
|
|
15696
15908
|
}
|
|
15697
15909
|
}
|
|
15698
15910
|
});
|
|
15699
|
-
|
|
15700
15911
|
// src/tools/safe-grep/cli.ts
|
|
15701
|
-
var {spawn:
|
|
15912
|
+
var {spawn: spawn6 } = globalThis.Bun;
|
|
15702
15913
|
|
|
15703
15914
|
// src/tools/safe-grep/constants.ts
|
|
15704
|
-
import { existsSync as
|
|
15705
|
-
import { join as
|
|
15915
|
+
import { existsSync as existsSync9 } from "fs";
|
|
15916
|
+
import { join as join6, dirname as dirname3 } from "path";
|
|
15706
15917
|
import { spawnSync } from "child_process";
|
|
15707
15918
|
var cachedCli = null;
|
|
15708
15919
|
function findExecutable(name) {
|
|
@@ -15723,13 +15934,13 @@ function getOpenCodeBundledRg() {
|
|
|
15723
15934
|
const isWindows = process.platform === "win32";
|
|
15724
15935
|
const rgName = isWindows ? "rg.exe" : "rg";
|
|
15725
15936
|
const candidates = [
|
|
15726
|
-
|
|
15727
|
-
|
|
15728
|
-
|
|
15729
|
-
|
|
15937
|
+
join6(execDir, rgName),
|
|
15938
|
+
join6(execDir, "bin", rgName),
|
|
15939
|
+
join6(execDir, "..", "bin", rgName),
|
|
15940
|
+
join6(execDir, "..", "libexec", rgName)
|
|
15730
15941
|
];
|
|
15731
15942
|
for (const candidate of candidates) {
|
|
15732
|
-
if (
|
|
15943
|
+
if (existsSync9(candidate)) {
|
|
15733
15944
|
return candidate;
|
|
15734
15945
|
}
|
|
15735
15946
|
}
|
|
@@ -15870,7 +16081,7 @@ async function runRg(options) {
|
|
|
15870
16081
|
}
|
|
15871
16082
|
const paths = options.paths?.length ? options.paths : ["."];
|
|
15872
16083
|
args.push(...paths);
|
|
15873
|
-
const proc =
|
|
16084
|
+
const proc = spawn6([cli.path, ...args], {
|
|
15874
16085
|
stdout: "pipe",
|
|
15875
16086
|
stderr: "pipe"
|
|
15876
16087
|
});
|
|
@@ -16168,7 +16379,14 @@ var OhMyOpenCodePlugin = async (ctx) => {
|
|
|
16168
16379
|
sessionID,
|
|
16169
16380
|
error: error45
|
|
16170
16381
|
};
|
|
16171
|
-
await sessionRecovery.handleSessionRecovery(messageInfo);
|
|
16382
|
+
const recovered = await sessionRecovery.handleSessionRecovery(messageInfo);
|
|
16383
|
+
if (recovered && sessionID && sessionID === mainSessionID) {
|
|
16384
|
+
await ctx.client.session.prompt({
|
|
16385
|
+
path: { id: sessionID },
|
|
16386
|
+
body: { parts: [{ type: "text", text: "continue" }] },
|
|
16387
|
+
query: { directory: ctx.directory }
|
|
16388
|
+
}).catch(() => {});
|
|
16389
|
+
}
|
|
16172
16390
|
}
|
|
16173
16391
|
if (sessionID && sessionID === mainSessionID) {
|
|
16174
16392
|
updateTerminalTitle({
|
|
@@ -8,4 +8,8 @@ export interface RunOptions {
|
|
|
8
8
|
context?: number;
|
|
9
9
|
updateAll?: boolean;
|
|
10
10
|
}
|
|
11
|
+
export declare function getAstGrepPath(): Promise<string | null>;
|
|
12
|
+
export declare function startBackgroundInit(): void;
|
|
11
13
|
export declare function runSg(options: RunOptions): Promise<CliMatch[]>;
|
|
14
|
+
export declare function isCliAvailable(): boolean;
|
|
15
|
+
export declare function ensureCliAvailable(): Promise<boolean>;
|
|
@@ -1,4 +1,27 @@
|
|
|
1
|
+
export declare function findSgCliPathSync(): string | null;
|
|
2
|
+
export declare function getSgCliPath(): string;
|
|
3
|
+
export declare function setSgCliPath(path: string): void;
|
|
1
4
|
export declare const SG_CLI_PATH: string;
|
|
2
5
|
export declare const CLI_LANGUAGES: readonly ["bash", "c", "cpp", "csharp", "css", "elixir", "go", "haskell", "html", "java", "javascript", "json", "kotlin", "lua", "nix", "php", "python", "ruby", "rust", "scala", "solidity", "swift", "typescript", "tsx", "yaml"];
|
|
3
6
|
export declare const NAPI_LANGUAGES: readonly ["html", "javascript", "tsx", "css", "typescript"];
|
|
4
7
|
export declare const LANG_EXTENSIONS: Record<string, string[]>;
|
|
8
|
+
export interface EnvironmentCheckResult {
|
|
9
|
+
cli: {
|
|
10
|
+
available: boolean;
|
|
11
|
+
path: string;
|
|
12
|
+
error?: string;
|
|
13
|
+
};
|
|
14
|
+
napi: {
|
|
15
|
+
available: boolean;
|
|
16
|
+
error?: string;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Check if ast-grep CLI and NAPI are available.
|
|
21
|
+
* Call this at startup to provide early feedback about missing dependencies.
|
|
22
|
+
*/
|
|
23
|
+
export declare function checkEnvironment(): EnvironmentCheckResult;
|
|
24
|
+
/**
|
|
25
|
+
* Format environment check result as user-friendly message.
|
|
26
|
+
*/
|
|
27
|
+
export declare function formatEnvironmentCheck(result: EnvironmentCheckResult): string;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function getCacheDir(): string;
|
|
2
|
+
export declare function getBinaryName(): string;
|
|
3
|
+
export declare function getCachedBinaryPath(): string | null;
|
|
4
|
+
export declare function downloadAstGrep(version?: string): Promise<string | null>;
|
|
5
|
+
export declare function ensureAstGrepBinary(): Promise<string | null>;
|
|
@@ -89,4 +89,8 @@ export declare const builtinTools: {
|
|
|
89
89
|
}, context: import("@opencode-ai/plugin").ToolContext): Promise<string>;
|
|
90
90
|
};
|
|
91
91
|
};
|
|
92
|
-
export { ast_grep_search, ast_grep_replace
|
|
92
|
+
export { ast_grep_search, ast_grep_replace };
|
|
93
|
+
export { ensureAstGrepBinary, getCachedBinaryPath, getCacheDir } from "./downloader";
|
|
94
|
+
export { getAstGrepPath, isCliAvailable, ensureCliAvailable, startBackgroundInit } from "./cli";
|
|
95
|
+
export { checkEnvironment, formatEnvironmentCheck } from "./constants";
|
|
96
|
+
export type { EnvironmentCheckResult } from "./constants";
|