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 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
- # donkicode
1
+ # DonkiCode
2
2
 
3
- Nombre reservado para **DonkiCode**.
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
- Este paquete es un marcador: el cliente todavía no está publicado. Cuando lo
6
- esté, este mismo nombre servirá para instalarlo.
5
+ ## Instalar
7
6
 
8
- Novedades en https://donkicode.com
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.0.1",
4
- "description": "DonkiCode — nombre reservado. El cliente aún no está publicado.",
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
- "private": false,
7
- "keywords": ["donkicode"],
8
- "author": "Nico Miragaya",
9
- "homepage": "https://donkicode.com",
10
- "files": ["README.md"]
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
+ }
@@ -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
+ }