dimcode 0.0.67-beta.9 → 0.0.67
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/bin/dim.mjs +150 -9
- package/package.json +6 -6
package/bin/dim.mjs
CHANGED
|
@@ -11,14 +11,25 @@ const __dirname = path.dirname(__filename)
|
|
|
11
11
|
const isWindows = os.platform() === 'win32'
|
|
12
12
|
|
|
13
13
|
let wrapperVersion = ''
|
|
14
|
+
let wrapperName = 'dimcode'
|
|
14
15
|
try {
|
|
15
16
|
const pkg = JSON.parse(
|
|
16
17
|
fs.readFileSync(path.join(__dirname, '..', 'package.json'), 'utf8'),
|
|
17
18
|
)
|
|
18
19
|
wrapperVersion = pkg.version || ''
|
|
20
|
+
if (pkg.name)
|
|
21
|
+
wrapperName = pkg.name
|
|
19
22
|
}
|
|
20
23
|
catch {}
|
|
21
24
|
|
|
25
|
+
// Inner binary file name shipped inside each platform sub-package's bin/.
|
|
26
|
+
// dimcode → bin/dimcode(.exe); goatchain-cli → bin/goatchain(.exe).
|
|
27
|
+
const BINARY_BASENAMES = {
|
|
28
|
+
'dimcode': 'dimcode',
|
|
29
|
+
'goatchain-cli': 'goatchain',
|
|
30
|
+
}
|
|
31
|
+
const binaryBasename = BINARY_BASENAMES[wrapperName] || wrapperName
|
|
32
|
+
|
|
22
33
|
const wrapperDir = path.join(__dirname, '..').replace(/\\/g, '/').toLowerCase()
|
|
23
34
|
const wrapperPm
|
|
24
35
|
= wrapperDir.includes('.bun/') || wrapperDir.includes('bun/install/')
|
|
@@ -27,9 +38,12 @@ const wrapperPm
|
|
|
27
38
|
|
|
28
39
|
const args = process.argv.slice(2)
|
|
29
40
|
const forwardArgs = args[0] === 'opentui' ? args.slice(1) : args
|
|
30
|
-
runOpentui(forwardArgs)
|
|
41
|
+
runOpentui(forwardArgs).catch((err) => {
|
|
42
|
+
console.error('[dim] Unexpected error: ' + (err && err.stack ? err.stack : err))
|
|
43
|
+
process.exit(1)
|
|
44
|
+
})
|
|
31
45
|
|
|
32
|
-
function runOpentui(restArgs) {
|
|
46
|
+
async function runOpentui(restArgs) {
|
|
33
47
|
const envPath = process.env.DIMCODE_BIN_PATH
|
|
34
48
|
if (envPath) {
|
|
35
49
|
if (!fs.existsSync(envPath)) {
|
|
@@ -49,17 +63,22 @@ function runOpentui(restArgs) {
|
|
|
49
63
|
const archMap = { x64: 'x64', arm64: 'arm64' }
|
|
50
64
|
const platform = platformMap[os.platform()] || os.platform()
|
|
51
65
|
const arch = archMap[os.arch()] || os.arch()
|
|
52
|
-
const base = '
|
|
53
|
-
const binary = platform === 'windows' ? '
|
|
66
|
+
const base = wrapperName + '-' + platform + '-' + arch
|
|
67
|
+
const binary = platform === 'windows' ? binaryBasename + '.exe' : binaryBasename
|
|
54
68
|
|
|
55
69
|
if (process.env.DIMCODE_DEBUG) {
|
|
56
|
-
console.error('[dim] Wrapper
|
|
70
|
+
console.error('[dim] Wrapper: ' + wrapperName + '@' + wrapperVersion)
|
|
57
71
|
console.error('[dim] Platform: ' + platform + ' Arch: ' + arch)
|
|
58
72
|
console.error('[dim] Looking for package: ' + base)
|
|
59
73
|
console.error('[dim] Script dir: ' + scriptDir)
|
|
60
74
|
}
|
|
61
75
|
|
|
62
|
-
|
|
76
|
+
let resolved = findBinary(scriptDir, base, binary)
|
|
77
|
+
|
|
78
|
+
if (!resolved) {
|
|
79
|
+
resolved = await ensureCachedBinary(base, binary, wrapperVersion)
|
|
80
|
+
}
|
|
81
|
+
|
|
63
82
|
if (!resolved) {
|
|
64
83
|
console.error(
|
|
65
84
|
'[dim] Could not find the opentui binary for your platform.\n'
|
|
@@ -70,7 +89,7 @@ function runOpentui(restArgs) {
|
|
|
70
89
|
+ ' Searched: ' + scriptDir + ' (and parent directories)\n'
|
|
71
90
|
+ '\n'
|
|
72
91
|
+ 'Try uninstalling and reinstalling the beta channel:\n'
|
|
73
|
-
+ ' npm uninstall -g
|
|
92
|
+
+ ' npm uninstall -g ' + wrapperName + ' && npm install -g ' + wrapperName + '@beta\n',
|
|
74
93
|
)
|
|
75
94
|
process.exit(1)
|
|
76
95
|
}
|
|
@@ -81,6 +100,128 @@ function runOpentui(restArgs) {
|
|
|
81
100
|
spawnBinary(resolved, restArgs)
|
|
82
101
|
}
|
|
83
102
|
|
|
103
|
+
async function ensureCachedBinary(base, binary, version) {
|
|
104
|
+
if (!version) {
|
|
105
|
+
if (process.env.DIMCODE_DEBUG)
|
|
106
|
+
console.error('[dim] No wrapper version available; skipping registry fallback')
|
|
107
|
+
return null
|
|
108
|
+
}
|
|
109
|
+
if (process.env.DIMCODE_NO_DOWNLOAD === '1') {
|
|
110
|
+
if (process.env.DIMCODE_DEBUG)
|
|
111
|
+
console.error('[dim] DIMCODE_NO_DOWNLOAD=1; skipping registry fallback')
|
|
112
|
+
return null
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const home = os.homedir()
|
|
116
|
+
const cacheDir = path.join(home, '.dimcode', 'binaries', base, version)
|
|
117
|
+
const cachedBin = path.join(cacheDir, 'bin', binary)
|
|
118
|
+
if (fs.existsSync(cachedBin)) {
|
|
119
|
+
if (process.env.DIMCODE_DEBUG)
|
|
120
|
+
console.error('[dim] Using cached binary: ' + cachedBin)
|
|
121
|
+
return cachedBin
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (typeof fetch !== 'function') {
|
|
125
|
+
console.error('[dim] Registry fallback requires Node 18+ (global fetch). Please reinstall after upgrading Node.')
|
|
126
|
+
return null
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const registry = (process.env.DIMCODE_REGISTRY || 'https://registry.npmjs.org').replace(/\/+$/, '')
|
|
130
|
+
const url = registry + '/' + base + '/-/' + base + '-' + version + '.tgz'
|
|
131
|
+
|
|
132
|
+
console.error('[dim] Platform binary missing locally. Fetching ' + base + '@' + version + '...')
|
|
133
|
+
if (process.env.DIMCODE_DEBUG)
|
|
134
|
+
console.error('[dim] URL: ' + url)
|
|
135
|
+
|
|
136
|
+
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'dimcode-dl-'))
|
|
137
|
+
const tgzPath = path.join(tmpDir, 'pkg.tgz')
|
|
138
|
+
|
|
139
|
+
try {
|
|
140
|
+
await downloadFile(url, tgzPath)
|
|
141
|
+
fs.mkdirSync(cacheDir, { recursive: true })
|
|
142
|
+
extractTarball(tgzPath, cacheDir)
|
|
143
|
+
if (!isWindows && fs.existsSync(cachedBin)) {
|
|
144
|
+
try { fs.chmodSync(cachedBin, 0o755) }
|
|
145
|
+
catch {}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
catch (err) {
|
|
149
|
+
console.error('[dim] Failed to fetch platform binary: ' + (err && err.message ? err.message : err))
|
|
150
|
+
console.error('[dim] You can retry, set DIMCODE_BIN_PATH to a local binary, or reinstall with:')
|
|
151
|
+
console.error(' npm uninstall -g ' + wrapperName + ' && npm install -g ' + wrapperName + '@beta')
|
|
152
|
+
return null
|
|
153
|
+
}
|
|
154
|
+
finally {
|
|
155
|
+
try { fs.rmSync(tmpDir, { recursive: true, force: true }) }
|
|
156
|
+
catch {}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (!fs.existsSync(cachedBin)) {
|
|
160
|
+
console.error('[dim] Downloaded archive did not contain expected binary at ' + cachedBin)
|
|
161
|
+
return null
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
console.error('[dim] Cached at ' + cachedBin)
|
|
165
|
+
return cachedBin
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
async function downloadFile(url, dest) {
|
|
169
|
+
let currentUrl = url
|
|
170
|
+
for (let hop = 0; hop < 5; hop++) {
|
|
171
|
+
const res = await fetch(currentUrl, { redirect: 'manual' })
|
|
172
|
+
if (res.status >= 300 && res.status < 400 && res.headers.get('location')) {
|
|
173
|
+
currentUrl = new URL(res.headers.get('location'), currentUrl).toString()
|
|
174
|
+
continue
|
|
175
|
+
}
|
|
176
|
+
if (!res.ok)
|
|
177
|
+
throw new Error('HTTP ' + res.status + ' ' + res.statusText + ' for ' + currentUrl)
|
|
178
|
+
|
|
179
|
+
const total = Number(res.headers.get('content-length') || 0)
|
|
180
|
+
const out = fs.createWriteStream(dest)
|
|
181
|
+
let downloaded = 0
|
|
182
|
+
let lastShown = -1
|
|
183
|
+
const reader = res.body.getReader()
|
|
184
|
+
for (;;) {
|
|
185
|
+
const { done, value } = await reader.read()
|
|
186
|
+
if (done) break
|
|
187
|
+
out.write(Buffer.from(value))
|
|
188
|
+
downloaded += value.length
|
|
189
|
+
if (total && process.stderr.isTTY) {
|
|
190
|
+
const pct = Math.floor((downloaded / total) * 100)
|
|
191
|
+
if (pct !== lastShown && pct % 5 === 0) {
|
|
192
|
+
process.stderr.write('\r[dim] Downloading... ' + pct + '%')
|
|
193
|
+
lastShown = pct
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
out.end()
|
|
198
|
+
await new Promise((resolve, reject) => {
|
|
199
|
+
out.on('close', resolve)
|
|
200
|
+
out.on('error', reject)
|
|
201
|
+
})
|
|
202
|
+
if (process.stderr.isTTY)
|
|
203
|
+
process.stderr.write('\r[dim] Downloaded ' + (downloaded / 1024 / 1024).toFixed(1) + ' MB \n')
|
|
204
|
+
else
|
|
205
|
+
console.error('[dim] Downloaded ' + (downloaded / 1024 / 1024).toFixed(1) + ' MB')
|
|
206
|
+
return
|
|
207
|
+
}
|
|
208
|
+
throw new Error('Too many redirects')
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function extractTarball(tgzPath, destDir) {
|
|
212
|
+
const result = childProcess.spawnSync(
|
|
213
|
+
'tar',
|
|
214
|
+
['-xzf', tgzPath, '-C', destDir, '--strip-components=1'],
|
|
215
|
+
{ stdio: process.env.DIMCODE_DEBUG ? 'inherit' : 'pipe' },
|
|
216
|
+
)
|
|
217
|
+
if (result.error)
|
|
218
|
+
throw new Error('tar not available: ' + result.error.message)
|
|
219
|
+
if (result.status !== 0) {
|
|
220
|
+
const stderr = result.stderr ? result.stderr.toString() : ''
|
|
221
|
+
throw new Error('tar exited with status ' + result.status + (stderr ? ': ' + stderr.trim() : ''))
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
84
225
|
function findBinary(startDir, base, binary) {
|
|
85
226
|
let current = startDir
|
|
86
227
|
for (;;) {
|
|
@@ -100,7 +241,7 @@ function findBinary(startDir, base, binary) {
|
|
|
100
241
|
function spawnBinary(target, forwardedArgs) {
|
|
101
242
|
const env = {
|
|
102
243
|
...process.env,
|
|
103
|
-
DIMCODE_NPM_PACKAGE:
|
|
244
|
+
DIMCODE_NPM_PACKAGE: wrapperName,
|
|
104
245
|
DIMCODE_NPM_PACKAGE_MANAGER: wrapperPm,
|
|
105
246
|
DIMCODE_NPM_PACKAGE_ROOT: path.resolve(__dirname, '..'),
|
|
106
247
|
}
|
|
@@ -124,7 +265,7 @@ function spawnBinary(target, forwardedArgs) {
|
|
|
124
265
|
'[dim] The binary file was not found. Try reinstalling:',
|
|
125
266
|
)
|
|
126
267
|
console.error(
|
|
127
|
-
' npm uninstall -g
|
|
268
|
+
' npm uninstall -g ' + wrapperName + ' && npm install -g ' + wrapperName + '@beta',
|
|
128
269
|
)
|
|
129
270
|
}
|
|
130
271
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dimcode",
|
|
3
|
-
"version": "0.0.67
|
|
3
|
+
"version": "0.0.67",
|
|
4
4
|
"description": "AI coding agent CLI and terminal coding assistant with an interactive TUI (beta channel)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -11,10 +11,10 @@
|
|
|
11
11
|
"bin"
|
|
12
12
|
],
|
|
13
13
|
"optionalDependencies": {
|
|
14
|
-
"dimcode-darwin-arm64": "0.0.67
|
|
15
|
-
"dimcode-darwin-x64": "0.0.67
|
|
16
|
-
"dimcode-linux-arm64": "0.0.67
|
|
17
|
-
"dimcode-linux-x64": "0.0.67
|
|
18
|
-
"dimcode-windows-x64": "0.0.67
|
|
14
|
+
"dimcode-darwin-arm64": "0.0.67",
|
|
15
|
+
"dimcode-darwin-x64": "0.0.67",
|
|
16
|
+
"dimcode-linux-arm64": "0.0.67",
|
|
17
|
+
"dimcode-linux-x64": "0.0.67",
|
|
18
|
+
"dimcode-windows-x64": "0.0.67"
|
|
19
19
|
}
|
|
20
20
|
}
|