CULTIVA IA — Guía de Integración Técnica

Pi Agent Harness Terminal

Guía completa para instalar, configurar y extender Pi en el stack de automatización de CULTIVA IA. Extensiones TypeScript · SDK embedding · Subagentes · MCP

Node.js 20+ 🔑 Anthropic claude-sonnet-4-5 📦 @earendil-works/pi-coding-agent 📅 Junio 2026

Instalación y primera sesión

Pi se instala globalmente via npm. El flag --ignore-scripts evita scripts de lifecycle de dependencias que no son necesarios.

bash
# Instalar Pi globalmente
npm install -g --ignore-scripts @earendil-works/pi-coding-agent

# Autenticar con Anthropic (proveedor principal de CULTIVA)
export ANTHROPIC_API_KEY=sk-ant-...

# Abrir una sesión en un proyecto de cliente
cd /projects/cliente-acme/
pi

# One-shot: resumir el repo pasando archivos explícitamente
pi -p "Resume la arquitectura de este proyecto" @README.md @src/

# Modo JSON para pipelines CI
pi --mode json "Lista todos los archivos TypeScript"

# RPC para integración desde Python/Go
pi --mode rpc --no-session
💡
Modelo por defecto CULTIVA IA Añade --provider anthropic --model claude-sonnet-4-5 o configúralo en ~/.pi/agent/models.json para que todos los proyectos usen el mismo modelo sin flags extra.

Pasos para un desarrollador junior

  1. 1
    Instalar Pi y verificar versión
    npm install -g --ignore-scripts @earendil-works/pi-coding-agentpi --version
  2. 2
    Exportar la API key del vault de equipo
    Añadir al ~/.zshrc: export ANTHROPIC_API_KEY=$(op read "op://CULTIVA/Anthropic/key")
  3. 3
    Crear AGENTS.md global
    Editar ~/.pi/agent/AGENTS.md con contexto de CULTIVA IA y reglas de comportamiento del equipo
  4. 4
    Instalar la extensión cultiva-guard
    Copiar cultiva-guard.ts a ~/.pi/agent/extensions/ y reiniciar Pi
  5. 5
    Instalar paquetes de subagentes y MCP
    pi install npm:pi-subagents + pi install npm:pi-mcp-adapter y verificar con /subagents-doctor

🗺Tabla de decisión: qué referencia leer

Antes de responder o generar código, Pi apunta al documento correcto según la intención del usuario.

Intención del usuario
Referencia
Instalar, autenticar, primera sesión
quickstart.md
Uso diario CLI, comandos, flags, modos
usage.md
Auth de proveedores, API keys, cloud
providers.md
Modelos custom, locales, proxies
models.md
Crear extensiones, tools custom, eventos
extensions.md
Embeber Pi en Node.js / TypeScript
sdk.md
Integrar desde otro proceso / lenguaje
rpc.md
Consumir eventos JSONL en streaming
json.md
Delegar a subagentes, chains, paralelo
pi-subagents.md
Conectar servidores MCP
pi-mcp-adapter.md
Seguridad, sandboxing, trust de proyecto
security.md
Crear skills para Pi
skills.md
Búsqueda web, fetch URLs/PDFs/repos
pi-web-access.md
Componentes TUI custom
tui.md
Sesiones, branching, compaction
sessions.md, compaction.md

🔧Extensión cultiva-guard

Extensión TypeScript para CULTIVA IA que bloquea comandos destructivos, registra sesiones en log de auditoría por cliente, y añade el comando /contexto-cliente.

⚠️
Fichero en: ~/.pi/agent/extensions/cultiva-guard.ts Las extensiones globales cargan en todos los proyectos sin requerir project trust. Las extensiones de proyecto en .pi/extensions/ requieren que el usuario confíe el directorio.
TypeScript
// ~/.pi/agent/extensions/cultiva-guard.ts
// Extensión de seguridad y auditoría para CULTIVA IA
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
import { appendFileSync, mkdirSync } from "node:fs";
import { join } from "node:path";
import { homedir } from "node:os";

/** Patrones de comandos destructivos a confirmar */
const DANGEROUS_PATTERNS = [
  /rm\s+-rf/,
  /DROP\s+(TABLE|DATABASE|SCHEMA)/i,
  /DELETE\s+FROM\s+\w+\s*;/i,   // DELETE sin WHERE
  /git\s+reset\s+--hard/,
  /truncate\s+table/i,
  /format\s+[a-z]:/i,           // Windows format
];

