merge: quick/ingest-tui-core-shell-devfactory — ingesta DevFactory al registry (tui, core, shell)

This commit is contained in:
2026-03-28 03:58:57 +01:00
162 changed files with 3721 additions and 0 deletions
+256
View File
@@ -0,0 +1,256 @@
# fn_operations — Schema de inteligencia operacional
Base de datos local por proyecto. Cada proyecto tiene su propio archivo `.db` independiente.
Referencia IDs del registry central (`fn_registry`) pero no los duplica — solo apunta a ellos.
---
## Propósito
El registry almacena **lo que sabes hacer**.
fn_operations almacena **lo que has hecho y cómo fluye** en un proyecto concreto.
| | fn_registry | fn_operations |
|---|---|---|
| **Naturaleza** | Conocimiento estático | Conocimiento dinámico |
| **Contenido** | Lo que sabes hacer | Lo que has hecho y cómo fluye |
| **Scope** | Compartida entre todos los proyectos | Local a cada proyecto — un `.db` por proyecto |
| **Tablas** | `functions`, `types` | `entities`, `relations`, `relation_inputs` |
| **Cuándo cambia** | Al añadir código al registry | En cada proyecto activo |
---
## Estructura de directorios
```
fn-registry/
fn_operations/
fn_operations.md ← este archivo
project_template/
operations.db ← plantilla vacía con schema y WAL mode aplicados
migrations/
001_init.sql ← script de creación de tablas
```
---
## Tabla: entities
Una entity es una instancia concreta de un tipo del registry dentro del contexto de un proyecto.
No es el tipo en abstracto — es el dato real que fluye: `ticks_btcusdt_2024`, `ohlcv_1h_binance`, `user_session_web`.
El tipo del registry (`type_ref`) aporta conocimiento heredado — campos, estructura, semántica algebraica.
La entity aporta conocimiento contextual — qué rol juega aquí, de dónde viene, qué propiedades específicas tiene.
```
type_ref → lo que la entidad ES (heredado del registry)
metadata → lo que la entidad TIENE (específico de este contexto)
```
| Campo | Tipo | Descripción | Notas / Restricciones |
|---|---|---|---|
| `id` | string | Identificador único de la entidad en el proyecto. | Formato: `{name}_{context}` ej: `ticks_btcusdt_2024`. Único dentro del proyecto. |
| `name` | string | Nombre semántico de la entidad. | Descriptivo y específico al dominio del proyecto. Obligatorio. |
| `type_ref` | string | ID del tipo del registry que modela esta entidad. | Referencia a `types.id` en `fn_registry`. Obligatorio. |
| `status` | enum | Estado actual de la entidad. | `active` \| `stale` \| `corrupted` \| `archived` |
| `description` | text | Qué representa esta entidad en el contexto del proyecto. | No qué es el tipo en abstracto, sino qué rol juega aquí. |
| `domain` | string | Área de dominio dentro del proyecto. | Ej: `market_data`, `auth`, `reporting`. |
| `tags` | []string | Etiquetas libres para búsqueda y agrupación. | |
| `source` | string | Origen del dato. | Obligatorio. Ej: `binance_api`, `csv_upload`, `user_input`, `pipeline_output`. |
| `metadata` | json | Propiedades específicas del contexto no capturadas por el tipo. | Valores concretos de los campos del tipo. Ej: `{"pair":"BTCUSDT","exchange":"binance"}`. |
| `notes` | text | Contexto extra libre sobre la entidad. | Para el agente o para ti. Decisiones, observaciones, advertencias, historial informal. |
| `created_at` | datetime | Fecha de registro de la entidad. | ISO 8601. Generado automáticamente. |
| `updated_at` | datetime | Fecha de última modificación. | ISO 8601. Actualizado automáticamente. |
### Valores de status — entities
| Valor | Significado |
|---|---|
| `active` | Dato en uso, actualizado y fiable. |
| `stale` | Existe pero puede estar desactualizado. El agente debe verificar antes de usar. |
| `corrupted` | Se sabe que tiene problemas de integridad. No usar en pipelines. |
| `archived` | Ya no se usa activamente. Se conserva por trazabilidad histórica. |
### Reglas de integridad — entities
| Condición | Regla |
|---|---|
| `type_ref` | Debe existir en `fn_registry.types.id`. Sin referencias huérfanas. |
| `id` | Único dentro del proyecto. Formato `{name}_{context}`. |
| `source` | Obligatorio. Todo dato tiene un origen conocido. |
| `name` | Obligatorio. Sin espacios, snake_case. |
| `metadata` | JSON válido. Debe contener los valores de los campos definidos por el tipo del registry. |
| `status: corrupted` | El agente nunca debe usar esta entidad como input de una relation activa. |
---
## Tabla: relations
Una relation describe cómo una entidad se conecta o transforma en otra. Puede documentar una
transformación técnica a través de una función del registry, o una relación puramente semántica
sin función asociada. El campo `name` expresa el significado humano de la conexión.
```
juan (type: person) → CONOCE A → paula (type: person)
ticks → AGREGA → ohlcv_1h (via: tick_to_ohlcv_go_finance)
```
Para relaciones que consumen **múltiples entidades** (joins, merges, agregaciones multi-fuente),
se usa la tabla `relation_inputs` en lugar de `from_entity`. Ver sección correspondiente.
| Campo | Tipo | Descripción | Notas / Restricciones |
|---|---|---|---|
| `id` | string | Identificador único de la relación. | Formato: `{from}__to__{to}__via__{fn}`. Legible sin joins. |
| `name` | string | Etiqueta semántica de la relación. | El verbo o concepto que describe la conexión. Ej: `CONOCE A`, `TRANSFORMA`, `PRODUCE`, `DEPENDE DE`. Obligatorio. |
| `from_entity` | string | ID de la entidad origen para relaciones simples (1-a-1). | Referencia a `entities.id`. Opcional si se usa `relation_inputs`. |
| `to_entity` | string | ID de la entidad destino. | Referencia a `entities.id`. Obligatorio. |
| `via` | string | ID de la función o pipeline del registry que realiza la transformación. | Referencia a `functions.id` en `fn_registry`. Opcional — vacío si la relación es puramente semántica. |
| `description` | text | Qué ocurre en esta conexión en el contexto del proyecto. | No qué hace la función en abstracto, sino qué significa aquí. |
| `purity` | enum | Naturaleza de la transformación. | `pure` \| `impure`. Si `via` está informado, debe ser consistente con `via.purity` en el registry. |
| `direction` | enum | Dirección semántica de la relación. | `unidirectional` \| `bidirectional` \| `inverse`. Ver valores abajo. |
| `weight` | float | Ponderación opcional de la relación. | Rango `0.0 1.0`. Permite queryar "relaciones con peso > 0.8". Opcional. |
| `status` | enum | Estado del flujo. | `designed` \| `implemented` \| `tested` \| `running` \| `deprecated` |
| `started_at` | datetime | Cuándo empezó el flujo realmente. | ISO 8601. Distinto de `created_at` — ese es cuándo lo documentaste. |
| `ended_at` | datetime | Cuándo terminó o dejó de ejecutarse el flujo. | ISO 8601. Vacío si sigue activo. |
| `order` | int | Posición en el pipeline si forma parte de una secuencia ordenada. | Opcional. Permite reconstruir el grafo en orden de ejecución. |
| `tags` | []string | Etiquetas libres. | |
| `notes` | text | Observaciones, decisiones de diseño, problemas conocidos. | Libre. El agente lee esto para entender contexto histórico del flujo. |
| `created_at` | datetime | Fecha de registro de la relación. | ISO 8601. Generado automáticamente. |
| `updated_at` | datetime | Fecha de última modificación. | ISO 8601. Actualizado automáticamente. |
### Valores de direction
| Valor | Significado |
|---|---|
| `unidirectional` | A → B. La relación fluye en un solo sentido. Valor por defecto. |
| `bidirectional` | A ↔ B. La relación es simétrica — vale en ambos sentidos. Ej: `CONOCE A`. |
| `inverse` | La relación se documenta de B a A pero su lectura natural es de A a B. Útil para linaje inverso. |
### Valores de status — relations
| Valor | Significado |
|---|---|
| `designed` | Flujo planificado. Existe en el grafo de arquitectura pero no hay código todavía. |
| `implemented` | Código escrito. No verificado en este contexto de proyecto aún. |
| `tested` | Verificado en este proyecto. Los datos fluyen correctamente. |
| `running` | Activo en producción o en uso continuo. |
| `deprecated` | Ya no se usa. Se mantiene por trazabilidad histórica. |
### Reglas de integridad — relations
| Condición | Regla |
|---|---|
| `name` | Obligatorio. Describe el verbo semántico de la relación. |
| `from_entity` | Si informado, debe existir en `entities.id`. Vacío si se usa `relation_inputs`. |
| `from_entity` o `relation_inputs` | Al menos uno de los dos debe estar presente. Una relation sin origen es inválida. |
| `to_entity` | Debe existir en `entities.id`. Obligatorio. |
| `via` | Si informado, debe existir en `fn_registry.functions.id`. |
| `purity` | Si `via` está informado, debe ser consistente con `via.purity` en el registry. |
| `weight` | Si informado, debe estar en el rango `0.0 1.0`. |
| `from_entity != to_entity` | Una entidad no puede relacionarse consigo misma. |
| `started_at` / `ended_at` | Si ambos informados, `started_at` debe ser anterior a `ended_at`. |
| `id` | Único dentro del proyecto. |
| **Sin ciclos** | El CLI valida al insertar que la nueva relation no crea un ciclo en el grafo. Si lo crea, la inserción se rechaza. SQLite no detecta ciclos — esta validación ocurre en la capa de aplicación. |
---
## Tabla: relation_inputs
Tabla intermedia para relaciones que consumen **múltiples entidades simultáneamente** — joins,
merges, agregaciones multi-fuente. Cuando una relation usa `relation_inputs`, el campo
`from_entity` en `relations` se deja vacío.
```
join(ticks_btcusdt, metadata_binance) → ENRIQUECE → ohlcv_enriquecido
↑ input role: "base" ↑ to_entity
↑ input role: "lookup"
```
| Campo | Tipo | Descripción | Notas / Restricciones |
|---|---|---|---|
| `id` | string | Identificador único del input. | Generado automáticamente. |
| `relation_id` | string | ID de la relation a la que pertenece este input. | Referencia a `relations.id`. Obligatorio. |
| `entity_id` | string | ID de la entidad que actúa como input. | Referencia a `entities.id`. Obligatorio. |
| `role` | string | Rol semántico de este input en la relación. | Ej: `base`, `lookup`, `filter`, `left`, `right`. Obligatorio. Permite al agente entender cómo se usa cada input. |
| `order` | int | Orden del input si la relación es sensible al orden. | Opcional. Ej: en un join `left`/`right` el orden importa. |
### Reglas de integridad — relation_inputs
| Condición | Regla |
|---|---|
| `relation_id` | Debe existir en `relations.id`. |
| `entity_id` | Debe existir en `entities.id`. |
| `role` | Obligatorio. Sin rol el agente no puede razonar sobre cómo se usa el input. |
| Mínimo 2 inputs | Una relation con `relation_inputs` debe tener al menos 2 entradas. Si solo hay una, usar `from_entity` en su lugar. |
---
## Referencias cruzadas completas
| Campo origen | → | Destino |
|---|---|---|
| `entities.type_ref` | → | `fn_registry → types.id` |
| `relations.from_entity` | → | `entities.id` (opcional) |
| `relations.to_entity` | → | `entities.id` |
| `relations.via` | → | `fn_registry → functions.id` (opcional) |
| `relation_inputs.relation_id` | → | `relations.id` |
| `relation_inputs.entity_id` | → | `entities.id` |
---
## Ejemplo — pipeline de market data
### Entities
| id | type_ref | status | source | metadata |
|---|---|---|---|---|
| `ticks_btcusdt_2024` | `tick_go_finance` | `active` | `binance_api` | `{"pair":"BTCUSDT","exchange":"binance"}` |
| `metadata_binance` | `exchange_meta_go_finance` | `active` | `binance_api` | `{"version":"v3"}` |
| `ohlcv_1h_btcusdt` | `ohlcv_go_finance` | `active` | `pipeline_output` | `{"interval":"1h","pair":"BTCUSDT"}` |
| `sma_20_btcusdt` | `float64_slice_go_core` | `active` | `pipeline_output` | `{"period":20,"field":"close"}` |
### Relations simples
| name | from_entity | to_entity | via | direction | status | weight |
|---|---|---|---|---|---|---|
| `CALCULA` | `ohlcv_1h_btcusdt` | `sma_20_btcusdt` | `sma_go_finance` | `unidirectional` | `tested` | 1.0 |
### Relation con múltiples inputs (relation_inputs)
**Relation:** `id: ticks_y_meta__to__ohlcv__via__enrich`, `name: ENRIQUECE`, `to_entity: ohlcv_1h_btcusdt`
| relation_id | entity_id | role | order |
|---|---|---|---|
| `ticks_y_meta__to__ohlcv__via__enrich` | `ticks_btcusdt_2024` | `base` | 1 |
| `ticks_y_meta__to__ohlcv__via__enrich` | `metadata_binance` | `lookup` | 2 |
### Grafo resultante
```
[ticks_btcusdt_2024] ──┐
├─ ENRIQUECE (impure · running) ──→ [ohlcv_1h_btcusdt]
[metadata_binance] ──┘ ↓
CALCULA (pure · tested)
[sma_20_btcusdt]
```
---
## Ejemplo — relaciones semánticas puras (sin via)
```
[juan] (type: person) → CONOCE A (bidirectional, weight: 0.9) → [paula]
[servicio_auth] → DEPENDE DE (unidirectional, weight: 1.0) → [bbdd_usuarios]
[modelo_riesgo] → ALIMENTA (unidirectional, weight: 0.7) → [dashboard_trading]
```
---
## Escalabilidad
| Fase | BBDD | Cuándo migrar |
|---|---|---|
| Inicial | SQLite + WAL mode | Proyectos personales, un agente escribiendo |
| Crecimiento | PostgreSQL | Múltiples agentes escribiendo concurrentemente |
| Analítico | ClickHouse | Millones de operaciones, dashboards de uso |
+9
View File
@@ -0,0 +1,9 @@
package core
// Implementation: github.com/lucasdataproyects/devfactory/core
// All devuelve true si todos los elementos del slice cumplen el predicado.
func All[T any](slice []T, predicate func(T) bool) bool {
// stub
return false
}
+32
View File
@@ -0,0 +1,32 @@
---
name: all_slice
kind: function
lang: go
domain: core
version: "1.0.0"
purity: pure
signature: "func All[T any](slice []T, predicate func(T) bool) bool"
description: "Devuelve true si todos los elementos del slice cumplen el predicado."
tags: [slice, functional, generic, predicate]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: []
tested: false
tests: []
test_file_path: ""
file_path: "functions/core/all_slice.go"
---
## Ejemplo
```go
result := All([]int{2, 4, 6}, func(x int) bool { return x%2 == 0 })
// result = true
```
## Notas
Funcion pura generica. Implementacion en devfactory/core.
+9
View File
@@ -0,0 +1,9 @@
package core
// Implementation: github.com/lucasdataproyects/devfactory/core
// Any devuelve true si al menos un elemento del slice cumple el predicado.
func Any[T any](slice []T, predicate func(T) bool) bool {
// stub
return false
}
+32
View File
@@ -0,0 +1,32 @@
---
name: any_slice
kind: function
lang: go
domain: core
version: "1.0.0"
purity: pure
signature: "func Any[T any](slice []T, predicate func(T) bool) bool"
description: "Devuelve true si al menos un elemento del slice cumple el predicado."
tags: [slice, functional, generic, predicate]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: []
tested: false
tests: []
test_file_path: ""
file_path: "functions/core/any_slice.go"
---
## Ejemplo
```go
result := Any([]int{1, 2, 3}, func(x int) bool { return x > 2 })
// result = true
```
## Notas
Funcion pura generica. Implementacion en devfactory/core.
+9
View File
@@ -0,0 +1,9 @@
package core
// Implementation: github.com/lucasdataproyects/devfactory/core
// Compose2 compone dos funciones de derecha a izquierda.
func Compose2[A, B, C any](f2 func(B) C, f1 func(A) B) func(A) C {
// stub
return nil
}
+34
View File
@@ -0,0 +1,34 @@
---
name: compose2
kind: function
lang: go
domain: core
version: "1.0.0"
purity: pure
signature: "func Compose2[A, B, C any](f2 func(B) C, f1 func(A) B) func(A) C"
description: "Compone dos funciones de derecha a izquierda. compose2(g, f)(x) = g(f(x))."
tags: [functional, composition, generic]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: []
tested: false
tests: []
test_file_path: ""
file_path: "functions/core/compose2.go"
---
## Ejemplo
```go
double := func(x int) int { return x * 2 }
toString := func(x int) string { return fmt.Sprintf("%d", x) }
doubleStr := Compose2(toString, double)
result := doubleStr(5) // "10"
```
## Notas
Funcion pura generica. Implementacion en devfactory/core.
+9
View File
@@ -0,0 +1,9 @@
package core
// Implementation: github.com/lucasdataproyects/devfactory/core
// Const devuelve una funcion que siempre retorna el valor dado, ignorando su argumento.
func Const[T, U any](value T) func(U) T {
// stub
return nil
}
+32
View File
@@ -0,0 +1,32 @@
---
name: const_func
kind: function
lang: go
domain: core
version: "1.0.0"
purity: pure
signature: "func Const[T, U any](value T) func(U) T"
description: "Devuelve una funcion que siempre retorna el valor dado, ignorando su argumento."
tags: [functional, generic, const]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: []
tested: false
tests: []
test_file_path: ""
file_path: "functions/core/const_func.go"
---
## Ejemplo
```go
always42 := Const[int, string](42)
result := always42("ignored") // 42
```
## Notas
Funcion pura generica. Implementacion en devfactory/core.
+9
View File
@@ -0,0 +1,9 @@
package core
// Implementation: github.com/lucasdataproyects/devfactory/core
// Curry2 transforma una funcion de dos argumentos en forma currificada.
func Curry2[A, B, C any](f func(A, B) C) func(A) func(B) C {
// stub
return nil
}
+34
View File
@@ -0,0 +1,34 @@
---
name: curry2
kind: function
lang: go
domain: core
version: "1.0.0"
purity: pure
signature: "func Curry2[A, B, C any](f func(A, B) C) func(A) func(B) C"
description: "Transforma una funcion de dos argumentos en forma currificada."
tags: [functional, generic, curry]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: []
tested: false
tests: []
test_file_path: ""
file_path: "functions/core/curry2.go"
---
## Ejemplo
```go
add := func(a, b int) int { return a + b }
curriedAdd := Curry2(add)
add5 := curriedAdd(5)
result := add5(3) // 8
```
## Notas
Funcion pura generica. Implementacion en devfactory/core.
+9
View File
@@ -0,0 +1,9 @@
package core
// Implementation: github.com/lucasdataproyects/devfactory/core
// Drop elimina los primeros n elementos de un slice y devuelve el resto.
func Drop[T any](slice []T, n int) []T {
// stub
return nil
}
+32
View File
@@ -0,0 +1,32 @@
---
name: drop
kind: function
lang: go
domain: core
version: "1.0.0"
purity: pure
signature: "func Drop[T any](slice []T, n int) []T"
description: "Elimina los primeros n elementos de un slice y devuelve el resto."
tags: [slice, functional, generic]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: []
tested: false
tests: []
test_file_path: ""
file_path: "functions/core/drop.go"
---
## Ejemplo
```go
result := Drop([]int{1, 2, 3, 4, 5}, 2)
// result = [3, 4, 5]
```
## Notas
Funcion pura generica. Implementacion en devfactory/core.
+9
View File
@@ -0,0 +1,9 @@
package core
// Implementation: github.com/lucasdataproyects/devfactory/core
// Find devuelve el primer elemento del slice que cumple el predicado, envuelto en Option.
func Find[T any](slice []T, predicate func(T) bool) Option[T] {
// stub
return Option[T]{}
}
+33
View File
@@ -0,0 +1,33 @@
---
name: find
kind: function
lang: go
domain: core
version: "1.0.0"
purity: pure
signature: "func Find[T any](slice []T, predicate func(T) bool) Option[T]"
description: "Devuelve el primer elemento del slice que cumple el predicado, envuelto en Option."
tags: [slice, functional, generic, search]
uses_functions: []
uses_types: [option_go_core]
returns: [option_go_core]
returns_optional: false
error_type: ""
imports: []
tested: false
tests: []
test_file_path: ""
file_path: "functions/core/find.go"
---
## Ejemplo
```go
nums := []int{1, 2, 3, 4, 5}
result := Find(nums, func(n int) bool { return n > 3 })
// result es Some(4)
```
## Notas
Funcion pura generica. Implementacion en devfactory/core.
+9
View File
@@ -0,0 +1,9 @@
package core
// Implementation: github.com/lucasdataproyects/devfactory/core
// FindIndex devuelve el indice del primer elemento que cumple el predicado.
func FindIndex[T any](slice []T, predicate func(T) bool) Option[int] {
// stub
return Option[int]{}
}
+32
View File
@@ -0,0 +1,32 @@
---
name: find_index
kind: function
lang: go
domain: core
version: "1.0.0"
purity: pure
signature: "func FindIndex[T any](slice []T, predicate func(T) bool) Option[int]"
description: "Devuelve el indice del primer elemento que cumple el predicado, envuelto en Option."
tags: [slice, functional, generic, search]
uses_functions: []
uses_types: [option_go_core]
returns: [option_go_core]
returns_optional: false
error_type: ""
imports: []
tested: false
tests: []
test_file_path: ""
file_path: "functions/core/find_index.go"
---
## Ejemplo
```go
idx := FindIndex([]int{10, 20, 30}, func(x int) bool { return x > 15 })
// idx = Some(1)
```
## Notas
Funcion pura generica. Implementacion en devfactory/core.
+9
View File
@@ -0,0 +1,9 @@
package core
// Implementation: github.com/lucasdataproyects/devfactory/core
// FlatMapSlice aplica una funcion que devuelve slices a cada elemento y aplana el resultado.
func FlatMapSlice[T, U any](slice []T, f func(T) []U) []U {
// stub
return nil
}
+32
View File
@@ -0,0 +1,32 @@
---
name: flat_map_slice
kind: function
lang: go
domain: core
version: "1.0.0"
purity: pure
signature: "func FlatMapSlice[T, U any](slice []T, f func(T) []U) []U"
description: "Aplica una funcion que devuelve slices a cada elemento y aplana el resultado."
tags: [slice, functional, generic, flatmap]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: []
tested: false
tests: []
test_file_path: ""
file_path: "functions/core/flat_map_slice.go"
---
## Ejemplo
```go
result := FlatMapSlice([]int{1, 2, 3}, func(x int) []int { return []int{x, x * 10} })
// result = [1, 10, 2, 20, 3, 30]
```
## Notas
Funcion pura generica. Implementacion en devfactory/core.
+9
View File
@@ -0,0 +1,9 @@
package core
// Implementation: github.com/lucasdataproyects/devfactory/core
// Flatten aplana un slice de slices en un unico slice.
func Flatten[T any](slices [][]T) []T {
// stub
return nil
}
+32
View File
@@ -0,0 +1,32 @@
---
name: flatten
kind: function
lang: go
domain: core
version: "1.0.0"
purity: pure
signature: "func Flatten[T any](slices [][]T) []T"
description: "Aplana un slice de slices en un unico slice."
tags: [slice, functional, generic]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: []
tested: false
tests: []
test_file_path: ""
file_path: "functions/core/flatten.go"
---
## Ejemplo
```go
result := Flatten([][]int{{1, 2}, {3, 4}, {5}})
// result = [1, 2, 3, 4, 5]
```
## Notas
Funcion pura generica. Implementacion en devfactory/core.
+9
View File
@@ -0,0 +1,9 @@
package core
// Implementation: github.com/lucasdataproyects/devfactory/core
// Flip intercambia el orden de los argumentos de una funcion de dos parametros.
func Flip[A, B, C any](f func(A, B) C) func(B, A) C {
// stub
return nil
}
+33
View File
@@ -0,0 +1,33 @@
---
name: flip
kind: function
lang: go
domain: core
version: "1.0.0"
purity: pure
signature: "func Flip[A, B, C any](f func(A, B) C) func(B, A) C"
description: "Intercambia el orden de los argumentos de una funcion de dos parametros."
tags: [functional, generic]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: []
tested: false
tests: []
test_file_path: ""
file_path: "functions/core/flip.go"
---
## Ejemplo
```go
sub := func(a, b int) int { return a - b }
flipped := Flip(sub)
result := flipped(3, 10) // 7 (10 - 3)
```
## Notas
Funcion pura generica. Implementacion en devfactory/core.
+9
View File
@@ -0,0 +1,9 @@
package core
// Implementation: github.com/lucasdataproyects/devfactory/core
// GroupBy agrupa elementos de un slice por clave generada con una funcion.
func GroupBy[T any, K comparable](slice []T, keyFn func(T) K) map[K][]T {
// stub
return nil
}
+32
View File
@@ -0,0 +1,32 @@
---
name: group_by
kind: function
lang: go
domain: core
version: "1.0.0"
purity: pure
signature: "func GroupBy[T any, K comparable](slice []T, keyFn func(T) K) map[K][]T"
description: "Agrupa elementos de un slice por clave generada con una funcion."
tags: [slice, functional, generic, grouping]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: []
tested: false
tests: []
test_file_path: ""
file_path: "functions/core/group_by.go"
---
## Ejemplo
```go
groups := GroupBy([]string{"go", "git", "python"}, func(s string) byte { return s[0] })
// groups = map[byte][]string{'g': {"go", "git"}, 'p': {"python"}}
```
## Notas
Funcion pura generica. Implementacion en devfactory/core.
+10
View File
@@ -0,0 +1,10 @@
package core
// Implementation: github.com/lucasdataproyects/devfactory/core
// Identity devuelve el valor recibido sin modificarlo.
func Identity[T any](x T) T {
// stub
var zero T
return zero
}
+32
View File
@@ -0,0 +1,32 @@
---
name: identity
kind: function
lang: go
domain: core
version: "1.0.0"
purity: pure
signature: "func Identity[T any](x T) T"
description: "Devuelve el valor recibido sin modificarlo. Elemento neutro de la composicion."
tags: [functional, generic, identity]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: []
tested: false
tests: []
test_file_path: ""
file_path: "functions/core/identity.go"
---
## Ejemplo
```go
x := Identity(42) // 42
s := Identity("abc") // "abc"
```
## Notas
Funcion pura generica. Implementacion en devfactory/core.
+9
View File
@@ -0,0 +1,9 @@
package core
// Implementation: github.com/lucasdataproyects/devfactory/core
// Partial2 aplica parcialmente el primer argumento de una funcion de dos parametros.
func Partial2[A, B, C any](f func(A, B) C, a A) func(B) C {
// stub
return nil
}
+33
View File
@@ -0,0 +1,33 @@
---
name: partial2
kind: function
lang: go
domain: core
version: "1.0.0"
purity: pure
signature: "func Partial2[A, B, C any](f func(A, B) C, a A) func(B) C"
description: "Aplica parcialmente el primer argumento de una funcion de dos parametros."
tags: [functional, generic, partial]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: []
tested: false
tests: []
test_file_path: ""
file_path: "functions/core/partial2.go"
---
## Ejemplo
```go
mul := func(a, b int) int { return a * b }
double := Partial2(mul, 2)
result := double(5) // 10
```
## Notas
Funcion pura generica. Implementacion en devfactory/core.
+9
View File
@@ -0,0 +1,9 @@
package core
// Implementation: github.com/lucasdataproyects/devfactory/core
// Pipe2 compone dos funciones de izquierda a derecha.
func Pipe2[A, B, C any](f1 func(A) B, f2 func(B) C) func(A) C {
// stub
return nil
}
+34
View File
@@ -0,0 +1,34 @@
---
name: pipe2
kind: function
lang: go
domain: core
version: "1.0.0"
purity: pure
signature: "func Pipe2[A, B, C any](f1 func(A) B, f2 func(B) C) func(A) C"
description: "Compone dos funciones de izquierda a derecha. pipe2(f, g)(x) = g(f(x))."
tags: [functional, composition, generic, pipe]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: []
tested: false
tests: []
test_file_path: ""
file_path: "functions/core/pipe2.go"
---
## Ejemplo
```go
double := func(x int) int { return x * 2 }
toString := func(x int) string { return fmt.Sprintf("%d", x) }
doubleStr := Pipe2(double, toString)
result := doubleStr(5) // "10"
```
## Notas
Funcion pura generica. Implementacion en devfactory/core.
+9
View File
@@ -0,0 +1,9 @@
package core
// Implementation: github.com/lucasdataproyects/devfactory/core
// Pipe3 compone tres funciones de izquierda a derecha.
func Pipe3[A, B, C, D any](f1 func(A) B, f2 func(B) C, f3 func(C) D) func(A) D {
// stub
return nil
}
+35
View File
@@ -0,0 +1,35 @@
---
name: pipe3
kind: function
lang: go
domain: core
version: "1.0.0"
purity: pure
signature: "func Pipe3[A, B, C, D any](f1 func(A) B, f2 func(B) C, f3 func(C) D) func(A) D"
description: "Compone tres funciones de izquierda a derecha."
tags: [functional, composition, generic, pipe]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: []
tested: false
tests: []
test_file_path: ""
file_path: "functions/core/pipe3.go"
---
## Ejemplo
```go
add1 := func(x int) int { return x + 1 }
double := func(x int) int { return x * 2 }
toString := func(x int) string { return fmt.Sprintf("%d", x) }
pipeline := Pipe3(add1, double, toString)
result := pipeline(3) // "8"
```
## Notas
Funcion pura generica. Implementacion en devfactory/core.
+9
View File
@@ -0,0 +1,9 @@
package core
// Implementation: github.com/lucasdataproyects/devfactory/core
// Reduce reduce un slice a un unico valor aplicando una funcion acumuladora.
func Reduce[T, U any](slice []T, initial U, f func(U, T) U) U {
// stub
return initial
}
+32
View File
@@ -0,0 +1,32 @@
---
name: reduce
kind: function
lang: go
domain: core
version: "1.0.0"
purity: pure
signature: "func Reduce[T, U any](slice []T, initial U, f func(U, T) U) U"
description: "Reduce un slice a un unico valor aplicando una funcion acumuladora de izquierda a derecha."
tags: [slice, functional, generic, fold]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: []
tested: false
tests: []
test_file_path: ""
file_path: "functions/core/reduce.go"
---
## Ejemplo
```go
sum := Reduce([]int{1, 2, 3, 4}, 0, func(acc, x int) int { return acc + x })
// sum = 10
```
## Notas
Funcion pura generica. Implementacion en devfactory/core.
+9
View File
@@ -0,0 +1,9 @@
package core
// Implementation: github.com/lucasdataproyects/devfactory/core
// Take devuelve los primeros n elementos de un slice.
func Take[T any](slice []T, n int) []T {
// stub
return nil
}
+32
View File
@@ -0,0 +1,32 @@
---
name: take
kind: function
lang: go
domain: core
version: "1.0.0"
purity: pure
signature: "func Take[T any](slice []T, n int) []T"
description: "Devuelve los primeros n elementos de un slice."
tags: [slice, functional, generic]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: []
tested: false
tests: []
test_file_path: ""
file_path: "functions/core/take.go"
---
## Ejemplo
```go
result := Take([]int{1, 2, 3, 4, 5}, 3)
// result = [1, 2, 3]
```
## Notas
Funcion pura generica. Implementacion en devfactory/core.
+9
View File
@@ -0,0 +1,9 @@
package core
// Implementation: github.com/lucasdataproyects/devfactory/core
// Uncurry2 transforma una funcion currificada en una funcion normal de dos argumentos.
func Uncurry2[A, B, C any](f func(A) func(B) C) func(A, B) C {
// stub
return nil
}
+35
View File
@@ -0,0 +1,35 @@
---
name: uncurry2
kind: function
lang: go
domain: core
version: "1.0.0"
purity: pure
signature: "func Uncurry2[A, B, C any](f func(A) func(B) C) func(A, B) C"
description: "Transforma una funcion currificada en una funcion normal de dos argumentos."
tags: [functional, generic, curry]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: []
tested: false
tests: []
test_file_path: ""
file_path: "functions/core/uncurry2.go"
---
## Ejemplo
```go
curriedAdd := func(a int) func(int) int {
return func(b int) int { return a + b }
}
add := Uncurry2(curriedAdd)
result := add(3, 5) // 8
```
## Notas
Funcion pura generica. Implementacion en devfactory/core.
+9
View File
@@ -0,0 +1,9 @@
package core
// Implementation: github.com/lucasdataproyects/devfactory/core
// Unique devuelve un slice con elementos unicos preservando el orden original.
func Unique[T comparable](slice []T) []T {
// stub
return nil
}
+32
View File
@@ -0,0 +1,32 @@
---
name: unique
kind: function
lang: go
domain: core
version: "1.0.0"
purity: pure
signature: "func Unique[T comparable](slice []T) []T"
description: "Devuelve un slice con elementos unicos preservando el orden original."
tags: [slice, functional, generic, dedup]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: []
tested: false
tests: []
test_file_path: ""
file_path: "functions/core/unique.go"
---
## Ejemplo
```go
result := Unique([]int{1, 2, 2, 3, 1, 4})
// result = [1, 2, 3, 4]
```
## Notas
Funcion pura generica. Implementacion en devfactory/core.
+9
View File
@@ -0,0 +1,9 @@
package core
// Implementation: github.com/lucasdataproyects/devfactory/core
// Zip combina dos slices en un slice de pares elemento a elemento.
func Zip[T, U any](a []T, b []U) []Pair[T, U] {
// stub
return nil
}
+32
View File
@@ -0,0 +1,32 @@
---
name: zip
kind: function
lang: go
domain: core
version: "1.0.0"
purity: pure
signature: "func Zip[T, U any](a []T, b []U) []Pair[T, U]"
description: "Combina dos slices en un slice de pares elemento a elemento."
tags: [slice, functional, generic, pair]
uses_functions: []
uses_types: [pair_go_core]
returns: [pair_go_core]
returns_optional: false
error_type: ""
imports: []
tested: false
tests: []
test_file_path: ""
file_path: "functions/core/zip.go"
---
## Ejemplo
```go
pairs := Zip([]string{"a", "b"}, []int{1, 2})
// pairs = [{a 1}, {b 2}]
```
## Notas
Funcion pura generica. Implementacion en devfactory/core.
+23
View File
@@ -0,0 +1,23 @@
package infra
import (
"fmt"
"os/exec"
"strconv"
)
// DockerContainerLogs obtiene los logs de un contenedor. tail limita las últimas N líneas (0 = todas).
func DockerContainerLogs(nameOrID string, tail int) (string, error) {
args := []string{"logs"}
if tail > 0 {
args = append(args, "--tail", strconv.Itoa(tail))
}
args = append(args, nameOrID)
out, err := exec.Command("docker", args...).CombinedOutput()
if err != nil {
return "", fmt.Errorf("docker logs %s: %w", nameOrID, err)
}
return string(out), nil
}
+32
View File
@@ -0,0 +1,32 @@
---
name: docker_container_logs
kind: function
lang: go
domain: infra
version: "1.0.0"
purity: impure
signature: "func DockerContainerLogs(nameOrID string, tail int) (string, error)"
description: "Obtiene los logs de un contenedor Docker. El parámetro tail limita a las últimas N líneas (0 devuelve todos los logs)."
tags: [docker, container, logs, infra]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: "error_go_core"
imports: [fmt, os/exec, strconv]
tested: false
tests: []
test_file_path: ""
file_path: "functions/infra/docker_container_logs.go"
---
## Ejemplo
```go
// Últimas 100 líneas
logs, err := DockerContainerLogs("my-app", 100)
if err != nil {
log.Fatal(err)
}
fmt.Println(logs)
```
@@ -0,0 +1,26 @@
package infra
import (
"encoding/json"
"fmt"
"os/exec"
)
// DockerInspectContainer devuelve los detalles completos de un contenedor como JSON genérico.
func DockerInspectContainer(nameOrID string) (map[string]any, error) {
out, err := exec.Command("docker", "inspect", nameOrID).Output()
if err != nil {
return nil, fmt.Errorf("docker inspect %s: %w", nameOrID, err)
}
var result []map[string]any
if err := json.Unmarshal(out, &result); err != nil {
return nil, fmt.Errorf("parsing inspect output: %w", err)
}
if len(result) == 0 {
return nil, fmt.Errorf("container %s not found", nameOrID)
}
return result[0], nil
}
@@ -0,0 +1,35 @@
---
name: docker_inspect_container
kind: function
lang: go
domain: infra
version: "1.0.0"
purity: impure
signature: "func DockerInspectContainer(nameOrID string) (map[string]any, error)"
description: "Devuelve los detalles completos de un contenedor Docker como mapa JSON genérico. Útil para inspeccionar configuración, red, volumes, etc."
tags: [docker, container, inspect, infra]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: "error_go_core"
imports: [encoding/json, fmt, os/exec]
tested: false
tests: []
test_file_path: ""
file_path: "functions/infra/docker_inspect_container.go"
---
## Ejemplo
```go
info, err := DockerInspectContainer("my-app")
if err != nil {
log.Fatal(err)
}
fmt.Println(info["State"])
```
## Notas
Devuelve `map[string]any` en vez de un struct tipado para maximizar flexibilidad. El caller puede navegar el JSON libremente.
+104
View File
@@ -0,0 +1,104 @@
package infra
import (
"encoding/json"
"fmt"
"os/exec"
)
// DockerListContainers lista contenedores Docker. Si all es true, incluye los detenidos.
func DockerListContainers(all bool) ([]ContainerInfo, error) {
args := []string{"ps", "--format", "{{json .}}", "--no-trunc"}
if all {
args = append(args, "-a")
}
out, err := exec.Command("docker", args...).Output()
if err != nil {
return nil, fmt.Errorf("docker ps: %w", err)
}
if len(out) == 0 {
return nil, nil
}
var containers []ContainerInfo
for _, line := range splitLines(out) {
if len(line) == 0 {
continue
}
var raw struct {
ID string `json:"ID"`
Names string `json:"Names"`
Image string `json:"Image"`
Status string `json:"Status"`
State string `json:"State"`
Ports string `json:"Ports"`
Created string `json:"CreatedAt"`
Labels string `json:"Labels"`
}
if err := json.Unmarshal(line, &raw); err != nil {
continue
}
containers = append(containers, ContainerInfo{
ID: raw.ID[:12],
Name: raw.Names,
Image: raw.Image,
Status: raw.Status,
State: raw.State,
Ports: raw.Ports,
Created: raw.Created,
Labels: parseLabels(raw.Labels),
})
}
return containers, nil
}
// splitLines divide bytes en líneas individuales.
func splitLines(data []byte) [][]byte {
var lines [][]byte
start := 0
for i, b := range data {
if b == '\n' {
lines = append(lines, data[start:i])
start = i + 1
}
}
if start < len(data) {
lines = append(lines, data[start:])
}
return lines
}
// parseLabels convierte "key=val,key2=val2" en map.
func parseLabels(s string) map[string]string {
m := make(map[string]string)
if s == "" {
return m
}
for _, part := range splitByComma(s) {
for i := 0; i < len(part); i++ {
if part[i] == '=' {
m[part[:i]] = part[i+1:]
break
}
}
}
return m
}
func splitByComma(s string) []string {
var parts []string
start := 0
for i := 0; i < len(s); i++ {
if s[i] == ',' {
parts = append(parts, s[start:i])
start = i + 1
}
}
if start < len(s) {
parts = append(parts, s[start:])
}
return parts
}
+37
View File
@@ -0,0 +1,37 @@
---
name: docker_list_containers
kind: function
lang: go
domain: infra
version: "1.0.0"
purity: impure
signature: "func DockerListContainers(all bool) ([]ContainerInfo, error)"
description: "Lista contenedores Docker locales. Si all es true incluye contenedores detenidos. Parsea la salida JSON de docker ps."
tags: [docker, container, list, infra]
uses_functions: []
uses_types: [container_info_go_infra]
returns: [container_info_go_infra]
returns_optional: false
error_type: "error_go_core"
imports: [encoding/json, fmt, os/exec]
tested: false
tests: []
test_file_path: ""
file_path: "functions/infra/docker_list_containers.go"
---
## Ejemplo
```go
containers, err := DockerListContainers(true)
if err != nil {
log.Fatal(err)
}
for _, c := range containers {
fmt.Printf("%s %s %s\n", c.ID, c.Name, c.Status)
}
```
## Notas
Usa `docker ps --format '{{json .}}'` para parsear la salida de forma confiable. Incluye helpers internos `splitLines` y `parseLabels`.
+45
View File
@@ -0,0 +1,45 @@
package infra
import (
"encoding/json"
"fmt"
"os/exec"
)
// DockerListImages lista las imágenes Docker locales.
func DockerListImages() ([]ImageInfo, error) {
out, err := exec.Command("docker", "images", "--format", "{{json .}}", "--no-trunc").Output()
if err != nil {
return nil, fmt.Errorf("docker images: %w", err)
}
if len(out) == 0 {
return nil, nil
}
var images []ImageInfo
for _, line := range splitLines(out) {
if len(line) == 0 {
continue
}
var raw struct {
ID string `json:"ID"`
Repository string `json:"Repository"`
Tag string `json:"Tag"`
Size string `json:"Size"`
Created string `json:"CreatedAt"`
}
if err := json.Unmarshal(line, &raw); err != nil {
continue
}
images = append(images, ImageInfo{
ID: raw.ID,
Repository: raw.Repository,
Tag: raw.Tag,
Size: raw.Size,
Created: raw.Created,
})
}
return images, nil
}
+33
View File
@@ -0,0 +1,33 @@
---
name: docker_list_images
kind: function
lang: go
domain: infra
version: "1.0.0"
purity: impure
signature: "func DockerListImages() ([]ImageInfo, error)"
description: "Lista las imágenes Docker disponibles localmente. Parsea la salida JSON de docker images."
tags: [docker, image, list, infra]
uses_functions: []
uses_types: [image_info_go_infra]
returns: [image_info_go_infra]
returns_optional: false
error_type: "error_go_core"
imports: [encoding/json, fmt, os/exec]
tested: false
tests: []
test_file_path: ""
file_path: "functions/infra/docker_list_images.go"
---
## Ejemplo
```go
images, err := DockerListImages()
if err != nil {
log.Fatal(err)
}
for _, img := range images {
fmt.Printf("%s:%s (%s)\n", img.Repository, img.Tag, img.Size)
}
```
+16
View File
@@ -0,0 +1,16 @@
package infra
import (
"fmt"
"os/exec"
"strings"
)
// DockerPullImage descarga una imagen Docker del registry remoto.
func DockerPullImage(image string) error {
out, err := exec.Command("docker", "pull", image).CombinedOutput()
if err != nil {
return fmt.Errorf("docker pull %s: %s", image, strings.TrimSpace(string(out)))
}
return nil
}
+30
View File
@@ -0,0 +1,30 @@
---
name: docker_pull_image
kind: function
lang: go
domain: infra
version: "1.0.0"
purity: impure
signature: "func DockerPullImage(image string) error"
description: "Descarga una imagen Docker desde el registry remoto (Docker Hub u otro configurado). Acepta formato image:tag."
tags: [docker, image, pull, infra]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: "error_go_core"
imports: [fmt, os/exec, strings]
tested: false
tests: []
test_file_path: ""
file_path: "functions/infra/docker_pull_image.go"
---
## Ejemplo
```go
err := DockerPullImage("nginx:latest")
if err != nil {
log.Fatal(err)
}
```
@@ -0,0 +1,22 @@
package infra
import (
"fmt"
"os/exec"
"strings"
)
// DockerRemoveContainer elimina un contenedor Docker. Si force es true, fuerza la eliminación de contenedores en ejecución.
func DockerRemoveContainer(nameOrID string, force bool) error {
args := []string{"rm"}
if force {
args = append(args, "-f")
}
args = append(args, nameOrID)
out, err := exec.Command("docker", args...).CombinedOutput()
if err != nil {
return fmt.Errorf("docker rm %s: %s", nameOrID, strings.TrimSpace(string(out)))
}
return nil
}
@@ -0,0 +1,31 @@
---
name: docker_remove_container
kind: function
lang: go
domain: infra
version: "1.0.0"
purity: impure
signature: "func DockerRemoveContainer(nameOrID string, force bool) error"
description: "Elimina un contenedor Docker. Con force=true puede eliminar contenedores en ejecución (equivale a docker rm -f)."
tags: [docker, container, remove, infra]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: "error_go_core"
imports: [fmt, os/exec, strings]
tested: false
tests: []
test_file_path: ""
file_path: "functions/infra/docker_remove_container.go"
---
## Ejemplo
```go
// Eliminar contenedor detenido
err := DockerRemoveContainer("old-app", false)
// Forzar eliminación
err = DockerRemoveContainer("stuck-app", true)
```
+22
View File
@@ -0,0 +1,22 @@
package infra
import (
"fmt"
"os/exec"
"strings"
)
// DockerRemoveImage elimina una imagen Docker local. Si force es true, fuerza la eliminación.
func DockerRemoveImage(image string, force bool) error {
args := []string{"rmi"}
if force {
args = append(args, "-f")
}
args = append(args, image)
out, err := exec.Command("docker", args...).CombinedOutput()
if err != nil {
return fmt.Errorf("docker rmi %s: %s", image, strings.TrimSpace(string(out)))
}
return nil
}
+30
View File
@@ -0,0 +1,30 @@
---
name: docker_remove_image
kind: function
lang: go
domain: infra
version: "1.0.0"
purity: impure
signature: "func DockerRemoveImage(image string, force bool) error"
description: "Elimina una imagen Docker local. Con force=true fuerza la eliminación incluso si hay contenedores que la usan."
tags: [docker, image, remove, infra]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: "error_go_core"
imports: [fmt, os/exec, strings]
tested: false
tests: []
test_file_path: ""
file_path: "functions/infra/docker_remove_image.go"
---
## Ejemplo
```go
err := DockerRemoveImage("nginx:latest", false)
if err != nil {
log.Fatal(err)
}
```
+55
View File
@@ -0,0 +1,55 @@
package infra
import (
"fmt"
"os/exec"
"strings"
)
// DockerRunOpts opciones para ejecutar un contenedor Docker.
type DockerRunOpts struct {
Name string // Nombre del contenedor (opcional)
Ports []string // Mapeo de puertos, ej: ["8080:80", "443:443"]
Env map[string]string // Variables de entorno
Volumes []string // Bind mounts, ej: ["/host/path:/container/path"]
Detach bool // Ejecutar en background
Remove bool // Eliminar al terminar (--rm)
Network string // Red Docker (opcional)
}
// DockerRunContainer ejecuta un contenedor Docker nuevo con la imagen y opciones dadas.
// Devuelve el ID del contenedor creado.
func DockerRunContainer(image string, opts DockerRunOpts) (string, error) {
args := []string{"run"}
if opts.Detach {
args = append(args, "-d")
}
if opts.Remove {
args = append(args, "--rm")
}
if opts.Name != "" {
args = append(args, "--name", opts.Name)
}
if opts.Network != "" {
args = append(args, "--network", opts.Network)
}
for _, p := range opts.Ports {
args = append(args, "-p", p)
}
for k, v := range opts.Env {
args = append(args, "-e", k+"="+v)
}
for _, vol := range opts.Volumes {
args = append(args, "-v", vol)
}
args = append(args, image)
out, err := exec.Command("docker", args...).CombinedOutput()
if err != nil {
return "", fmt.Errorf("docker run %s: %s", image, strings.TrimSpace(string(out)))
}
return strings.TrimSpace(string(out)), nil
}
+40
View File
@@ -0,0 +1,40 @@
---
name: docker_run_container
kind: function
lang: go
domain: infra
version: "1.0.0"
purity: impure
signature: "func DockerRunContainer(image string, opts DockerRunOpts) (string, error)"
description: "Ejecuta un contenedor Docker nuevo a partir de una imagen. Soporta puertos, env vars, volumes, network, detach y auto-remove. Devuelve el ID del contenedor."
tags: [docker, container, run, infra]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: "error_go_core"
imports: [fmt, os/exec, strings]
tested: false
tests: []
test_file_path: ""
file_path: "functions/infra/docker_run_container.go"
---
## Ejemplo
```go
id, err := DockerRunContainer("nginx:latest", DockerRunOpts{
Name: "web-server",
Ports: []string{"8080:80"},
Env: map[string]string{"NGINX_HOST": "localhost"},
Detach: true,
})
if err != nil {
log.Fatal(err)
}
fmt.Println("Container ID:", id)
```
## Notas
`DockerRunOpts` es un struct de opciones definido en el mismo archivo. No se registra como tipo del registry porque es específico de esta función.
+16
View File
@@ -0,0 +1,16 @@
package infra
import (
"fmt"
"os/exec"
"strings"
)
// DockerStartContainer inicia un contenedor existente por nombre o ID.
func DockerStartContainer(nameOrID string) error {
out, err := exec.Command("docker", "start", nameOrID).CombinedOutput()
if err != nil {
return fmt.Errorf("docker start %s: %s", nameOrID, strings.TrimSpace(string(out)))
}
return nil
}
+30
View File
@@ -0,0 +1,30 @@
---
name: docker_start_container
kind: function
lang: go
domain: infra
version: "1.0.0"
purity: impure
signature: "func DockerStartContainer(nameOrID string) error"
description: "Inicia un contenedor Docker existente que está detenido. Recibe nombre o ID del contenedor."
tags: [docker, container, start, infra]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: "error_go_core"
imports: [fmt, os/exec, strings]
tested: false
tests: []
test_file_path: ""
file_path: "functions/infra/docker_start_container.go"
---
## Ejemplo
```go
err := DockerStartContainer("my-app")
if err != nil {
log.Fatal(err)
}
```
+23
View File
@@ -0,0 +1,23 @@
package infra
import (
"fmt"
"os/exec"
"strconv"
"strings"
)
// DockerStopContainer detiene un contenedor Docker. timeoutSecs indica el tiempo de gracia antes de SIGKILL.
func DockerStopContainer(nameOrID string, timeoutSecs int) error {
args := []string{"stop"}
if timeoutSecs > 0 {
args = append(args, "-t", strconv.Itoa(timeoutSecs))
}
args = append(args, nameOrID)
out, err := exec.Command("docker", args...).CombinedOutput()
if err != nil {
return fmt.Errorf("docker stop %s: %s", nameOrID, strings.TrimSpace(string(out)))
}
return nil
}
+30
View File
@@ -0,0 +1,30 @@
---
name: docker_stop_container
kind: function
lang: go
domain: infra
version: "1.0.0"
purity: impure
signature: "func DockerStopContainer(nameOrID string, timeoutSecs int) error"
description: "Detiene un contenedor Docker en ejecución. timeoutSecs controla el tiempo de gracia antes de SIGKILL (0 usa el default de Docker)."
tags: [docker, container, stop, infra]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: "error_go_core"
imports: [fmt, os/exec, strconv, strings]
tested: false
tests: []
test_file_path: ""
file_path: "functions/infra/docker_stop_container.go"
---
## Ejemplo
```go
err := DockerStopContainer("my-app", 10)
if err != nil {
log.Fatal(err)
}
```
+22
View File
@@ -0,0 +1,22 @@
package infra
// ContainerInfo representa la información básica de un contenedor Docker.
type ContainerInfo struct {
ID string
Name string
Image string
Status string
State string
Ports string
Created string
Labels map[string]string
}
// ImageInfo representa la información básica de una imagen Docker local.
type ImageInfo struct {
ID string
Repository string
Tag string
Size string
Created string
}
+9
View File
@@ -0,0 +1,9 @@
package shell
// Implementation: github.com/lucasdataproyects/devfactory/shell
// Run ejecuta un comando del sistema con timeout de 30 segundos y devuelve el resultado.
func Run(name string, args ...string) Result[CmdResult] {
// stub — implementation in devfactory/shell
return Result[CmdResult]{}
}
+31
View File
@@ -0,0 +1,31 @@
---
name: run_cmd
kind: function
lang: go
domain: shell
version: "1.0.0"
purity: impure
signature: "func Run(name string, args ...string) core.Result[CmdResult]"
description: "Ejecuta un comando del sistema con timeout de 30 segundos y devuelve el resultado."
tags: [shell, command, process, exec]
uses_functions: []
uses_types: [cmd_result_go_shell, result_go_core]
returns: [result_go_core]
returns_optional: false
error_type: "error_go_core"
imports: []
tested: false
tests: []
test_file_path: ""
file_path: "functions/shell/run_cmd.go"
---
## Ejemplo
```go
result := Run("ls", "-la")
```
## Notas
Implementacion en devfactory/shell.
+11
View File
@@ -0,0 +1,11 @@
package shell
import "time"
// Implementation: github.com/lucasdataproyects/devfactory/shell
// RunWithTimeout ejecuta un comando del sistema con timeout configurable.
func RunWithTimeout(name string, timeout time.Duration, args ...string) Result[CmdResult] {
// stub — implementation in devfactory/shell
return Result[CmdResult]{}
}
+31
View File
@@ -0,0 +1,31 @@
---
name: run_cmd_timeout
kind: function
lang: go
domain: shell
version: "1.0.0"
purity: impure
signature: "func RunWithTimeout(name string, timeout time.Duration, args ...string) core.Result[CmdResult]"
description: "Ejecuta un comando del sistema con timeout configurable."
tags: [shell, command, process, exec, timeout]
uses_functions: []
uses_types: [cmd_result_go_shell, result_go_core]
returns: [result_go_core]
returns_optional: false
error_type: "error_go_core"
imports: [time]
tested: false
tests: []
test_file_path: ""
file_path: "functions/shell/run_cmd_timeout.go"
---
## Ejemplo
```go
result := RunWithTimeout("curl", 5*time.Second, "https://example.com")
```
## Notas
Implementacion en devfactory/shell.
+9
View File
@@ -0,0 +1,9 @@
package shell
// Implementation: github.com/lucasdataproyects/devfactory/shell
// RunPipe encadena multiples comandos con pipe y devuelve el resultado final.
func RunPipe(commands ...string) Result[CmdResult] {
// stub — implementation in devfactory/shell
return Result[CmdResult]{}
}
+31
View File
@@ -0,0 +1,31 @@
---
name: run_pipe
kind: function
lang: go
domain: shell
version: "1.0.0"
purity: impure
signature: "func RunPipe(commands ...string) core.Result[CmdResult]"
description: "Encadena multiples comandos con pipe y devuelve el resultado final."
tags: [shell, command, process, pipe]
uses_functions: []
uses_types: [cmd_result_go_shell, result_go_core]
returns: [result_go_core]
returns_optional: false
error_type: "error_go_core"
imports: []
tested: false
tests: []
test_file_path: ""
file_path: "functions/shell/run_pipe.go"
---
## Ejemplo
```go
result := RunPipe("ls -la", "grep go", "wc -l")
```
## Notas
Implementacion en devfactory/shell.
+9
View File
@@ -0,0 +1,9 @@
package shell
// Implementation: github.com/lucasdataproyects/devfactory/shell
// RunShell ejecuta un comando shell interpretado por /bin/sh.
func RunShell(command string) Result[CmdResult] {
// stub — implementation in devfactory/shell
return Result[CmdResult]{}
}
+31
View File
@@ -0,0 +1,31 @@
---
name: run_shell
kind: function
lang: go
domain: shell
version: "1.0.0"
purity: impure
signature: "func RunShell(command string) core.Result[CmdResult]"
description: "Ejecuta un comando shell interpretado por /bin/sh."
tags: [shell, command, process, exec]
uses_functions: []
uses_types: [cmd_result_go_shell, result_go_core]
returns: [result_go_core]
returns_optional: false
error_type: "error_go_core"
imports: []
tested: false
tests: []
test_file_path: ""
file_path: "functions/shell/run_shell.go"
---
## Ejemplo
```go
result := RunShell("ls -la | grep go")
```
## Notas
Implementacion en devfactory/shell.
+11
View File
@@ -0,0 +1,11 @@
package shell
import "time"
// Implementation: github.com/lucasdataproyects/devfactory/shell
// RunShellTimeout ejecuta un comando shell con timeout configurable.
func RunShellTimeout(command string, timeout time.Duration) Result[CmdResult] {
// stub — implementation in devfactory/shell
return Result[CmdResult]{}
}
+31
View File
@@ -0,0 +1,31 @@
---
name: run_shell_timeout
kind: function
lang: go
domain: shell
version: "1.0.0"
purity: impure
signature: "func RunShellTimeout(command string, timeout time.Duration) core.Result[CmdResult]"
description: "Ejecuta un comando shell con timeout configurable."
tags: [shell, command, process, exec, timeout]
uses_functions: []
uses_types: [cmd_result_go_shell, result_go_core]
returns: [result_go_core]
returns_optional: false
error_type: "error_go_core"
imports: [time]
tested: false
tests: []
test_file_path: ""
file_path: "functions/shell/run_shell_timeout.go"
---
## Ejemplo
```go
result := RunShellTimeout("long-running-cmd", 30*time.Second)
```
## Notas
Implementacion en devfactory/shell.
+9
View File
@@ -0,0 +1,9 @@
package shell
// Implementation: github.com/lucasdataproyects/devfactory/shell
// Which busca la ruta de un ejecutable en el PATH del sistema. Devuelve None si no existe.
func Which(name string) Option[string] {
// stub — implementation in devfactory/shell
return Option[string]{}
}
+31
View File
@@ -0,0 +1,31 @@
---
name: which
kind: function
lang: go
domain: shell
version: "1.0.0"
purity: pure
signature: "func Which(name string) core.Option[string]"
description: "Busca la ruta de un ejecutable en el PATH del sistema. Devuelve None si no existe."
tags: [shell, path, lookup]
uses_functions: []
uses_types: [option_go_core]
returns: [option_go_core]
returns_optional: false
error_type: ""
imports: []
tested: false
tests: []
test_file_path: ""
file_path: "functions/shell/which.go"
---
## Ejemplo
```go
path := Which("docker")
```
## Notas
Implementacion en devfactory/shell.
+8
View File
@@ -0,0 +1,8 @@
package tui
// Implementation: github.com/lucasdataproyects/devfactory/tui
// ClearScreen devuelve el codigo de escape ANSI para limpiar la pantalla del terminal.
func ClearScreen() string {
return "\033[2J\033[H"
}
+32
View File
@@ -0,0 +1,32 @@
---
name: clear_screen
kind: function
lang: go
domain: tui
version: "1.0.0"
purity: pure
signature: "func ClearScreen() string"
description: "Devuelve el codigo de escape ANSI para limpiar la pantalla del terminal."
tags: [tui, ansi, terminal, screen]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: []
tested: false
tests: []
test_file_path: ""
file_path: "functions/tui/clear_screen.go"
---
## Ejemplo
```go
fmt.Print(ClearScreen())
// Limpia toda la pantalla y mueve el cursor a la posicion inicial
```
## Notas
Combina ESC[2J (borrar pantalla completa) con ESC[H (mover cursor a home). No tiene side effects: solo devuelve el string ANSI.
+9
View File
@@ -0,0 +1,9 @@
package tui
// Implementation: github.com/lucasdataproyects/devfactory/tui
// Confirm muestra un dialogo de confirmacion Si/No en terminal y devuelve la eleccion del usuario.
func Confirm(prompt string) Result[bool] {
// stub — implementation in devfactory/tui
return Result[bool]{Value: false}
}
+37
View File
@@ -0,0 +1,37 @@
---
name: confirm_prompt
kind: function
lang: go
domain: tui
version: "1.0.0"
purity: impure
signature: "func Confirm(prompt string) core.Result[bool]"
description: "Muestra un dialogo de confirmacion Si/No en terminal y devuelve la eleccion del usuario."
tags: [tui, confirm, prompt, interactive]
uses_functions: []
uses_types: [result_go_core]
returns: [result_go_core]
returns_optional: false
error_type: "error_go_core"
imports: []
tested: false
tests: []
test_file_path: ""
file_path: "functions/tui/confirm_prompt.go"
---
## Ejemplo
```go
result := tui.Confirm("¿Deseas continuar?")
if result.IsErr() {
log.Fatal(result.Error())
}
if result.Unwrap() {
fmt.Println("Confirmado")
}
```
## Notas
Implementacion real en github.com/lucasdataproyects/devfactory/tui. Este stub existe para documentar la firma y mantener el registry.
+9
View File
@@ -0,0 +1,9 @@
package tui
// Implementation: github.com/lucasdataproyects/devfactory/tui
// DarkStyles crea estilos oscuros usando el tema dark.
func DarkStyles() Styles {
// stub — implementation in devfactory/tui
return Styles{}
}
+32
View File
@@ -0,0 +1,32 @@
---
name: dark_styles
kind: function
lang: go
domain: tui
version: "1.0.0"
purity: pure
signature: "func DarkStyles() Styles"
description: "Construye estilos oscuros combinando DarkTheme con NewStyles. Atajo conveniente para terminales con fondo negro."
tags: [tui, styles, dark, constructor]
uses_functions: []
uses_types: []
returns: [styles_go_tui]
returns_optional: false
error_type: ""
imports: []
tested: false
tests: []
test_file_path: ""
file_path: "functions/tui/dark_styles.go"
---
## Ejemplo
```go
styles := DarkStyles()
model := NewProgressWithStyles(100.0, "Compilando", styles)
```
## Notas
Equivalente a NewStyles(DarkTheme()). Usa esta funcion para aplicaciones TUI en terminales oscuras.
+9
View File
@@ -0,0 +1,9 @@
package tui
// Implementation: github.com/lucasdataproyects/devfactory/tui
// DarkTheme crea un tema de colores oscuro.
func DarkTheme() Theme {
// stub — implementation in devfactory/tui
return Theme{}
}
+32
View File
@@ -0,0 +1,32 @@
---
name: dark_theme
kind: function
lang: go
domain: tui
version: "1.0.0"
purity: pure
signature: "func DarkTheme() Theme"
description: "Construye un tema de colores oscuro para componentes TUI. Paleta optimizada para terminales con fondo negro."
tags: [tui, theme, colors, dark, constructor]
uses_functions: []
uses_types: []
returns: [theme_go_tui]
returns_optional: false
error_type: ""
imports: []
tested: false
tests: []
test_file_path: ""
file_path: "functions/tui/dark_theme.go"
---
## Ejemplo
```go
theme := DarkTheme()
styles := NewStyles(theme)
```
## Notas
Alternativa oscura al DefaultTheme. Colores de alto contraste para fondos negros.
+9
View File
@@ -0,0 +1,9 @@
package tui
// Implementation: github.com/lucasdataproyects/devfactory/tui
// DefaultStyles crea estilos por defecto usando el tema base.
func DefaultStyles() Styles {
// stub — implementation in devfactory/tui
return Styles{}
}
+32
View File
@@ -0,0 +1,32 @@
---
name: default_styles
kind: function
lang: go
domain: tui
version: "1.0.0"
purity: pure
signature: "func DefaultStyles() Styles"
description: "Construye estilos por defecto combinando DefaultTheme con NewStyles. Atajo conveniente para el caso comun."
tags: [tui, styles, constructor]
uses_functions: []
uses_types: []
returns: [styles_go_tui]
returns_optional: false
error_type: ""
imports: []
tested: false
tests: []
test_file_path: ""
file_path: "functions/tui/default_styles.go"
---
## Ejemplo
```go
styles := DefaultStyles()
model := NewSpinnerWithStyle("Cargando...", styles)
```
## Notas
Equivalente a NewStyles(DefaultTheme()). Usa esta funcion cuando no necesitas personalizar el tema.
+9
View File
@@ -0,0 +1,9 @@
package tui
// Implementation: github.com/lucasdataproyects/devfactory/tui
// DefaultTheme crea el tema de colores por defecto.
func DefaultTheme() Theme {
// stub — implementation in devfactory/tui
return Theme{}
}
+32
View File
@@ -0,0 +1,32 @@
---
name: default_theme
kind: function
lang: go
domain: tui
version: "1.0.0"
purity: pure
signature: "func DefaultTheme() Theme"
description: "Construye el tema de colores por defecto para componentes TUI. Paleta clara optimizada para terminales con fondo blanco."
tags: [tui, theme, colors, constructor]
uses_functions: []
uses_types: []
returns: [theme_go_tui]
returns_optional: false
error_type: ""
imports: []
tested: false
tests: []
test_file_path: ""
file_path: "functions/tui/default_theme.go"
---
## Ejemplo
```go
theme := DefaultTheme()
styles := NewStyles(theme)
```
## Notas
Tema base del sistema de estilos. Usar DarkTheme para terminales con fondo oscuro.
+8
View File
@@ -0,0 +1,8 @@
package tui
// Implementation: github.com/lucasdataproyects/devfactory/tui
// HideCursor devuelve el codigo de escape ANSI para ocultar el cursor del terminal.
func HideCursor() string {
return "\033[?25l"
}
+32
View File
@@ -0,0 +1,32 @@
---
name: hide_cursor
kind: function
lang: go
domain: tui
version: "1.0.0"
purity: pure
signature: "func HideCursor() string"
description: "Devuelve el codigo de escape ANSI para ocultar el cursor del terminal."
tags: [tui, ansi, terminal, cursor]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: []
tested: false
tests: []
test_file_path: ""
file_path: "functions/tui/hide_cursor.go"
---
## Ejemplo
```go
fmt.Print(HideCursor())
// Oculta el cursor del terminal usando DECTCEM
```
## Notas
Usa la secuencia DECTCEM (ESC[?25l) del estandar VT220. Recordar restaurar el cursor con ShowCursor al finalizar la aplicacion.
+9
View File
@@ -0,0 +1,9 @@
package tui
// Implementation: github.com/lucasdataproyects/devfactory/tui
// NewBaseModel crea un modelo base con configuracion por defecto.
func NewBaseModel() BaseModel {
// stub — implementation in devfactory/tui
return BaseModel{}
}
+31
View File
@@ -0,0 +1,31 @@
---
name: new_base_model
kind: function
lang: go
domain: tui
version: "1.0.0"
purity: pure
signature: "func NewBaseModel() BaseModel"
description: "Construye un modelo base con dimensiones de terminal y estilos por defecto. Sirve como fundacion para componer modelos mas complejos."
tags: [tui, base, constructor]
uses_functions: []
uses_types: []
returns: [base_model_go_tui]
returns_optional: false
error_type: ""
imports: []
tested: false
tests: []
test_file_path: ""
file_path: "functions/tui/new_base_model.go"
---
## Ejemplo
```go
base := NewBaseModel()
```
## Notas
Modelo raiz que encapsula estado comun (dimensiones, estilos, keybindings) compartido por todos los componentes TUI.
+9
View File
@@ -0,0 +1,9 @@
package tui
// Implementation: github.com/lucasdataproyects/devfactory/tui
// NewConfirm crea un modelo de dialogo de confirmacion si/no.
func NewConfirm(prompt string) ConfirmModel {
// stub — implementation in devfactory/tui
return ConfirmModel{}
}
+31
View File
@@ -0,0 +1,31 @@
---
name: new_confirm
kind: function
lang: go
domain: tui
version: "1.0.0"
purity: pure
signature: "func NewConfirm(prompt string) ConfirmModel"
description: "Construye un modelo de dialogo de confirmacion con una pregunta si/no."
tags: [tui, confirm, dialog, constructor]
uses_functions: []
uses_types: []
returns: [confirm_model_go_tui]
returns_optional: false
error_type: ""
imports: []
tested: false
tests: []
test_file_path: ""
file_path: "functions/tui/new_confirm.go"
---
## Ejemplo
```go
model := NewConfirm("Deseas continuar?")
```
## Notas
Dialogo binario si/no. El resultado se obtiene del modelo tras la interaccion del usuario en el loop de Bubble Tea.
+9
View File
@@ -0,0 +1,9 @@
package tui
// Implementation: github.com/lucasdataproyects/devfactory/tui
// NewFilteredList crea un modelo de lista con filtrado por texto.
func NewFilteredList(items []ListItem, placeholder string) FilteredListModel {
// stub — implementation in devfactory/tui
return FilteredListModel{}
}
+35
View File
@@ -0,0 +1,35 @@
---
name: new_filtered_list
kind: function
lang: go
domain: tui
version: "1.0.0"
purity: pure
signature: "func NewFilteredList(items []ListItem, placeholder string) FilteredListModel"
description: "Construye un modelo de lista con campo de busqueda integrado. El placeholder se muestra en el input de filtro cuando esta vacio."
tags: [tui, list, filter, constructor]
uses_functions: []
uses_types: [list_item_go_tui]
returns: [filtered_list_model_go_tui]
returns_optional: false
error_type: ""
imports: []
tested: false
tests: []
test_file_path: ""
file_path: "functions/tui/new_filtered_list.go"
---
## Ejemplo
```go
items := []ListItem{
{Title: "main.go", Description: "Punto de entrada"},
{Title: "server.go", Description: "Servidor HTTP"},
}
model := NewFilteredList(items, "Buscar archivo...")
```
## Notas
Incluye un input de texto que filtra los items en tiempo real por coincidencia parcial.
+9
View File
@@ -0,0 +1,9 @@
package tui
// Implementation: github.com/lucasdataproyects/devfactory/tui
// NewList crea un modelo de lista simple a partir de items.
func NewList(items []ListItem) ListModel {
// stub — implementation in devfactory/tui
return ListModel{}
}
+35
View File
@@ -0,0 +1,35 @@
---
name: new_list
kind: function
lang: go
domain: tui
version: "1.0.0"
purity: pure
signature: "func NewList(items []ListItem) ListModel"
description: "Construye un modelo de lista simple a partir de una coleccion de items. Cada item se renderiza como una fila seleccionable."
tags: [tui, list, constructor]
uses_functions: []
uses_types: [list_item_go_tui]
returns: [list_model_go_tui]
returns_optional: false
error_type: ""
imports: []
tested: false
tests: []
test_file_path: ""
file_path: "functions/tui/new_list.go"
---
## Ejemplo
```go
items := []ListItem{
{Title: "Opcion 1", Description: "Primera opcion"},
{Title: "Opcion 2", Description: "Segunda opcion"},
}
model := NewList(items)
```
## Notas
Constructor puro para listas de seleccion simple. No permite seleccion multiple — usar NewMultiList para eso.
+9
View File
@@ -0,0 +1,9 @@
package tui
// Implementation: github.com/lucasdataproyects/devfactory/tui
// NewMultiList crea un modelo de lista con seleccion multiple.
func NewMultiList(items []ListItem) ListModel {
// stub — implementation in devfactory/tui
return ListModel{}
}
+36
View File
@@ -0,0 +1,36 @@
---
name: new_multi_list
kind: function
lang: go
domain: tui
version: "1.0.0"
purity: pure
signature: "func NewMultiList(items []ListItem) ListModel"
description: "Construye un modelo de lista con seleccion multiple. Permite al usuario marcar varios items antes de confirmar."
tags: [tui, list, multi, constructor]
uses_functions: []
uses_types: [list_item_go_tui]
returns: [list_model_go_tui]
returns_optional: false
error_type: ""
imports: []
tested: false
tests: []
test_file_path: ""
file_path: "functions/tui/new_multi_list.go"
---
## Ejemplo
```go
items := []ListItem{
{Title: "Go", Description: "Lenguaje compilado"},
{Title: "Python", Description: "Lenguaje interpretado"},
{Title: "Rust", Description: "Lenguaje de sistemas"},
}
model := NewMultiList(items)
```
## Notas
Variante de lista que habilita seleccion multiple con toggles por item.

Some files were not shown because too many files have changed in this diff Show More