ratacode 0.2.5
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/CREDITS.md +80 -0
- package/LICENSE +21 -0
- package/README.md +289 -0
- package/apreton/README.md +54 -0
- package/apreton/handshake.md +33 -0
- package/apreton/headless.md +58 -0
- package/apreton/mcp.md +221 -0
- package/apreton/navegador.md +58 -0
- package/bin/instalacion.js +148 -0
- package/bin/ratacode.js +1251 -0
- package/fabrica/settings.yaml +247 -0
- package/mcp/README.md +253 -0
- package/mcp/bin/ratacode-mcp.js +215 -0
- package/mcp/lib/actividad.js +49 -0
- package/mcp/lib/casa.js +126 -0
- package/mcp/lib/claves.js +148 -0
- package/mcp/lib/espacios.js +117 -0
- package/mcp/lib/http.js +184 -0
- package/mcp/lib/lectura.js +210 -0
- package/mcp/lib/modelos.js +235 -0
- package/mcp/lib/nucleo.js +332 -0
- package/mcp/lib/registro.js +21 -0
- package/mcp/lib/seguridad.js +283 -0
- package/mcp/lib/servidor.js +397 -0
- package/mcp/lib/tareas.js +406 -0
- package/mcp/package.json +22 -0
- package/mcp/tunel.mjs +209 -0
- package/modos/arquitecto/agent.cordis.yml +120 -0
- package/modos/arquitecto/preset.yml +3 -0
- package/modos/capataz/agent.cordis.yml +120 -0
- package/modos/capataz/preset.yml +3 -0
- package/modos/faro/agent.cordis.yml +120 -0
- package/modos/faro/preset.yml +3 -0
- package/modos/gepeto/agent.cordis.yml +191 -0
- package/modos/gepeto/preset.yml +3 -0
- package/modos/hero/agent.cordis.yml +198 -0
- package/modos/hero/preset.yml +3 -0
- package/modos/modo-rata/agent.cordis.yml +198 -0
- package/modos/modo-rata/preset.yml +3 -0
- package/modos/nex/agent.cordis.yml +213 -0
- package/modos/nex/preset.yml +3 -0
- package/modos/nex/skills/cordis-plugin-development/SKILL.md +420 -0
- package/modos/nex/skills/editing-cordis-compositions/SKILL.md +165 -0
- package/modos/pix/agent.cordis.yml +207 -0
- package/modos/pix/preset.yml +3 -0
- package/modos/tirita/agent.cordis.yml +130 -0
- package/modos/tirita/preset.yml +3 -0
- package/package.json +49 -0
- package/piel/activos/ratacode-emblema.svg +14 -0
- package/piel/activos/ratacode-es.js +1331 -0
- package/piel/activos/ratacode-identidad.css +50 -0
- package/piel/activos/ratacode-piel.css +217 -0
- package/piel/activos/ratacode-piel.js +487 -0
- package/piel/activos/ratacode-vida.js +424 -0
- package/piel/cordis.patch.yml +6 -0
- package/piel/lib/cliente.js +1020 -0
- package/piel/lib/index.js +1230 -0
- package/piel/package.json +36 -0
package/apreton/mcp.md
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
# MCP: cómo conectar tu app a RATACODE
|
|
2
|
+
|
|
3
|
+
RATACODE es una terminal de trabajo con IA con la cara de RATACODE, montada sobre un motor libre que no se toca. El MCP (Model Context Protocol) deja que cualquier app con MCP (Claude Code, Codex, OpenClaw, Rowboat, ChatGPT web con túnel) le mande trabajo a los modelos que ya tienes configurados en RATACODE —incluidos los locales, con Ollama o LM Studio—. Los modelos baratos hacen el trabajo; tú planificas, revisas y cierras.
|
|
4
|
+
|
|
5
|
+
**Es la vía recomendada** para cualquier app que hable MCP: cuesta menos que mirar la pantalla (dos llamadas y texto, sin capturas), tiene estado explícito (`run_task` con `esperar_segundos` + `get_task_status`) y **cada tarea sale en la barra lateral del panel**, con su conversación.
|
|
6
|
+
|
|
7
|
+
## Cómo darlo de alta (por app)
|
|
8
|
+
|
|
9
|
+
El servidor es `ratacode mcp` (subcomando del mismo binario). Si `ratacode` no está en el PATH,
|
|
10
|
+
usa `node <ruta>\bin\ratacode.js mcp`.
|
|
11
|
+
|
|
12
|
+
**Las claves NO van por aquí.** Están en un solo sitio —RATACODE › Ajustes › Models— y el MCP las
|
|
13
|
+
lee de ahí (preguntándole al motor). No hay que pasarle ninguna variable de entorno: su alta es
|
|
14
|
+
`ratacode mcp` y nada más. `<casa>` es tu casa (`%USERPROFILE%\.ratacode` si no le has dicho otra
|
|
15
|
+
cosa con `--home`).
|
|
16
|
+
|
|
17
|
+
### Claude Code — COMPROBADO
|
|
18
|
+
Documentación oficial: <https://code.claude.com/docs/en/mcp> (opción 3, servidor stdio local).
|
|
19
|
+
Todo lo que va detrás de `--` es el comando del servidor, sin tocarlo.
|
|
20
|
+
|
|
21
|
+
```sh
|
|
22
|
+
claude mcp add --transport stdio ratacode -- ratacode mcp
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Lo que NO hay que hacer es terminar el turno con la tarea en marcha: por stdio el servidor vive lo
|
|
26
|
+
que vive el cliente (mira «La regla del tropiezo 17», abajo).
|
|
27
|
+
|
|
28
|
+
### Codex — COMPROBADO
|
|
29
|
+
Documentación oficial: <https://learn.chatgpt.com/docs/extend/mcp> (Codex CLI → *Configure with the CLI*).
|
|
30
|
+
|
|
31
|
+
```toml
|
|
32
|
+
[mcp_servers.ratacode]
|
|
33
|
+
command = "ratacode"
|
|
34
|
+
args = ["mcp"]
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Ni `--env` ni `env_vars`: la clave no se le pasa al servidor, se lee de Ajustes › Models.
|
|
38
|
+
|
|
39
|
+
**Codex y las aprobaciones.** Codex no ejecuta herramientas MCP con la política de aprobación en
|
|
40
|
+
«never»: sale `MCP tool call requires approval, but approval policy is never`, y el encargo no llega
|
|
41
|
+
a RATACODE. Se arregla aprobando: `codex exec --approve-for-me "…"` (comprobado el 26-sep), o
|
|
42
|
+
aprobando la herramienta en la sesión interactiva. Sin una de las dos cosas, Codex se queda mirando.
|
|
43
|
+
|
|
44
|
+
### OpenClaw — COMPROBADO
|
|
45
|
+
Documentación oficial: <https://docs.openclaw.ai/cli/mcp/registry>. Aquí no hay `--`: cada cosa va
|
|
46
|
+
con su bandera (`--command`, un `--arg` por argumento, `--cwd`).
|
|
47
|
+
|
|
48
|
+
```sh
|
|
49
|
+
openclaw mcp add ratacode --command ratacode --arg mcp
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Rowboat — SOSPECHA
|
|
53
|
+
Lo único que dice la documentación oficial (<https://github.com/rowboatlabs/rowboat>, *Extend Rowboat
|
|
54
|
+
with tools (MCP)*) es: **Settings → MCP Servers**, añadir la entrada al objeto `mcpServers` y *Save*.
|
|
55
|
+
El ejemplo que publican es de un servidor HTTP (`url`), así que **no está comprobado que su editor
|
|
56
|
+
acepte un servidor stdio** con `command`/`args`. Si lo acepta, la entrada sería:
|
|
57
|
+
|
|
58
|
+
```json
|
|
59
|
+
{
|
|
60
|
+
"mcpServers": {
|
|
61
|
+
"ratacode": {
|
|
62
|
+
"command": "ratacode",
|
|
63
|
+
"args": ["mcp"]
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**SOSPECHA:** no he encontrado un `rowboat mcp add` por línea de órdenes ni un fichero de
|
|
70
|
+
configuración documentado; compruébalo en tu versión de Rowboat.
|
|
71
|
+
|
|
72
|
+
### Genérico (cualquier cliente MCP por stdio)
|
|
73
|
+
Añade esto a la configuración MCP de tu app:
|
|
74
|
+
|
|
75
|
+
```json
|
|
76
|
+
{
|
|
77
|
+
"mcpServers": {
|
|
78
|
+
"ratacode": {
|
|
79
|
+
"command": "ratacode",
|
|
80
|
+
"args": [
|
|
81
|
+
"mcp",
|
|
82
|
+
"--home",
|
|
83
|
+
"C:\\Users\\tu-usuario\\.ratacode"
|
|
84
|
+
]
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**Las claves están en la casa, no en tu entorno.** El servidor no mira las variables del cliente ni
|
|
91
|
+
abre ficheros de claves: le pregunta al motor si la credencial de esa ruta está puesta. Si no lo
|
|
92
|
+
está, se para y dice: `Falta la clave de B.AI. Pégala en RATACODE › Ajustes › Models.`
|
|
93
|
+
|
|
94
|
+
## Lo que una tarea puede LEER (y por qué el HTTP pide permiso)
|
|
95
|
+
|
|
96
|
+
Escríbelo en tu cabeza antes de abrir el túnel: **una tarea MCP lee y escribe solo dentro de las
|
|
97
|
+
carpetas que tú autorizas** (`mcp.workspaces`). No es un descuido del motor: DSH no tiene ningún
|
|
98
|
+
modo que acote la lectura —`read-only`, `workspace-write` y `danger-full-access` son ejes de
|
|
99
|
+
ESCRITURA, y su propio código lo dice: «Reads pass through untouched: every mode permits
|
|
100
|
+
reading»—, y su encierre de Windows restringe el token a la escritura («`WRITE_RESTRICTED`
|
|
101
|
+
intersects only write accesses»). Por eso la lectura la encierra RATACODE, con el gancho
|
|
102
|
+
`tools/pre-execute` del motor: cada herramienta que lleve una ruta fuera de tus carpetas se para
|
|
103
|
+
y el agente ve una línea: «Fuera de la carpeta autorizada: `<ruta>`».
|
|
104
|
+
|
|
105
|
+
Y no hay puertas por detrás: en una tarea del MCP no hay terminal, ni trabajos en segundo plano,
|
|
106
|
+
ni red, ni subagentes, ni guiones.
|
|
107
|
+
|
|
108
|
+
Consecuencias, claras:
|
|
109
|
+
|
|
110
|
+
- Lo que la tarea lea **viaja al proveedor del modelo** que hayas elegido, así que la carpeta
|
|
111
|
+
autorizada es, de verdad, todo lo que ese chat puede ver. No pongas ahí claves de otros sitios.
|
|
112
|
+
- `ratacode mcp --http` y `node mcp/tunel.mjs` **ya no piden nada**: antes exigían
|
|
113
|
+
`--acepto-lectura-total` porque la lectura no estaba encerrada; desde R25 sí lo está, y esa
|
|
114
|
+
bandera se acepta como no-op (para no romper los comandos viejos).
|
|
115
|
+
- Por stdio, igual: la superficie la controlas tú (es tu propio cliente local el que arranca el
|
|
116
|
+
servidor).
|
|
117
|
+
- Si además quieres aislarlo del sistema operativo (un usuario o una máquina virtual solo para
|
|
118
|
+
esto), mejor: son dos cierres, no uno.
|
|
119
|
+
|
|
120
|
+
## ChatGPT web (y cualquier app que hable MCP por HTTP): el túnel
|
|
121
|
+
|
|
122
|
+
ChatGPT web no arranca procesos: necesita una **URL** de MCP por HTTP. Por eso existe
|
|
123
|
+
`mcp/tunel.mjs`: expone el MCP de tu PC a Internet con Cloudflare mientras corre.
|
|
124
|
+
|
|
125
|
+
```sh
|
|
126
|
+
# 1) el MCP por HTTP (local), con espacios declarados en `mcp.workspaces`
|
|
127
|
+
ratacode mcp --http
|
|
128
|
+
|
|
129
|
+
# 2) el túnel, en otra ventana
|
|
130
|
+
node mcp/tunel.mjs --home <casa>
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
`tunel.mjs` te imprime la **URL pública completa** (dominio + `/mcp/<clave>`): esa es la que se
|
|
134
|
+
pega en ChatGPT (modo desarrollador → conector MCP) o en la app que sea. Al abrirlo **estrena
|
|
135
|
+
clave** (el servidor que ya corre la adopta sin reiniciar; con `--misma-clave` reutiliza la
|
|
136
|
+
anterior). La clave vive en `<casa>\mcp\http-url.txt` y `<casa>\mcp\http-secret.txt`, con permisos
|
|
137
|
+
de sólo-dueño; no se imprime en los registros. Con `Ctrl+C` se cierra el túnel y el puerto deja de
|
|
138
|
+
estar expuesto.
|
|
139
|
+
|
|
140
|
+
Si tienes dado de alta el túnel nombrado `mcp.mod-rat.com` en tu Cloudflare, lo usa con ese
|
|
141
|
+
hostname fijo (por fichero de configuración, nunca pasando la URL por argumentos); si no, abre un
|
|
142
|
+
quick tunnel con URL efímera.
|
|
143
|
+
|
|
144
|
+
**Lo que implica abrirlo:** el túnel expone el MCP a Internet, así que quien tenga esa URL puede
|
|
145
|
+
mandar tareas. Lo que **no** puede es salirse de tus carpetas: la tarea lee y escribe solo dentro
|
|
146
|
+
de `mcp.workspaces` y no tiene terminal ni red (mira el apartado de arriba). No lo dejes abierto
|
|
147
|
+
más de lo que dure el trabajo, y cámbiale la clave (basta con volver a lanzar `tunel.mjs`) cuando
|
|
148
|
+
cierres.
|
|
149
|
+
|
|
150
|
+
**Rowboat.** Su editor documenta servidores por `url`, no por `command`; con el túnel o con el MCP
|
|
151
|
+
por HTTP puedes darle la URL con la clave y no depender de que acepte un servidor stdio (que es lo
|
|
152
|
+
que sigue sin estar comprobado, ver arriba).
|
|
153
|
+
|
|
154
|
+
## Cómo usarlo
|
|
155
|
+
|
|
156
|
+
1. **`list_models`** — llama primero para ver qué modelos hay, con proveedor, id, contexto, capacidades y estado.
|
|
157
|
+
2. **`run_task`** — lanza el encargo. Sin `esperar_segundos` devuelve `task_id` al momento y el trabajo sigue en segundo plano. **Con `esperar_segundos` (1-600), la llamada ESPERA y devuelve el resultado completo en esa misma respuesta**, sin llamar a nada más.
|
|
158
|
+
3. **`get_task_status`** — consulta el estado: `queued`, `running`, `completed`, `failed`, `cancelled`.
|
|
159
|
+
4. **`get_task_result`** — recoge la respuesta, modelo, proveedor, tokens, coste (si está declarado), duración y errores.
|
|
160
|
+
|
|
161
|
+
**Si el usuario eligió un modelo, no lo cambies.** Si no eligió, se usa el modelo por defecto de la casa y se te dice cuál.
|
|
162
|
+
|
|
163
|
+
### La regla del tropiezo 17: no dejes la tarea a medias
|
|
164
|
+
|
|
165
|
+
Por stdio, **las tareas viven lo que vive el cliente**: si el cliente se cierra, el servidor se va y la
|
|
166
|
+
tarea muere donde esté (así quedó un `hola.txt` con un «hola» y nada más: el cliente había terminado su
|
|
167
|
+
turno con «despiertas en 60 s», y a los 60 s ya no había nadie). Con un cliente de una sola vuelta
|
|
168
|
+
(`claude -p`, `codex exec`, una llamada suelta), haz UNA de estas dos cosas:
|
|
169
|
+
|
|
170
|
+
- lanza `run_task` **con `esperar_segundos`** (p. ej. 300) y recoge el resultado de esa misma respuesta; o
|
|
171
|
+
- **no termines tu turno hasta que `get_task_status` diga `completed` o `failed`**.
|
|
172
|
+
|
|
173
|
+
Con `esperar_segundos`, si la tarea no acaba dentro del plazo, la respuesta lo dice (`espera.agotada:
|
|
174
|
+
true`) y queda el `task_id` para seguir preguntando. El máximo son 600 s (10 minutos); si tu cliente
|
|
175
|
+
corta las llamadas largas antes, usa un valor por debajo de ese corte.
|
|
176
|
+
|
|
177
|
+
## Cómo escribir un encargo
|
|
178
|
+
Usa esta plantilla (funcionó a la primera):
|
|
179
|
+
|
|
180
|
+
```
|
|
181
|
+
Soy [tu nombre], [tu rol]. Lee [fichero o carpeta].
|
|
182
|
+
LÍMITES: escribe SOLO en [carpeta]. [Lo que NO toques]. No leas ficheros de credenciales. Sin git, sin publicar.
|
|
183
|
+
TAREA:
|
|
184
|
+
1) [Primer paso]
|
|
185
|
+
2) [Segundo paso]
|
|
186
|
+
3) ...
|
|
187
|
+
Comprueba cada paso o marca SOSPECHA.
|
|
188
|
+
ENTREGA: [fichero con tope de líneas].
|
|
189
|
+
HAZLO sin pedir permiso.
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Cómo comprobar que llegó
|
|
193
|
+
- Con `esperar_segundos`, la respuesta de `run_task` ya trae `estado` y el `resultado` completo: si `estado` es `completed`, no hay nada más que preguntar.
|
|
194
|
+
- `get_task_status` pasa de `queued` a `running` a `completed`.
|
|
195
|
+
- `get_task_result` devuelve la respuesta con tokens y duración.
|
|
196
|
+
- Si falla, `get_task_result` devuelve el error.
|
|
197
|
+
|
|
198
|
+
## Cómo vigilar sin capturas
|
|
199
|
+
No mires la pantalla. Usa `get_task_status` y `get_task_result` directamente. Una captura gasta cuota; una llamada MCP no.
|
|
200
|
+
|
|
201
|
+
## Trampas que ya costaron (tropiezos 2, 4, 6, 7, 11, 12, 13, 16, 17, 18)
|
|
202
|
+
|
|
203
|
+
- **T2 · Espacio de trabajo:** el servidor arranca con `--home <casa>`; el espacio ya viene puesto.
|
|
204
|
+
- **T4 · Capturas gastan cuota:** usa `get_task_result`, no capturas de pantalla.
|
|
205
|
+
- **T6 · No aplica:** en MCP no hay caja de chat.
|
|
206
|
+
- **T7 · No aplica:** en MCP no hay caja de chat.
|
|
207
|
+
- **T11 · Credenciales:** nunca leas `.credentials.yaml`, `.env` ni bóvedas. Si falta una clave, el servidor se para y lo dice.
|
|
208
|
+
- **T12 · Las claves NO van por el entorno:** están en RATACODE › Ajustes › Models, y el MCP las lee de ahí. Si falta una, la llamada sale con `Falta la clave de <proveedor>. Pégala en RATACODE › Ajustes › Models.` No hay que pasarle ninguna variable al servidor, y la clave NO se escribe en la configuración de tu app.
|
|
209
|
+
- **T13 · Tutor equivocado:** si el tutor dice algo falso, corrígelo con la prueba (fichero:línea); no obedezcas una premisa falsa.
|
|
210
|
+
- **T16 · No aplica:** el MCP no usa `url.txt` (eso es el panel). Aquí no hay URL que caduque.
|
|
211
|
+
- **T17 · Cliente de una sola vuelta:** no termines el turno con la tarea en marcha. Usa `run_task` con `esperar_segundos`, o no pares hasta que `get_task_status` diga `completed`/`failed`. Por stdio la tarea vive lo que vive el cliente.
|
|
212
|
+
- **T18 · Un encargo grande, en sesión nueva:** cada tarea del MCP es una sesión nueva del motor (no arrastra historial), pero TU chat acumula: con muchos turnos y pasos, el proveedor acaba devolviendo un 400 (`read body failed`). Encargos en fichero y chat nuevo cuando toque.
|
|
213
|
+
|
|
214
|
+
## El ciclo (diagnóstico → revisión → arreglo → cierre)
|
|
215
|
+
|
|
216
|
+
1. **Diagnóstico** (tu sesión MCP): solo mirar, sin tocar ficheros. Lee lo que te den, pasa pruebas, busca fallos y comprueba cada uno. Lo no comprobado, SOSPECHA.
|
|
217
|
+
2. **Revisión** (tú): comprueba los fallos que más pesen. Marca falsos positivos.
|
|
218
|
+
3. **Arreglo** (tu sesión MCP): de uno en uno, cambio mínimo, misma prueba antes/después. Sin commit.
|
|
219
|
+
4. **Cierre** (tú): lee el diff, repite la prueba, abre la app y lo ve. Commit solo si toca.
|
|
220
|
+
|
|
221
|
+
**No arranques servidores. No publiques. Si falta algo, dilo.**
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Navegador: cómo manejar RATACODE desde tu chat
|
|
2
|
+
|
|
3
|
+
RATACODE es una terminal de trabajo con IA con la cara de RATACODE, montada sobre un motor libre que no se toca. Se abre en el navegador (puerto 3777) y recibe encargos de cualquier agente. Los modelos baratos —o los tuyos, en local— hacen el trabajo; tú planificas, revisas y cierras.
|
|
4
|
+
|
|
5
|
+
## Dónde está la URL
|
|
6
|
+
Lee `<casa>\url.txt` y ábrela en tu navegador. La casa es la carpeta desde la que se arrancó `ratacode` (o `%USERPROFILE%\.ratacode` por defecto).
|
|
7
|
+
|
|
8
|
+
`ratacode` borra ese fichero al empezar y sólo lo escribe cuando el puerto ya escucha de verdad, así
|
|
9
|
+
que la URL que leas es la de ESTA vez (no la de la vez anterior). Si no carga, o el fichero todavía no
|
|
10
|
+
está: espera 15 s, vuelve a leerlo y, si el puerto no escucha, arranca `ratacode` otra vez. El motivo
|
|
11
|
+
de cada cierre del motor queda en `<casa>\ratacode.log` (código de salida y señal).
|
|
12
|
+
|
|
13
|
+
## Cómo escribir un encargo
|
|
14
|
+
Usa esta plantilla (funcionó a la primera):
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
Soy [tu nombre], [tu rol]. Lee [fichero o carpeta].
|
|
18
|
+
LÍMITES: escribe SOLO en [carpeta]. [Lo que NO toques]. No leas ficheros de credenciales. Sin git, sin publicar.
|
|
19
|
+
TAREA:
|
|
20
|
+
1) [Primer paso]
|
|
21
|
+
2) [Segundo paso]
|
|
22
|
+
3) ...
|
|
23
|
+
Comprueba cada paso o marca SOSPECHA.
|
|
24
|
+
ENTREGA: [fichero con tope de líneas].
|
|
25
|
+
HAZLO sin pedir permiso.
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
**Antes de escribir**, comprueba que la caja del chat está visible y es la del título correcto (el usuario puede tener ajustes abiertos, la caja puede estar fuera de pantalla).
|
|
29
|
+
**Después de enviar**, comprueba que la sesión avanza (fichero de sesión o respuesta). Si no avanza, mira por qué antes de repetir.
|
|
30
|
+
|
|
31
|
+
## Cómo comprobar que llegó
|
|
32
|
+
- El fichero de sesión crece (cada turno añade líneas).
|
|
33
|
+
- El encargo aparece en la lista de tareas de la web.
|
|
34
|
+
- Si el modelo contesta, la respuesta sale en el panel.
|
|
35
|
+
|
|
36
|
+
## Cómo vigilar sin capturas
|
|
37
|
+
No mires la pantalla. Lee los ficheros de sesión directamente: estado, herramientas usadas, permisos pedidos, último mensaje. Una captura cada vez gasta cuota; un fichero no.
|
|
38
|
+
|
|
39
|
+
## Trampas que ya costaron (tropiezos 2, 4, 6, 7, 11, 13, 16, 17, 18)
|
|
40
|
+
|
|
41
|
+
- **T2 · Espacio de trabajo:** el diálogo nativo de Windows no lo ves. Arranca `ratacode` desde la carpeta de trabajo; el espacio ya viene puesto.
|
|
42
|
+
- **T4 · Capturas gastan cuota:** pide la entrega en un fichero y vigila ese fichero, no la pantalla.
|
|
43
|
+
- **T6 · La caja no recibe:** el usuario puede tener los Ajustes abiertos o la caja fuera de pantalla. Antes de escribir, comprueba que la caja es la correcta y está visible.
|
|
44
|
+
- **T7 · Caja fuera de pantalla:** haz clic en la caja, escribe con el teclado y pulsa Enter. Si no llega, el div editable no cuenta como texto escrito; usa el teclado, no el formulario.
|
|
45
|
+
- **T11 · Credenciales:** nunca leas `.credentials.yaml`, `.env` ni bóvedas. Si falta una clave, para y dilo.
|
|
46
|
+
- **T13 · Tutor equivocado:** si el tutor dice algo falso, corrígelo con la prueba (fichero:línea); no obedezcas una premisa falsa.
|
|
47
|
+
- **T16 · La URL a medias y el cierre sin rastro:** `url.txt` se borra al empezar y se escribe SÓLO cuando el puerto contesta, así que si lo lees y no carga, espera 15 s y vuelve a leerlo; si el puerto no escucha, arranca `ratacode` otra vez. Si el panel se cierra solo, el motivo está en `<casa>\ratacode.log` (código de salida y señal): no lo cierres tú antes de leerlo.
|
|
48
|
+
- **T17 · El panel es el cliente:** aquí la tarea vive lo que viva el panel. Si cierras la ventana con una tarea en marcha, se queda sin quien la recoja. Pide la entrega en un fichero y no cierres hasta que esté.
|
|
49
|
+
- **T18 · Un encargo grande, en chat nuevo:** un chat con 6 turnos y 519 pasos acumulados acaba con un 400 del proveedor (`read body failed`). Los encargos van en ficheros y no necesitan historial: abre chat nuevo para cada encargo grande.
|
|
50
|
+
|
|
51
|
+
## El ciclo (diagnóstico → revisión → arreglo → cierre)
|
|
52
|
+
|
|
53
|
+
1. **Diagnóstico** (tu chat): solo mirar, sin tocar ficheros. Lee lo que te den, pasa pruebas, busca fallos y comprueba cada uno. Lo no comprobado, SOSPECHA.
|
|
54
|
+
2. **Revisión** (tú): comprueba los fallos que más pesen. Marca falsos positivos.
|
|
55
|
+
3. **Arreglo** (tu chat): de uno en uno, cambio mínimo, misma prueba antes/después. Sin commit.
|
|
56
|
+
4. **Cierre** (tú): lee el diff, repite la prueba, abre la app y lo ve. Commit solo si toca.
|
|
57
|
+
|
|
58
|
+
**No arranques servidores. No publiques. Si falta algo, dilo.**
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* instalación de RATACODE · el paso que npm 11 deja «pendiente».
|
|
4
|
+
*
|
|
5
|
+
* ── QUÉ PASA (medido el 24-sep-2026, npm 11.16.0 / Node 24.18.0) ────────────
|
|
6
|
+
* npm 11 estrenó la política `allow-scripts` (RFC npm/rfcs#868). Al instalar,
|
|
7
|
+
* recorre el árbol y lista los paquetes con guiones de instalación que NO están
|
|
8
|
+
* cubiertos por `allowScripts`:
|
|
9
|
+
*
|
|
10
|
+
* npm warn allow-scripts 5 packages have install scripts not yet covered by allowScripts:
|
|
11
|
+
* npm warn allow-scripts @deepseek-ai/dsh-subprocess-local@0.1.5-rc.3 (postinstall: …)
|
|
12
|
+
* npm warn allow-scripts koffi@3.3.1 (install: node ./cnoke.cjs …)
|
|
13
|
+
* npm warn allow-scripts node-pty@1.2.0-beta.15 (install: …; postinstall: …)
|
|
14
|
+
*
|
|
15
|
+
* Con la configuración por defecto (`strict-allow-scripts=false`) esos guiones
|
|
16
|
+
* SÍ se ejecutan: el aviso es una lista de «pendientes de aprobar», no un
|
|
17
|
+
* salto. Medido en una instalación global recién hecha y sin `--foreground-scripts`:
|
|
18
|
+
* `node-pty` arranca un PTY y `koffi` llama a kernel32 (trabajo\S1\comprobar-nativos.mjs).
|
|
19
|
+
*
|
|
20
|
+
* ── POR QUÉ HACE FALTA ESTE FICHERO ─────────────────────────────────────────
|
|
21
|
+
* La capa `package.json#allowScripts` se ignora en las instalaciones globales
|
|
22
|
+
* (`npm.global === true` ⇒ npm no mira el package.json del «proyecto»; medido:
|
|
23
|
+
* un paquete con `allowScripts` en su tarball sigue saliendo en el aviso). En
|
|
24
|
+
* cambio, los guiones del PAQUETE RAÍZ sí corren siempre en `npm i -g`.
|
|
25
|
+
*
|
|
26
|
+
* Así que aquí, en el postinstall de RATACODE, se comprueba cada uno de los
|
|
27
|
+
* tres y se ejecuta SU guion de instalación si le falta el fruto. Es
|
|
28
|
+
* idempotente (si ya está, no hace nada), best-effort (nunca tumba la
|
|
29
|
+
* instalación) y no imprime ningún valor de credencial.
|
|
30
|
+
*
|
|
31
|
+
* ── LO QUE SE COMPRUEBA, PAQUETE A PAQUETE ──────────────────────────────────
|
|
32
|
+
* · node-pty → `build/Release/conpty/conpty.dll` (lo copia su
|
|
33
|
+
* postinstall desde `third_party/conpty`). Los
|
|
34
|
+
* `.node` viajan en `prebuilds/<plataforma>-<arch>/`.
|
|
35
|
+
* · koffi → `build/koffi/<toolchain>/koffi.node`, o el
|
|
36
|
+
* paquete de plataforma `@koromix/koffi-*` (que es
|
|
37
|
+
* lo normal: por eso su guion no construye nada).
|
|
38
|
+
* · dsh-subprocess-local → `chmod 0755` sobre el `spawn-helper` de node-pty
|
|
39
|
+
* (sólo POSIX: en Windows no existe y es un no-op).
|
|
40
|
+
*/
|
|
41
|
+
import { spawnSync } from 'node:child_process';
|
|
42
|
+
import { createRequire } from 'node:module';
|
|
43
|
+
import { existsSync, readFileSync, readdirSync } from 'node:fs';
|
|
44
|
+
import { dirname, join } from 'node:path';
|
|
45
|
+
|
|
46
|
+
const require = createRequire(import.meta.url);
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Desde dónde se busca cada paquete. `koffi` y `node-pty` cuelgan de la raíz,
|
|
50
|
+
* pero `@deepseek-ai/dsh-subprocess-local` cuelga DENTRO de `@deepseek-ai/dsh`,
|
|
51
|
+
* así que hay que resolver también desde ahí o no se encuentra.
|
|
52
|
+
*/
|
|
53
|
+
const BASES = [require];
|
|
54
|
+
try {
|
|
55
|
+
BASES.push(createRequire(require.resolve('@deepseek-ai/dsh/package.json')));
|
|
56
|
+
} catch { /* sin motor instalado: las otras bases bastan */ }
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* La carpeta de un paquete del árbol, resolviendo su entrada y subiendo hasta
|
|
60
|
+
* el `package.json` que lleva su nombre (algunos no exportan `./package.json`,
|
|
61
|
+
* como `koffi`). Devuelve null si no está.
|
|
62
|
+
*/
|
|
63
|
+
function carpetaDe(nombre) {
|
|
64
|
+
for (const base of BASES) {
|
|
65
|
+
let entrada = null;
|
|
66
|
+
try {
|
|
67
|
+
entrada = base.resolve(nombre);
|
|
68
|
+
} catch {
|
|
69
|
+
try { entrada = base.resolve(nombre + '/package.json'); } catch { continue; }
|
|
70
|
+
}
|
|
71
|
+
let dir = dirname(entrada);
|
|
72
|
+
for (let saltos = 0; saltos < 6; saltos += 1) {
|
|
73
|
+
const manifiesto = join(dir, 'package.json');
|
|
74
|
+
if (existsSync(manifiesto)) {
|
|
75
|
+
try {
|
|
76
|
+
if (JSON.parse(readFileSync(manifiesto, 'utf8')).name === nombre) return dir;
|
|
77
|
+
} catch { /* package.json ilegible: se sigue subiendo */ }
|
|
78
|
+
}
|
|
79
|
+
const padre = dirname(dir);
|
|
80
|
+
if (padre === dir) break;
|
|
81
|
+
dir = padre;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** ¿Está ya el fruto del guion de instalación de este paquete? */
|
|
88
|
+
function yaEsta(nombre, carpeta) {
|
|
89
|
+
if (carpeta === null) return false;
|
|
90
|
+
if (nombre === 'node-pty') {
|
|
91
|
+
return existsSync(join(carpeta, 'build', 'Release', 'conpty', 'conpty.dll'));
|
|
92
|
+
}
|
|
93
|
+
if (nombre === 'koffi') {
|
|
94
|
+
if (existsSync(join(carpeta, 'build'))) {
|
|
95
|
+
for (const toolchain of readdirSync(join(carpeta, 'build'))) {
|
|
96
|
+
if (existsSync(join(carpeta, 'build', toolchain, 'koffi.node'))) return true;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// El paquete de plataforma es la vía normal y suficiente.
|
|
100
|
+
for (const plataforma of ['win32', 'linux', 'darwin', 'freebsd', 'openbsd', 'android']) {
|
|
101
|
+
if (carpetaDe('@koromix/koffi-' + plataforma + '-' + process.arch)) return true;
|
|
102
|
+
}
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
// dsh-subprocess-local sólo repara permisos de un fichero POSIX.
|
|
106
|
+
return process.platform === 'win32';
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const PENDIENTES = [
|
|
110
|
+
{ nombre: 'node-pty', guion: 'install' },
|
|
111
|
+
{ nombre: 'koffi', guion: 'install' },
|
|
112
|
+
{ nombre: '@deepseek-ai/dsh-subprocess-local', guion: 'postinstall' },
|
|
113
|
+
];
|
|
114
|
+
|
|
115
|
+
const hechos = [];
|
|
116
|
+
const fallos = [];
|
|
117
|
+
|
|
118
|
+
for (const { nombre, guion } of PENDIENTES) {
|
|
119
|
+
const carpeta = carpetaDe(nombre);
|
|
120
|
+
if (carpeta === null) {
|
|
121
|
+
fallos.push(nombre + ': no está en el árbol (¿instalación incompleta?)');
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
if (yaEsta(nombre, carpeta)) {
|
|
125
|
+
hechos.push(nombre + ': ya estaba');
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
// `npm run <guion>` dentro de la carpeta del paquete: es exactamente lo que
|
|
129
|
+
// npm habría ejecutado, con su mismo entorno (npm_config_* incluidos).
|
|
130
|
+
const r = spawnSync('npm', ['run', guion], {
|
|
131
|
+
cwd: carpeta,
|
|
132
|
+
stdio: 'inherit',
|
|
133
|
+
shell: true,
|
|
134
|
+
windowsHide: true,
|
|
135
|
+
});
|
|
136
|
+
if (r.status === 0 && yaEsta(nombre, carpeta)) hechos.push(nombre + ': ejecutado ahora');
|
|
137
|
+
else if (r.status === 0) hechos.push(nombre + ': ejecutado (su guion no deja fruto en esta plataforma)');
|
|
138
|
+
else fallos.push(nombre + ': su guion «' + guion + '» salió con ' + r.status);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
process.stdout.write('RATACODE · instalación: ' + hechos.join(' · ') + '\n');
|
|
142
|
+
if (fallos.length > 0) {
|
|
143
|
+
process.stdout.write('RATACODE · instalación: AVISO, no pude completar: ' + fallos.join(' · ') + '\n');
|
|
144
|
+
process.stdout.write('RATACODE · instalación: RATACODE arranca igual; si la terminal falla, '
|
|
145
|
+
+ 'ejecuta a mano «npm run install» en la carpeta de cada paquete.\n');
|
|
146
|
+
}
|
|
147
|
+
// Nunca se tumba la instalación por esto: el panel web no necesita estos guiones.
|
|
148
|
+
process.exitCode = 0;
|