donkicode 0.0.1 → 0.1.1
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/LICENSE +21 -0
- package/README.md +35 -5
- package/bin/donkicode +264 -0
- package/package.json +22 -8
- package/postinstall.mjs +139 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 opencode
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,8 +1,38 @@
|
|
|
1
|
-
#
|
|
1
|
+
# DonkiCode
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Entorno visual de desarrollo multi-agente. Un Manager que habla contigo y un equipo de especialistas que trabajan en paralelo. Skills premium con metodología empaquetada. BYOM: usas tu suscripción de Claude, ChatGPT u Ollama, no vendemos créditos.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
esté, este mismo nombre servirá para instalarlo.
|
|
5
|
+
## Instalar
|
|
7
6
|
|
|
8
|
-
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g donkicode
|
|
9
|
+
donkicode
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Eso es todo. `donkicode` levanta la app localmente y abre tu navegador. La primera vez, entras con Google. Cross-platform (macOS · Windows · Linux), un solo comando.
|
|
13
|
+
|
|
14
|
+
> ¿Prefieres pnpm? `pnpm install -g donkicode` funciona igual.
|
|
15
|
+
|
|
16
|
+
## Planes
|
|
17
|
+
|
|
18
|
+
- **Free · 0€/mes** — para probarlo. BYOM incluido.
|
|
19
|
+
- **Pro · [precio pendiente]/mes** — límites ampliados + skills premium completas + soporte prioritario. BYOM incluido.
|
|
20
|
+
- **BYOM (Bring Your Own Model)** — usa tu suscripción de Claude Pro, ChatGPT Plus u Ollama local. DonkiCode no cobra por tokens de LLM.
|
|
21
|
+
|
|
22
|
+
Tu plan lo decide tu cuenta al entrar con Google. El binario es el mismo para todo el mundo.
|
|
23
|
+
|
|
24
|
+
## ¿Qué hace?
|
|
25
|
+
|
|
26
|
+
- **Chat con un Manager**: le describes lo que quieres en lenguaje natural, él delega a los especialistas.
|
|
27
|
+
- **Equipo bajo demanda**: Frontend, Backend, Diseño, DevOps y más se crean solo cuando hacen falta.
|
|
28
|
+
- **Skills premium empaquetadas**: la primera es **DonkiDesign**, un flujo cinemático de diseño web con clonado fiel de referencias visuales.
|
|
29
|
+
- **Editor visual**: retocas el diseño en vivo, sin tocar código a mano.
|
|
30
|
+
- **Memorias persistentes**: cada agente recuerda lo que hizo la sesión anterior.
|
|
31
|
+
|
|
32
|
+
## Créditos
|
|
33
|
+
|
|
34
|
+
Fork de [OpenCode](https://github.com/anomalyco/opencode) por Anomaly Innovations Inc. (MIT).
|
|
35
|
+
|
|
36
|
+
## Licencia
|
|
37
|
+
|
|
38
|
+
MIT
|
package/bin/donkicode
ADDED
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* DEC-041 / T-238b — entry point del paquete `donkicode` publicado en npm.
|
|
5
|
+
*
|
|
6
|
+
* Este shim vive AQUÍ (en `packages/opencode/`) porque reutilizamos toda la
|
|
7
|
+
* infraestructura del fork: build, sidecar server, catálogo de comandos.
|
|
8
|
+
* El paquete publicado a npm se llama `donkicode` (ver `"bin"` en el
|
|
9
|
+
* `package.json`), la carpeta interna sigue llamándose `opencode` por
|
|
10
|
+
* regla del fork (DEC-LEG-008).
|
|
11
|
+
*
|
|
12
|
+
* Comportamiento:
|
|
13
|
+
* - Sin args → equivalente a `donkicode web`: arranca sidecar local + abre
|
|
14
|
+
* el navegador del sistema al UI en `http://127.0.0.1:<puerto>`.
|
|
15
|
+
* Es la experiencia por defecto del release público (Ruta 1 CLI).
|
|
16
|
+
* - Con args → forwarda tal cual al binario nativo (headless, dev, etc).
|
|
17
|
+
*
|
|
18
|
+
* Resolución del binario nativo:
|
|
19
|
+
* 1. env `DONKICODE_BIN_PATH` (override explícito, útil para dev).
|
|
20
|
+
* 2. Cache local `./bin/.donkicode` junto al shim (post-install).
|
|
21
|
+
* 3. Paquetes optionalDependencies `donkicode-<platform>-<arch>` (release).
|
|
22
|
+
* 4. Fallback `opencode-<platform>-<arch>` (cuando el usuario tiene el fork
|
|
23
|
+
* upstream instalado en la misma máquina; útil para dev local).
|
|
24
|
+
*
|
|
25
|
+
* El código de detección de plataforma/arch/avx2/musl es idéntico al que
|
|
26
|
+
* usa `bin/opencode` del upstream porque los binarios son los mismos —
|
|
27
|
+
* solo cambia el nombre del paquete.
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
import childProcess from "node:child_process"
|
|
31
|
+
import fs from "node:fs"
|
|
32
|
+
import path from "node:path"
|
|
33
|
+
import os from "node:os"
|
|
34
|
+
import { fileURLToPath } from "node:url"
|
|
35
|
+
|
|
36
|
+
const __filename = fileURLToPath(import.meta.url)
|
|
37
|
+
|
|
38
|
+
function run(target, args) {
|
|
39
|
+
// DEC-041 (T-238b / Cabo 5) — si al lado del binario nativo vive un bundle
|
|
40
|
+
// de frontend estático (`<pkg-dir>/dist/index.html`), el shim exporta
|
|
41
|
+
// `DONKICODE_STATIC_DIR` antes de arrancar. Así `donkicode web` sirve la UI
|
|
42
|
+
// sin fricción, coherente con la experiencia de release público. En dev
|
|
43
|
+
// (bun run dev sin dist) esta rama simplemente no dispara. Si el usuario ya
|
|
44
|
+
// definió la env var, no la sobreescribimos.
|
|
45
|
+
const env = { ...process.env }
|
|
46
|
+
if (!env.DONKICODE_STATIC_DIR) {
|
|
47
|
+
const pkgDir = path.dirname(path.dirname(fs.realpathSync(target)))
|
|
48
|
+
const staticDir = path.join(pkgDir, "dist")
|
|
49
|
+
if (fs.existsSync(path.join(staticDir, "index.html"))) {
|
|
50
|
+
env.DONKICODE_STATIC_DIR = staticDir
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const result = childProcess.spawnSync(target, args, {
|
|
54
|
+
stdio: "inherit",
|
|
55
|
+
env,
|
|
56
|
+
})
|
|
57
|
+
if (result.error) {
|
|
58
|
+
console.error(result.error.message)
|
|
59
|
+
process.exit(1)
|
|
60
|
+
}
|
|
61
|
+
const code = typeof result.status === "number" ? result.status : 0
|
|
62
|
+
process.exit(code)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Args por defecto: si el usuario no pasa subcomando, arrancamos `web`
|
|
66
|
+
// (sidecar + navegador). Coincide con la experiencia esperada por el
|
|
67
|
+
// mensaje de instalación del landing (`pnpm install -g donkicode` seguido
|
|
68
|
+
// de `donkicode` → aparece el navegador con DonkiCode).
|
|
69
|
+
const rawArgs = process.argv.slice(2)
|
|
70
|
+
const forwardArgs = rawArgs.length === 0 ? ["web"] : rawArgs
|
|
71
|
+
|
|
72
|
+
const envPath = process.env.DONKICODE_BIN_PATH || process.env.OPENCODE_BIN_PATH
|
|
73
|
+
if (envPath) {
|
|
74
|
+
run(envPath, forwardArgs)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const scriptPath = fs.realpathSync(__filename)
|
|
78
|
+
const scriptDir = path.dirname(scriptPath)
|
|
79
|
+
|
|
80
|
+
const cached = path.join(scriptDir, ".donkicode")
|
|
81
|
+
if (fs.existsSync(cached)) {
|
|
82
|
+
run(cached, forwardArgs)
|
|
83
|
+
}
|
|
84
|
+
const cachedLegacy = path.join(scriptDir, ".opencode")
|
|
85
|
+
if (fs.existsSync(cachedLegacy)) {
|
|
86
|
+
run(cachedLegacy, forwardArgs)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const platformMap = {
|
|
90
|
+
darwin: "darwin",
|
|
91
|
+
linux: "linux",
|
|
92
|
+
win32: "windows",
|
|
93
|
+
}
|
|
94
|
+
const archMap = {
|
|
95
|
+
x64: "x64",
|
|
96
|
+
arm64: "arm64",
|
|
97
|
+
arm: "arm",
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
let platform = platformMap[os.platform()]
|
|
101
|
+
if (!platform) {
|
|
102
|
+
platform = os.platform()
|
|
103
|
+
}
|
|
104
|
+
let arch = archMap[os.arch()]
|
|
105
|
+
if (!arch) {
|
|
106
|
+
arch = os.arch()
|
|
107
|
+
}
|
|
108
|
+
const binary = platform === "windows" ? "donkicode.exe" : "donkicode"
|
|
109
|
+
// Fallback para dev local: los paquetes `opencode-<platform>-<arch>` también
|
|
110
|
+
// contienen el binario `donkicode` (build.ts:184 lo llama así), no `opencode`.
|
|
111
|
+
// El nombre legacy `opencode` solo aparecería si un usuario tiene instalado
|
|
112
|
+
// además el fork upstream, escenario raro que ignoramos aquí.
|
|
113
|
+
const legacyBinary = binary
|
|
114
|
+
|
|
115
|
+
function supportsAvx2() {
|
|
116
|
+
if (arch !== "x64") return false
|
|
117
|
+
|
|
118
|
+
if (platform === "linux") {
|
|
119
|
+
try {
|
|
120
|
+
return /(^|\s)avx2(\s|$)/i.test(fs.readFileSync("/proc/cpuinfo", "utf8"))
|
|
121
|
+
} catch {
|
|
122
|
+
return false
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (platform === "darwin") {
|
|
127
|
+
try {
|
|
128
|
+
const result = childProcess.spawnSync("sysctl", ["-n", "hw.optional.avx2_0"], {
|
|
129
|
+
encoding: "utf8",
|
|
130
|
+
timeout: 1500,
|
|
131
|
+
})
|
|
132
|
+
if (result.status !== 0) return false
|
|
133
|
+
return (result.stdout || "").trim() === "1"
|
|
134
|
+
} catch {
|
|
135
|
+
return false
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (platform === "windows") {
|
|
140
|
+
const cmd =
|
|
141
|
+
'(Add-Type -MemberDefinition "[DllImport(""kernel32.dll"")] public static extern bool IsProcessorFeaturePresent(int ProcessorFeature);" -Name Kernel32 -Namespace Win32 -PassThru)::IsProcessorFeaturePresent(40)'
|
|
142
|
+
|
|
143
|
+
for (const exe of ["powershell.exe", "pwsh.exe", "pwsh", "powershell"]) {
|
|
144
|
+
try {
|
|
145
|
+
const result = childProcess.spawnSync(exe, ["-NoProfile", "-NonInteractive", "-Command", cmd], {
|
|
146
|
+
encoding: "utf8",
|
|
147
|
+
timeout: 3000,
|
|
148
|
+
windowsHide: true,
|
|
149
|
+
})
|
|
150
|
+
if (result.status !== 0) continue
|
|
151
|
+
const out = (result.stdout || "").trim().toLowerCase()
|
|
152
|
+
if (out === "true" || out === "1") return true
|
|
153
|
+
if (out === "false" || out === "0") return false
|
|
154
|
+
} catch {
|
|
155
|
+
continue
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return false
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return false
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function candidateNames(baseName) {
|
|
166
|
+
const base = baseName + "-" + platform + "-" + arch
|
|
167
|
+
const avx2 = supportsAvx2()
|
|
168
|
+
const baseline = arch === "x64" && !avx2
|
|
169
|
+
|
|
170
|
+
if (platform === "linux") {
|
|
171
|
+
const musl = (() => {
|
|
172
|
+
try {
|
|
173
|
+
if (fs.existsSync("/etc/alpine-release")) return true
|
|
174
|
+
} catch {
|
|
175
|
+
/* ignore */
|
|
176
|
+
}
|
|
177
|
+
try {
|
|
178
|
+
const result = childProcess.spawnSync("ldd", ["--version"], { encoding: "utf8" })
|
|
179
|
+
const text = ((result.stdout || "") + (result.stderr || "")).toLowerCase()
|
|
180
|
+
if (text.includes("musl")) return true
|
|
181
|
+
} catch {
|
|
182
|
+
/* ignore */
|
|
183
|
+
}
|
|
184
|
+
return false
|
|
185
|
+
})()
|
|
186
|
+
|
|
187
|
+
if (musl) {
|
|
188
|
+
if (arch === "x64") {
|
|
189
|
+
if (baseline) return [`${base}-baseline-musl`, `${base}-musl`, `${base}-baseline`, base]
|
|
190
|
+
return [`${base}-musl`, `${base}-baseline-musl`, base, `${base}-baseline`]
|
|
191
|
+
}
|
|
192
|
+
return [`${base}-musl`, base]
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
if (arch === "x64") {
|
|
196
|
+
if (baseline) return [`${base}-baseline`, base, `${base}-baseline-musl`, `${base}-musl`]
|
|
197
|
+
return [base, `${base}-baseline`, `${base}-musl`, `${base}-baseline-musl`]
|
|
198
|
+
}
|
|
199
|
+
return [base, `${base}-musl`]
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
if (arch === "x64") {
|
|
203
|
+
if (baseline) return [`${base}-baseline`, base]
|
|
204
|
+
return [base, `${base}-baseline`]
|
|
205
|
+
}
|
|
206
|
+
return [base]
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Buscamos primero paquetes `donkicode-*` (release nativo), luego
|
|
210
|
+
// `opencode-*` (fallback para dev local con fork upstream instalado).
|
|
211
|
+
const donkicodeNames = candidateNames("donkicode")
|
|
212
|
+
const opencodeNames = candidateNames("opencode")
|
|
213
|
+
|
|
214
|
+
function findBinary(startDir) {
|
|
215
|
+
// Dev local: `script/build.ts` deja los paquetes por plataforma en
|
|
216
|
+
// `<paquete>/dist/`, no en `node_modules/`. Esta rama permite que
|
|
217
|
+
// `node bin/donkicode` funcione tras `bun run build --single` sin
|
|
218
|
+
// simular un `npm install`. En release el paquete vive en node_modules
|
|
219
|
+
// y esta ruta simplemente no existe.
|
|
220
|
+
const shimDir = path.dirname(startDir)
|
|
221
|
+
const localDist = path.join(shimDir, "dist")
|
|
222
|
+
if (fs.existsSync(localDist)) {
|
|
223
|
+
for (const name of donkicodeNames) {
|
|
224
|
+
const candidate = path.join(localDist, name, "bin", binary)
|
|
225
|
+
if (fs.existsSync(candidate)) return candidate
|
|
226
|
+
}
|
|
227
|
+
for (const name of opencodeNames) {
|
|
228
|
+
const candidate = path.join(localDist, name, "bin", legacyBinary)
|
|
229
|
+
if (fs.existsSync(candidate)) return candidate
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
let current = startDir
|
|
234
|
+
for (;;) {
|
|
235
|
+
const modules = path.join(current, "node_modules")
|
|
236
|
+
if (fs.existsSync(modules)) {
|
|
237
|
+
for (const name of donkicodeNames) {
|
|
238
|
+
const candidate = path.join(modules, name, "bin", binary)
|
|
239
|
+
if (fs.existsSync(candidate)) return candidate
|
|
240
|
+
}
|
|
241
|
+
for (const name of opencodeNames) {
|
|
242
|
+
const candidate = path.join(modules, name, "bin", legacyBinary)
|
|
243
|
+
if (fs.existsSync(candidate)) return candidate
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
const parent = path.dirname(current)
|
|
247
|
+
if (parent === current) {
|
|
248
|
+
return
|
|
249
|
+
}
|
|
250
|
+
current = parent
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
const resolved = findBinary(scriptDir)
|
|
255
|
+
if (!resolved) {
|
|
256
|
+
const tried = [...donkicodeNames, ...opencodeNames].map((n) => `"${n}"`).join(" o ")
|
|
257
|
+
console.error(
|
|
258
|
+
"No se encontró el binario nativo de DonkiCode para tu plataforma. Es probable que tu gestor de paquetes no haya instalado la variante correcta. Intenta instalar manualmente uno de estos paquetes: " +
|
|
259
|
+
tried,
|
|
260
|
+
)
|
|
261
|
+
process.exit(1)
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
run(resolved, forwardArgs)
|
package/package.json
CHANGED
|
@@ -1,11 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "donkicode",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "DonkiCode —
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "DonkiCode — el estudio de agentes con memoria memodonki.",
|
|
5
|
+
"bin": {
|
|
6
|
+
"donkicode": "./bin/donkicode"
|
|
7
|
+
},
|
|
8
|
+
"scripts": {
|
|
9
|
+
"postinstall": "bun ./postinstall.mjs || node ./postinstall.mjs"
|
|
10
|
+
},
|
|
5
11
|
"license": "UNLICENSED",
|
|
6
|
-
"
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
+
"optionalDependencies": {
|
|
13
|
+
"donkicode-linux-arm64": "0.1.1",
|
|
14
|
+
"donkicode-linux-x64-baseline": "0.1.1",
|
|
15
|
+
"donkicode-linux-x64-baseline-musl": "0.1.1",
|
|
16
|
+
"donkicode-windows-x64": "0.1.1",
|
|
17
|
+
"donkicode-windows-x64-baseline": "0.1.1",
|
|
18
|
+
"donkicode-darwin-arm64": "0.1.1",
|
|
19
|
+
"donkicode-linux-x64-musl": "0.1.1",
|
|
20
|
+
"donkicode-linux-arm64-musl": "0.1.1",
|
|
21
|
+
"donkicode-darwin-x64-baseline": "0.1.1",
|
|
22
|
+
"donkicode-linux-x64": "0.1.1",
|
|
23
|
+
"donkicode-darwin-x64": "0.1.1"
|
|
24
|
+
}
|
|
25
|
+
}
|
package/postinstall.mjs
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import fs from "fs"
|
|
4
|
+
import path from "path"
|
|
5
|
+
import os from "os"
|
|
6
|
+
import { fileURLToPath } from "url"
|
|
7
|
+
import { createRequire } from "module"
|
|
8
|
+
|
|
9
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
10
|
+
const require = createRequire(import.meta.url)
|
|
11
|
+
|
|
12
|
+
function detectPlatformAndArch() {
|
|
13
|
+
// Map platform names
|
|
14
|
+
let platform
|
|
15
|
+
switch (os.platform()) {
|
|
16
|
+
case "darwin":
|
|
17
|
+
platform = "darwin"
|
|
18
|
+
break
|
|
19
|
+
case "linux":
|
|
20
|
+
platform = "linux"
|
|
21
|
+
break
|
|
22
|
+
case "win32":
|
|
23
|
+
platform = "windows"
|
|
24
|
+
break
|
|
25
|
+
default:
|
|
26
|
+
platform = os.platform()
|
|
27
|
+
break
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Map architecture names
|
|
31
|
+
let arch
|
|
32
|
+
switch (os.arch()) {
|
|
33
|
+
case "x64":
|
|
34
|
+
arch = "x64"
|
|
35
|
+
break
|
|
36
|
+
case "arm64":
|
|
37
|
+
arch = "arm64"
|
|
38
|
+
break
|
|
39
|
+
case "arm":
|
|
40
|
+
arch = "arm"
|
|
41
|
+
break
|
|
42
|
+
default:
|
|
43
|
+
arch = os.arch()
|
|
44
|
+
break
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return { platform, arch }
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function findBinary() {
|
|
51
|
+
const { platform, arch } = detectPlatformAndArch()
|
|
52
|
+
// El binario del release se publica como `donkicode-<plat>-<arch>` (build.ts lo genera
|
|
53
|
+
// así). El fallback `opencode-*` es SOLO para dev local con el fork upstream instalado
|
|
54
|
+
// —el mismo orden que el shim `bin/donkicode`—: en una instalación real de `donkicode`
|
|
55
|
+
// el optionalDependency que baja npm es `donkicode-*`. Antes esto buscaba solo
|
|
56
|
+
// `opencode-*` (cabo del fork) y la instalación petaba: los binarios ya no se llaman así.
|
|
57
|
+
const binaryName = platform === "windows" ? "donkicode.exe" : "donkicode"
|
|
58
|
+
const candidates = [`donkicode-${platform}-${arch}`, `opencode-${platform}-${arch}`]
|
|
59
|
+
const errors = []
|
|
60
|
+
for (const packageName of candidates) {
|
|
61
|
+
const bin = packageName.startsWith("donkicode") ? binaryName : platform === "windows" ? "opencode.exe" : "opencode"
|
|
62
|
+
try {
|
|
63
|
+
const packageJsonPath = require.resolve(`${packageName}/package.json`)
|
|
64
|
+
const packageDir = path.dirname(packageJsonPath)
|
|
65
|
+
const binaryPath = path.join(packageDir, "bin", bin)
|
|
66
|
+
if (!fs.existsSync(binaryPath)) throw new Error(`Binary not found at ${binaryPath}`)
|
|
67
|
+
return { binaryPath, binaryName: bin }
|
|
68
|
+
} catch (error) {
|
|
69
|
+
errors.push(`${packageName}: ${error.message}`)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
throw new Error(`No encuentro el binario nativo. Probé:\n ${errors.join("\n ")}`)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function prepareBinDirectory(binaryName) {
|
|
76
|
+
const binDir = path.join(__dirname, "bin")
|
|
77
|
+
const targetPath = path.join(binDir, binaryName)
|
|
78
|
+
|
|
79
|
+
// Ensure bin directory exists
|
|
80
|
+
if (!fs.existsSync(binDir)) {
|
|
81
|
+
fs.mkdirSync(binDir, { recursive: true })
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Remove existing binary/symlink if it exists
|
|
85
|
+
if (fs.existsSync(targetPath)) {
|
|
86
|
+
fs.unlinkSync(targetPath)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return { binDir, targetPath }
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function symlinkBinary(sourcePath, binaryName) {
|
|
93
|
+
const { targetPath } = prepareBinDirectory(binaryName)
|
|
94
|
+
|
|
95
|
+
fs.symlinkSync(sourcePath, targetPath)
|
|
96
|
+
console.log(`opencode binary symlinked: ${targetPath} -> ${sourcePath}`)
|
|
97
|
+
|
|
98
|
+
// Verify the file exists after operation
|
|
99
|
+
if (!fs.existsSync(targetPath)) {
|
|
100
|
+
throw new Error(`Failed to symlink binary to ${targetPath}`)
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
async function main() {
|
|
105
|
+
try {
|
|
106
|
+
if (os.platform() === "win32") {
|
|
107
|
+
// On Windows, the .exe is already included in the package and bin field points to it
|
|
108
|
+
// No postinstall setup needed
|
|
109
|
+
console.log("Windows detected: binary setup not needed (using packaged .exe)")
|
|
110
|
+
return
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// On non-Windows platforms, just verify the binary package exists
|
|
114
|
+
// Don't replace the wrapper script - it handles binary execution
|
|
115
|
+
const { binaryPath } = findBinary()
|
|
116
|
+
// El shim `bin/donkicode` busca PRIMERO `.donkicode` (y `.opencode` solo como
|
|
117
|
+
// legacy). Antes esto creaba `.opencode`, que funcionaba de rebote pero dejaba el
|
|
118
|
+
// cache con el nombre viejo; ahora es el que el shim espera.
|
|
119
|
+
const target = path.join(__dirname, "bin", ".donkicode")
|
|
120
|
+
if (fs.existsSync(target)) fs.unlinkSync(target)
|
|
121
|
+
try {
|
|
122
|
+
fs.linkSync(binaryPath, target)
|
|
123
|
+
} catch {
|
|
124
|
+
fs.copyFileSync(binaryPath, target)
|
|
125
|
+
}
|
|
126
|
+
fs.chmodSync(target, 0o755)
|
|
127
|
+
console.log(`donkicode: binario nativo enlazado (${binaryPath})`)
|
|
128
|
+
} catch (error) {
|
|
129
|
+
console.error("No pude preparar el binario de donkicode:", error.message)
|
|
130
|
+
process.exit(1)
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
try {
|
|
135
|
+
main()
|
|
136
|
+
} catch (error) {
|
|
137
|
+
console.error("Postinstall script error:", error.message)
|
|
138
|
+
process.exit(0)
|
|
139
|
+
}
|