dimcode 0.0.67-beta.8 → 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 +152 -53
- package/package.json +7 -8
- package/dist/ink.mjs +0 -1291
package/bin/dim.mjs
CHANGED
|
@@ -4,21 +4,32 @@ import fs from 'node:fs'
|
|
|
4
4
|
import os from 'node:os'
|
|
5
5
|
import path from 'node:path'
|
|
6
6
|
import process from 'node:process'
|
|
7
|
-
import { fileURLToPath
|
|
7
|
+
import { fileURLToPath } from 'node:url'
|
|
8
8
|
|
|
9
9
|
const __filename = fileURLToPath(import.meta.url)
|
|
10
10
|
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/')
|
|
@@ -26,52 +37,13 @@ const wrapperPm
|
|
|
26
37
|
: 'npm'
|
|
27
38
|
|
|
28
39
|
const args = process.argv.slice(2)
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
else {
|
|
35
|
-
await runInk()
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function resolveRouting(argv) {
|
|
39
|
-
// Explicit `dim ink ...` forces the Ink TUI fallback.
|
|
40
|
-
if (argv[0] === 'ink')
|
|
41
|
-
return { target: 'ink', forwardArgs: argv.slice(1) }
|
|
42
|
-
// Explicit `dim opentui ...` also routes to the opentui binary
|
|
43
|
-
// (kept for symmetry; opentui is the default).
|
|
44
|
-
if (argv[0] === 'opentui')
|
|
45
|
-
return { target: 'opentui', forwardArgs: argv.slice(1) }
|
|
46
|
-
|
|
47
|
-
// Default: everything goes to the opentui binary.
|
|
48
|
-
return { target: 'opentui', forwardArgs: argv }
|
|
49
|
-
}
|
|
40
|
+
const forwardArgs = args[0] === 'opentui' ? args.slice(1) : args
|
|
41
|
+
runOpentui(forwardArgs).catch((err) => {
|
|
42
|
+
console.error('[dim] Unexpected error: ' + (err && err.stack ? err.stack : err))
|
|
43
|
+
process.exit(1)
|
|
44
|
+
})
|
|
50
45
|
|
|
51
|
-
async function
|
|
52
|
-
const inkEntry = path.join(__dirname, '..', 'dist', 'ink.mjs')
|
|
53
|
-
if (!fs.existsSync(inkEntry)) {
|
|
54
|
-
console.error('[dim] Ink bundle missing: ' + inkEntry)
|
|
55
|
-
console.error('[dim] Try reinstalling dimcode@beta.')
|
|
56
|
-
process.exit(1)
|
|
57
|
-
}
|
|
58
|
-
// Inner CLI's DEFAULT_PACKAGE_NAME is already 'dimcode', so no override
|
|
59
|
-
// needed. Pass wrapper version through for diagnostics.
|
|
60
|
-
process.env.DIMCODE_NPM_PACKAGE = 'dimcode'
|
|
61
|
-
process.env.DIMCODE_NPM_PACKAGE_MANAGER = wrapperPm
|
|
62
|
-
if (wrapperVersion)
|
|
63
|
-
process.env.DIMCODE_NPM_PACKAGE_VERSION = wrapperVersion
|
|
64
|
-
try {
|
|
65
|
-
await import(pathToFileURL(inkEntry).href)
|
|
66
|
-
}
|
|
67
|
-
catch (err) {
|
|
68
|
-
console.error('[dim] Failed to start Ink TUI:')
|
|
69
|
-
console.error(err)
|
|
70
|
-
process.exit(1)
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
function runOpentui(restArgs) {
|
|
46
|
+
async function runOpentui(restArgs) {
|
|
75
47
|
const envPath = process.env.DIMCODE_BIN_PATH
|
|
76
48
|
if (envPath) {
|
|
77
49
|
if (!fs.existsSync(envPath)) {
|
|
@@ -91,17 +63,22 @@ function runOpentui(restArgs) {
|
|
|
91
63
|
const archMap = { x64: 'x64', arm64: 'arm64' }
|
|
92
64
|
const platform = platformMap[os.platform()] || os.platform()
|
|
93
65
|
const arch = archMap[os.arch()] || os.arch()
|
|
94
|
-
const base = '
|
|
95
|
-
const binary = platform === 'windows' ? '
|
|
66
|
+
const base = wrapperName + '-' + platform + '-' + arch
|
|
67
|
+
const binary = platform === 'windows' ? binaryBasename + '.exe' : binaryBasename
|
|
96
68
|
|
|
97
69
|
if (process.env.DIMCODE_DEBUG) {
|
|
98
|
-
console.error('[dim] Wrapper
|
|
70
|
+
console.error('[dim] Wrapper: ' + wrapperName + '@' + wrapperVersion)
|
|
99
71
|
console.error('[dim] Platform: ' + platform + ' Arch: ' + arch)
|
|
100
72
|
console.error('[dim] Looking for package: ' + base)
|
|
101
73
|
console.error('[dim] Script dir: ' + scriptDir)
|
|
102
74
|
}
|
|
103
75
|
|
|
104
|
-
|
|
76
|
+
let resolved = findBinary(scriptDir, base, binary)
|
|
77
|
+
|
|
78
|
+
if (!resolved) {
|
|
79
|
+
resolved = await ensureCachedBinary(base, binary, wrapperVersion)
|
|
80
|
+
}
|
|
81
|
+
|
|
105
82
|
if (!resolved) {
|
|
106
83
|
console.error(
|
|
107
84
|
'[dim] Could not find the opentui binary for your platform.\n'
|
|
@@ -112,7 +89,7 @@ function runOpentui(restArgs) {
|
|
|
112
89
|
+ ' Searched: ' + scriptDir + ' (and parent directories)\n'
|
|
113
90
|
+ '\n'
|
|
114
91
|
+ 'Try uninstalling and reinstalling the beta channel:\n'
|
|
115
|
-
+ ' npm uninstall -g
|
|
92
|
+
+ ' npm uninstall -g ' + wrapperName + ' && npm install -g ' + wrapperName + '@beta\n',
|
|
116
93
|
)
|
|
117
94
|
process.exit(1)
|
|
118
95
|
}
|
|
@@ -123,6 +100,128 @@ function runOpentui(restArgs) {
|
|
|
123
100
|
spawnBinary(resolved, restArgs)
|
|
124
101
|
}
|
|
125
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
|
+
|
|
126
225
|
function findBinary(startDir, base, binary) {
|
|
127
226
|
let current = startDir
|
|
128
227
|
for (;;) {
|
|
@@ -142,7 +241,7 @@ function findBinary(startDir, base, binary) {
|
|
|
142
241
|
function spawnBinary(target, forwardedArgs) {
|
|
143
242
|
const env = {
|
|
144
243
|
...process.env,
|
|
145
|
-
DIMCODE_NPM_PACKAGE:
|
|
244
|
+
DIMCODE_NPM_PACKAGE: wrapperName,
|
|
146
245
|
DIMCODE_NPM_PACKAGE_MANAGER: wrapperPm,
|
|
147
246
|
DIMCODE_NPM_PACKAGE_ROOT: path.resolve(__dirname, '..'),
|
|
148
247
|
}
|
|
@@ -166,7 +265,7 @@ function spawnBinary(target, forwardedArgs) {
|
|
|
166
265
|
'[dim] The binary file was not found. Try reinstalling:',
|
|
167
266
|
)
|
|
168
267
|
console.error(
|
|
169
|
-
' npm uninstall -g
|
|
268
|
+
' npm uninstall -g ' + wrapperName + ' && npm install -g ' + wrapperName + '@beta',
|
|
170
269
|
)
|
|
171
270
|
}
|
|
172
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": {
|
|
@@ -8,14 +8,13 @@
|
|
|
8
8
|
"dimcode": "./bin/dim.mjs"
|
|
9
9
|
},
|
|
10
10
|
"files": [
|
|
11
|
-
"bin"
|
|
12
|
-
"dist"
|
|
11
|
+
"bin"
|
|
13
12
|
],
|
|
14
13
|
"optionalDependencies": {
|
|
15
|
-
"dimcode-darwin-arm64": "0.0.67
|
|
16
|
-
"dimcode-darwin-x64": "0.0.67
|
|
17
|
-
"dimcode-linux-arm64": "0.0.67
|
|
18
|
-
"dimcode-linux-x64": "0.0.67
|
|
19
|
-
"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"
|
|
20
19
|
}
|
|
21
20
|
}
|