xonecode 0.8.23 → 0.8.25

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.
@@ -73,6 +73,35 @@ export function esRutaDeArtefacto(ruta) {
73
73
  return false;
74
74
  return segmentos.every((s) => SEGMENTO.test(s) && s !== "." && s !== "..");
75
75
  }
76
+ /**
77
+ * Lo que aparece en la carpeta de artefactos y NO es un artefacto que enseñar.
78
+ *
79
+ * Existe porque la foto que toma la shell (`agent/grafo/proyecto.ts#anunciarArtefactosDeLaShell`)
80
+ * mira la carpeta ENTERA, subcarpetas incluidas: un `unzip` deja un árbol, no un fichero. Y
81
+ * un `.zip` hecho desde el Finder no trae solo lo que se empaquetó — trae `__MACOSX/` con
82
+ * una sombra `._<fichero>` por cada uno, del mismo nombre y la misma extensión que el bueno.
83
+ * Sin esto, descomprimir una maqueta de tres ficheros pintaba seis tarjetas, tres de ellas
84
+ * con `mime: image/png` y doscientos bytes dentro: una imagen rota con nombre de imagen.
85
+ *
86
+ * **No es `BASURA_DEL_SO` (`agent/sesiones/gitSync.ts`) y no puede serlo**, y no solo porque
87
+ * `core/` no importe de `agent/`: aquella contesta «qué no se commitea NUNCA» y vive del
88
+ * lado de git, con su lista cerrada apuntando a `info/exclude`. Esta contesta «qué no se le
89
+ * ENSEÑA a una persona como salida del agente», que es otra pregunta y otro conjunto — el
90
+ * `__MACOSX/` de un zip no tiene nada que hacer en el `info/exclude` de la app del cliente.
91
+ * Comparten tres nombres por coincidencia, no por ser la misma regla.
92
+ *
93
+ * Se mira SEGMENTO a segmento: un `__MACOSX` a media ruta se lleva lo que cuelgue de él, y
94
+ * un `notas-sobre-__MACOSX.md` no es basura por contener el nombre. La sombra se reconoce
95
+ * por el prefijo `._` y no por «empieza por punto», que dejaría fuera un `.perfil.json` que
96
+ * el agente sí escribió a propósito.
97
+ */
98
+ const BASURA = new Set(["__MACOSX", ".DS_Store", "Thumbs.db", "desktop.ini"]);
99
+ export function esBasuraDeArtefacto(relativa) {
100
+ return relativa
101
+ .split("/")
102
+ .filter((s) => s.length > 0)
103
+ .some((s) => BASURA.has(s) || s.startsWith("._"));
104
+ }
76
105
  /**
77
106
  * ¿Es esta ruta un artefacto escrito en el SITIO EQUIVOCADO? Y si lo es, dónde iba.
78
107
  *
@@ -1 +1 @@
1
- {"version":3,"file":"artefactos.js","sourceRoot":"","sources":["../../src/core/artefactos.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"artefactos.js","sourceRoot":"","sources":["../../src/core/artefactos.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Dónde deja una shell lo que saca del CONTEXTO, y por qué eso no es un artefacto.
3
+ *
4
+ * El script `xone-hotswap` (skill de serie) no imprime una respuesta del aparato que pase de
5
+ * un par de miles de caracteres: la escribe a fichero y en la salida del comando deja una
6
+ * línea que dice dónde está. El motivo es bueno —el árbol de controles de una pantalla llena
7
+ * son varios miles de caracteres, y volcarlo en la salida es meterlo en el contexto del
8
+ * agente para siempre—. Lo que estaba mal era el DESTINO: escribía en la carpeta de
9
+ * artefactos, que es la que se ANUNCIA.
10
+ *
11
+ * **Y se anunciaban diez volcados de los que seis no volvía a abrir nadie.** Medido sobre una
12
+ * sesión real de `device-controller` (MyAllXOne, 22-09-2026): de 10 `respuesta-status-*.json`
13
+ * de 8 KB, 4 se volvieron a tocar y 6 no se abrieron jamás; los que sí, 9 veces por shell y 4
14
+ * por `read_file`, y cuando se abrían se recortaban —`print(json.dumps(d)[:1500])` de un
15
+ * fichero de 8 KB—. Ningún otro lector los mira: ni el juez del turno, ni el verificador, ni
16
+ * la persona. El contraste está medido al lado: las CAPTURAS sí tienen un segundo lector
17
+ * —`capturasDelTurno` se lleva la última al crítico de pantalla—, y por eso las capturas se
18
+ * quedan donde estaban.
19
+ *
20
+ * Y había un segundo efecto, que es el que esta carpeta arregla de paso: **el agente no sabía
21
+ * cómo volver a abrirlos**. El script devolvía un nombre pelado (`<guardado como
22
+ * respuesta-status-….json>`) y lo único que el entorno le daba era `XONECODE_ARTEFACTOS`, que
23
+ * es la carpeta del DISCO. En la traza se le ve intentando leer el mismo fichero por tres
24
+ * rutas —la absoluta de la máquina y `/.xonecode/sesiones/…`, denegada— antes de rendirse y
25
+ * usar `python3`. De regalo, esa ruta absoluta viajó por el cable dentro de la línea de la
26
+ * tool, que es justo lo que `sinRutas` existe para impedir.
27
+ *
28
+ * Así que esto es la MISMA pieza que `/large_tool_results/` (`core/descargas.ts`) y por la
29
+ * misma razón declarada allí: «un artefacto es una salida para una persona y por eso se
30
+ * anuncia; esto es el andamio del agente». Cambia quién descarga —allí la librería, aquí un
31
+ * script nuestro— y no cambia nada más.
32
+ *
33
+ * Este módulo es `core/`: el nombre y dónde va la carpeta. Quién la monta es de `agent/`
34
+ * (`agent/grafo/proyecto.ts#backendConHotswap`), y quién escribe ahí es el script.
35
+ */
36
+ import { dirname, join } from "node:path";
37
+ /**
38
+ * El prefijo virtual, con barra final: `CompositeBackend` la exige para no reconstruir
39
+ * `//nombre` fuera de la raíz montada — la misma trampa medida con `/skills/`.
40
+ *
41
+ * **El nombre ata el harness a UNA skill, y eso se declara en vez de disimularse.** Lo
42
+ * honesto sería un nombre que diga la función y no el protocolo (`/volcados/`), porque
43
+ * mañana otra skill querrá lo mismo; se deja `hotswap` porque hoy hay exactamente un
44
+ * escritor, y un nombre genérico con un solo usuario es una abstracción que nadie ha medido.
45
+ * El día que haya un segundo, el sitio de la decisión es este.
46
+ */
47
+ export const RUTA_HOTSWAP = "/hotswap/";
48
+ /** El nombre llano de la carpeta en disco: `/hotswap/` → `hotswap`. */
49
+ const CARPETA = RUTA_HOTSWAP.replace(/^\/+/, "").replace(/\/+$/, "");
50
+ /**
51
+ * Dónde cae en DISCO: al LADO de la de artefactos de la sesión, nunca dentro.
52
+ *
53
+ * **Hermana y no subcarpeta**, y eso no es estética: desde que la foto de
54
+ * `anunciarArtefactosDeLaShell` es recursiva, cualquier cosa que cuelgue de `artefactos/` se
55
+ * anuncia — o sea que un `artefactos/hotswap/` volvería a llenar la pestaña de volcados, que
56
+ * es justo lo que esto viene a quitar.
57
+ *
58
+ * Se deriva de la carpeta de artefactos en vez de recibir su propio parámetro, por lo mismo
59
+ * que `carpetaDeDescargas`: esa carpeta ya lleva dentro la única decisión que hace falta
60
+ * —¿hay una sesión con IDENTIDAD?—, que `turnoReal.ts` resuelve pasando
61
+ * `.xonecode/sesiones/<id>/artefactos` en la web y cayendo a `.xonecode/artefactos` en el
62
+ * terminal. Dos parámetros serían dos sitios donde contestar la misma pregunta, y el segundo
63
+ * es justo el que se cae en un cableado de ocho saltos.
64
+ *
65
+ * Y de vivir ahí cuelga gratis lo que si no habría que escribir: `borrarSesion` borra la
66
+ * carpeta `<id>` entera, así que borrar una conversación se lleva también sus volcados.
67
+ */
68
+ export function carpetaDeHotswap(carpetaDeArtefactos) {
69
+ return join(dirname(carpetaDeArtefactos), CARPETA);
70
+ }
71
+ //# sourceMappingURL=hotswap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hotswap.js","sourceRoot":"","sources":["../../src/core/hotswap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,WAAW,CAAC;AAExC,uEAAuE;AACvE,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AAErE;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,gBAAgB,CAAC,mBAA2B;IAC1D,OAAO,IAAI,CAAC,OAAO,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC,CAAC;AACrD,CAAC"}
@@ -57,6 +57,16 @@ const PREFIJO_DE_CLAVE = "XONECODE_CLAVE_";
57
57
  * `artefactoFueraDeSitio` prohíbe a las tools de fichero, y una shell no pasa por ahí.
