codecane 1.0.420-beta.261 → 1.0.420-beta.263

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 +77 -4
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  const { spawn } = require('child_process')
4
4
  const fs = require('fs')
5
+ const http = require('http')
5
6
  const https = require('https')
6
7
  const os = require('os')
7
8
  const path = require('path')
@@ -31,6 +32,70 @@ function createConfig(packageName) {
31
32
 
32
33
  const CONFIG = createConfig(packageName)
33
34
 
35
+ function getPostHogConfig() {
36
+ const apiKey =
37
+ process.env.CODEBUFF_POSTHOG_API_KEY ||
38
+ process.env.NEXT_PUBLIC_POSTHOG_API_KEY
39
+ const host =
40
+ process.env.CODEBUFF_POSTHOG_HOST ||
41
+ process.env.NEXT_PUBLIC_POSTHOG_HOST_URL
42
+
43
+ if (!apiKey || !host) {
44
+ return null
45
+ }
46
+
47
+ return { apiKey, host }
48
+ }
49
+
50
+ /**
51
+ * Track update failure event to PostHog.
52
+ * Fire-and-forget - errors are silently ignored.
53
+ */
54
+ function trackUpdateFailed(errorMessage, version, context = {}) {
55
+ try {
56
+ const posthogConfig = getPostHogConfig()
57
+ if (!posthogConfig) {
58
+ return
59
+ }
60
+
61
+ const payload = JSON.stringify({
62
+ api_key: posthogConfig.apiKey,
63
+ event: 'cli.update_codebuff_failed',
64
+ properties: {
65
+ distinct_id: `anonymous-${CONFIG.homeDir}`,
66
+ error: errorMessage,
67
+ version: version || 'unknown',
68
+ platform: process.platform,
69
+ arch: process.arch,
70
+ isStaging: true,
71
+ ...context,
72
+ },
73
+ timestamp: new Date().toISOString(),
74
+ })
75
+
76
+ const parsedUrl = new URL(`${posthogConfig.host}/capture/`)
77
+ const isHttps = parsedUrl.protocol === 'https:'
78
+ const options = {
79
+ hostname: parsedUrl.hostname,
80
+ port: parsedUrl.port || (isHttps ? 443 : 80),
81
+ path: parsedUrl.pathname + parsedUrl.search,
82
+ method: 'POST',
83
+ headers: {
84
+ 'Content-Type': 'application/json',
85
+ 'Content-Length': Buffer.byteLength(payload),
86
+ },
87
+ }
88
+
89
+ const transport = isHttps ? https : http
90
+ const req = transport.request(options)
91
+ req.on('error', () => {}) // Silently ignore errors
92
+ req.write(payload)
93
+ req.end()
94
+ } catch (e) {
95
+ // Silently ignore any tracking errors
96
+ }
97
+ }
98
+
34
99
  const PLATFORM_TARGETS = {
35
100
  'linux-x64': `${packageName}-linux-x64.tar.gz`,
36
101
  'linux-arm64': `${packageName}-linux-arm64.tar.gz`,
@@ -256,7 +321,9 @@ async function downloadBinary(version) {
256
321
  const fileName = PLATFORM_TARGETS[platformKey]
257
322
 
258
323
  if (!fileName) {
259
- throw new Error(`Unsupported platform: ${process.platform} ${process.arch}`)
324
+ const error = new Error(`Unsupported platform: ${process.platform} ${process.arch}`)
325
+ trackUpdateFailed(error.message, version, { stage: 'platform_check' })
326
+ throw error
260
327
  }
261
328
 
262
329
  const downloadUrl = `${
@@ -278,7 +345,9 @@ async function downloadBinary(version) {
278
345
 
279
346
  if (res.statusCode !== 200) {
280
347
  fs.rmSync(CONFIG.tempDownloadDir, { recursive: true })
281
- throw new Error(`Download failed: HTTP ${res.statusCode}`)
348
+ const error = new Error(`Download failed: HTTP ${res.statusCode}`)
349
+ trackUpdateFailed(error.message, version, { stage: 'http_download', statusCode: res.statusCode })
350
+ throw error
282
351
  }
283
352
 
284
353
  const totalSize = parseInt(res.headers['content-length'] || '0', 10)
@@ -318,9 +387,11 @@ async function downloadBinary(version) {
318
387
  if (!fs.existsSync(tempBinaryPath)) {
319
388
  const files = fs.readdirSync(CONFIG.tempDownloadDir)
320
389
  fs.rmSync(CONFIG.tempDownloadDir, { recursive: true })
321
- throw new Error(
390
+ const error = new Error(
322
391
  `Binary not found after extraction. Expected: ${CONFIG.binaryName}, Available files: ${files.join(', ')}`,
323
392
  )
393
+ trackUpdateFailed(error.message, version, { stage: 'extraction' })
394
+ throw error
324
395
  }
325
396
 
326
397
  // Set executable permissions
@@ -334,7 +405,9 @@ async function downloadBinary(version) {
334
405
 
335
406
  if (!smokeTestPassed) {
336
407
  fs.rmSync(CONFIG.tempDownloadDir, { recursive: true })
337
- throw new Error('Downloaded binary failed smoke test (--version check)')
408
+ const error = new Error('Downloaded binary failed smoke test (--version check)')
409
+ trackUpdateFailed(error.message, version, { stage: 'smoke_test' })
410
+ throw error
338
411
  }
339
412
 
340
413
  // Smoke test passed - move binary to final location
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codecane",
3
- "version": "1.0.420-beta.261",
3
+ "version": "1.0.420-beta.263",
4
4
  "description": "AI coding agent CLI (staging)",
5
5
  "license": "MIT",
6
6
  "bin": {