/** Log de auditoría: ~/.cultiva-audit/YYYY-MM-DD.log */
function auditLog(entry: string) {
  const dir = join(homedir(), ".cultiva-audit");
  mkdirSync(dir, { recursive: true });
  const date = new Date().toISOString().slice(0, 10);
  appendFileSync(
    join(dir, `${date}.log`),
    `[${new Date().toISOString()}] ${entry}\n`
  );
}

/** Detectar cliente desde cwd: /projects/<cliente>/... */
function detectCliente(cwd: string): string {
  const match = cwd.match(/\/projects\/([^/]+)/);
  return match?.[1] ?? "unknown";
}

export default function cultivaGuard(pi: ExtensionAPI) {
  // 1. Log de inicio de sesión
  pi.on("session_start", async (_evt, ctx) => {
    const cliente = detectCliente(process.cwd());
    auditLog(`SESSION_START cliente=${cliente} model=${ctx.model?.id ?? "?"}`);
    if (ctx.mode === "tui")
      ctx.ui.notify(`cultiva-guard activo — cliente: ${cliente}`, "info");
  });

  // 2. Bloqueo de comandos destructivos
  pi.on("tool_call", async (event, ctx) => {
    if (event.toolName !== "bash") return;
    const cmd = event.input?.command ?? "";
    const isDangerous = DANGEROUS_PATTERNS.some(p => p.test(cmd));

    if (isDangerous) {
      const cliente = detectCliente(process.cwd());
      auditLog(`DANGEROUS_CMD cliente=${cliente} cmd="${cmd}"`);

      if (ctx.hasUI) {
        const ok = await ctx.ui.confirm(
          "⚠️ Comando destructivo",
          `¿Ejecutar "${cmd.slice(0, 80)}"?\n\nEsto se registrará en el log de auditoría.`
        );
        if (!ok) {
          auditLog(`BLOCKED_CMD cliente=${cliente} cmd="${cmd}"`);
          return { block: true, reason: "Bloqueado por cultiva-guard. Confirma en UI." };
        }
        auditLog(`ALLOWED_CMD cliente=${cliente} cmd="${cmd}"`);
      } else {
        // En modo RPC/JSON sin UI, bloquear por defecto
        return { block: true, reason: "Bloqueado en modo no-interactivo (seguridad CULTIVA)" };
      }
    }
  });

  // 3. Log de tool results para trazabilidad
  pi.on("tool_result", async (event) => {
    if (event.toolName === "write" || event.toolName === "edit") {
      const cliente = detectCliente(process.cwd());
      auditLog(`FILE_WRITE cliente=${cliente} tool=${event.toolName}`);
    }
  });

  // 4. Comando /contexto-cliente
  pi.registerCommand("contexto-cliente", {
    description: "Inyecta el briefing del cliente activo en el contexto de la sesión",
    handler: async (_args, ctx) => {
      const cliente = detectCliente(process.cwd());
      const briefPath = join(process.cwd(), ".pi/cliente-brief.md");
      try {
        const { readFileSync } = await import("node:fs");
        const brief = readFileSync(briefPath, "utf8");
        // Inyectar como mensaje del sistema
        await ctx.session.prompt(`[CONTEXTO CLIENTE: ${cliente}]\n\n${brief}`, {
          source: "system"
        });
        ctx.ui.notify(`Contexto de "${cliente}" inyectado`, "success");
      } catch {
        ctx.ui.notify(`No se encontró .pi/cliente-brief.md en este proyecto`, "error");
      }
    }
  });
}

Flujo de eventos de una extensión

project_trust
session_start
input
before_agent_start
tool_call
tool_result
agent_end
session_shutdown
Evento Cuándo se dispara Uso en cultiva-guard
session_start Al arrancar / cambiar sesión Log de inicio, notificación TUI
tool_call Antes de ejecutar cada tool Bloqueo de comandos destructivos
tool_result Tras ejecutar cada tool Auditoría de escrituras de ficheros
before_agent_start Antes de enviar el prompt al LLM Inyectar system prompt de cliente
context Antes de cada llamada al LLM Añadir mensajes sin destruir historial
session_shutdown Al cerrar Pi Log de fin de sesión

🤖Workflow de subagentes: auditoría de repositorio

El caso de uso más frecuente en CULTIVA: recibir un repo de cliente y generar un plan de mejoras. Usando pi-subagents con el chain: scout → planner → worker → reviewer.

bash
# Instalar paquete de subagentes
pi install npm:pi-subagents

# Verificar setup
/subagents-doctor

# Ejecutar el workflow de auditoría completo
/run-chain auditoria-repo -- "Auditar el repositorio y generar un plan de mejoras priorizado"