58
58
  */
59
59
  export const VARIABLE_DE_ARTEFACTOS = "XONECODE_ARTEFACTOS";
60
+ /**
61
+ * Y la que nombra la carpeta donde dejar lo que **no** se le enseña a nadie: lo que un script
62
+ * saca del contexto para no metérselo al agente en el hilo (`core/hotswap.ts`).
63
+ *
64
+ * Son dos variables y no una porque son dos preguntas: la de arriba dice «dónde dejo lo que
65
+ * quiero que vea», ésta «dónde dejo lo que quiero poder releer». Con una sola, el script
66
+ * escribía sus volcados donde se anuncian — medido: diez tarjetas en el hilo, seis de ellas
67
+ * de ficheros que nadie volvió a abrir.
68
+ */
69
+ export const VARIABLE_DE_HOTSWAP = "XONECODE_HOTSWAP";
60
70
  /**
61
71
  * Cómo se llama la variable que lleva la ruta real de una skill.
62
72
  *
@@ -136,6 +146,8 @@ export function entornoDeShell(opciones) {
136
146
  }
137
147
  if (opciones.artefactos !== undefined)
138
148
  limpio[VARIABLE_DE_ARTEFACTOS] = opciones.artefactos;
149
+ if (opciones.hotswap !== undefined)
150
+ limpio[VARIABLE_DE_HOTSWAP] = opciones.hotswap;
139
151
  // Después de la copia del entorno heredado, así que lo que resuelve el localizador gana
140
152
  // sobre un valor que viniera de fuera: el localizador SÍ ha comprobado que el fichero está.
141
153
  Object.assign(limpio, opciones.android ?? {});
@@ -1 +1 @@
1
- {"version":3,"file":"shellDeAgente.js","sourceRoot":"","sources":["../../src/core/shellDeAgente.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"shellDeAgente.js","sourceRoot":"","sources":["../../src/core/shellDeAgente.ts"],"names":[],"mappings":"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"}
@@ -2008,6 +2008,29 @@ export function montarRutas(servidor, vestibulo, opciones = {}) {
2008
2008
  * Si no hay escritor, se DICE que no se ha guardado en vez de callarlo: un ajuste que
2009
2009
  * parece puesto y no lo está es peor que uno que falta.
2010
2010
  */
