vesper-code 1.0.10 → 1.0.13

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/index.js +158 -3
  2. package/package.json +6 -6
package/index.js CHANGED
@@ -1,10 +1,15 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const { spawn } = require('child_process')
3
+ const { spawn, spawnSync } = require('child_process')
4
4
  const fs = require('fs')
5
+ const https = require('https')
5
6
  const os = require('os')
6
7
  const path = require('path')
7
8
 
9
+ const PACKAGE_NAME = 'vesper-code'
10
+ const NPM_LATEST_URL = `https://registry.npmjs.org/${PACKAGE_NAME}/latest`
11
+ const UPDATE_CHECK_TIMEOUT_MS = 1500
12
+
8
13
  const TARGET_PACKAGES = {
9
14
  'darwin-arm64': {
10
15
  packageName: 'vesper-code-darwin-arm64',
@@ -32,6 +37,138 @@ function getTarget() {
32
37
  return `${process.platform}-${process.arch}`
33
38
  }
34
39
 
40
+ function parseVersion(version) {
41
+ const match = String(version || '').match(/^(\d+)\.(\d+)\.(\d+)/)
42
+ if (!match) return null
43
+ return [Number(match[1]), Number(match[2]), Number(match[3])]
44
+ }
45
+
46
+ function compareVersions(a, b) {
47
+ const parsedA = parseVersion(a)
48
+ const parsedB = parseVersion(b)
49
+ if (!parsedA || !parsedB) return 0
50
+
51
+ for (let index = 0; index < 3; index += 1) {
52
+ const diff = parsedA[index] - parsedB[index]
53
+ if (diff !== 0) return diff
54
+ }
55
+
56
+ return 0
57
+ }
58
+
59
+ function getCurrentVersion() {
60
+ try {
61
+ const packageJsonPath = path.join(__dirname, 'package.json')
62
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'))
63
+ return typeof packageJson.version === 'string' ? packageJson.version : null
64
+ } catch {
65
+ return null
66
+ }
67
+ }
68
+
69
+ function fetchLatestVersion() {
70
+ return new Promise((resolve) => {
71
+ const request = https.get(
72
+ NPM_LATEST_URL,
73
+ {
74
+ headers: {
75
+ accept: 'application/json',
76
+ 'user-agent': `${PACKAGE_NAME}-cli`,
77
+ },
78
+ },
79
+ (response) => {
80
+ if (response.statusCode !== 200) {
81
+ response.resume()
82
+ resolve(null)
83
+ return
84
+ }
85
+
86
+ let body = ''
87
+ response.setEncoding('utf8')
88
+ response.on('data', (chunk) => {
89
+ body += chunk
90
+ })
91
+ response.on('end', () => {
92
+ try {
93
+ const data = JSON.parse(body)
94
+ resolve(typeof data.version === 'string' ? data.version : null)
95
+ } catch {
96
+ resolve(null)
97
+ }
98
+ })
99
+ },
100
+ )
101
+
102
+ request.on('error', () => resolve(null))
103
+ request.setTimeout(UPDATE_CHECK_TIMEOUT_MS, () => {
104
+ request.destroy()
105
+ resolve(null)
106
+ })
107
+ })
108
+ }
109
+
110
+ function shouldSkipAutoUpdate() {
111
+ return (
112
+ process.env.VESPER_SKIP_AUTO_UPDATE === '1' ||
113
+ process.env.VESPER_NO_AUTO_UPDATE === '1' ||
114
+ process.env.VESPER_AUTO_UPDATE_IN_PROGRESS === '1'
115
+ )
116
+ }
117
+
118
+ function getNpmCommand() {
119
+ return process.platform === 'win32' ? 'npm.cmd' : 'npm'
120
+ }
121
+
122
+ function installLatestVersion(latestVersion) {
123
+ console.error(`Updating Vesper Code to ${latestVersion}...`)
124
+
125
+ const result = spawnSync(
126
+ getNpmCommand(),
127
+ ['install', '-g', `${PACKAGE_NAME}@latest`],
128
+ {
129
+ stdio: 'inherit',
130
+ env: {
131
+ ...process.env,
132
+ VESPER_AUTO_UPDATE_IN_PROGRESS: '1',
133
+ VESPER_SKIP_AUTO_UPDATE: '1',
134
+ },
135
+ },
136
+ )
137
+
138
+ return result.status === 0
139
+ }
140
+
141
+ async function autoUpdateIfAvailable(options = {}) {
142
+ try {
143
+ const shouldSkip = options.shouldSkipAutoUpdate || shouldSkipAutoUpdate
144
+ if (shouldSkip()) return
145
+
146
+ const readCurrentVersion = options.getCurrentVersion || getCurrentVersion
147
+ const readLatestVersion = options.fetchLatestVersion || fetchLatestVersion
148
+ const installVersion = options.installLatestVersion || installLatestVersion
149
+
150
+ const currentVersion = readCurrentVersion()
151
+ if (!currentVersion) return
152
+
153
+ const latestVersion = await readLatestVersion()
154
+ if (!latestVersion || compareVersions(latestVersion, currentVersion) <= 0) {
155
+ return
156
+ }
157
+
158
+ const installed = installVersion(latestVersion)
159
+ if (installed) {
160
+ console.error(`Vesper Code updated: ${currentVersion} -> ${latestVersion}`)
161
+ return
162
+ }
163
+
164
+ console.error(
165
+ `Vesper Code update failed. Run manually: npm install -g ${PACKAGE_NAME}@latest`,
166
+ )
167
+ } catch {
168
+ // Auto-update must never block or break the CLI.
169
+ }
170
+ }
171
+
35
172
  function getPlatformPackage() {
36
173
  const target = getTarget()
37
174
  const platformPackage = TARGET_PACKAGES[target]
@@ -78,7 +215,9 @@ function resolveBinaryPath() {
78
215
  return binaryPath
79
216
  }
80
217
 
81
- function main() {
218
+ async function main() {
219
+ await autoUpdateIfAvailable()
220
+
82
221
  let binaryPath
83
222
  try {
84
223
  binaryPath = resolveBinaryPath()
@@ -114,4 +253,20 @@ function main() {
114
253
  })
115
254
  }
116
255
 
117
- main()
256
+ if (require.main === module) {
257
+ main().catch((error) => {
258
+ console.error('Failed to start Vesper Code.')
259
+ console.error(error instanceof Error ? error.message : String(error))
260
+ process.exit(1)
261
+ })
262
+ }
263
+
264
+ module.exports = {
265
+ autoUpdateIfAvailable,
266
+ compareVersions,
267
+ fetchLatestVersion,
268
+ getCurrentVersion,
269
+ installLatestVersion,
270
+ parseVersion,
271
+ shouldSkipAutoUpdate,
272
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vesper-code",
3
- "version": "1.0.10",
3
+ "version": "1.0.13",
4
4
  "description": "Vesper Code — AI coding agent",
5
5
  "license": "MIT",
6
6
  "bin": {
@@ -28,11 +28,11 @@
28
28
  "node": ">=16"
29
29
  },
30
30
  "optionalDependencies": {
31
- "vesper-code-darwin-arm64": "1.0.10",
32
- "vesper-code-darwin-x64": "1.0.10",
33
- "vesper-code-linux-arm64": "1.0.10",
34
- "vesper-code-linux-x64": "1.0.10",
35
- "vesper-code-windows-x64": "1.0.10"
31
+ "vesper-code-darwin-arm64": "1.0.13",
32
+ "vesper-code-darwin-x64": "1.0.13",
33
+ "vesper-code-linux-arm64": "1.0.13",
34
+ "vesper-code-linux-x64": "1.0.13",
35
+ "vesper-code-windows-x64": "1.0.13"
36
36
  },
37
37
  "repository": {
38
38
  "type": "git",