# O ejecutar paso a paso
/chain scout "Escanear el codebase: entry points, dependencias, riesgos" \
  -> planner "Crear plan de mejoras priorizado por impacto y esfuerzo" \
  -> worker "Implementar las mejoras quick wins (esfuerzo bajo, impacto alto)" \
  -> reviewer[thinking=high] "Revisar cambios: correctitud, tests, regresiones"

# Revisión paralela (velocidad + cobertura)
/parallel-review

Agentes disponibles en pi-subagents

🔍 scout
Reconocimiento rápido del codebase: entry points, flujo de datos, riesgos. Contexto: fresh.
📋 planner
Plan concreto desde el contexto existente. Contexto: fork (hereda estado padre).
⚙️ worker
Implementación: edita ficheros, valida resultados. Contexto: fork.
🔎 reviewer
Code review y pequeños fixes. Contexto: fresh para máxima objetividad.
🔮 oracle
Segunda opinión que desafía asunciones. Sin ediciones. Ideal para validar decisiones.
🌐 researcher
Investigación web/docs con fuentes y briefing conciso. Requiere pi-web-access.

🔗Chain file: auditoria-repo.chain.md

Guardar en .pi/chains/auditoria-repo.chain.md para reutilizar en cualquier proyecto de cliente.

Markdown
# Auditoría de repositorio CULTIVA IA
## Workflow: scout → planner → worker → reviewer

## scout
phase: Reconocimiento
label: Escanear codebase
as: contexto
output: .pi/contexto-repo.md
outputMode: file-only
model: anthropic/claude-haiku-4-5

Escanea el repositorio completo. Documenta:
- Estructura de directorios y responsabilidades
- Entry points (main, index, server)
- Dependencias críticas y versiones
- Deuda técnica visible (TODOs, FIXMEs)
- Posibles vulnerabilidades de seguridad
- Cobertura de tests

Tarea: {task}

## planner
phase: Planificación
label: Generar plan de mejoras
as: plan
reads: .pi/contexto-repo.md
output: .pi/plan-mejoras.md
model: anthropic/claude-sonnet-4-5
thinking: high

Con el contexto del scout, genera un plan de mejoras priorizado por:
1. Impacto en el negocio del cliente
2. Esfuerzo de implementación (S/M/L)
3. Riesgo de regresión

Clasifica en: Quick Wins (alta prio), Mejoras Estratégicas, Deuda Técnica.

## worker
phase: Implementación
label: Implementar Quick Wins
reads: .pi/plan-mejoras.md
model: anthropic/claude-sonnet-4-5

Implementa solo los Quick Wins del plan (esfuerzo S, impacto alto).
NO modifiques arquitectura central. Crea tests para cada cambio.

## reviewer
phase: Revisión
label: Revisar cambios
model: anthropic/claude-sonnet-4-5
thinking: high

Revisa todos los cambios implementados:
- Correctitud lógica
- Tests añadidos / pasando
- Sin regresiones en funcionalidad existente
- Adherencia al plan original
- Calidad de código (naming, DRY, SOLID básico)
Acceptance gate opcional Añade acceptance.verify con "command": "npm test" al paso worker para validar automáticamente que los tests pasan antes de avanzar al reviewer.

📦Integración SDK Node.js

Para embeber Pi en la plataforma interna de CULTIVA (Node.js) y automatizar workflows desde código.

bash
npm install @earendil-works/pi-coding-agent
TypeScript — Sesión básica
import {
  AuthStorage,
  createAgentSession,
  ModelRegistry,
  SessionManager,
} from "@earendil-works/pi-coding-agent";

async function runAuditoria(projectPath: string) {
  const authStorage = AuthStorage.create();
  const modelRegistry = ModelRegistry.create(authStorage);

  const { session } = await createAgentSession({
    sessionManager: SessionManager.inMemory(),
    authStorage,
    modelRegistry,
    cwd: projectPath,      // contexto del proyecto del cliente
    model: { provider: "anthropic", id: "claude-sonnet-4-5" },
    tools: ["read", "grep", "find", "ls"], // solo lectura por seguridad
  });

  // Suscribirse a los eventos de streaming
  let output = "";
  session.subscribe((event) => {
    if (
      event.type === "message_update" &&
      event.assistantMessageEvent.type === "text_delta"
    ) {
      process.stdout.write(event.assistantMessageEvent.delta);
      output += event.assistantMessageEvent.delta;
    }
  });

  // Lanzar la auditoría
  await session.prompt(
    "Analiza este repositorio y genera un informe de calidad de código en Markdown."
  );

  await session.dispose();
  return output;
}