2011
+ /**
2012
+ * Las CLAVES con las que un control que refleja un ESTADO sustituye su propia línea
2013
+ * pendiente (`LineaDeConsola.sustituye`).
2014
+ *
2015
+ * Los tres son pastillas del compositor: se pulsan una vez por cambio de opinión, y si el
2016
+ * turno está en vuelo las líneas se quedan en la cola y el lazo las ejecuta seguidas al
2017
+ * terminar — dos acuses contiguos, con el primero ya caduco. Los tres tienen el mismo
2018
+ * acuse y el mismo defecto, así que llevan clave los tres: una lista que hay que acordarse
2019
+ * de ampliar es el patrón de fallo de este repo.
2020
+ *
2021
+ * **Hoy ninguna de las tres llega a encolarse dos veces**, y hay que decirlo: la pastilla
2022
+ * no manda si pulsas la que ya está puesta, y ese estado es el CONFIRMADO por el servidor,
2023
+ * que durante un turno no cambia. Reproducido en el navegador. Esto es el lado fail-closed
2024
+ * de esa guarda, que además pierde una pulsación rápida en silencio y está sin arreglar.
2025
+ *
2026
+ * **`/sync` NO está aquí, y esa ausencia es la decisión**: dos subidas son dos operaciones,
2027
+ * no una opinión que cambia. Y nada de lo que teclea una persona se coalesce jamás.
2028
+ */
2029
+ const CLAVE_DE_CONTROL = {
2030
+ modo: "control:modo-de-escritura",
2031
+ modelo: "control:modelo",
2032
+ esfuerzo: "control:esfuerzo",
2033
+ };
2011
2034
  /**
2012
2035
  * El esfuerzo de la sesión abierta. `nivel` ausente = quitarlo.
2013
2036
  *
@@ -2037,7 +2060,7 @@ export function montarRutas(servidor, vestibulo, opciones = {}) {
2037
2060
  informar(`«${nivel}» no es un nivel de esfuerzo`);
2038
2061
  return;
2039
2062
  }
2040
- abierto.consola.encolar(`/esfuerzo ${nivel}`);
2063
+ abierto.consola.encolar(`/esfuerzo ${nivel}`, CLAVE_DE_CONTROL.esfuerzo);
2041
2064
  };
2042
2065
  /**
2043
2066
  * El MODO DE ESCRITURA de la sesión abierta.
@@ -2064,7 +2087,7 @@ export function montarRutas(servidor, vestibulo, opciones = {}) {
2064
2087
  informar(`«${String(modo)}» no es un modo de escritura`);
2065
2088
  return;
2066
2089
  }
2067
- abierto.consola.encolar(`/aprobacion ${modo}`);
2090
+ abierto.consola.encolar(`/aprobacion ${modo}`, CLAVE_DE_CONTROL.modo);
2068
2091
  };
2069
2092
  /**
2070
2093
  * Pregunta a Ollama si el modelo en vigor piensa, y vuelve a emitir cuando conteste.
@@ -2115,7 +2138,7 @@ export function montarRutas(servidor, vestibulo, opciones = {}) {
2115
2138
  informar("esta ejecución no puede guardar el modelo por defecto");
2116
2139
  return;
2117
2140
  }
2118
- abierto.consola.encolar(`/modelo ${id}`);
2141
+ abierto.consola.encolar(`/modelo ${id}`, CLAVE_DE_CONTROL.modelo);
2119
2142
  informar(`modelo de esta sesión: ${id} · esta ejecución no lo guarda como defecto`);
2120
2143
  return;
2121
2144
  }
@@ -2131,7 +2154,7 @@ export function montarRutas(servidor, vestibulo, opciones = {}) {
2131
2154
  informar(`modelo por defecto: ${id} · lo usarán las sesiones nuevas`);
2132
2155
  }
2133
2156
  else {
2134
- abierto.consola.encolar(`/modelo ${id}`);
2157
+ abierto.consola.encolar(`/modelo ${id}`, CLAVE_DE_CONTROL.modelo);
2135
2158
  informar(`${id} guardado como modelo por defecto, además de aplicarlo a esta sesión`);
2136
2159
  }
2137
2160
  // El defecto acaba de cambiar, así que lo que el cliente pinta como «por defecto» se