@@ -7,6 +7,7 @@ import './polyfills/intl-stub.mts'
77import { setTheme } from '@socketsecurity/lib/themes'
88setTheme ( 'socket' )
99
10+ import path from 'node:path'
1011import process from 'node:process'
1112import { fileURLToPath , pathToFileURL } from 'node:url'
1213
@@ -33,9 +34,12 @@ import { messageWithCauses, stackWithCauses } from 'pony-cause'
3334import lookupRegistryAuthToken from 'registry-auth-token'
3435import lookupRegistryUrl from 'registry-url'
3536
36- import { debug , debugDir } from '@socketsecurity/lib/debug'
37+ import { debug as debugNs , debugDir } from '@socketsecurity/lib/debug'
3738import { getDefaultLogger } from '@socketsecurity/lib/logger'
3839
40+ // Debug logger for manifest operations
41+ const debug = debugNs
42+
3943import { rootAliases , rootCommands } from './commands.mts'
4044import ENV from './constants/env.mts'
4145import { SOCKET_CLI_BIN_NAME } from './constants/packages.mts'
@@ -51,9 +55,55 @@ import { serializeResultJson } from './utils/output/result-json.mts'
5155import { runPreflightDownloads } from './utils/preflight/downloads.mts'
5256import { isSeaBinary } from './utils/sea/detect.mts'
5357import { scheduleUpdateCheck } from './utils/update/manager.mts'
58+ import { dlxManifest } from '@socketsecurity/lib/dlx-manifest'
5459
5560const __filename = fileURLToPath ( import . meta. url )
5661
62+ /**
63+ * Write manifest entry for CLI installed via bootstrap.
64+ * Bootstrap passes spec and cache dir via environment variables.
65+ */
66+ async function writeBootstrapManifestEntry ( ) : Promise < void > {
67+ const spec = ENV . SOCKET_CLI_BOOTSTRAP_SPEC
68+ const cacheDir = ENV . SOCKET_CLI_BOOTSTRAP_CACHE_DIR
69+
70+ if ( ! spec || ! cacheDir ) {
71+ // Not launched via bootstrap, skip.
72+ return
73+ }
74+
75+ try {
76+ // Extract cache key from path (last segment)
77+ const cacheKey = path . basename ( cacheDir )
78+
79+ // Read package.json to get installed version
80+ const pkgJsonPath = path . join (
81+ cacheDir ,
82+ 'node_modules' ,
83+ '@socketsecurity' ,
84+ 'cli' ,
85+ 'package.json' ,
86+ )
87+
88+ let installedVersion = '0.0.0'
89+ try {
90+ const fs = await import ( 'node:fs/promises' )
91+ const pkgJson = JSON . parse ( await fs . readFile ( pkgJsonPath , 'utf8' ) )
92+ installedVersion = pkgJson . version || '0.0.0'
93+ } catch {
94+ // Failed to read version, use default
95+ }
96+
97+ // Write manifest entry.
98+ await dlxManifest . setPackageEntry ( spec , cacheKey , {
99+ installed_version : installedVersion ,
100+ } )
101+ } catch ( error ) {
102+ // Silently ignore manifest write errors - not critical
103+ debug ( `Failed to write bootstrap manifest entry: ${ error } ` )
104+ }
105+ }
106+
57107void ( async ( ) => {
58108 // Skip update checks in test environments.
59109 if ( ! ENV . VITEST && ! ENV . CI ) {
@@ -68,6 +118,10 @@ void (async () => {
68118 version : ENV . INLINED_SOCKET_CLI_VERSION || '0.0.0' ,
69119 } )
70120
121+ // Write manifest entry if launched via bootstrap (SEA/smol).
122+ // Bootstrap passes spec and cache dir via env vars.
123+ await writeBootstrapManifestEntry ( )
124+
71125 // Background preflight downloads for optional dependencies.
72126 // This silently downloads @coana -tech/cli and @socketbin/cli-ai in the
73127 // background to ensure they're cached for future use.
0 commit comments