// Uso desde la plataforma de CULTIVA
const informe = await runAuditoria("/projects/cliente-acme");
console.log(informe);
TypeScript — Runtime con múltiples sesiones
import { createAgentSessionRuntime, SessionManager } from "@earendil-works/pi-coding-agent";

// Usar Runtime cuando necesitas crear/reemplazar sesiones dinámicamente
const runtime = await createAgentSessionRuntime({
  sessionManager: SessionManager.create(),   // persistente en disco
  authStorage,
  modelRegistry,
});

// Sesión 1: Scout del proyecto A
await runtime.newSession({ cwd: "/projects/cliente-a" });
await runtime.session.prompt("Escanea el codebase");

// Fork para planner (hereda contexto del scout)
await runtime.fork();
await runtime.session.prompt("Con el contexto anterior, genera el plan");

// Re-suscribir tras cada fork/switch
runtime.session.subscribe(handleEvent);

SDK vs RPC — cuándo usar cada uno

CriterioSDK (Node.js)RPC (proceso externo)
Lenguaje del clienteNode.js / TypeScriptPython, Go, Ruby, cualquiera
Acceso al estado interno✅ DirectoVia eventos JSONL
Type safety✅ TotalManual / generated
Aislamiento de procesoMismo proceso✅ Proceso separado
Custom tools in-processcustomToolsVia extensiones externas
OverheadMínimoLigero (IPC)

🔌Integración MCP adapter

Pi-MCP-adapter expone un único tool proxy mcp() en vez de registrar miles de tokens de definiciones de herramientas MCP.

bash
pi install npm:pi-mcp-adapter
.pi/mcp.json — Servidores MCP para proyectos CULTIVA
{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": { "GITHUB_TOKEN": "${GITHUB_TOKEN}" },
      "directTools": ["search_repositories", "get_file_contents", "create_issue"],
      "lifecycle": "lazy"
    },
    "postgres": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-postgres"],
      "env": { "POSTGRES_URL": "${DATABASE_URL}" },
      "lifecycle": "eager"
    },
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/projects"],
      "lifecycle": "lazy"
    }
  }
}
💡
Direct tools: balance tokens vs disponibilidad Usa directTools solo para 5-20 herramientas que el modelo invoca frecuentemente (GitHub search, get_file). El resto se descubre via el proxy mcp() bajo demanda, ahorrando 10,000+ tokens por servidor.

🛡Sandboxing para repos de cliente

Pi no tiene sandbox built-in. Para repos de clientes no confiables o automatizaciones desatendidas, usar aislamiento explícito.

bash — Docker para repos de cliente (recomendado)
# Ejecutar Pi en Docker con el repo del cliente montado
docker run --rm -it \
  -v /projects/cliente-acme:/workspace:ro \   # read-only
  -e ANTHROPIC_API_KEY \
  --network none \                             # sin red
  node:20-alpine sh -c \
  "npm install -g @earendil-works/pi-coding-agent && \
   cd /workspace && \
   pi -p 'Analiza este repositorio' --mode json"

# Con red para repos que requieren npm install
docker run --rm -it \
  -v /projects/cliente-acme:/workspace \
  -e ANTHROPIC_API_KEY \
  node:20-alpine sh -c "cd /workspace && pi"
🚫
Reglas de seguridad CULTIVA IA No montar ~/.pi/agent/ en el contenedor de cliente (contiene credenciales). Pasar solo las API keys mínimas necesarias. Revisar siempre los diffs antes de copiar resultados al sistema host.

🔒Gestión de secrets

✅ Correcto

Variable de entorno: export ANTHROPIC_API_KEY=sk-...

Auth storage de Pi: /login → guarda en ~/.pi/agent/auth.json

Vault del equipo: $(op read "op://CULTIVA/...")

🚫 Nunca

No guardar secrets en .pi/settings.json

No hardcodear API keys en extensiones

No incluir .pi/ en el repo del cliente

models.json — Provider con secret lookup
{
  "models": [
    {
      "provider": "anthropic",
      "id": "claude-sonnet-4-5",
      "label": "CULTIVA default",
      "apiKeyCommand": "op read op://CULTIVA/Anthropic/key"
    }
  ]
}

⌨️Comandos frecuentes — Quick reference

sesiónpi -c
sesiónpi -r
sesiónpi --name "tarea"
archivopi @README.md "Resume"
pipelinepi --mode json "prompt"
integraciónpi --mode rpc --no-session
extensionpi -e ./mi-extension.ts
reload/reload
mcp/mcp tools
subagent/run scout
chain/chain scout -> planner -> worker
review/parallel-review
shell!npm run lint
shell (no ctx)!!npm test
extensión/contexto-cliente