oh-my-opencode 2.0.0 → 2.0.1

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.
Files changed (2) hide show
  1. package/dist/index.js +66 -37
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -6989,6 +6989,7 @@ function createBackgroundNotificationHook(manager) {
6989
6989
  // src/hooks/auto-update-checker/checker.ts
6990
6990
  import * as fs4 from "fs";
6991
6991
  import * as path4 from "path";
6992
+ import { fileURLToPath } from "url";
6992
6993
 
6993
6994
  // src/hooks/auto-update-checker/constants.ts
6994
6995
  import * as path3 from "path";
@@ -7018,6 +7019,9 @@ var USER_OPENCODE_CONFIG = path3.join(USER_CONFIG_DIR, "opencode", "opencode.jso
7018
7019
  function isLocalDevMode(directory) {
7019
7020
  return getLocalDevPath(directory) !== null;
7020
7021
  }
7022
+ function stripJsonComments(json) {
7023
+ return json.replace(/^\s*\/\/.*$/gm, "").replace(/,(\s*[}\]])/g, "$1");
7024
+ }
7021
7025
  function getLocalDevPath(directory) {
7022
7026
  const projectConfig = path4.join(directory, ".opencode", "opencode.json");
7023
7027
  for (const configPath of [projectConfig, USER_OPENCODE_CONFIG]) {
@@ -7025,7 +7029,7 @@ function getLocalDevPath(directory) {
7025
7029
  if (!fs4.existsSync(configPath))
7026
7030
  continue;
7027
7031
  const content = fs4.readFileSync(configPath, "utf-8");
7028
- const config = JSON.parse(content);
7032
+ const config = JSON.parse(stripJsonComments(content));
7029
7033
  const plugins = config.plugin ?? [];
7030
7034
  for (const entry of plugins) {
7031
7035
  if (entry.startsWith("file://") && entry.includes(PACKAGE_NAME)) {
@@ -7038,13 +7042,35 @@ function getLocalDevPath(directory) {
7038
7042
  }
7039
7043
  return null;
7040
7044
  }
7045
+ function findPackageJsonUp(startPath) {
7046
+ try {
7047
+ const stat = fs4.statSync(startPath);
7048
+ let dir = stat.isDirectory() ? startPath : path4.dirname(startPath);
7049
+ for (let i = 0;i < 10; i++) {
7050
+ const pkgPath = path4.join(dir, "package.json");
7051
+ if (fs4.existsSync(pkgPath)) {
7052
+ try {
7053
+ const content = fs4.readFileSync(pkgPath, "utf-8");
7054
+ const pkg = JSON.parse(content);
7055
+ if (pkg.name === PACKAGE_NAME)
7056
+ return pkgPath;
7057
+ } catch {}
7058
+ }
7059
+ const parent = path4.dirname(dir);
7060
+ if (parent === dir)
7061
+ break;
7062
+ dir = parent;
7063
+ }
7064
+ } catch {}
7065
+ return null;
7066
+ }
7041
7067
  function getLocalDevVersion(directory) {
7042
7068
  const localPath = getLocalDevPath(directory);
7043
7069
  if (!localPath)
7044
7070
  return null;
7045
7071
  try {
7046
- const pkgPath = path4.join(localPath, "package.json");
7047
- if (!fs4.existsSync(pkgPath))
7072
+ const pkgPath = findPackageJsonUp(localPath);
7073
+ if (!pkgPath)
7048
7074
  return null;
7049
7075
  const content = fs4.readFileSync(pkgPath, "utf-8");
7050
7076
  const pkg = JSON.parse(content);
@@ -7060,7 +7086,7 @@ function findPluginEntry(directory) {
7060
7086
  if (!fs4.existsSync(configPath))
7061
7087
  continue;
7062
7088
  const content = fs4.readFileSync(configPath, "utf-8");
7063
- const config = JSON.parse(content);
7089
+ const config = JSON.parse(stripJsonComments(content));
7064
7090
  const plugins = config.plugin ?? [];
7065
7091
  for (const entry of plugins) {
7066
7092
  if (entry === PACKAGE_NAME) {
@@ -7088,14 +7114,17 @@ function getCachedVersion() {
7088
7114
  }
7089
7115
  } catch {}
7090
7116
  try {
7091
- const pkgPath = path4.resolve(import.meta.dirname, "..", "..", "..", "package.json");
7092
- if (fs4.existsSync(pkgPath)) {
7117
+ const currentDir = path4.dirname(fileURLToPath(import.meta.url));
7118
+ const pkgPath = findPackageJsonUp(currentDir);
7119
+ if (pkgPath) {
7093
7120
  const content = fs4.readFileSync(pkgPath, "utf-8");
7094
7121
  const pkg = JSON.parse(content);
7095
7122
  if (pkg.version)
7096
7123
  return pkg.version;
7097
7124
  }
7098
- } catch {}
7125
+ } catch (err) {
7126
+ log("[auto-update-checker] Failed to resolve version from current directory:", err);
7127
+ }
7099
7128
  return null;
7100
7129
  }
7101
7130
  async function getLatestVersion() {
@@ -7761,8 +7790,8 @@ function startCallbackServer(timeoutMs = 5 * 60 * 1000) {
7761
7790
  });
7762
7791
  const actualPort = server.port;
7763
7792
  const waitForCallback = () => {
7764
- return new Promise((resolve6, reject) => {
7765
- resolveCallback = resolve6;
7793
+ return new Promise((resolve5, reject) => {
7794
+ resolveCallback = resolve5;
7766
7795
  rejectCallback = reject;
7767
7796
  timeoutId = setTimeout(() => {
7768
7797
  cleanup();
@@ -8712,7 +8741,7 @@ async function attemptFetch(options) {
8712
8741
  if (attempt < maxPermissionRetries) {
8713
8742
  const delay = calculateRetryDelay2(attempt);
8714
8743
  debugLog6(`[RETRY] GCP permission error, retry ${attempt + 1}/${maxPermissionRetries} after ${delay}ms`);
8715
- await new Promise((resolve6) => setTimeout(resolve6, delay));
8744
+ await new Promise((resolve5) => setTimeout(resolve5, delay));
8716
8745
  continue;
8717
8746
  }
8718
8747
  debugLog6(`[RETRY] GCP permission error, max retries exceeded`);
@@ -9816,7 +9845,7 @@ function getAllServers() {
9816
9845
  // src/tools/lsp/client.ts
9817
9846
  var {spawn: spawn4 } = globalThis.Bun;
9818
9847
  import { readFileSync as readFileSync17 } from "fs";
9819
- import { extname, resolve as resolve6 } from "path";
9848
+ import { extname, resolve as resolve5 } from "path";
9820
9849
  class LSPServerManager {
9821
9850
  static instance;
9822
9851
  clients = new Map;
@@ -9966,7 +9995,7 @@ class LSPClient {
9966
9995
  }
9967
9996
  this.startReading();
9968
9997
  this.startStderrReading();
9969
- await new Promise((resolve7) => setTimeout(resolve7, 100));
9998
+ await new Promise((resolve6) => setTimeout(resolve6, 100));
9970
9999
  if (this.proc.exitCode !== null) {
9971
10000
  const stderr = this.stderrBuffer.join(`
9972
10001
  `);
@@ -10103,8 +10132,8 @@ stderr: ${stderr}` : ""));
10103
10132
  \r
10104
10133
  `;
10105
10134
  this.proc.stdin.write(header + msg);
10106
- return new Promise((resolve7, reject) => {
10107
- this.pending.set(id, { resolve: resolve7, reject });
10135
+ return new Promise((resolve6, reject) => {
10136
+ this.pending.set(id, { resolve: resolve6, reject });
10108
10137
  setTimeout(() => {
10109
10138
  if (this.pending.has(id)) {
10110
10139
  this.pending.delete(id);
@@ -10212,7 +10241,7 @@ ${msg}`);
10212
10241
  await new Promise((r) => setTimeout(r, 300));
10213
10242
  }
10214
10243
  async openFile(filePath) {
10215
- const absPath = resolve6(filePath);
10244
+ const absPath = resolve5(filePath);
10216
10245
  if (this.openedFiles.has(absPath))
10217
10246
  return;
10218
10247
  const text = readFileSync17(absPath, "utf-8");
@@ -10230,7 +10259,7 @@ ${msg}`);
10230
10259
  await new Promise((r) => setTimeout(r, 1000));
10231
10260
  }
10232
10261
  async hover(filePath, line, character) {
10233
- const absPath = resolve6(filePath);
10262
+ const absPath = resolve5(filePath);
10234
10263
  await this.openFile(absPath);
10235
10264
  return this.send("textDocument/hover", {
10236
10265
  textDocument: { uri: `file://${absPath}` },
@@ -10238,7 +10267,7 @@ ${msg}`);
10238
10267
  });
10239
10268
  }
10240
10269
  async definition(filePath, line, character) {
10241
- const absPath = resolve6(filePath);
10270
+ const absPath = resolve5(filePath);
10242
10271
  await this.openFile(absPath);
10243
10272
  return this.send("textDocument/definition", {
10244
10273
  textDocument: { uri: `file://${absPath}` },
@@ -10246,7 +10275,7 @@ ${msg}`);
10246
10275
  });
10247
10276
  }
10248
10277
  async references(filePath, line, character, includeDeclaration = true) {
10249
- const absPath = resolve6(filePath);
10278
+ const absPath = resolve5(filePath);
10250
10279
  await this.openFile(absPath);
10251
10280
  return this.send("textDocument/references", {
10252
10281
  textDocument: { uri: `file://${absPath}` },
@@ -10255,7 +10284,7 @@ ${msg}`);
10255
10284
  });
10256
10285
  }
10257
10286
  async documentSymbols(filePath) {
10258
- const absPath = resolve6(filePath);
10287
+ const absPath = resolve5(filePath);
10259
10288
  await this.openFile(absPath);
10260
10289
  return this.send("textDocument/documentSymbol", {
10261
10290
  textDocument: { uri: `file://${absPath}` }
@@ -10265,7 +10294,7 @@ ${msg}`);
10265
10294
  return this.send("workspace/symbol", { query });
10266
10295
  }
10267
10296
  async diagnostics(filePath) {
10268
- const absPath = resolve6(filePath);
10297
+ const absPath = resolve5(filePath);
10269
10298
  const uri = `file://${absPath}`;
10270
10299
  await this.openFile(absPath);
10271
10300
  await new Promise((r) => setTimeout(r, 500));
@@ -10280,7 +10309,7 @@ ${msg}`);
10280
10309
  return { items: this.diagnosticsStore.get(uri) ?? [] };
10281
10310
  }
10282
10311
  async prepareRename(filePath, line, character) {
10283
- const absPath = resolve6(filePath);
10312
+ const absPath = resolve5(filePath);
10284
10313
  await this.openFile(absPath);
10285
10314
  return this.send("textDocument/prepareRename", {
10286
10315
  textDocument: { uri: `file://${absPath}` },
@@ -10288,7 +10317,7 @@ ${msg}`);
10288
10317
  });
10289
10318
  }
10290
10319
  async rename(filePath, line, character, newName) {
10291
- const absPath = resolve6(filePath);
10320
+ const absPath = resolve5(filePath);
10292
10321
  await this.openFile(absPath);
10293
10322
  return this.send("textDocument/rename", {
10294
10323
  textDocument: { uri: `file://${absPath}` },
@@ -10297,7 +10326,7 @@ ${msg}`);
10297
10326
  });
10298
10327
  }
10299
10328
  async codeAction(filePath, startLine, startChar, endLine, endChar, only) {
10300
- const absPath = resolve6(filePath);
10329
+ const absPath = resolve5(filePath);
10301
10330
  await this.openFile(absPath);
10302
10331
  return this.send("textDocument/codeAction", {
10303
10332
  textDocument: { uri: `file://${absPath}` },
@@ -10329,10 +10358,10 @@ ${msg}`);
10329
10358
  }
10330
10359
  }
10331
10360
  // src/tools/lsp/utils.ts
10332
- import { extname as extname2, resolve as resolve7 } from "path";
10361
+ import { extname as extname2, resolve as resolve6 } from "path";
10333
10362
  import { existsSync as existsSync25, readFileSync as readFileSync18, writeFileSync as writeFileSync9 } from "fs";
10334
10363
  function findWorkspaceRoot(filePath) {
10335
- let dir = resolve7(filePath);
10364
+ let dir = resolve6(filePath);
10336
10365
  if (!existsSync25(dir) || !__require("fs").statSync(dir).isDirectory()) {
10337
10366
  dir = __require("path").dirname(dir);
10338
10367
  }
@@ -10345,10 +10374,10 @@ function findWorkspaceRoot(filePath) {
10345
10374
  }
10346
10375
  dir = __require("path").dirname(dir);
10347
10376
  }
10348
- return __require("path").dirname(resolve7(filePath));
10377
+ return __require("path").dirname(resolve6(filePath));
10349
10378
  }
10350
10379
  async function withLspClient(filePath, fn) {
10351
- const absPath = resolve7(filePath);
10380
+ const absPath = resolve6(filePath);
10352
10381
  const ext = extname2(absPath);
10353
10382
  const server = findServerForExtension(ext);
10354
10383
  if (!server) {
@@ -23264,8 +23293,8 @@ var lsp_code_action_resolve = tool({
23264
23293
  });
23265
23294
  // src/tools/ast-grep/constants.ts
23266
23295
  import { createRequire as createRequire4 } from "module";
23267
- import { dirname as dirname5, join as join33 } from "path";
23268
- import { existsSync as existsSync27, statSync as statSync3 } from "fs";
23296
+ import { dirname as dirname6, join as join33 } from "path";
23297
+ import { existsSync as existsSync27, statSync as statSync4 } from "fs";
23269
23298
 
23270
23299
  // src/tools/ast-grep/downloader.ts
23271
23300
  var {spawn: spawn5 } = globalThis.Bun;
@@ -23379,7 +23408,7 @@ async function ensureAstGrepBinary() {
23379
23408
  // src/tools/ast-grep/constants.ts
23380
23409
  function isValidBinary(filePath) {
23381
23410
  try {
23382
- return statSync3(filePath).size > 1e4;
23411
+ return statSync4(filePath).size > 1e4;
23383
23412
  } catch {
23384
23413
  return false;
23385
23414
  }
@@ -23407,7 +23436,7 @@ function findSgCliPathSync() {
23407
23436
  try {
23408
23437
  const require2 = createRequire4(import.meta.url);
23409
23438
  const cliPkgPath = require2.resolve("@ast-grep/cli/package.json");
23410
- const cliDir = dirname5(cliPkgPath);
23439
+ const cliDir = dirname6(cliPkgPath);
23411
23440
  const sgPath = join33(cliDir, binaryName);
23412
23441
  if (existsSync27(sgPath) && isValidBinary(sgPath)) {
23413
23442
  return sgPath;
@@ -23418,7 +23447,7 @@ function findSgCliPathSync() {
23418
23447
  try {
23419
23448
  const require2 = createRequire4(import.meta.url);
23420
23449
  const pkgPath = require2.resolve(`${platformPkg}/package.json`);
23421
- const pkgDir = dirname5(pkgPath);
23450
+ const pkgDir = dirname6(pkgPath);
23422
23451
  const astGrepName = process.platform === "win32" ? "ast-grep.exe" : "ast-grep";
23423
23452
  const binaryPath = join33(pkgDir, astGrepName);
23424
23453
  if (existsSync27(binaryPath) && isValidBinary(binaryPath)) {
@@ -23796,7 +23825,7 @@ var {spawn: spawn7 } = globalThis.Bun;
23796
23825
 
23797
23826
  // src/tools/grep/constants.ts
23798
23827
  import { existsSync as existsSync30 } from "fs";
23799
- import { join as join35, dirname as dirname6 } from "path";
23828
+ import { join as join35, dirname as dirname7 } from "path";
23800
23829
  import { spawnSync } from "child_process";
23801
23830
 
23802
23831
  // src/tools/grep/downloader.ts
@@ -23831,7 +23860,7 @@ function findExecutable(name) {
23831
23860
  }
23832
23861
  function getOpenCodeBundledRg() {
23833
23862
  const execPath = process.execPath;
23834
- const execDir = dirname6(execPath);
23863
+ const execDir = dirname7(execPath);
23835
23864
  const isWindows = process.platform === "win32";
23836
23865
  const rgName = isWindows ? "rg.exe" : "rg";
23837
23866
  const candidates = [
@@ -24246,7 +24275,7 @@ var glob = tool({
24246
24275
  // src/tools/slashcommand/tools.ts
24247
24276
  import { existsSync as existsSync31, readdirSync as readdirSync8, readFileSync as readFileSync19 } from "fs";
24248
24277
  import { homedir as homedir15 } from "os";
24249
- import { join as join36, basename as basename3, dirname as dirname7 } from "path";
24278
+ import { join as join36, basename as basename3, dirname as dirname8 } from "path";
24250
24279
  function discoverCommandsFromDir(commandsDir, scope) {
24251
24280
  if (!existsSync31(commandsDir)) {
24252
24281
  return [];
@@ -24330,7 +24359,7 @@ async function formatLoadedCommand(cmd) {
24330
24359
  `);
24331
24360
  sections.push(`## Command Instructions
24332
24361
  `);
24333
- const commandDir = dirname7(cmd.path);
24362
+ const commandDir = dirname8(cmd.path);
24334
24363
  const withFileRefs = await resolveFileReferencesInText(cmd.content, commandDir);
24335
24364
  const resolvedContent = await resolveCommandsInText(withFileRefs);
24336
24365
  sections.push(resolvedContent.trim());
@@ -24745,7 +24774,7 @@ Use \`background_output\` tool with task_id="${task.id}" to check progress:
24745
24774
  });
24746
24775
  }
24747
24776
  function delay(ms) {
24748
- return new Promise((resolve8) => setTimeout(resolve8, ms));
24777
+ return new Promise((resolve7) => setTimeout(resolve7, ms));
24749
24778
  }
24750
24779
  function truncateText(text, maxLength) {
24751
24780
  if (text.length <= maxLength)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oh-my-opencode",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "OpenCode plugin - custom agents (oracle, librarian) and enhanced features",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",