# Hooks, plugins, timeline e IA

Extensões e subsistemas adiados do runtime com limites precisos de execução, registro e autoridade.

<span class="section-anchor" id="section-1"></span>

## Middleware de lifecycle

Os hooks recebem `(context, next)`. Chamar `next()` permite continuar; omiti-lo cancela a cadeia. Uma prioridade maior é executada antes. O registro retorna uma função de cancelamento da inscrição que você deve guardar se o middleware tiver um lifecycle mais curto que o shell. A declaração TypeScript de `use` indica `void`; o runtime fornece esse cleanup.

```js
const remove = wu.hooks.use('beforeMount', async (context, next) => {
  console.log('Montando', context.appName);
  await next();
}, { name: 'mount-observer', priority: 10 });

// Después de observar el escenario:
remove();
```

As fases são `beforeInit`, `afterInit`, `beforeLoad`, `afterLoad`, `beforeMount`, `afterMount`, `beforeUpdate`, `afterUpdate`, `beforeUnmount`, `afterUnmount`, `beforeDestroy` e `afterDestroy`. O contexto depende da fase; nem todos os hooks recebem lifecycle, sandbox ou props.

Um middleware que lança um erro antes de `next` cancela por padrão; `failOpen: true` permite continuar diante dessa falha. Os helpers exportados `createSimpleHook`, `createConditionalHook`, `createGuardHook`, `createTransformHook` e `createTimedHook` constroem middleware. O helper timed registra seu erro e chama next: não é adequado como controle que deva fechar o acesso diante de um timeout.

<span id="plugin-con-grants-explícitos"></span>

<span class="section-anchor" id="section-2"></span>

## Plugin com grants explícitos

```js
let stop = () => {};

await wu.pluginSystem.use({
  name: 'catalog-observer',
  permissions: ['events'],
  install(api) {
    stop = api.on('catalog:selected', (event) => {
      console.info('Selección observada', event.data);
    });
  },
  uninstall() { stop(); },
}, { grants: ['events'] });

// Al retirarlo:
await wu.pluginSystem.uninstall('catalog-observer');
```

`use` aceita um objeto ou uma factory, aguarda a instalação e valida as permissões. `ready()` permite aguardar instalações pendentes; `init` já espera essa barreira. O timeout padrão dos hooks de plugins é 5000 ms.

As factories recebem opções, não o core. Os grants do host são copiados antes de chamar a factory para que ela não amplie suas opções e se autorize sozinha. Ainda assim, um plugin é código executado no host: a API filtrada não isola closures nem o acesso global que esse código já tem.

<span id="timeline-y-tiempo-de-carga"></span>

<span class="section-anchor" id="section-3"></span>

## Timeline e tempo de carregamento

```js
await wu.timelineReady();
wu.timeline.record({ snapshotEvery: 64, maxEntries: 5000 });

wu.store.set('demo.counter', 1);
wu.store.set('demo.counter', 2);

await wu.timeline.stepBack();
console.log(wu.store.get('demo.counter'));
await wu.timeline.live();

const recording = await wu.timeline.export();
wu.timeline.stop();
```

`timelineReady()` carrega o chunk antes de começar. Se você chamar `record()` pela primeira vez e gravar imediatamente, a gravação pode ocorrer antes de o registro adiado estar preparado. A facade mantém a intenção de record/stop enquanto o módulo chega; para capturar a próxima gravação sem ambiguidade, use ready primeiro.

O journal registra gravações no store, eventos e lifecycle/props que passam pelo WU. Tem um limite padrão de 5000 entradas e snapshots a cada 64. `seek`, `stepBack`, `stepForward`, `live`, `export`, `import`, `entries` e `status` permitem inspecionar esse registro.

Retroceder rematerializa projeções; não reverte timers internos das apps, solicitações HTTP nem infraestrutura. Quando você está no passado, novas gravações não são adicionadas ao journal, e voltar a live as descarta. Não existe branching do histórico nem auditoria durável implícita.

<span id="ia-optativa"></span>

<span class="section-anchor" id="section-4"></span>

## IA opcional

O import principal instala um proxy lazy. Métodos encadeáveis como `provider`, `action`, `trigger`, `capability` e `workflow` podem enfileirar configurações enquanto o chunk chega; operações de valor exigem aguardar o módulo real. `aiReady()` é a forma explícita de obtê-lo.

```js
const ai = await wu.aiReady();
ai.init({ permissions: { executeActions: true } });

ai.action('sum_local', {
  description: 'Suma dos valores de demostración sin efectos externos',
  parameters: {
    type: 'object',
    properties: {
      a: { type: 'number' },
      b: { type: 'number' },
    },
    required: ['a', 'b'],
  },
  handler: async ({ a, b }) => ({ total: a + b }),
});

const result = await ai.execute('sum_local', { a: 2, b: 3 });
console.log(result);
```

Registrar e executar essa action local não exige enviar dados a um modelo. Para conversação, existem providers, `send`, `stream`, `json`, `agent`, triggers e workflows, com suas próprias permissões e configurações. Não use uma chave privada de serviço em um bundle público.

Actions validam parâmetros, verificam `executeActions`, consultam permissões adicionais/condicionais e podem pedir confirmação. `dangerous: true` exige confirmação no código atual. Os resultados de execução usam um envelope `{ success, result? , reason? }`: uma rejeição de permissões pode ser um resultado negativo, não uma exceção.

Os padrões permitem `readStore` e `emitEvents`; `writeStore`, `readDOM`, `modifyDOM`, `readDiagnostics`, `navigate`, `executeActions`, `network` e `allowDirectKey` começam desativados. São flags do módulo IA, independentes dos grants da app e da autorização do servidor.

<span id="mcp-y-automatización"></span>

<span class="section-anchor" id="section-5"></span>

## MCP e automação

`wu.mcp.connect(url, options)`, `disconnect()` e `isConnected()` expõem a ponte cliente adiada. O pacote também inclui o binário `wu-mcp-server` e seu subpath. A ponte pode inspecionar e alterar o estado e a interface conforme os controles do módulo; não acrescenta, por si só, dry-run vinculante, idempotência, autorização de domínio, rollback ou um registro permanente.

Para um agente que opera recursos reais, use um serviço que receba comandos validados e retorne receipts. O store pode projetar seu progresso; a action não deve se tornar uma closure que exerce privilégios sem revalidação.

<span id="referencia-de-implementación"></span>

<span class="section-anchor" id="section-6"></span>

## Referência de implementação

Hooks: `src/core/wu-hooks.js`; plugins: `src/core/wu-plugin.js`; facade da timeline: `src/index.js`; journal: `src/core/wu-timeline.js`; IA: `src/ai/wu-ai.js`, `src/ai/wu-ai-actions.js`, `src/ai/wu-ai-actions.js`; padrões: `src/ai/wu-ai-permissions.js`; MCP: `src/index.js`. Testes: `tests/unit/plugin-security.test.js`, `tests/unit/timeline-facade.test.js`, `tests/unit/lazy-ai-proxy.test.js`, `tests/unit/ai-actions.test.js`, `tests/unit/mcp-bridge-security.test.js`.