Cómo funciona
Mutar archivos de forma confiable siempre ha sido la parte complicada de la generación de código. Project Builder lo vuelve simple repartiendo el trabajo entre tres partes con responsabilidades claramente delimitadas — y dejando que dos de ellas mantengan una conversación.
La conversación SDK–engine
Sección titulada «La conversación SDK–engine»SDK — registros de instrucciones y experiencia de desarrollo
Sección titulada «SDK — registros de instrucciones y experiencia de desarrollo»El SDK (@pbuilder/sdk) tiene dos responsabilidades. Primero, produce IR —
registros de instrucciones: directivas JSON que describen qué debe suceder («crea este
archivo con este contenido», «mueve este otro allá»). Tu factory nunca escribe en tu
proyecto; emite intención. Segundo, es dueño de la experiencia de desarrollo:
verbos de mutación tipados, plantillas,
dialectos y el harness de testing — todo para que algo
históricamente tan doloroso como la mutación de archivos se sienta simple.
El SDK y el engine mantienen una conversación. Las directivas no cruzan una por una: a medida que tu factory encadena mutaciones, estas se acumulan en un buffer dentro del SDK, y el buffer hace flush (vaciado del buffer) hacia el engine como un único lote en exactamente dos momentos — cuando el factory termina, o en el instante en que lees un archivo, de modo que una lectura siempre ve primero tus propias escrituras pendientes.
Engine — aplicar los registros
Sección titulada «Engine — aplicar los registros»El engine recibe esos registros de instrucciones y los aplica, con varios mecanismos para hacerlo de forma segura: todo aterriza en un árbol de staging mientras tu factory corre, y solo después de que el factory retorna con éxito se escribe en disco el resultado preparado. El engine es el único componente que escribe — y una ejecución fallida no escribe nada.
El engine es ciego a los AST y a la API de autoría. No sabe qué es un verbo ni un
dialecto — las ediciones de código le llegan como contenido final de archivo, listo para
aplicar. Su única tarea de autoría es renderizar las plantillas {= =}
contra tus entradas. Esa ignorancia es una virtud: la superficie del SDK puede
enriquecerse sin que el contrato de ejecución cambie jamás.
CLI — la superficie orientada a agentes
Sección titulada «CLI — la superficie orientada a agentes»La CLI builder es la puerta de entrada: init, new, execute. Valida tu entrada,
resuelve el schematic y arranca el engine — que es dueño de la ejecución desde ahí. La CLI
está diseñada deliberadamente para que la manejen agentes de IA: la salida regresa como
JSON estructurado, así que un agente puede ejecutar un schematic y parsear el resultado
como cualquier otra API.
La historia de los AST
Sección titulada «La historia de los AST»He aquí una simplificación extrema — pero útil —: escribir software, en el día a día, es mutar archivos. Y un archivo es solo texto; la extensión es lo que le da significado a ese texto.
Visto así, la mayoría de las mutaciones son simples: crear, reemplazar, mover y copiar
tratan el archivo como texto y nunca necesitan saber qué significa. La excepción es
modify. Para cambiar un archivo programáticamente primero tienes que entenderlo — y
la manera en que un programa entiende un archivo es a través de un AST (árbol de
sintaxis abstracta).
Aquí está el problema: cada tipo de archivo tiene su propia librería de parsing, y los AST que producen nunca se parecen entre sí — ninguno sigue una convención compartida. Sin ayuda, cada autor de schematics tendría que elegir librerías, instalarlas y aprender la forma del árbol de cada una.
El SDK lo resuelve centralizando los AST: se apoya en esas librerías y las expone como dialectos listos para usar — TypeScript y React hoy, con más tipos de archivo (HTML, CSS) y dialectos de frameworks (Angular, Vue, Svelte) en el plan. No instalas nada extra; ya forman parte del SDK.
La frontera se mantiene limpia: los AST pertenecen al SDK. Para cuando una edición de AST llega al engine, ya fue reducida a un registro plano y listo para aplicar — el engine nunca parsea código.
Bajo el capó: un engine que habla el protocolo, no el lenguaje
Sección titulada «Bajo el capó: un engine que habla el protocolo, no el lenguaje»El SDK es TypeScript; el engine es Go. Se comunican a través de un puente deliberadamente
delgado: el engine ejecuta un sidecar de Bun mediante un adaptador, y ese sidecar
arranca el runner del SDK — el punto de entrada que carga tu factory y abre la
conversación. A partir de ahí, todo lo que cruza entre ambos es JSON enmarcado (framed
JSON) por el cable: ir.emit, tree.read, ir.commit, ir.discard.
De este diseño se desprenden dos propiedades:
- El engine es agnóstico del lenguaje. No habla TypeScript — habla el protocolo del cable. Un SDK en Python, Rust o cualquier otro lenguaje solo necesita un adaptador nuevo; el engine, el árbol de staging y las garantías de seguridad se mantienen exactamente iguales.
- El SDK es autocontenido. Todo lo que un factory produce es IR, así que el harness de testing puede sustituir por completo al lado del engine y ejecutar factories enteramente en memoria — sin CLI, sin engine, sin disco. Por eso los schematics son testeables como cualquier otro código.