coder-config 0.40.7 → 0.40.9

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.
package/lib/constants.js CHANGED
@@ -2,7 +2,7 @@
2
2
  * Constants and tool path configurations
3
3
  */
4
4
 
5
- const VERSION = '0.40.7';
5
+ const VERSION = '0.40.9';
6
6
 
7
7
  // Tool-specific path configurations
8
8
  const TOOL_PATHS = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coder-config",
3
- "version": "0.40.7",
3
+ "version": "0.40.9",
4
4
  "description": "Configuration manager for AI coding tools - Claude Code, Gemini CLI, Codex CLI, Antigravity. Manage MCPs, rules, permissions, memory, and workstreams.",
5
5
  "author": "regression.io",
6
6
  "main": "config-loader.js",
@@ -37,10 +37,11 @@ function getVersionFromFile(filePath) {
37
37
 
38
38
  /**
39
39
  * Fetch npm version and verify it's installable
40
- * Returns version only if the tarball is accessible (CDN propagated)
40
+ * Uses multiple verification steps to ensure CDN has propagated
41
41
  */
42
42
  function fetchNpmVersion() {
43
43
  return new Promise((resolve) => {
44
+ // Step 1: Get latest version from registry
44
45
  const url = 'https://registry.npmjs.org/coder-config/latest';
45
46
  const req = https.get(url, (res) => {
46
47
  let data = '';
@@ -49,41 +50,76 @@ function fetchNpmVersion() {
49
50
  try {
50
51
  const parsed = JSON.parse(data);
51
52
  const version = parsed.version;
52
- const tarballUrl = parsed.dist?.tarball;
53
53
 
54
- if (!version || !tarballUrl) {
55
- console.log('[update-check] npm registry response missing version or tarball');
54
+ if (!version) {
55
+ console.log('[update-check] npm registry response missing version');
56
56
  resolve(null);
57
57
  return;
58
58
  }
59
59
 
60
- // Verify tarball is accessible (HEAD request)
61
- const tarball = new URL(tarballUrl);
62
- const options = {
63
- hostname: tarball.hostname,
64
- path: tarball.pathname,
65
- method: 'HEAD'
66
- };
67
-
68
- const verifyReq = https.request(options, (verifyRes) => {
69
- // 200 = accessible, anything else = not yet propagated
70
- if (verifyRes.statusCode === 200) {
71
- resolve(version);
72
- } else {
73
- console.log(`[update-check] tarball not accessible (status ${verifyRes.statusCode})`);
74
- resolve(null);
75
- }
60
+ // Step 2: Verify specific version endpoint is accessible
61
+ // This is what npm install actually uses
62
+ const versionUrl = `https://registry.npmjs.org/coder-config/${version}`;
63
+ const verifyReq = https.get(versionUrl, (verifyRes) => {
64
+ let verifyData = '';
65
+ verifyRes.on('data', chunk => verifyData += chunk);
66
+ verifyRes.on('end', () => {
67
+ if (verifyRes.statusCode !== 200) {
68
+ console.log(`[update-check] version ${version} not yet available (status ${verifyRes.statusCode})`);
69
+ resolve(null);
70
+ return;
71
+ }
72
+
73
+ try {
74
+ const versionInfo = JSON.parse(verifyData);
75
+ // Step 3: Verify the tarball URL is present and accessible
76
+ const tarballUrl = versionInfo.dist?.tarball;
77
+ if (!tarballUrl) {
78
+ console.log('[update-check] version info missing tarball URL');
79
+ resolve(null);
80
+ return;
81
+ }
82
+
83
+ // Step 4: HEAD request to tarball to verify CDN propagation
84
+ const tarball = new URL(tarballUrl);
85
+ const headReq = https.request({
86
+ hostname: tarball.hostname,
87
+ path: tarball.pathname,
88
+ method: 'HEAD'
89
+ }, (headRes) => {
90
+ if (headRes.statusCode === 200) {
91
+ console.log(`[update-check] version ${version} verified available`);
92
+ resolve(version);
93
+ } else {
94
+ console.log(`[update-check] tarball not accessible (status ${headRes.statusCode})`);
95
+ resolve(null);
96
+ }
97
+ });
98
+ headReq.setTimeout(5000, () => {
99
+ console.log('[update-check] tarball verification timed out');
100
+ headReq.destroy();
101
+ resolve(null);
102
+ });
103
+ headReq.on('error', (e) => {
104
+ console.log('[update-check] tarball verification error:', e.message);
105
+ resolve(null);
106
+ });
107
+ headReq.end();
108
+ } catch (e) {
109
+ console.log('[update-check] failed to parse version info:', e.message);
110
+ resolve(null);
111
+ }
112
+ });
76
113
  });
77
114
  verifyReq.setTimeout(5000, () => {
78
- console.log('[update-check] tarball verification timed out');
115
+ console.log('[update-check] version verification timed out');
79
116
  verifyReq.destroy();
80
117
  resolve(null);
81
118
  });
82
119
  verifyReq.on('error', (e) => {
83
- console.log('[update-check] tarball verification error:', e.message);
120
+ console.log('[update-check] version verification error:', e.message);
84
121
  resolve(null);
85
122
  });
86
- verifyReq.end();
87
123
  } catch (e) {
88
124
  console.log('[update-check] failed to parse npm response:', e.message);
89
125
  resolve(null);
@@ -121,8 +157,30 @@ function isNewerVersion(source, installed) {
121
157
  return false;
122
158
  }
123
159
 
160
+ /**
161
+ * Pre-cache the npm package to verify it's actually installable
162
+ * Returns true if package is cached and ready to install
163
+ */
164
+ async function preCachePackage(version) {
165
+ return new Promise((resolve) => {
166
+ try {
167
+ console.log(`[update-check] pre-caching coder-config@${version}...`);
168
+ execSync(`npm cache add coder-config@${version}`, {
169
+ stdio: 'pipe',
170
+ timeout: 60000
171
+ });
172
+ console.log(`[update-check] pre-cache successful for ${version}`);
173
+ resolve(true);
174
+ } catch (error) {
175
+ console.log(`[update-check] pre-cache failed: ${error.message}`);
176
+ resolve(false);
177
+ }
178
+ });
179
+ }
180
+
124
181
  /**
125
182
  * Check for updates
183
+ * Only reports update available if package is pre-cached and ready to install
126
184
  */
127
185
  async function checkForUpdates(manager, dirname) {
128
186
  // Get current installed version
@@ -136,7 +194,22 @@ async function checkForUpdates(manager, dirname) {
136
194
  console.log(`[update-check] installed: ${installedVersion}, npm: ${npmVersion}`);
137
195
 
138
196
  if (npmVersion && isNewerVersion(npmVersion, installedVersion)) {
139
- console.log('[update-check] update available');
197
+ // Pre-cache the package before showing notification
198
+ // This ensures the update will actually work when clicked
199
+ const cached = await preCachePackage(npmVersion);
200
+
201
+ if (!cached) {
202
+ console.log('[update-check] update found but not yet installable, skipping notification');
203
+ return {
204
+ updateAvailable: false,
205
+ installedVersion,
206
+ latestVersion: installedVersion,
207
+ sourceVersion: installedVersion,
208
+ installDir: manager.installDir
209
+ };
210
+ }
211
+
212
+ console.log('[update-check] update available and pre-cached');
140
213
  return {
141
214
  updateAvailable: true,
142
215
  installedVersion,