11import * as fs from "node:fs"
22import * as path from "node:path"
3+ import { fileURLToPath } from "node:url"
34import type { NpmDistTags , OpencodeConfig , PackageJson , UpdateCheckResult } from "./types"
45import {
56 PACKAGE_NAME ,
@@ -14,14 +15,18 @@ export function isLocalDevMode(directory: string): boolean {
1415 return getLocalDevPath ( directory ) !== null
1516}
1617
18+ function stripJsonComments ( json : string ) : string {
19+ return json . replace ( / ^ \s * \/ \/ .* $ / gm, "" ) . replace ( / , ( \s * [ } \] ] ) / g, "$1" )
20+ }
21+
1722export function getLocalDevPath ( directory : string ) : string | null {
1823 const projectConfig = path . join ( directory , ".opencode" , "opencode.json" )
1924
2025 for ( const configPath of [ projectConfig , USER_OPENCODE_CONFIG ] ) {
2126 try {
2227 if ( ! fs . existsSync ( configPath ) ) continue
2328 const content = fs . readFileSync ( configPath , "utf-8" )
24- const config = JSON . parse ( content ) as OpencodeConfig
29+ const config = JSON . parse ( stripJsonComments ( content ) ) as OpencodeConfig
2530 const plugins = config . plugin ?? [ ]
2631
2732 for ( const entry of plugins ) {
@@ -37,13 +42,35 @@ export function getLocalDevPath(directory: string): string | null {
3742 return null
3843}
3944
45+ function findPackageJsonUp ( startPath : string ) : string | null {
46+ try {
47+ const stat = fs . statSync ( startPath )
48+ let dir = stat . isDirectory ( ) ? startPath : path . dirname ( startPath )
49+
50+ for ( let i = 0 ; i < 10 ; i ++ ) {
51+ const pkgPath = path . join ( dir , "package.json" )
52+ if ( fs . existsSync ( pkgPath ) ) {
53+ try {
54+ const content = fs . readFileSync ( pkgPath , "utf-8" )
55+ const pkg = JSON . parse ( content ) as PackageJson
56+ if ( pkg . name === PACKAGE_NAME ) return pkgPath
57+ } catch { }
58+ }
59+ const parent = path . dirname ( dir )
60+ if ( parent === dir ) break
61+ dir = parent
62+ }
63+ } catch { }
64+ return null
65+ }
66+
4067export function getLocalDevVersion ( directory : string ) : string | null {
4168 const localPath = getLocalDevPath ( directory )
4269 if ( ! localPath ) return null
4370
4471 try {
45- const pkgPath = path . join ( localPath , "package.json" )
46- if ( ! fs . existsSync ( pkgPath ) ) return null
72+ const pkgPath = findPackageJsonUp ( localPath )
73+ if ( ! pkgPath ) return null
4774 const content = fs . readFileSync ( pkgPath , "utf-8" )
4875 const pkg = JSON . parse ( content ) as PackageJson
4976 return pkg . version ?? null
@@ -65,7 +92,7 @@ export function findPluginEntry(directory: string): PluginEntryInfo | null {
6592 try {
6693 if ( ! fs . existsSync ( configPath ) ) continue
6794 const content = fs . readFileSync ( configPath , "utf-8" )
68- const config = JSON . parse ( content ) as OpencodeConfig
95+ const config = JSON . parse ( stripJsonComments ( content ) ) as OpencodeConfig
6996 const plugins = config . plugin ?? [ ]
7097
7198 for ( const entry of plugins ) {
@@ -96,13 +123,16 @@ export function getCachedVersion(): string | null {
96123 } catch { }
97124
98125 try {
99- const pkgPath = path . resolve ( import . meta. dirname , ".." , ".." , ".." , "package.json" )
100- if ( fs . existsSync ( pkgPath ) ) {
126+ const currentDir = path . dirname ( fileURLToPath ( import . meta. url ) )
127+ const pkgPath = findPackageJsonUp ( currentDir )
128+ if ( pkgPath ) {
101129 const content = fs . readFileSync ( pkgPath , "utf-8" )
102130 const pkg = JSON . parse ( content ) as PackageJson
103131 if ( pkg . version ) return pkg . version
104132 }
105- } catch { }
133+ } catch ( err ) {
134+ log ( "[auto-update-checker] Failed to resolve version from current directory:" , err )
135+ }
106136
107137 return null
108138}
0 commit comments