diff --git a/.botvalia/openrouter-model.txt b/.botvalia/openrouter-model.txt new file mode 100644 index 0000000..87d7f40 --- /dev/null +++ b/.botvalia/openrouter-model.txt @@ -0,0 +1 @@ +qwen/qwen3-coder:free \ No newline at end of file diff --git a/.github/workflows/security-preflight.yml b/.github/workflows/security-preflight.yml new file mode 100644 index 0000000..2be4a4c --- /dev/null +++ b/.github/workflows/security-preflight.yml @@ -0,0 +1,33 @@ +name: Security Preflight + +on: + pull_request: + push: + branches: + - main + workflow_dispatch: + +permissions: + contents: read + +jobs: + security-preflight: + runs-on: windows-latest + + steps: + - name: Checkout + uses: actions/checkout@v5 + + - name: Setup Bun + uses: oven-sh/setup-bun@v2 + with: + bun-version: 1.3.12 + + - name: Run OSS security preflight + run: bun run security:preflight + + - name: Install dependencies + run: bun install --frozen-lockfile + + - name: Boot version check + run: bun run version diff --git a/.gitignore b/.gitignore index 4b273a4..5a08499 100644 --- a/.gitignore +++ b/.gitignore @@ -9,10 +9,57 @@ coverage/ .turbo/ *.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* *.tmp *.swp *.swo +*.pid +*.seed .claude/ +.botvalia/ +.agents/ .idea/ -.vscode/ \ No newline at end of file +.vscode/ +skills-lock.json + +# Secrets and local env overrides +.env +.env.* +!.env.example +!.env.sample +!.env.template +!.env.test.example +!.env.test.sample +*.local +*.secret +*.secrets +.npmrc + +# Certificates and private keys +*.pem +*.key +*.p12 +*.pfx +*.crt +*.cer +*.der +*.csr + +# Local session/state artifacts +server-sessions.json +*.session.json +*.sqlite +*.sqlite3 +*.db +*.db-* + +# Generated package/runtime artifacts +*.tgz +BotValia-CodeUI/.next/ +BotValia-CodeUI/.runtime-next/ +BotValia-CodeUI/.swc/ +BotValia-CodeUI/.vercel/ +BotValia-CodeUI/out/ diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..7e9c7f0 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,79 @@ + +> **REGLA OBLIGATORIA PARA CUALQUIER IA** +> +> Ningun agente de IA, incluyendo Codex, ChatGPT, Gemini o similares, puede modificar, mover, borrar, instalar, desinstalar o intervenir archivos del sistema Windows, navegadores, perfiles de navegador, extensiones, complementos, configuraciones del equipo ni otros recursos fuera de este proyecto sin permiso explicito y especifico del usuario. +> +> Si el usuario no lo pide de forma explicita y puntual, se asume prohibido. + +# AGENTS.md + +This file provides guidance to Codex (Codex.ai/code) when working with code in this repository. + +## What This Is + +Reconstructed TypeScript source tree of the Codex CLI, recovered from source maps of the public npm release. Some native modules are replaced with compatible shims in `shims/`. This is **not** the original private upstream development repo. + +## Development Commands + +```bash +bun install # Install dependencies (includes local shim packages) +bun run dev # Start CLI interactively (alias: bun run start) +bun run version # Verify the CLI boots and prints version +``` + +**Requirements:** Bun >= 1.3.5, Node.js >= 24 + +There is no lint, test, or build script. Validation is manual: boot the CLI and exercise the changed path. + +## Boot Sequence + +`src/dev-entry.ts` is the entry point. It scans for missing relative imports across `src/` and `vendor/`. If any are missing, it prints a diagnostic and exits. When all imports resolve, it forwards to `src/entrypoints/cli.tsx` → `src/main.tsx` which runs full initialization (auth, GrowthBook, MCP, settings, Commander.js) and launches the React/Ink REPL. + +## Architecture + +- **`src/main.tsx`** — Full CLI initialization: side-effect imports for startup profiling, MDM reads, and keychain prefetch must stay at the top and in order. +- **`src/query.ts` / `src/QueryEngine.ts`** — Streaming API call loop, tool execution, auto-compaction, session lifecycle, and persistence. +- **`src/commands.ts`** — Slash command registration (`/commit`, `/review`, `/config`, `/compact`, `/memory`, `/plan`, etc.). +- **`src/tools/`** — 53 tool implementations, each in its own directory (e.g., `BashTool/`, `FileEditTool/`, `AgentTool/`). +- **`src/commands/`** — 87 slash command implementations, each in its own directory with an `index.ts` entry. +- **`src/services/`** — Backend services: API client (`api/`), MCP protocol (`mcp/`), session compaction (`compact/`), analytics/feature flags (`analytics/`). +- **`src/components/`** — Terminal UI components built with React + Ink (messages, inputs, diffs, permission dialogs, status bar). +- **`src/hooks/`** — Custom React hooks for tools, voice, IDE integration, vim mode, sessions, tasks. +- **`src/ink/`** — Custom Ink fork handling layout, focus, ANSI rendering, virtual scrolling, and click detection. +- **`src/vim/`** — Full vim keybinding engine (motions, operators, text objects). +- **`src/coordinator/`** — Multi-agent coordination, conditionally loaded via `bun:bundle` feature flag `COORDINATOR_MODE`. +- **`src/assistant/`** — KAIROS assistant mode, conditionally loaded via feature flag `KAIROS`. +- **`src/bridge/`** — Remote bridge control for web/IDE connections. +- **`shims/`** — Compatibility replacements for private native modules (`color-diff-napi`, `modifiers-napi`, `url-handler-napi`, and upstream-private MCP packages). +- **`vendor/`** — Native binding source code (`audio-capture-src`, `image-processor-src`, `modifiers-napi-src`, `url-handler-src`). + +## Code Style + +- TypeScript with ESM imports and `react-jsx`. `strict` mode is off in tsconfig. +- Most files omit semicolons and use single quotes — match surrounding file style exactly. +- `camelCase` for variables/functions, `PascalCase` for React components and classes, `kebab-case` for command directories. +- Import order: when comments warn against reordering, keep imports stable. `main.tsx` side-effect imports at the top are order-sensitive. +- Path alias: `src/*` maps to `./src/*` via tsconfig paths. +- Prefer small, focused modules over broad utility dumps. + +## Testing & Validation + +There is no automated test suite. For any change: + +1. Boot the CLI with `bun run dev`. +2. Smoke-test version output with `bun run version`. +3. Exercise the specific command, service, or UI path you changed. + +When adding tests, place them close to the feature they cover and name them after the module or behavior under test. + +## Commit Style + +Use short, imperative commit subjects (e.g., `Fix MCP config normalization`). In PRs, explain user-visible impact and list validation steps. + +## Key Constraints + +- `dev-entry.ts` gates startup on zero missing imports. Any new module must be resolvable or the CLI won't boot. +- Conditional imports via `bun:bundle` feature flags (`COORDINATOR_MODE`, `KAIROS`) use `require()` to avoid circular dependencies — preserve this pattern. +- Changes to shims should maintain API compatibility with the original native modules they replace. +- This is a reconstructed source tree — prefer minimal, auditable changes. Document any workaround added because a module was restored with fallbacks or shim behavior. + diff --git a/BASE.md b/BASE.md new file mode 100644 index 0000000..6dd7d0e --- /dev/null +++ b/BASE.md @@ -0,0 +1,93 @@ + +> **REGLA OBLIGATORIA PARA CUALQUIER IA** +> +> Ningun agente de IA, incluyendo Codex, Claude, ChatGPT, Gemini o similares, puede modificar, mover, borrar, instalar, desinstalar o intervenir archivos del sistema Windows, navegadores, perfiles de navegador, extensiones, complementos, configuraciones del equipo ni otros recursos fuera de este proyecto sin permiso explicito y especifico del usuario. +> +> Si el usuario no lo pide de forma explicita y puntual, se asume prohibido. + +# BotValia Base + +## Overview + +Base Markdown template for documenting the `botvalia-code` repository. + +## Project + +- Name: `@botvalia/botvalia-code` +- Type: Reconstructed TypeScript CLI source tree +- Runtime: Bun `>=1.3.5`, Node.js `>=24` + +## Purpose + +Describe here what this project does, who it is for, and the main problem it solves. + +## Quickstart + +```bash +bun install +bun run dev:auto +bun run version +``` + +## Main Areas + +- `src/`: core CLI source code +- `shims/`: compatibility replacements for native/private modules +- `vendor/`: native binding source code +- `scripts/`: helper scripts for local execution modes + +## Notes + +- `src/dev-entry.ts` blocks startup if relative imports are missing. +- This repository is reconstructed, so changes should stay minimal and auditable. +- Manual validation is preferred for each changed path. + +## Model Routing + +- `/model` top level: `Auto (All)`, `Auto (OpenRouter)`, `Auto (Ollama)`, `Manual`. +- `Auto (All)`: recommended hybrid free routing across OpenRouter and Ollama, organized by `Code`, `General`, and `Fast`. +- `Auto (OpenRouter)`: same-provider OpenRouter routing with multiple curated fallbacks per lane. +- `Auto (Ollama)`: same-provider Ollama routing with multiple curated fallbacks per lane. +- `Manual`: opens a second list with fixed models ordered by use-case (`Code`, `General`, `Fast`). +- `openrouter/free`: OpenRouter router for free models, not a fixed manual model. +- BotValia persists per-project route cooldowns in `.claude/model-route-cooldowns.json` so failed free routes go to the back of the queue between sessions. +- Launchers can query the live OpenRouter free catalog via `/api/v1/models` and prefer models that are actually free/visible there. +- Launchers can query Ollama inventory via `/api/tags` and prefer models that are actually installed. +- `BOTVALIA_OPENROUTER_API_KEYS`: comma-separated OpenRouter key pool for credential/credit failover. +- `BOTVALIA_OLLAMA_ENDPOINTS`: semicolon/comma-separated endpoint pool using `baseUrl|apiKey`. +- `BOTVALIA_OLLAMA_BASE_URLS` + `BOTVALIA_OLLAMA_API_KEYS`: alternate indexed pool format for Ollama/LiteLLM-compatible endpoints. + +## Local Memory + +- Current local memory is low-token and practical, not a full vector DB. +- Semantic retrieval uses local hash embeddings plus cosine similarity over project JSON files in `.botvalia/memory/`. +- There is a heavier `memory_plugin/` prototype in the repo, but it is not the main runtime path today. +- Instruction memory currently resolves in this order: + 1. managed `CLAUDE.md` + 2. user `~/.claude/CLAUDE.md` + 3. project `CLAUDE.md`, `.claude/CLAUDE.md`, `.claude/rules/*.md` + 4. local `CLAUDE.local.md` +- Memory files support `@path` includes and files closer to the current working directory have higher priority. + +## Onboarding And Profiles + +- `/init` is the current onboarding command for generating or updating project instructions. +- With `NEW_INIT` enabled, `/init` can also scaffold `CLAUDE.local.md`, project skills, and hooks. +- `/memory` opens instruction files and memory folders in the configured editor. +- `/skills` lists bundled, plugin, user, and project skills available to the current session. +- The cleanest current specialization paths are: + - project skills in `.claude/skills//SKILL.md` + - per-session prompt profiles via `--append-system-prompt-file` + - plugins for enable/disable bundles +- Suggested activable workflows: `ux-audit`, `ui-polish`, `qa-regression`. +- Starter templates: [UX_UI_QA_SKILLS.md](UX_UI_QA_SKILLS.md) + +## Validation + +```bash +bun run version +bun run version:auto +``` + +Document here any extra manual checks needed for the specific feature being worked on. + diff --git a/BotValia-CodeUI/.env.example b/BotValia-CodeUI/.env.example new file mode 100644 index 0000000..7a550fe --- /dev/null +++ b/BotValia-CodeUI/.env.example @@ -0,0 +1,9 @@ +# GEMINI_API_KEY: Required for Gemini AI API calls. +# AI Studio automatically injects this at runtime from user secrets. +# Users configure this via the Secrets panel in the AI Studio UI. +GEMINI_API_KEY="MY_GEMINI_API_KEY" + +# APP_URL: The URL where this applet is hosted. +# AI Studio automatically injects this at runtime with the Cloud Run service URL. +# Used for self-referential links, OAuth callbacks, and API endpoints. +APP_URL="MY_APP_URL" diff --git a/BotValia-CodeUI/.eslintrc.json b/BotValia-CodeUI/.eslintrc.json new file mode 100644 index 0000000..15b1ed9 --- /dev/null +++ b/BotValia-CodeUI/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": "next" +} diff --git a/BotValia-CodeUI/README.md b/BotValia-CodeUI/README.md new file mode 100644 index 0000000..4ba1a7f --- /dev/null +++ b/BotValia-CodeUI/README.md @@ -0,0 +1,31 @@ + + + +> **REGLA OBLIGATORIA PARA CUALQUIER IA** +> +> Ningun agente de IA, incluyendo Codex, Claude, ChatGPT, Gemini o similares, puede modificar, mover, borrar, instalar, desinstalar o intervenir archivos del sistema Windows, navegadores, perfiles de navegador, extensiones, complementos, configuraciones del equipo ni otros recursos fuera de este proyecto sin permiso explicito y especifico del usuario. +> +> Si el usuario no lo pide de forma explicita y puntual, se asume prohibido. + +
+GHBanner +
+ +# Run and deploy your AI Studio app + +This contains everything you need to run your app locally. + +View your app in AI Studio: https://ai.studio/apps/ba94abc3-bfa9-4693-b322-8a9519a5c0fa + +## Run Locally + +**Prerequisites:** Node.js + + +1. Install dependencies with `pnpm 11`: + `pnpm install` + If the repo still lacks `pnpm-lock.yaml`, migrate it with `pnpm import` and rerun `pnpm install`. +2. Set the `GEMINI_API_KEY` in [.env.local](.env.local) to your Gemini API key +3. Run the app: + `pnpm run dev` + diff --git a/BotValia-CodeUI/app/globals.css b/BotValia-CodeUI/app/globals.css new file mode 100644 index 0000000..b401d2d --- /dev/null +++ b/BotValia-CodeUI/app/globals.css @@ -0,0 +1,81 @@ +@import "tailwindcss"; + +@theme { + --color-canvas: var(--color-canvas); + --color-panel: var(--color-panel); + --color-border-subtle: var(--color-border-subtle); + --color-text-main: var(--color-text-main); + --color-text-muted: var(--color-text-muted); + --color-glass-bg: var(--color-glass-bg); + --color-glass-border: var(--color-glass-border); +} + +:root { + --color-canvas: #050505; + --color-panel: #0c0c0c; + --color-border-subtle: rgba(255, 255, 255, 0.05); + --color-text-main: #f3f4f6; + --color-text-muted: #9ca3af; + --color-glass-bg: rgba(0, 0, 0, 0.4); + --color-glass-border: rgba(255, 255, 255, 0.05); + --font-sans: "Segoe UI", "SF Pro Display", "Inter", system-ui, sans-serif; + --font-mono: "JetBrains Mono", "Cascadia Code", "SFMono-Regular", Consolas, monospace; +} + +html, +body { + min-height: 100%; +} + +body { + font-family: var(--font-sans); + background: var(--color-canvas); + color: var(--color-text-main); +} + +code, +pre, +kbd, +samp { + font-family: var(--font-mono); +} + +/* Magic Premium Theme Inversion */ +.light-theme { + /* Corporate AI Light: Soft cool-gray background instead of blinding white */ + filter: invert(0.9) hue-rotate(180deg) brightness(1.05) contrast(1.02) saturate(1.1); + background-color: #030712; /* Subtle dark blue base influences the inversion towards corporate cool-gray */ +} + +/* Re-invert things that shouldn't be inverted (like images, avatars) */ +.light-theme img, +.light-theme video, +.light-theme [style*="background-image"] { + filter: invert(1) hue-rotate(180deg); +} + +@layer utilities { + .scrollbar-hide { + -ms-overflow-style: none; /* IE and Edge */ + scrollbar-width: none; /* Firefox */ + } + .scrollbar-hide::-webkit-scrollbar { + display: none; /* Chrome, Safari and Opera */ + } + + /* Custom thin scrollbar */ + .scrollbar-thin::-webkit-scrollbar { + width: 6px; + height: 6px; + } + .scrollbar-thin::-webkit-scrollbar-track { + background: transparent; + } + .scrollbar-thin::-webkit-scrollbar-thumb { + background: rgba(255, 255, 255, 0.1); + border-radius: 10px; + } + .scrollbar-thin::-webkit-scrollbar-thumb:hover { + background: rgba(255, 255, 255, 0.2); + } +} diff --git a/BotValia-CodeUI/app/layout.tsx b/BotValia-CodeUI/app/layout.tsx new file mode 100644 index 0000000..034b45e --- /dev/null +++ b/BotValia-CodeUI/app/layout.tsx @@ -0,0 +1,15 @@ +import type {Metadata} from 'next'; +import './globals.css'; // Global styles + +export const metadata: Metadata = { + title: 'BotValia Runtime', + description: 'BotValia Runtime Inspector', +}; + +export default function RootLayout({children}: {children: React.ReactNode}) { + return ( + + {children} + + ); +} diff --git a/BotValia-CodeUI/app/page.tsx b/BotValia-CodeUI/app/page.tsx new file mode 100644 index 0000000..fe2a227 --- /dev/null +++ b/BotValia-CodeUI/app/page.tsx @@ -0,0 +1,5 @@ +import { RuntimeShell } from '@/components/runtime/RuntimeShell'; + +export default function Page() { + return ; +} diff --git a/BotValia-CodeUI/components/runtime/Composer.tsx b/BotValia-CodeUI/components/runtime/Composer.tsx new file mode 100644 index 0000000..89e16ec --- /dev/null +++ b/BotValia-CodeUI/components/runtime/Composer.tsx @@ -0,0 +1,260 @@ +import { useState, useRef } from "react"; +import { ArrowUp, Sparkles, StopCircle, Zap, Paperclip } from "lucide-react"; +import { Button } from "@/components/ui/button"; +import { Textarea } from "@/components/ui/textarea"; + +const QUICK_PROMPTS = ["Resumen", "Estado", "Coordinar swarm"]; + +const COMMANDS = [ + { name: "/init", desc: "Initialize workspace" }, + { name: "/modal", desc: "Open modal component" }, + { name: "/clear", desc: "Clear chat history" }, + { name: "/help", desc: "Show available commands" } +]; + +const SKILLS = [ + { name: "@FrontendDesign", desc: "Design & UX guidelines" }, + { name: "@GeminiAPI", desc: "AI integrations" }, + { name: "@Firestore", desc: "Database recipes" }, + { name: "@OAuth", desc: "Auth integration" } +]; + +type ComposerProps = { + isRunning: boolean; + onSend: (text: string) => void; + onStop?: () => void; + onAttach?: () => void; + onCyclePermissionMode?: () => void; + placeholder?: string; + permissionModeLabel?: string; + disabled?: boolean; +}; + +export function Composer({ + isRunning, + onSend, + onStop, + onAttach, + onCyclePermissionMode, + placeholder, + permissionModeLabel, + disabled, +}: ComposerProps) { + const [text, setText] = useState(""); + const [showQuick, setShowQuick] = useState(false); + const [isFocused, setIsFocused] = useState(false); + const fileInputRef = useRef(null); + + // Suggestion state + const [suggestionType, setSuggestionType] = useState<'command' | 'skill' | null>(null); + const [suggestionQuery, setSuggestionQuery] = useState(""); + + const handleSend = () => { + if (!text.trim() || disabled) return; + onSend(text); + setText(""); + setSuggestionType(null); + }; + + const handleAttach = () => { + if (disabled) return; + if (onAttach) { + onAttach(); + return; + } + fileInputRef.current?.click(); + }; + + const handleTextChange = (e: React.ChangeEvent) => { + const val = e.target.value; + setText(val); + + const words = val.split(' '); + const lastWord = words[words.length - 1]; + + if (lastWord.startsWith('/')) { + setSuggestionType('command'); + setSuggestionQuery(lastWord.slice(1).toLowerCase()); + } else if (lastWord.startsWith('@')) { + setSuggestionType('skill'); + setSuggestionQuery(lastWord.slice(1).toLowerCase()); + } else { + setSuggestionType(null); + } + }; + + const insertSuggestion = (suggestion: string) => { + const words = text.split(' '); + words.pop(); + const newText = [...words, suggestion, ""].join(" "); + setText(newText.replace(/^\s+/, '')); + setSuggestionType(null); + }; + + const filteredCommands = COMMANDS.filter(c => c.name.toLowerCase().includes(suggestionQuery)); + const filteredSkills = SKILLS.filter(s => s.name.toLowerCase().includes(suggestionQuery)); + + return ( +
+ {/* Glow Behind the Composer */} +
+ +
+ + {/* Command / Skill Suggestions */} + {suggestionType && ( +
+
+ {suggestionType === 'command' ? 'Commands' : 'Plugins & Skills'} +
+
+ {(suggestionType === 'command' ? filteredCommands : filteredSkills).map(item => ( + + ))} + {(suggestionType === 'command' ? filteredCommands : filteredSkills).length === 0 && ( +
No matches found.
+ )} +
+
+ )} + + {showQuick && !suggestionType && ( +
+ {QUICK_PROMPTS.map(p => ( + + ))} +
+ )} + +