Communitygithub.com

NovelAI Scripting & TypeScript Skill Guide

Guia completo e referência para Scripts de Usuário do NovelAI, regras de script em TypeScript, referência da API v1, extensões de UI, hooks de geração e configuração de geração de texto. Use ao escrever, depurar, refatorar ou revisar scripts NovelAI, integração com Lorebook, construção de contexto ou código TypeScript do NovelAI.

O que é NovelAI Scripting & TypeScript Skill Guide?

Este skill fornece instruções abrangentes, referências de API, regras de tipagem e diretrizes arquiteturais para desenvolver **Scripts de Usuário do NovelAI** e interagir com o motor de geração de texto do NovelAI. Ele é essencial para desenvolvedores que trabalham com scripts do NovelAI, pois cobre desde as regras críticas de TypeScript para evitar falhas no interpretador Web Worker, até a referência completa de todas as namespaces da `api.v1` (Storage, UI, Document, Hooks, Generation, Lorebook, entre outras). O guia também inclui arquivos de documentação detalhados no diretório `references/`, como o guia de JSX para componentes de UI customizados e as definições oficiais de tipos TypeScript. O skill é útil para qualquer pessoa que precise escrever, depurar, refatorar ou revisar scripts NovelAI, incluindo integração com Lorebook, construção de contexto ou código TypeScript do NovelAI. Ele suporta todos os aspectos do desenvolvimento de scripts, desde a configuração inicial do cabeçalho do script até a implementação de hooks de ciclo de vida, extensões de UI e manipulação de armazenamento persistente. A documentação é compatível com a plataforma NovelAI, especificamente com a interface de script baseada em Web Worker, e inclui exemplos práticos e recomendações para evitar armadilhas comuns, como promessas rejeitadas silenciosamente e a transiência dos scripts.

Funciona com~Claude Code✓Codex CLI~Cursor
npx skills add MidMeantime/nai-scripting-skill

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Guia de Scripting & TypeScript do NovelAI

Este skill fornece instruções abrangentes, referências de API, regras de tipagem e diretrizes arquiteturais para desenvolver Scripts de Usuário do NovelAI e interagir com o motor de geração de texto do NovelAI.


1. Referência Rápida e Arquivos de Documentação

