11import { createHash } from "node:crypto" ;
22import { access , mkdir , readFile } from "node:fs/promises" ;
33import path from "node:path" ;
4+ import { fileURLToPath } from "node:url" ;
45import pc from "picocolors" ;
56import type { DocsCacheLock , DocsCacheLockSource } from "#cache/lock" ;
67import { readLock , resolveLockPath , writeLock } from "#cache/lock" ;
@@ -18,6 +19,7 @@ import {
1819 type DocsCacheResolvedSource ,
1920 loadConfig ,
2021} from "#config" ;
22+ import { isRecord } from "#core/is-record" ;
2123import { resolveCacheDir , resolveTargetDir } from "#core/paths" ;
2224import { fetchSource } from "#git/fetch-source" ;
2325import { resolveRemoteCommit } from "#git/resolve-remote" ;
@@ -187,35 +189,56 @@ export const getSyncPlan = async (
187189 } ;
188190} ;
189191
190- const loadToolVersion = async ( ) => {
191- const cwdPath = path . resolve ( process . cwd ( ) , "package.json" ) ;
192+ const TOOL_PACKAGE_NAME = "docs-cache" ;
193+
194+ const readToolVersionFromPackageFile = async ( packagePath : string ) => {
192195 try {
193- const raw = await readFile ( cwdPath , "utf8" ) ;
194- const pkg = JSON . parse ( raw . toString ( ) ) ;
195- return typeof pkg . version === "string" ? pkg . version : "0.0.0" ;
196+ const raw = await readFile ( packagePath , "utf8" ) ;
197+ const parsed : unknown = JSON . parse ( raw ) ;
198+ if ( ! isRecord ( parsed ) ) {
199+ return null ;
200+ }
201+ const pkgName = parsed . name ;
202+ const pkgVersion = parsed . version ;
203+ if ( pkgName !== TOOL_PACKAGE_NAME ) {
204+ return null ;
205+ }
206+ if ( typeof pkgVersion !== "string" || pkgVersion . length === 0 ) {
207+ return null ;
208+ }
209+ return pkgVersion ;
196210 } catch {
197- // fallback to bundle-relative location
211+ return null ;
198212 }
199- try {
200- const raw = await readFile (
201- new URL ( "../package.json" , import . meta. url ) ,
202- "utf8" ,
203- ) ;
204- const pkg = JSON . parse ( raw . toString ( ) ) ;
205- return typeof pkg . version === "string" ? pkg . version : "0.0.0" ;
206- } catch {
207- // fallback to dist/chunks relative location
213+ } ;
214+
215+ const findToolVersionFrom = async ( startDir : string ) => {
216+ let currentDir = startDir ;
217+ while ( true ) {
218+ const packagePath = path . join ( currentDir , "package.json" ) ;
219+ const version = await readToolVersionFromPackageFile ( packagePath ) ;
220+ if ( version ) {
221+ return version ;
222+ }
223+ const parentDir = path . dirname ( currentDir ) ;
224+ if ( parentDir === currentDir ) {
225+ return null ;
226+ }
227+ currentDir = parentDir ;
208228 }
209- try {
210- const raw = await readFile (
211- new URL ( "../../package.json" , import . meta. url ) ,
212- "utf8" ,
213- ) ;
214- const pkg = JSON . parse ( raw . toString ( ) ) ;
215- return typeof pkg . version === "string" ? pkg . version : "0.0.0" ;
216- } catch {
217- return "0.0.0" ;
229+ } ;
230+
231+ const loadToolVersion = async ( ) => {
232+ const moduleDir = path . dirname ( fileURLToPath ( import . meta. url ) ) ;
233+ const moduleVersion = await findToolVersionFrom ( moduleDir ) ;
234+ if ( moduleVersion ) {
235+ return moduleVersion ;
236+ }
237+ const cwdVersion = await findToolVersionFrom ( process . cwd ( ) ) ;
238+ if ( cwdVersion ) {
239+ return cwdVersion ;
218240 }
241+ return "0.0.0" ;
219242} ;
220243
221244const buildLockSource = (
0 commit comments