From bun-agent
Migre les 414 .tsx Ink/React de gemini-cli vers le runtime JSX natif de Bun — supprime esbuild/vitest-jsx, configure tsconfig + bunfig, gère les pièges Ink (raw mode TTY, useStdin, alt-screen)
How this skill is triggered — by the user, by Claude, or both
Slash command
/bun-agent:gemini-cli-jsxThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Cible : `tests/targets/gemini-cli/packages/cli/src/**/*.tsx` (414 fichiers Ink + React).
Cible : tests/targets/gemini-cli/packages/cli/src/**/*.tsx (414 fichiers Ink + React).
Bun a un runtime JSX natif (transpileur Zig, pas oxc) qui remplace esbuild/swc/tsc pour le JSX. Ce skill liste les étapes mécaniques + les 4 pièges Ink connus.
n2b build release dispo (cargo build --release -p n2b)--hot stable + Fast Refresh)gemini-cli cloné dans tests/targets/gemini-cli/n2b tests/targets/gemini-cli/packages/cli --report=json \
| jq '.files[].findings[] | select(.rule_id | startswith("api/") or startswith("imports/")) | .rule_id' \
| sort -u
Patterns attendus (Ink-specific) :
import { render, Box, Text, useInput, useStdin } from 'ink'import React, { useState, useEffect, useMemo } from 'react'import Spinner from 'ink-spinner', Gradient from 'ink-gradient', etc.Bun honore compilerOptions.jsx du tsconfig.json racine. Pour Ink/React 19 :
{
"compilerOptions": {
"target": "ESNext",
"module": "Preserve",
"moduleResolution": "bundler",
"jsx": "react-jsx",
"jsxImportSource": "react",
"allowImportingTsExtensions": true,
"verbatimModuleSyntax": true,
"noEmit": true,
"types": ["bun-types"]
}
}
Points clés :
jsx: "react-jsx" → automatic runtime, pas besoin de import React from 'react' dans chaque .tsxjsxImportSource: "react" → Bun importe react/jsx-runtime automatiquementjsxImportSource: "ink" — Ink n'a pas de jsx-runtime, il consomme React tel quelesbuild.config.js et tsconfig.build.json (devenus inutiles)À la racine du monorepo :
[run]
# Hot reload : utile pour `bun --hot ./packages/cli/src/index.ts`
hot = false # défaut, opt-in via CLI
[install]
# gemini-cli a un .npmrc Artifact Registry — on garde
# scopes via NPM_CONFIG_REGISTRY env si besoin
[loader]
# Bun infère .tsx → tsx loader. Pas besoin de configurer.
useStdin + raw modeInk utilise process.stdin.setRawMode(true). Bun supporte mais via Bun.stdin qui ne re-export pas setRawMode. Solution : Ink détecte process.stdin natif → fonctionne. Ne pas remplacer process.stdin par Bun.stdin dans les composants Ink.
// CORRECT — laisser tel quel
import { useStdin } from 'ink';
const { stdin, setRawMode } = useStdin();
// INCORRECT — Bun.stdin n'a pas setRawMode
import { stdin } from 'bun';
enterAltScreenink envoie \x1b[?1049h/\x1b[?1049l directement à process.stdout.write. Bun route ça correctement. Aucune action.
bun --hotBun 1.3+ implémente React Fast Refresh (vu dans upstream/bun/src/bundler/p.zig). Pour Ink, le re-render full-tree est OK car Ink reconstruit son framebuffer. Activer :
bun --hot ./packages/cli/src/index.ts
import.meta.resolve vs require.resolvegemini-cli a quelques require.resolve('@google/gemini-cli-core/...') (rule globals/require-dynamic). Sous ESM Bun :
// Avant
const corePath = require.resolve('@google/gemini-cli-core');
// Après
const corePath = import.meta.resolve('@google/gemini-cli-core');
n2b --aggressive propose le rewrite automatiquement (rule globals/require-dynamic).
cd tests/targets/gemini-cli/packages/cli
bun --hot ./src/gemini.tsx
Si TTY n'est pas alloué (ex. exécution dans un sub-process non-tty), Ink throw Raw mode is not supported. Forcer un PTY :
bun --hot ./src/gemini.tsx </dev/tty
# ou via script-pty si CI
Bundler Bun avec --compile produit un binaire portable :
bun build ./packages/cli/src/gemini.tsx \
--compile --minify --sourcemap \
--target=bun-linux-x64 \
--outfile gemini
Pour cross-compile (mac/windows) : voir le skill gemini-cli-cli (étape "Single-file executable matrix").
# Type-check (Bun n'exécute pas le type-check au runtime)
bun tsc --noEmit
# Lance l'app
./gemini --help
# n2b doit voir 0 finding api/* sur le code post-migration
n2b tests/targets/gemini-cli/packages/cli --report=text | rg -e 'api/|imports/'
jsxFactory: "h" ou autre — Ink consomme React, le factory doit rester react-jsx."type": "module"), garder.docs/bun/runtime/jsx.mdx — runtime natifdocs/bun/bundler/loaders.mdx — règles d'inférence par extensionupstream/bun/src/bundler/p.zig — implémentation Fast Refreshtests/targets/gemini-cli/packages/cli/src/test-utils/render.tsx — exemple Ink réelProvides UI/UX resources: 50+ styles, color palettes, font pairings, guidelines, charts for web/mobile across React, Next.js, Vue, Svelte, Tailwind, React Native, Flutter. Aids planning, building, reviewing interfaces.
Fetches up-to-date documentation from Context7 for libraries and frameworks like React, Next.js, Prisma. Use for setup questions, API references, and code examples.
npx claudepluginhub aphrody-code/rs-bun --plugin bun-agent