Toda a documentação detalhada e tipos estão localizados no diretório references/:

  • Diretrizes TypeScript — Regras críticas para evitar falhas de tempo de execução no interpretador Web Worker, padrões de tipagem, manipulação de eventos e casting.
  • Documentação Completa da API de Scripting — Referência completa para todas as namespaces api.v1 (Storage, UI, Document, Hooks, Generation, Lorebook, TTS, etc.).
  • Documentação de Geração de Texto — Informações sobre o editor e recursos do site NovelAI (modelos, configurações de contexto, amostradores, interface do lorebook, ATTG, Text Adventure). Raramente necessário para código de script; consulte-o quando um script precisar raciocinar sobre como o editor constrói o contexto ou o que uma configuração significa.
  • Definição de Tipos de Script (.d.ts) — As definições oficiais do TypeScript (de https://novelai.net/scripting/types/script-types.d.ts). Esta é a fonte da verdade para nomes de propriedades e valores permitidos. Quando ela discordar da documentação em prosa, confie nos tipos.
  • Guia JSX + Tipos JSX — Partes de UI jsx baseadas em Preact para visuais personalizados (tabelas, gráficos SVG/canvas, widgets ao vivo): globais (h, render, hooks, createStore), a lista de elementos/atributos permitidos, eventos, canvas e como fazer verificação de tipos. Opt-in apenas: use JSX somente quando o usuário explicitamente pedir. Caso contrário, construa a UI a partir de partes padrão, mesmo para layouts complexos, e no máximo mencione que JSX pode ajudar.
  • Tipos Experimentais — api.v1.editor.block() e api.v1.document.transaction(), controlados pela configuração experimentalScriptingApi do usuário (veja Seção 18 da documentação da API). Não use estes a menos que o usuário diga que os habilitou.
  • Sistema de Componentes de UI — Como construir UI reutilizável e escalável: tokens, predefinições de estilo, fábricas de componentes tipados, campos vinculados ao armazenamento, estratégia de renderização/atualização, diálogos reutilizáveis. Use esta como a estrutura padrão para qualquer script com UI.
  • Exemplo de Cabeçalho e Configuração de Script — O cabeçalho de script /*--- ... ---*/ com cada tipo de opção de configuração (string, string multilinha, número, booleano, seleção).
  • Exemplos oficiais: https://github.com/NovelAI/novelai-script-examples. O cenário Scripting Demo e scripts como Find & Replace, Notes, e Smart Summarizer mostram padrões do mundo real.

2. Arquitetura Central e Ambiente de Execução

  1. Execução Isolada em Web Worker:
    • Scripts são executados dentro de um interpretador JavaScript isolado em um Web Worker.
    • Scripts não podem acessar elementos arbitrários do DOM ou fazer requisições de rede brutas.
    • Todas as interações com o NovelAI ocorrem através da interface assíncrona versionada api.v1.
    • Os globais setTimeout/clearTimeout não estão disponíveis. Use await api.v1.timers.setTimeout(...), api.v1.timers.clearTimeout(...), e api.v1.timers.sleep(ms).
  2. Scripts São Transientes:
    • Scripts podem ser recarregados ou descarregados quando as histórias mudam, quando o modal de Scripts de Usuário fecha, ou quando são ativados/desativados.
    • Nunca armazene estado persistente em variáveis de memória global. Sempre persista o estado usando api.v1.storage.
  3. Rejeições Silenciosas de Promessas:
    • Promessas rejeitadas não tratadas no worker não são exibidas no console ou na interface.
    • Sempre envolva chamadas assíncronas com try/catch ou anexe manipuladores .catch((err) => ...).
  4. Recuperação de Emergência:
    • Se um script causar instabilidade, anexe ?noscript=true à URL do NovelAI para desabilitar a execução do script no carregamento.

3. Diretrizes Críticas de TypeScript para Scripts NovelAI

O interpretador Web Worker requer código TypeScript limpo e estritamente anotado para evitar erros de compilação/tempo de execução:

A. Anotações Explícitas de Parâmetros

Sempre tipifique todos os parâmetros em funções padrão e callbacks de arrow:

// ❌ ERRADO
function processEntry(id, data) { ... }
itens.filter(item => item.active);

// ✅ CORRETO
function processEntry(id: string, data: any): void { ... }
itens.filter((item: any) => item.active);

B. Casting em Iteração de Objetos

Object.entries() e Object.values() devem ser explicitamente convertidos:

// ✅ CORRETO
for (const [key, value] of Object.entries(meuObj) as [string, any][]) { ... }
for (const val of Object.values(meuObj) as any[]) { ... }

C. Verificações de Indefinido em shift de Array

Array.prototype.shift() retorna T | undefined:

// ✅ CORRETO
const item = fila.shift();
if (!item) return;

D. Await Apenas em Contextos Assíncronos

Funções auxiliares e de construção de UI que invocam métodos assíncronos da API devem ser async:

// ✅ CORRETO
async function carregarDadosUsuario(): Promise<void> {
    const temDados = await api.v1.storage.has('userData');
    if (temDados) {
        const dados = await api.v1.storage.get('userData');
    }
}

4. Principais Namespaces da API (api.v1)

Namespace / MétodoPropósito
api.v1.storageArmazenamento chave-valor persistente: get, getOrDefault, set, setIfAbsent, has, remove, list (também storyStorage, historyStorage, tempStorage).
api.v1.hooksRegistrar hooks do ciclo de vida de eventos (onGenerationRequested, onBeforeContextBuild, onContextBuilt, onResponse, onGenerationEnd, onScriptsLoaded, onLorebookEntrySelected, onTextAdventureInput, onHistoryNavigated, onDocumentConvertedToText). Um callback por hook por script; registrar novamente substitui o anterior.
api.v1.uiCriar extensões de UI (scriptPanel, sidebarPanel, lorebookPanel, toolbarButton, contextMenuButton, toolboxOption), modais, janelas, notificações; updateParts() para alterar partes individuais por id.
api.v1.documentLer e editar o documento da história por ID de seção (parágrafo): scan(), sectionIds(), textFromSelection(), append(), appendParagraph(s)(), insertParagraph(s)After(), updateParagraph(s)(), removeParagraph(s)(), além de document.history.
api.v1.editorgenerate(), isBlocked(), selection.get(), e editor.decorations (destaques, marcadores, widgets).
api.v1.memory / systemPrompt / prefillObter ou definir a Memória, o Prompt do Sistema e o Preenchimento da história (definir requer storyEdit).
api.v1.generate()Executar geração de texto direta com parâmetros personalizados e contexto.
api.v1.generateWithStory()Executar geração usando o contexto e as configurações atuais da história.
api.v1.lorebookConsultar, atualizar, criar ou excluir entradas e categorias do Lorebook.
api.v1.anObter ou definir o texto da Nota do Autor.
api.v1.buildContext()Acessar e inspecionar a montagem do contexto antes de ser enviado à IA.
api.v1.configawait api.v1.config.get('nome') lê um valor configurável pelo usuário declarado no cabeçalho do script (veja abaixo).
api.v1.permissionshas() / request() / list(). Solicite documentEdit, storyEdit, lorebookEdit, editorDecorations, clipboardWrite, fileInput, fileDownload (e presetEdit) antes de usar as APIs controladas.

Cabeçalho e Configuração do Script

Todo .naiscript começa com um cabeçalho YAML em um comentário /*--- ... ---*/ (compatibilityVersion: naiscript-1.0, id, name, version, author, description, memoryLimit, opcional config). As entradas config (name, prettyName, type, default, description) aparecem na aba Config do modal de Scripts de Usuário, permitindo que os usuários as alterem sem editar o código. Os tipos são string (opcionalmente multiline: true), number (opcional min/max/decimal), boolean, e select (options: [{ label, value }]; padrão é a primeira opção). Veja script_config_examples.ts. Leia valores em tempo de execução com um fallback:

const abertoAoCriar: boolean = (await api.v1.config.get('open_on_create')) ?? true;

5. Estrutura Padrão de Script

Ao criar um novo script NovelAI, siga esta estrutura:

(async () => {
    try {
        const CHAVE_ARMAZENAMENTO = "meus_dados_script_personalizado";

        // 1. Inicializar estado persistente
        const estado = await api.v1.storage.getOrDefault(CHAVE_ARMAZENAMENTO, { habilitado: true, contador: 0 });
        await api.v1.storage.setIfAbsent(CHAVE_ARMAZENAMENTO, estado);

        // 2. Registrar hooks do ciclo de vida
        // onGenerationRequested é executado antes da construção do contexto; só pode parar a geração ou preparar o estado.
        api.v1.hooks.register('onGenerationRequested', async (params: any) => {
            if (!estado.habilitado) return;
            // Prepare o estado para hooks posteriores aqui, ou retorne { stopGeneration: true } para bloqueá-lo
        });

        // Para modificar o que o modelo vê, use onBeforeContextBuild (memória, lorebook, AN...)
        // ou onContextBuilt (retorne { messages } com o array de mensagens editado).
        api.v1.hooks.register('onContextBuilt', async (params: any) => {
            if (!estado.habilitado || params.dryRun) return;
            return { messages: params.messages };
        });

        // 3. Registrar UI — sempre use update(), NUNCA register()
        api.v1.hooks.register('onScriptsLoaded', async () => {
            await api.v1.ui.update([{
                type: 'sidebarPanel' as const,
                id: 'meu-painel-script',
                name: 'Ferramenta Personalizada',
                content: [
                    { type: 'text' as const, text: `Status: ${estado.habilitado ? 'Ativo' : 'Inativo'}` } as any
                ]
            }]);
        });

    } catch (err: any) {
        api.v1.error("Erro de Inicialização do Script:", err);
    }
})();

6. Estilização, Tokens de Tema e Funções Fábrica

Scripts NovelAI são executados em um Web Worker isolado com nenhum acesso ao DOM. Nunca use document.createElement, document.head, cloneNode, ou qualquer API de navegador que toque na página diretamente. Toda a UI é construída a partir de objetos de Parte de UI declarativos passados para api.v1.ui.update().

Arquitetura padrão para qualquer script com UI: siga NovelAI_UI_Component_System.md. Ele tem uma camada reutilizável e escalável que faz verificação de tipos contra os tipos oficiais:

  1. Namespace e tokens: NS + id(), mapa de tokens de tema COLOR, constantes SPACE/RADIUS
  2. Predefinições de estilo combinadas com sx()
  3. Fábricas de componentes construídas em api.v1.ui.part.* com objetos de opções e variantes
  4. Ligações field() que mantêm prefixos storageKey e APIs de armazenamento sincronizados
  5. Um render(), com updateParts/{{templates}} para pequenas atualizações
  6. Diálogos reutilizáveis confirm()/notify()

Os trechos abaixo são a versão mínima da mesma ideia. Se o usuário pedir JSX, veja NovelAI_JSX_Guide.md. Estilos JSX usam CSS normal e var(--theme-*), não nomes de tokens. Não mude para JSX por iniciativa própria.

Predefinições de Objetos de Estilo

Defina objetos de estilo tipados no topo do seu script e espalhe-os nas partes de UI:

const ESTILO_CARD: Record<string, string> = {
    backgroundColor: 'bg1',      // token de tema
    border: '1px solid bg2',     // token de tema
    borderRadius: '6px',
    padding: '10px',
    margin: '6px 0',
};

const ESTILO_PERIGO: Record<string, string> = {
    ...ESTILO_CARD,
    borderColor: 'warning',
};

// Aplique via spread em uma Parte de UI:
{ type: 'container' as const, style: ESTILO_CARD, content: [...] } as any

Tokens de Tema

Em vez de codificar cores hexadecimais, use strings de token de tema NovelAI diretamente como valores em objetos style. No momento da renderização, cada token é substituído pelo valor do tema ativo do usuário como um valor inline literal (por exemplo, 'bg1' torna-se um código rgb(...)). Estes não são variáveis CSS: não há propriedades personalizadas --theme-* para usar com var(), e CSS personalizado em outro lugar no site não pode referenciá-los. Para valores brutos do tema dentro de um script, use api.v1.theme.get(). (Exceção: de acordo com os tipos oficiais, partes de UI JSX obtêm propriedades personalizadas --theme-* dentro de seu próprio shadow DOM.)

TokenFunção
'bg0'Fundo mais profundo / mais externo
'bg1'Fundo padrão do painel
'bg2'Superfície elevada / borda / fundo do botão
'bg3'Superfície destacada / selecionada
'textHeadings'Títulos de alto contraste e texto de título
'textMain'Texto do corpo padrão
'textDisabled'Texto desabilitado / silenciado
'textPlaceholder'Texto de espaço reservado de entrada
'textHighlight'Cor de pesquisa / destaque
'warning'Estado de aviso / alerta
'textPrompt', 'textUser', 'textAI', 'textEdit'Cores do texto da história
'lowIntensityColor', 'midIntensityColor', 'highIntensityColor'Cores de probabilidade baixa/média/alta (como usadas por probabilidades de token)
'default'Família de fonte do corpo (use em fontFamily)
'headings'Família de fonte de títulos (use em fontFamily)
'code'Família de fonte monoespaçada de código
'field'Família de fonte de campo de formulário/entrada

⚠️ Nota sobre 'primary': NovelAI NÃO tem um token de tema 'primary' ou 'error'. Usar color: 'primary' produz CSS inválido que os navegadores ignoram. Para superfícies ativas/destacadas use 'bg3', para acentos de alto contraste use 'textHeadings', ou forneça strings de cores hex/rgba explícitas (por exemplo, '#90caf9').

Funções Fábrica (Substitui cloneNode / Templates)

Escreva funções fábrica no topo do seu script que retornam objetos de Parte de UI pré-estilizados e pré-configurados. Isso evita repetir objetos de estilo inline em todo o script.

// Fábrica de botão estilizado reutilizável
function criarBotao(
    texto: string,
    aoClicar: () => Promise<void>
    …

[truncado para tradução]

Habilidades Relacionadas