diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b600d8b..f9e1997 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,74 +1,74 @@ -name: Release & Publish - -on: - push: - tags: - - 'v*' - workflow_dispatch: - inputs: - tag: - description: 'Tag to release (e.g. v1.3.4)' - required: true - type: string - -permissions: - contents: write - -jobs: - test: - runs-on: ubuntu-latest - strategy: - matrix: - node-version: [18, 20, 22] - steps: - - uses: actions/checkout@v4 - with: - ref: ${{ github.event.inputs.tag || github.ref }} - - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node-version }} - - run: npm install - - run: npm test - - publish: - needs: test - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - ref: ${{ github.event.inputs.tag || github.ref }} - - uses: actions/setup-node@v4 - with: - node-version: 20 - registry-url: https://registry.npmjs.org - - run: npm install - - run: npm publish - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - - release: - needs: test - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - ref: ${{ github.event.inputs.tag || github.ref }} - fetch-depth: 0 - - name: Extract release notes from tag message - id: notes - run: | - TAG="${{ github.event.inputs.tag || github.ref_name }}" - NOTES=$(git tag -l --format='%(contents)' "$TAG") - EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64) - echo "notes<<$EOF" >> "$GITHUB_OUTPUT" - echo "$NOTES" >> "$GITHUB_OUTPUT" - echo "$EOF" >> "$GITHUB_OUTPUT" - - name: Create GitHub Release - uses: softprops/action-gh-release@v2 - with: - tag_name: ${{ github.event.inputs.tag || github.ref_name }} - generate_release_notes: true - body: ${{ steps.notes.outputs.notes }} - make_latest: true - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} +name: Release & Publish + +on: + push: + tags: + - 'v*' + workflow_dispatch: + inputs: + tag: + description: 'Tag to release (e.g. v1.3.4)' + required: true + type: string + +permissions: + contents: write + +jobs: + test: + runs-on: ubuntu-latest + strategy: + matrix: + node-version: [18, 20, 22] + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ github.event.inputs.tag || github.ref }} + - uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + - run: npm install + - run: npm test + + publish: + needs: test + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ github.event.inputs.tag || github.ref }} + - uses: actions/setup-node@v4 + with: + node-version: 20 + registry-url: https://registry.npmjs.org + - run: npm install + - run: npm publish + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + + release: + needs: test + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ github.event.inputs.tag || github.ref }} + fetch-depth: 0 + - name: Extract release notes from tag message + id: notes + run: | + TAG="${{ github.event.inputs.tag || github.ref_name }}" + NOTES=$(git tag -l --format='%(contents)' "$TAG") + EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64) + echo "notes<<$EOF" >> "$GITHUB_OUTPUT" + echo "$NOTES" >> "$GITHUB_OUTPUT" + echo "$EOF" >> "$GITHUB_OUTPUT" + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + tag_name: ${{ github.event.inputs.tag || github.ref_name }} + generate_release_notes: true + body: ${{ steps.notes.outputs.notes }} + make_latest: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.trae-html-share-packages/desktop/renderer/index.html.zip b/.trae-html-share-packages/desktop/renderer/index.html.zip new file mode 100644 index 0000000..7747448 Binary files /dev/null and b/.trae-html-share-packages/desktop/renderer/index.html.zip differ diff --git a/CHANGELOG.md b/CHANGELOG.md index f897c1a..18ac438 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,25 @@ - 1|# Changelog - 2| - 3|All notable changes to Hax Agent CLI will be documented in this file. - 4| - 5|## [1.5.4] - 2026-05-30 +# Changelog + +All notable changes to Hax Agent CLI will be documented in this file. + +## [1.6.0] - 2026-06-30 + +### Changed +- **TypeScript + ESM migration (full repo):** All `src/` modules converted from CommonJS `.js` to TypeScript (`.ts`). `"type": "module"`, NodeNext module resolution, ES2022 target; relative imports now require the `.js` extension. `npm run build` compiles to `dist/` via `tsc`, `npm run dev` runs `src/cli.ts` directly via tsx, and `bin`/`main` point to `dist/`. +- **Ink TUI is now the default interface:** Three-part layout (Static history + live area + input), slash command palette, Select-based approval menus, rich status bar with context usage visualization, and tool call folding with Ctrl+R detail toggle. Display components use native ink elements for correct CJK alignment. The classic readline interface remains available via `--legacy`, `--no-ink`, or `HAXAGENT_LEGACY=1`; `--ink` is kept as a no-op for compatibility. +- **Default models updated across providers:** Anthropic default is now `claude-sonnet-4-6`; profile defaults refreshed (opus, haiku, gemini, deepseek, qwen, glm, openrouter). + +### Added +- `src/tui-ink/` module: `App.tsx` root component, pure `reducer.ts` state machine, keybindings, markdown rendering, slash completions; components (`CommandPalette`, `DiffView`, `ConversationTurn`, `StatusBar`, `ApprovalPrompt`, `ToolCall`, `ToolList`, `ThinkingBlock`, `TextStream`); `ui/` primitives (`Select` with pure navigation logic, `Separator`, `useTerminalSize`). +- Consolidated subsystem modules: `swarm/` (multi-agent collaboration with subprocess and in-process backends, mailbox, worktree isolation), `channels/` (IM adapters: Feishu, Slack, Discord, Telegram, DingTalk, Email, Matrix, WeChat, QQ, WhatsApp, MoChat), `sandbox/` (Docker, bubblewrap, macOS, Windows backends with path validation), `tasks/` (background task manager), `keybindings/`, `auth/`, `bridge/`, `autopilot/`, `coordinator/`, `personalization/`, `output-styles/`, `vim/`, `voice/`. +- Extended slash commands: `/session`, `/continue`, `/summary`, `/rewind`, `/mcp`, `/plugin`, `/agents`, `/dream`, `/diff`, `/branch`, `/keybindings`, `/feedback`, `/files`, `/turns`, `/release-notes`, `/reload`, `/tag`, `/tags`. +- `web.search` tool works out of the box via DuckDuckGo (no API key needed). +- `--sandbox` CLI flag and sandbox settings block (`backend`, `image`, `network`, `cpus`, `memory`) for shell command isolation. + +### Fixed +- Anthropic tool names containing dots are sanitized before API calls (previously broke tool calls entirely: tools reported as nonexistent with missing parameters). + +## [1.5.4] - 2026-05-30 ### Changed - **Architecture Rewrite (Complete):** Fully rebuilt following OpenHarness reference architecture and industry-grade standards. Flat src (~560 files) → layered modular (144 consolidated JS files). All 30+ OpenHarness subsystems covered with full feature parity. @@ -36,26 +53,26 @@ - Legacy flat modules superseded by layered architecture (agent-engine, session, renderer, hub, batch, config, permissions, undo-stack, context-compaction, context-window, config-presets, init-wizard, updater, debug, i18n, and ~70 legacy subsystem directories). ## [1.4.0] - 2026-05-15 - 6| - 7|### Added - 8|- `/context` command and `/cache` alias to view and tune context cache budgets. - 9|- Tab completion for context cache subcommands (`status`, `window`, `reserve`, `chars-per-token`, `auto`, `on`, `off`). - 10|- Broader model context-window inference for GPT-5, Claude 4.x, Gemini, DeepSeek, Qwen, Kimi, GLM, Doubao, Hunyuan, MiniMax, Yi, and Baichuan model IDs. - 11|- Token-count context meter now shows sub-percent usage and input-budget counts. - 12| - 13|### Changed - 14|- YOLO/full permission mode now maps consistently across CLI and desktop flows. - 15|- Shell execution no longer uses a hard allowlist gate; normal mode asks for permission and YOLO mode auto-approves. - 16|- CLI status line is rendered outside chat history so workspace/model/context metadata stays visible without becoming user input. - 17|- Windows shell command resolution now prefers executable shims and wraps `.cmd`/`.bat` launchers correctly. - 18| - 19|### Fixed - 20|- Repeated empty tool preamble loops from OpenAI-compatible providers. - 21|- `shell.run` spinner flooding the terminal while commands are running. - 22|- Windows `npm` execution failures caused by spawning extensionless npm shims. - 23|- Desktop permission mode and approval flow edge cases. - 24| - 25|## [1.3.14] - 2026-05-14 + +### Added +- `/context` command and `/cache` alias to view and tune context cache budgets. +- Tab completion for context cache subcommands (`status`, `window`, `reserve`, `chars-per-token`, `auto`, `on`, `off`). +- Broader model context-window inference for GPT-5, Claude 4.x, Gemini, DeepSeek, Qwen, Kimi, GLM, Doubao, Hunyuan, MiniMax, Yi, and Baichuan model IDs. +- Token-count context meter now shows sub-percent usage and input-budget counts. + +### Changed +- YOLO/full permission mode now maps consistently across CLI and desktop flows. +- Shell execution no longer uses a hard allowlist gate; normal mode asks for permission and YOLO mode auto-approves. +- CLI status line is rendered outside chat history so workspace/model/context metadata stays visible without becoming user input. +- Windows shell command resolution now prefers executable shims and wraps `.cmd`/`.bat` launchers correctly. + +### Fixed +- Repeated empty tool preamble loops from OpenAI-compatible providers. +- `shell.run` spinner flooding the terminal while commands are running. +- Windows `npm` execution failures caused by spawning extensionless npm shims. +- Desktop permission mode and approval flow edge cases. + +## [1.3.14] - 2026-05-14 ### Fixed - Desktop i18n path corrections and component updates @@ -66,129 +83,128 @@ - LICENSE file and .gitignore hardening ## [1.3.13] - 2026-05-14 - 26| - 27|### Added - 28|- `stock.quote` tool for real-time stock/index quotes (A-shares, HK stocks, US stocks) - 29|- `file.read` auto-truncation + `offset`/`limit` line pagination for large files - 30|- Inline diff view for `file.edit` tool - 31|- Context window usage meter in status line - 32|- Multi-line input support (`\` line continuation) - 33|- Ctrl+←/→ word jump navigation, status bar cwd, `/help` shortcut cheatsheet - 34|- Ctrl+R reverse history search - 35|- Command syntax highlighting and improved error messages - 36|- Session file change summary on `/exit` - 37|- `/copy` command to copy last AI response to clipboard - 38|- `/rename` command to name the current session - 39|- Tool execution timing displayed in file modification notices - 40|- `-v` shorthand for `--version` flag - 41| - 42|### Changed - 43|- Local tools modularized into separate files (`file-edit`, `file-readdir`, `file-delete`, `web-fetch`, `web-search`, `stock-quote`) - 44|- Enhanced tab autocomplete with first-run onboarding - 45|- Enhanced `/clear` with cleared message count and user guidance - 46|- `file.read`/`file.search`/`file.write` tool descriptions discourage AI from passing tiny `maxBytes` - 47|- Increased empty tool preamble retry tolerance (1→3) with stronger continuation prompts - 48| - 49|### Fixed - 50|- Google provider dependency: `require("@google/genai")` → `@google/generative-ai` - 51|- Stream `finalMessage()` returning `null` on non-Anthropic endpoints - 52|- Chinese text falsely detected as tool preamble in `forceTextResponse` mode - 53|- Tab autocomplete not working due to readline inserting `\t` before keypress event - 54| - 55|## [1.3.12] - 2026-05-14 - 56| - 57|### Added - 58|- Quick setup mode in init wizard: skip optional questions with recommended defaults - 59|- `hax-agent config` command to view current configuration - 60|- `hax-agent config edit` to open config file in default editor - 61|- Smart API key detection during init (auto-detects env vars to skip input) - 62|- `hax-agent --version` / `-V` flag to print version number - 63|- `hax-agent doctor` command for one-line diagnostics - 64|- `--no-color` flag to disable ANSI terminal output - 65| - 66|### Changed - 67|- Init wizard flow: quick mode asks only Provider + Key, full mode keeps all 9 questions - 68|- CLI better supports piping and non-TTY environments for config viewing - 69|- Improved i18n for Chinese (zh-CN) translations - 70| - 71|## [1.3.11] - 2026-05-07 - 72| - 73|### Added - 74|- Desktop approval dialog for tool permissions - 75|- Workspace search in desktop app - 76|- Git diff/review tools in desktop app - 77| - 78|### Changed - 79|- Refactored shared serialization utilities to `src/utils/serialization.js` - 80|- Improved web-search with Bing RSS fallback when DuckDuckGo fails - 81|- Updated User-Agent version string - 82| - 83|## [1.3.10] - 2026-05-05 - 84| - 85|### Changed - 86|- Improved context handling and tool-call recovery - 87|- Better error messages for empty tool preamble detection - 88| - 89|## [1.3.9] - 2026-04-28 - 90| - 91|### Changed - 92|- Modularized tools into separate files - 93|- Unified DSML tool call parsing across providers - 94| - 95|## [1.3.8] - 2026-04-20 - 96| - 97|### Added - 98|- Desktop app renderer with Vue.js components - 99|- File tree, chat area, sidebar, and settings UI - 100| - 101|## [1.3.7] - 2026-04-15 - 102| - 103|### Added - 104|- Command suggestions for slash and CLI commands - 105|- Typo-tolerant command matching - 106| - 107|## [1.3.6] - 2026-04-10 - 108| - 109|### Added - 110|- Interactive initialization wizard (`hax-agent init`) - 111|- Enhanced permission management system - 112| - 113|## [1.3.5] - 2026-04-05 - 114| - 115|### Added - 116|- CI/CD workflow for automated testing and npm publishing - 117|- Manual release trigger via `workflow_dispatch` - 118| - 119|## [1.3.4] - 2026-03-30 - 120| - 121|### Added - 122|- Self-update check and installation (`/update` command) - 123| - 124|### Changed - 125|- Refactored provider code for better maintainability - 126|- Raised tool execution limits - 127| - 128|## [1.3.3] - 2026-03-25 - 129| - 130|### Added - 131|- Shell command execution with allowlist control - 132|- Improved terminal UI rendering - 133| - 134|## [1.3.2] - 2026-03-20 - 135| - 136|### Fixed - 137|- CLI test suite failures - 138|- Various bug fixes and refactoring - 139| - 140|## [1.3.1] - 2026-03-15 - 141| - 142|### Added - 143|- Permission management system - 144|- DeepSeek DSML format support - 145|- `reasoning_content` handling for extended thinking models - 146| - 147|### Fixed - 148|- Single-call tool deduplication - 149|- Recursive web.fetch loop prevention - 150|- Windows shell spawn issues - 151| \ No newline at end of file + +### Added +- `stock.quote` tool for real-time stock/index quotes (A-shares, HK stocks, US stocks) +- `file.read` auto-truncation + `offset`/`limit` line pagination for large files +- Inline diff view for `file.edit` tool +- Context window usage meter in status line +- Multi-line input support (`\` line continuation) +- Ctrl+←/→ word jump navigation, status bar cwd, `/help` shortcut cheatsheet +- Ctrl+R reverse history search +- Command syntax highlighting and improved error messages +- Session file change summary on `/exit` +- `/copy` command to copy last AI response to clipboard +- `/rename` command to name the current session +- Tool execution timing displayed in file modification notices +- `-v` shorthand for `--version` flag + +### Changed +- Local tools modularized into separate files (`file-edit`, `file-readdir`, `file-delete`, `web-fetch`, `web-search`, `stock-quote`) +- Enhanced tab autocomplete with first-run onboarding +- Enhanced `/clear` with cleared message count and user guidance +- `file.read`/`file.search`/`file.write` tool descriptions discourage AI from passing tiny `maxBytes` +- Increased empty tool preamble retry tolerance (1→3) with stronger continuation prompts + +### Fixed +- Google provider dependency: `require("@google/genai")` → `@google/generative-ai` +- Stream `finalMessage()` returning `null` on non-Anthropic endpoints +- Chinese text falsely detected as tool preamble in `forceTextResponse` mode +- Tab autocomplete not working due to readline inserting `\t` before keypress event + +## [1.3.12] - 2026-05-14 + +### Added +- Quick setup mode in init wizard: skip optional questions with recommended defaults +- `hax-agent config` command to view current configuration +- `hax-agent config edit` to open config file in default editor +- Smart API key detection during init (auto-detects env vars to skip input) +- `hax-agent --version` / `-V` flag to print version number +- `hax-agent doctor` command for one-line diagnostics +- `--no-color` flag to disable ANSI terminal output + +### Changed +- Init wizard flow: quick mode asks only Provider + Key, full mode keeps all 9 questions +- CLI better supports piping and non-TTY environments for config viewing +- Improved i18n for Chinese (zh-CN) translations + +## [1.3.11] - 2026-05-07 + +### Added +- Desktop approval dialog for tool permissions +- Workspace search in desktop app +- Git diff/review tools in desktop app + +### Changed +- Refactored shared serialization utilities to `src/utils/serialization.js` +- Improved web-search with Bing RSS fallback when DuckDuckGo fails +- Updated User-Agent version string + +## [1.3.10] - 2026-05-05 + +### Changed +- Improved context handling and tool-call recovery +- Better error messages for empty tool preamble detection + +## [1.3.9] - 2026-04-28 + +### Changed +- Modularized tools into separate files +- Unified DSML tool call parsing across providers + +## [1.3.8] - 2026-04-20 + +### Added +- Desktop app renderer with Vue.js components +- File tree, chat area, sidebar, and settings UI + +## [1.3.7] - 2026-04-15 + +### Added +- Command suggestions for slash and CLI commands +- Typo-tolerant command matching + +## [1.3.6] - 2026-04-10 + +### Added +- Interactive initialization wizard (`hax-agent init`) +- Enhanced permission management system + +## [1.3.5] - 2026-04-05 + +### Added +- CI/CD workflow for automated testing and npm publishing +- Manual release trigger via `workflow_dispatch` + +## [1.3.4] - 2026-03-30 + +### Added +- Self-update check and installation (`/update` command) + +### Changed +- Refactored provider code for better maintainability +- Raised tool execution limits + +## [1.3.3] - 2026-03-25 + +### Added +- Shell command execution with allowlist control +- Improved terminal UI rendering + +## [1.3.2] - 2026-03-20 + +### Fixed +- CLI test suite failures +- Various bug fixes and refactoring + +## [1.3.1] - 2026-03-15 + +### Added +- Permission management system +- DeepSeek DSML format support +- `reasoning_content` handling for extended thinking models + +### Fixed +- Single-call tool deduplication +- Recursive web.fetch loop prevention +- Windows shell spawn issues diff --git a/CLAUDE.md b/CLAUDE.md index 87d12c6..a24450a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -2,246 +2,272 @@ ## Project Overview -HaxAgent is a professional AI coding assistant with a Claude-like CLI experience. It supports 12+ LLM providers (Anthropic, OpenAI, DeepSeek, Groq, Mistral, Google, Moonshot, Zhipu, DashScope, Ollama, vLLM, OpenRouter), agent teams, plugins, skills, session memory, and a desktop UI. **Architecture: Fully refactored following the OpenHarness reference architecture and industry-grade standards.** Rebuilt from flat directory (~560 files) into layered modular design: `core/` (typed protocols) → `engine/` (agent runtime) → `api/`/`tools/`/`services/` (implementations). 229 OpenHarness Python modules ported to 144 consolidated JS modules with full feature parity. +HaxAgent is a professional AI coding assistant with a Claude-like CLI experience. It supports 12+ LLM providers (Anthropic, OpenAI, DeepSeek, Groq, Mistral, Google, Moonshot, Zhipu, DashScope, Ollama, vLLM, OpenRouter), agent teams, plugins, skills, session memory, and a desktop UI. -- **Language:** Node.js (>= 18), JavaScript (CommonJS) -- **Entry point (CLI):** `src/cli.js` (bin: `hax-agent`) -- **Entry point (library):** `src/index.js` (main: `hax-agent-cli`) -- **Desktop UI:** Vue 3 + Electron under `desktop/` -- **Tests:** Node.js built-in test runner (`node --test`) -- **Dependencies:** `@anthropic-ai/sdk`, `openai`, `@google/generative-ai`, `markdown-it`, `dompurify` +The codebase is **TypeScript + ESM** (`"type": "module"`, module resolution `NodeNext`, target ES2022). All relative imports must carry the `.js` extension (the source file is `.ts`, but the specifier refers to the compiled output). The interactive default interface is an **Ink TUI** (`src/tui-ink/`); the classic readline interface remains available via `--legacy`. + +- **Language:** TypeScript (strict), ESM, Node.js >= 18 +- **Entry point (CLI):** `src/cli.ts` (bin: `hax-agent` → `dist/cli.js`) +- **Entry point (library):** `src/index.ts` (main: `hax-agent-cli` → `dist/index.js`) +- **Desktop UI:** Electron + Vue 3 under `desktop/` +- **Tests:** Node.js built-in test runner (`node --test`) executed through `tsx` +- **Runtime deps:** `@anthropic-ai/sdk`, `openai`, `@google/generative-ai`, `ink`, `react`, `ink-text-input`, `markdown-it`, `dompurify` ## Quick Start ```bash -# Install -npm install - -# Run the CLI (interactive shell) -npm start - -# Run all tests -npm test - -# Run specific tests -node --test test/cli.test.js - -# Lint -npm run lint - -# Desktop development -npm run desktop:dev # Start dev server -npm run desktop:build # Build for production +npm install # install dependencies +npm run dev # run the CLI from source (tsx src/cli.ts) +npm run build # compile TypeScript to dist/ (tsc) +npm start # run the compiled dist/cli.js +npm run typecheck # tsc --noEmit (this is also what `npm run lint` runs today) +npm test # run the test suite + +npm run desktop:dev # desktop development mode +npm run desktop:build # build desktop frontend assets ``` +Before committing, `npm run typecheck` and `npm test` must both pass. + ## Architecture & Data Flow ``` -User input (stdin) - -> cli.js -- parse commands, manage readline - -> commands/registry.js -- route slash commands and chat messages - -> engine/agent.js (AgentEngine) -- core agent loop: prompt, tool use, streaming - -> api/provider.js -- LLM API calls (12+ providers) - -> engine/query.js (QueryContext) -- state tracking, compaction, offloading - -> core/permissions/checker.js -- tool permission evaluation - -> tui/index.js (TUI) -- terminal rendering - -> stdout (rendered output) +User input + -> src/cli.ts -- arg parsing; dispatch Ink TUI or readline + -> src/tui-ink/run.tsx -- default: render , wire approval bridge + -> src/tui-ink/App.tsx -- handleSubmit -> engine.sendMessage() + -> src/engine/agent.ts -- AgentEngine: prompt build, tool loop + -> src/api/provider.ts -- LLM streaming (12+ providers, withRetry) + -> src/tools/registry.ts -- tool execution + permission checks + -> src/core/permissions/ -- permission evaluation + <- typed events (async generator): message.delta / tool.start / + tool.result / turn.completed / turn.failed ... + -> src/tui-ink/reducer.ts -- events -> UI state + -> terminal rendering (Static history + live area) ``` -**Key data flow for a user message:** -1. `cli.js` readline captures input -> slash command or chat message -2. `commands/registry.js` routes to handler -> `engine.sendMessage()` -3. `engine/agent.js` builds system prompt (skills + context + history) and runs tool loop -4. `api/provider.js` sends prompt to LLM -> streams response tokens -5. Agent engine parses tool calls from response -> executes via `tools/registry.js` -6. Tool results fed back to provider -> loop until no more tool calls -7. `tui/index.js` renders events to terminal +Key points for a user message: + +1. `cli.ts` parses flags and starts the Ink TUI (default) or the legacy readline loop. +2. Slash commands route through `src/commands/registry.ts` and `src/commands/extended-commands.ts` (~55 commands); plain messages go to `engine.sendMessage()`. +3. `AgentEngine` assembles the system prompt (skills + context + history) and runs the tool loop. +4. `api/provider.ts` streams LLM responses; Anthropic tool names with dots are sanitized for the API. +5. Tool calls execute via `tools/registry.ts` after permission checks; results feed back into the conversation until the model stops calling tools. +6. The engine yields typed events; the Ink reducer consumes them for incremental rendering. The desktop app forwards the same event stream over Electron IPC. + +The approval bridge between engine and TUI uses a deferred-promise pattern: `run.tsx` creates the approval callback before `App` renders, `dispatchRef` exposes the reducer dispatch, and resolutions are applied via `setImmediate` with a one-shot `resolvedRef` guard. Preserve this contract when touching approval code. ## Directory Structure ``` src/ -├── index.js # Library entry — exports engine, tools, api, config, skills, memory, tui, commands -├── cli.js # CLI entry: argument parsing, readline loop, session wiring -├── api/ -│ ├── provider.js # 12+ provider clients (Anthropic, OpenAI, DeepSeek, Groq, Mistral, Google, Moonshot, Zhipu, DashScope, Ollama, vLLM, OpenRouter) -│ └── retry.js # Retry logic with exponential backoff +├── cli.ts # CLI entry: arg parsing, Ink/readline dispatch +├── index.ts # Library barrel: nested default export (api.engine.Session, api.tools.ToolRegistry, ...) +├── context.ts, session.ts, setup.ts, platforms.ts, pricing.ts +├── renderer*.ts # readline-era renderers (used by --legacy path) +├── tui-ink/ # Ink TUI (default interface) +│ ├── App.tsx # root component, three-part layout + +│ ├── run.tsx # bootstrap: engine wiring, approval bridge +│ ├── reducer.ts # state machine (engine events + UI actions) +│ ├── types.ts # AppState, actions, CommittedTurn +│ ├── keybindings.tsx # key handling (incl. Ctrl+R detail toggle) +│ ├── markdown.ts # markdown -> ink elements +│ ├── completions.ts # slash command completion +│ ├── components/ # ToolCall, ToolList, DiffView, CommandPalette, +│ │ # ApprovalPrompt, StatusBar, ConversationTurn, +│ │ # ThinkingBlock, TextStream, SpinnerLine, UserInput +│ └── ui/ # primitives: Select (+select-state), Separator, useTerminalSize +├── core/ # Foundation layer — typed protocols (no deps upward) +│ ├── api/ # errors.ts (error classification), provider-adapter.ts (ApiStreamEvent, adapters) +│ ├── messages/ # StandardMessage, ContentBlock discriminated union +│ ├── memory/ # compaction utilities +│ └── permissions/ # PermissionChecker, modes, sensitive paths +├── engine/ # Agent runtime +│ ├── agent.ts # AgentEngine, Session, HookExecutor, PermissionChecker +│ ├── query.ts # QueryContext: task focus, file tracking, maxTurns (default 200) +│ ├── cost-tracker.ts # token/cost accounting +│ └── stream-events.ts # event type definitions +├── api/ # Provider layer +│ ├── provider.ts # REGISTRY (12+ providers), createProvider, streaming clients +│ ├── registry.ts, retry.ts # provider registry helpers, exponential backoff with Retry-After +│ └── codex-client.ts, copilot-client.ts, copilot-auth.ts, usage.ts +├── tools/ +│ ├── registry.ts # ToolRegistry + 9 core tools (file.*, shell.run, web.*) +│ ├── extended.ts # extended tool set (agent, task.*, team.*, cron.*, todo_write, ...) +│ ├── agent-tool.ts # subagent delegation +│ ├── mcp-tools.ts # list/read MCP resources and tools +│ ├── plan-mode-tool.ts, worktree-tool.ts, send-message-tool.ts, remote-trigger-tool.ts, image-tools.ts ├── commands/ -│ ├── registry.js # Slash command registry (~30 commands) -│ └── extended-commands.js # Extended command set +│ ├── registry.ts # ~37 core slash commands +│ └── extended-commands.ts # ~18 extended commands (/session, /mcp, /plugin, /diff, ...) ├── config/ -│ ├── settings.js # Settings management (~/.haxagent/settings.json) -│ └── profiles.js # Provider profiles (claude, gpt, sonnet, haiku, local, etc.) -├── core/ # Foundation layer — typed, protocol-driven -│ ├── index.js # Core module exports -│ ├── api/ -│ │ ├── errors.js # API error classification (CONTEXT_TOO_LONG, RATE_LIMITED, etc.) -│ │ └── provider-adapter.js # Provider adapter protocol (ApiStreamEvent types, ProviderAdapter base class) -│ ├── memory/ -│ │ └── compaction.js # Token estimation and compaction utilities -│ ├── messages/ -│ │ └── types.js # StandardMessage, ContentBlock types, stream events, token estimation -│ └── permissions/ -│ └── checker.js # PermissionChecker, PermissionMode, sensitive path patterns -├── engine/ # Agent runtime -│ ├── agent.js # AgentEngine, Session, HookExecutor, PermissionChecker, HookEvent -│ └── query.js # QueryContext: task focus, file tracking, skill tracking, output offloading, tool context -├── hooks/ -│ └── registry.js # Hook registry for lifecycle events -├── memory/ -│ ├── compact.js # Message micro-compaction and token estimation -│ └── store.js # Persistent memory store (CRUD, search) -├── plugins/ -│ ├── installer.js # Plugin installer -│ ├── registry.js # Plugin auto-discovery and lifecycle hooks -│ └── schema.js # Plugin manifest schema validation -├── prompts/ -│ └── manager.js # System prompt assembly and management -├── services/ # Auxiliary services -│ ├── autodream.js # AutoDream — automated goal continuation -│ ├── lsp.js # LSP-like code navigation (go-to-def, workspace search) -│ ├── mcp.js # MCP (Model Context Protocol) server integration -│ ├── memory-extract.js # Memory extraction from conversation -│ ├── personalization.js # Environment fact extraction and rules.md generation -│ └── session-memory.js # Session memory persistence -├── shared/ -│ ├── themes.js # Terminal color themes -│ └── utils.js # ANSI escape codes, styled() output helper, THEME constants -├── skills/ -│ └── registry.js # Skill auto-discovery, loading, and system prompt generation -├── tools/ -│ ├── registry.js # Tool registry: 10 built-in tools (file.*, shell.run, web.*) -│ ├── agent-tool.js # Agent subprocess tool -│ ├── extended.js # Extended tool set -│ ├── image-tools.js # Image processing tools -│ ├── mcp-tools.js # MCP tool integration -│ ├── plan-mode-tool.js # Plan mode tool (EnterPlanMode/ExitPlanMode) -│ ├── send-message-tool.js # Inter-agent message tool -│ └── worktree-tool.js # Git worktree management tool -└── tui/ - └── index.js # Terminal UI: alt-screen, event rendering, status bar, approval prompts - -desktop/ # Electron + Vue 3 desktop application -├── main/ # Electron main process -├── preload/ # Preload scripts -└── renderer/ # Vue 3 frontend (Vite) -test/ # Test suite -scripts/ # Build, lint, and test scripts -docs/plans/ # Architecture and design plans +│ ├── settings.ts # defaults + ~/.haxagent/settings.json merge +│ ├── profiles.ts # ProfileManager, builtin profiles +│ └── paths.ts # all data directory resolution (HAXAGENT_* env overrides) +├── skills/ # SKILL.md discovery, frontmatter parsing, prompt generation +├── plugins/ # plugin.json manifest validation, registry, installer +├── hooks/ # hook registry: command/http/prompt/agent hook types, hot-reload +├── memory/ # persistent memory store, compaction, relevance ranking, scan, team memory +├── prompts/ # system prompt assembly (skills, context, environment) +├── services/ # lsp, mcp (+mcp-bootstrap), cron, session-storage, session-memory, +│ # token-estimation, memory-extract, personalization, autodream +├── sandbox/ # docker / bwrap / macOS / Windows backends, session, path-validator +├── swarm/ # multi-agent: registry, in-process + subprocess backends, mailbox, worktree +├── channels/ # IM channel adapters (feishu, slack, discord, telegram, dingtalk, email, +│ # matrix, mochat, qq, wechat, whatsapp) + bus +├── tasks/ # background task manager, local agent task, stop-task +├── auth/ # auth manager, flows, storage, external +├── keybindings/ # default bindings, loader, parser, resolver +├── autopilot/ bridge/ coordinator/ personalization/ output-styles/ state/ vim/ voice/ +└── shared/ # themes.ts, utils.ts (ANSI, styled()) + +desktop/ # Electron + Vue 3 app +├── main/index.js # main process: IPC handlers (agent:sendMessage, approval:request/respond) +├── preload/index.js # contextBridge exposing window.haxAgent +└── renderer/ # Vue 3 + Vite frontend (App.vue, components/, composables/) + +test/ # node:test files (must be listed in scripts/run-tests.js) +test-helpers/ # assertions, fixtures, mocks, temp dirs +scripts/ # run-tests.js, dev/build/start helpers for desktop +docs/plans/, docs/superpowers/ # dated design documents and specs (historical records) ``` ## Core Module Responsibilities | Module | Responsibility | |--------|---------------| -| `api/provider.js` | Provider clients with unified streaming interface, provider registry (12+ providers) | -| `core/api/provider-adapter.js` | Typed provider adapter protocol: ApiStreamEvent types, AnthropicAdapter, OpenAIAdapter, factory | -| `core/messages/types.js` | StandardMessage class, ContentBlock discriminated union, token estimation, format conversion | -| `core/permissions/checker.js` | PermissionChecker with mode (normal/yolo/plan/fullauto), always-allow/deny sets, sensitive path detection | -| `engine/agent.js` | AgentEngine with async generator tool loop, Session, HookExecutor, HookEvent lifecycle | -| `engine/query.js` | QueryContext for state tracking: task focus, read files, skills, work log, verified work | -| `config/settings.js` | Settings load/save from `~/.haxagent/settings.json` with defaults merging | -| `config/profiles.js` | ProfileManager: built-in + custom provider profiles with switching | -| `commands/registry.js` | ~30 slash commands: help, model, provider, skills, goal, yolo, plan, perms, lsp, cost, export, etc. | -| `tools/registry.js` | ToolRegistry with 10 built-in tools, isReadOnly classification, path sandboxing | -| `tui/index.js` | Terminal UI with alt-screen buffer, event-driven rendering, approval prompts, status bar | -| `skills/registry.js` | Skill discovery from `.hax-agent/skills/`, system prompt generation | -| `services/lsp.js` | Code navigation: go-to-definition, workspace symbol search | -| `services/personalization.js` | Environment fact extraction, rules.md generation | -| `memory/store.js` | Persistent memory CRUD with search | -| `memory/compact.js` | Message compaction with token-aware truncation | +| `src/engine/agent.ts` | AgentEngine async-generator tool loop, Session state, HookExecutor lifecycle dispatch, approval prompts | +| `src/engine/query.ts` | QueryContext: task focus, read files, skills invoked, work log, maxTurns (default 200) | +| `src/api/provider.ts` | Unified streaming provider clients; `REGISTRY` maps provider names to class + env key + default model; `createProvider` factory | +| `src/api/retry.ts` | `withRetry`: retryable status codes/messages, Retry-After parsing, exponential backoff with jitter | +| `src/core/api/provider-adapter.ts` | Typed adapter protocol (`ApiStreamEvent`), Anthropic/OpenAI adapters | +| `src/core/messages/types.ts` | StandardMessage, ContentBlock discriminated union, token estimation | +| `src/core/permissions/checker.ts` | PermissionChecker: normal/yolo/plan/full_auto, always-allow/deny sets, sensitive path detection | +| `src/tools/registry.ts` | ToolRegistry: 9 core tools, `isReadOnly` classification, workspace path sandboxing | +| `src/commands/registry.ts` + `extended-commands.ts` | ~55 slash commands: `register(name, handler, description)` | +| `src/tui-ink/reducer.ts` | Pure state machine: engine events and UI actions -> AppState | +| `src/config/settings.ts` | Defaults deep-merged with `~/.haxagent/settings.json` (cached; `reloadSettings` busts cache) | +| `src/config/paths.ts` | All directory resolution: `~/.haxagent/` base, `data/`, `logs/`, project `.hax-agent/`; `HAXAGENT_CONFIG_DIR` / `HAXAGENT_DATA_DIR` / `HAXAGENT_LOGS_DIR` overrides | +| `src/memory/store.ts` | MemoryStore (Markdown memories + MEMORY.md index, signature dedup, TTL) and SessionMemoryStore (`~/.haxagent/sessions/` JSON snapshots) | +| `src/memory/compact.ts` | Micro-compaction (old tool results) and full LLM summarization; CompactionManager | +| `src/services/lsp.ts` | Symbol extraction for JS/TS/Python, go-to-definition, find-references, workspace search | +| `src/services/mcp.ts` | MCP client manager: stdio/http/ws transports, tool discovery, JSON config | +| `src/skills/registry.ts` | SKILL.md frontmatter parsing, user + project discovery, `` prompt block | ## Module Organization Principles -1. **Layered architecture.** `core/` (protocols, types) → `engine/` (runtime) → `api/`/`tools/`/`services/` (implementations). Dependencies flow downward. -2. **Provider-agnostic engine.** The AgentEngine works with any provider via the common streaming interface in `core/api/provider-adapter.js`. +1. **Layered architecture.** `core/` (protocols, types) → `engine/` (runtime) → `api/` / `tools/` / `services/` (implementations). Dependencies flow downward only. +2. **Provider-agnostic engine.** AgentEngine works with any provider through the streaming interface; provider specifics live in `api/`. 3. **Tools are self-describing.** Each tool registers `{ name, description, inputSchema, execute, isReadOnly }`. The schema is sent to the LLM for function calling. -4. **Event-driven streaming.** The agent loop uses async generators yielding typed events (`message.delta`, `tool.start`, `tool.result`, `turn.completed`). The TUI consumes these events. -5. **Hooks for lifecycle extension.** HookExecutor supports: `session.start`, `session.end`, `pre.compact`, `post.compact`, `pre.tool_use`, `post.tool_use`, `user.prompt_submit`, `notification`, `stop`, `subagent.stop`. -6. **Permission modes.** Four modes: `normal` (ask), `yolo` (auto-approve all), `plan` (block mutating tools), `fullauto` (silent auto-approve). Plus per-tool always-allow/always-deny sets. +4. **Event-driven streaming.** The engine loop is an async generator yielding typed events; the Ink reducer and the desktop IPC bridge both consume the same stream. +5. **Hooks for lifecycle extension.** HookExecutor dispatches: `session.start`, `session.end`, `pre.compact`, `post.compact`, `pre.tool_use`, `post.tool_use`, `user.prompt_submit`, `notification`, `stop`, `subagent.stop`. +6. **Permission modes.** `normal` (ask), `yolo` (auto-approve), `plan` (block mutating tools), `full_auto` (silent auto-approve), plus per-tool always-allow/always-deny sets. +7. **Tool output offloading.** Large tool outputs (>8000 chars) are written to disk with inline previews to avoid context bloat. +8. **ESM everywhere.** Relative imports require the `.js` extension. `__dirname` is `import.meta.dirname`. JSON is read with `fs` or imported with `with { type: "json" }`. ## How to Add a New Feature ### Add a Slash Command -1. In `src/commands/registry.js`, call `register("commandname", handler, "Description")`. -2. The handler receives `(args, ctx)` where `ctx` has `{ screen, session, rl, settings }`. -3. Use `ctx.screen.write()` for output and `ctx.rl.prompt()` to re-display the prompt. +In `src/commands/registry.ts` (or `extended-commands.ts` for extended set): + +```ts +register("commandname", (args, ctx) => { + // args: string[] — ctx: { screen, session, rl, settings, engine, ... } + ctx.screen.write("output\n"); + ctx.rl?.prompt?.(); +}, "One-line description shown in /help"); +``` ### Add a Tool -1. Add the tool definition to the `tools` object in `src/tools/registry.js`: - ```js - "tool.name": { - name: "tool.name", description: "...", - inputSchema: { type: "object", required: [...], properties: {...} }, - async execute(args, ctx) { ... return { ok: true, data: {...} }; }, - isReadOnly: (args) => true/false, - } - ``` -2. It will be auto-registered by `createDefaultRegistry()`. +Add the tool definition to `src/tools/registry.ts` (core) or `src/tools/extended.ts` (extended set): + +```ts +const myTool: ToolDefinition = { + name: "tool.name", + description: "What it does", + inputSchema: { type: "object", required: ["path"], properties: { path: { type: "string" } } }, + async execute(args, ctx) { + // return { ok: true, data: {...} } or { ok: false, error: { code, message } } + }, + isReadOnly: (args) => true, +}; +``` + +Tools in `extended.ts` are merged automatically by `createDefaultRegistry()`. ### Add a Provider -1. Add an entry to the `REGISTRY` object in `src/api/provider.js`: - ```js - providername: { cls: BaseOpenAICompatible, envKey: "PROVIDER_API_KEY", url: "https://...", model: "...", name: "providername" } - ``` -2. For non-OpenAI-compatible APIs, create a new class implementing the `stream()` async generator method. +Add an entry to the `REGISTRY` object in `src/api/provider.ts`: -### Add a Plugin +```ts +providername: { cls: BaseOpenAICompatible, envKey: "PROVIDER_API_KEY", url: "https://api.example.com/v1", model: "default-model", name: "providername" }, +``` -1. Create a plugin directory with a manifest in `~/.haxagent/plugins/` or `/.hax-agent/plugins/`. -2. Plugins register hooks on lifecycle events. See `HookEvent` in `engine/agent.js` for available events. +For non-OpenAI-compatible APIs, implement a class with an async-generator `stream()` method following `AnthropicProvider`. Consider adding a matching profile in `src/config/profiles.ts`. ### Add a Skill -1. Create a `SKILL.md` file with YAML frontmatter (`name`, `description`, `triggers`) and markdown body. -2. Place it in `~/.haxagent/skills//` or `/.hax-agent/skills//`. -3. Skills are auto-discovered by `loadSkillRegistry()`. +Create `~/.haxagent/skills//SKILL.md` or `/.hax-agent/skills//SKILL.md` with YAML frontmatter (`name`, `description`, `when_to_use`, optional `allowed-tools`, `arguments`). Discovery is automatic. + +### Add a Plugin + +Create a plugin directory with a `plugin.json` manifest under `~/.haxagent/plugins/` or `/.hax-agent/plugins/`. Plugins register hooks on lifecycle events; see `src/hooks/registry.ts` for hook types (command/http/prompt/agent). ## Coding Conventions -- **Language:** JavaScript (CommonJS `require`/`module.exports`), strict mode. -- **Formatting:** 2-space indentation, semicolons. -- **Naming:** camelCase for functions/variables, PascalCase for classes/constructors, UPPER_SNAKE for constants. -- **Error handling:** Use try/catch for async operations. Tool errors return `{ ok: false, error: { code, message } }`. -- **JSDoc:** Document public APIs with `@param`, `@returns`, `@throws`. Explain WHY, not WHAT. -- **Imports:** Group in order: Node built-ins, npm packages, local modules. Use destructuring for named imports. +- **Language:** TypeScript, strict mode, ESM with NodeNext resolution. Relative imports must end with `.js`. +- **Formatting:** 2-space indentation, semicolons, double quotes (match existing files). +- **Naming:** camelCase for functions/variables, PascalCase for classes/components, UPPER_SNAKE for constants. +- **Error handling:** try/catch for async operations. Tool errors return `{ ok: false, error: { code, message } }`; never throw across the engine boundary. +- **JSDoc:** document public APIs with `@param` / `@returns` / `@throws`; explain why, not what. +- **Imports:** order Node built-ins → npm packages → local modules; use destructuring for named imports. +- **Ink components:** use native ink elements (``, ``) — do not introduce ANSI-passthrough rendering. New interactive primitives belong in `src/tui-ink/ui/`. ## Testing Conventions -- **Framework:** Node.js built-in test runner (`node --test`). -- **File naming:** `test/.test.js` mirrors `src/.js`. -- **Run all tests:** `npm test` -- **Run specific tests:** `node --test test/cli.test.js` or `node --test "test/**/config*.test.js"` +- **Framework:** Node.js built-in test runner (`node:test`, `node:assert/strict`). +- **Runner:** `npm test` executes `scripts/run-tests.js`, which spawns `node --import tsx --test ` with a hard-coded file list, a 15s per-test timeout (Node >= 20.10), and a 300s global timeout. +- **Critical gotcha:** a new test file is NOT picked up automatically — add its path to the list in `scripts/run-tests.js` or it will never run. +- **File naming:** `test/.test.ts` mirrors `src/.ts`. +- **Run a single file:** `node --import tsx --test test/tui-ink-reducer.test.ts` +- **Helpers:** `test-helpers/` provides assertions, fixtures, mocks, and temp directory utilities. +- **Ink tests:** reducer and pure-logic tests run headless (see `tui-ink-reducer.test.ts`, `tui-ink-select-state.test.ts`); interactive rendering is verified via the preview harnesses (`src/tui-ink/*-preview.tsx`) and manual TTY checks. ## Key Design Patterns -1. **Layered Architecture:** `core/` (types, protocols) → `engine/` (runtime) → `api/`/`tools/`/`services/` (implementations). Each layer only depends on the layer below. -2. **Async Generator Streaming:** AgentEngine uses `async *sendMessage()` yielding typed events consumed by the TUI for incremental rendering. -3. **Hook System (Observer Pattern):** HookExecutor dispatches lifecycle events to registered handlers with fnmatch-style tool name matching. -4. **Strategy Pattern:** Provider adapters implement a common streaming interface so the engine is provider-agnostic. -5. **Factory Functions:** `createProvider()`, `createDefaultRegistry()`, `loadSkillRegistry()` — dependency injection without DI frameworks. -6. **Composite Config:** Settings merge defaults → user config file → environment variables → runtime overrides. -7. **QueryContext (State Tracking):** A single context object tracks task focus, read files, invoked skills, work log, and verified work across a query. -8. **Tool Output Offloading:** Large tool outputs (>8000 chars) are written to disk files with inline previews to avoid context bloat. +1. **Async generator streaming:** `AgentEngine.sendMessage()` yields typed events consumed by the TUI for incremental rendering. +2. **Reducer state machine:** `tui-ink/reducer.ts` is pure — engine events and UI actions are the only inputs; this keeps rendering testable. +3. **Hook system (observer):** HookExecutor dispatches lifecycle events with fnmatch-style tool name matching. +4. **Strategy for providers:** adapters implement a common streaming interface so the engine stays provider-agnostic. +5. **Factory functions:** `createProvider()`, `createDefaultRegistry()`, `loadSkillRegistry()` — dependency injection without DI frameworks. +6. **Composite config:** defaults → user file → environment variables → runtime overrides (persisted on slash command changes). ## Common Development Tasks ```bash # After editing the agent engine: -node --test test/agent-engine.test.js - -# After editing a tool in tools/registry.js: -node --test test/tools/ +node --import tsx --test test/engine-system-prompt.test.ts test/engine-tool-result.test.ts -# After editing CLI commands: -node --test test/cli.test.js test/cli-commands.test.js +# After editing TUI state/components: +node --import tsx --test test/tui-ink-reducer.test.ts test/tui-ink-reducer-redesign.test.ts # After editing the provider layer: -node --test test/providers/ +node --import tsx --test test/anthropic-provider.test.ts test/anthropic-tool-names.test.ts -# Full test suite before pushing: -npm test +# After editing permissions: +node --import tsx --test test/permissions-checker.test.ts + +# Full suite before pushing: +npm run typecheck && npm test ``` + +## Known Gaps (as of v1.6.0) + +- `npm run lint` currently aliases `tsc --noEmit`; ESLint is configured (`.eslintrc.json`) but not wired up. +- `npm run test:desktop` points at a `test/desktop/` directory that does not exist yet. +- Test coverage is concentrated in core/engine/api/TUI modules; tools, memory, skills, plugins, channels, and sandbox have no tests. +- CI runs on Node 18/ubuntu only and marks both test steps `continue-on-error: true` (failures do not fail the build). +- `examples/` still references the pre-1.5 `src/hub` API, which was removed in the architecture rewrite; example code does not run. +- Improvement roadmap: `docs/superpowers/specs/2026-08-21-v1.7-quality-and-features-spec.md`. diff --git a/README.en.md b/README.en.md index 058cbb5..97578da 100644 --- a/README.en.md +++ b/README.en.md @@ -7,7 +7,7 @@ [![PRs](https://img.shields.io/badge/PRs-welcome-brightgreen)](#development--contributing) [![npm](https://img.shields.io/npm/v/hax-agent-cli)](https://www.npmjs.com/package/hax-agent-cli) -Hax Agent is an AI coding assistant for developers, with CLI as the primary entry point and an Electron + Vue desktop app alongside it. It supports 12+ AI providers (Anthropic, OpenAI, DeepSeek, Groq, Mistral, Google, Moonshot, Zhipu, DashScope, Ollama, vLLM, OpenRouter), interactive chat, provider profile switching, local file tools, session memory management, LSP code navigation, terminal themes, and hook lifecycle extension. +Hax Agent is an AI coding assistant for developers. The terminal runs an Ink TUI by default (three-part layout, streaming output, menu-driven approvals), with an Electron + Vue desktop app alongside. It supports 12+ AI providers (Anthropic, OpenAI, DeepSeek, Groq, Mistral, Google, Moonshot, Zhipu, DashScope, OpenRouter, Ollama, vLLM), built-in file tools, shell execution, web search (DuckDuckGo, no API key needed), Skills/Plugins/Hooks extension, MCP integration, Docker sandboxing, multi-agent collaboration (swarm), and persistent memory. The codebase is TypeScript + ESM. --- @@ -16,15 +16,16 @@ Hax Agent is an AI coding assistant for developers, with CLI as the primary entr - [Features](#features) - [Prerequisites](#prerequisites) - [Quick Start](#quick-start) -- [Desktop App](#desktop-app) -- [Usage](#usage) +- [Command Line Usage](#command-line-usage) - [Interactive Commands](#interactive-commands) - [Skills System](#skills-system) +- [Plugins & Hooks](#plugins--hooks) - [Configuration](#configuration) - [Local Tools](#local-tools) - [Architecture Overview](#architecture-overview) - [Sessions & Memory](#sessions--memory) - [Provider Profiles](#provider-profiles) +- [Desktop App](#desktop-app) - [Development & Testing](#development--testing) - [License](#license) @@ -32,20 +33,22 @@ Hax Agent is an AI coding assistant for developers, with CLI as the primary entr ## Features -- **Interactive Agent Shell** — Enters chat mode by default, supporting continuous contextual conversations, slash commands, and streaming output. -- **Desktop GUI** — Electron + Vue interface that keeps the CLI workflow intact while adding session lists, file tree browsing, a right-side status panel, and session recovery. -- **Multi-Provider Support** — Built-in 12+ providers: Anthropic (Claude), OpenAI (GPT), Google (Gemini), DeepSeek, Groq, Mistral, Moonshot, Zhipu, DashScope, Ollama, vLLM, OpenRouter. -- **Provider Profiles** — Pre-configured profiles (claude, gpt, sonnet, haiku, gpt-mini, local) with custom profile support and one-command switching. -- **Model Management** — View available models and switch models at runtime. -- **Local Toolset** — File read/write, search, glob matching, and permission-gated shell command execution. -- **Skills System** — Create, manage, and invoke reusable skills by packaging repetitive workflows into SKILL.md files. -- **Hook Lifecycle** — 10 lifecycle hooks (session.start/end, pre/post.compact, pre/post.tool_use, etc.) for plugins and script extension. -- **LSP Code Navigation** — Built-in `/lsp` command for go-to-definition and workspace symbol search. -- **Terminal Themes** — Multiple color themes switchable via `/theme` command. -- **Session Memory** — Automatically saves conversation transcripts; new sessions automatically load recent context. -- **Layered Configuration** — Multi-level config merging with independent provider profile management. -- **Cost Tracking** — Token usage and cost estimation statistics. -- **Permission Management** — Four modes: normal (ask), yolo (auto-approve all), plan (block writes), fullauto (silent auto-approve). +- **Ink TUI interface** — Full-screen terminal UI by default: fixed three-part layout (history + live area + input), `` rendering of completed turns, slash command palette, menu-driven tool approvals, rich status bar (model / context usage / cost), native ink elements with correct CJK alignment. +- **Classic readline fallback** — `--legacy` or `HAXAGENT_LEGACY=1` switches to the classic readline interface with feature parity. +- **Desktop GUI** — Electron + Vue interface that keeps the CLI workflow while adding session lists, file tree browsing, a right-side status panel, and session recovery. +- **Multi-Provider Support** — Built-in 12+ providers: Anthropic (Claude), OpenAI (GPT), Google (Gemini), DeepSeek, Groq, Mistral, Moonshot, Zhipu, DashScope, OpenRouter, Ollama, vLLM. +- **Provider Profiles** — 22 pre-configured profiles (claude, sonnet, haiku, opus, gpt, gpt-mini, o3, deepseek, gemini, local, etc.) with custom profile support and one-command switching. +- **Local Toolset** — File read/write/edit/search/glob, permission-gated shell execution, web fetching, and key-free DuckDuckGo web search. +- **Multi-Agent Collaboration** — `agent` subtask tool, task/team lifecycle management, git worktree isolation, subprocess and in-process swarm backends. +- **Scheduled Tasks** — `cron.create` and related tools, `/dream` goal continuation, background tasks. +- **Skills System** — Package repetitive workflows into SKILL.md files, auto-discovered at both user and project level. +- **Plugin & Hook Lifecycle** — 10 lifecycle hooks (session.start/end, pre/post.compact, pre/post.tool_use, etc.) for plugin and script extension. +- **MCP Integration** — MCP client management over stdio/http/ws transports with automatic tool and resource discovery. +- **Sandbox Isolation** — Docker / bubblewrap / macOS / Windows backends; enable shell isolation with `--sandbox`. +- **LSP Code Navigation** — `/lsp` command for go-to-definition, find-references, and workspace symbol search. +- **Sessions & Memory** — Persistent session snapshots, `/continue` context recovery, persistent memory (Markdown files + MEMORY.md index), automatic memory extraction, context compaction. +- **Permission Management** — Four modes: normal (ask), yolo (auto-approve all), plan (block writes), full_auto (silent auto-approve). +- **Cost Tracking** — Token usage and cost statistics with cache hit analysis. --- @@ -53,7 +56,7 @@ Hax Agent is an AI coding assistant for developers, with CLI as the primary entr - **Node.js** >= 18 - **npm** (or pnpm / yarn) -- **API Key** (at least one provider) +- **API Key** (at least one cloud provider; not needed for Ollama / vLLM local inference) --- @@ -69,24 +72,26 @@ npm install -g hax-agent-cli git clone https://github.com/IdiotTIQS/hax-agent-cli.git cd hax-agent-cli npm install +npm run build ``` -### 2. Start the Interactive Shell +### 2. Start an Interactive Session ```bash -hax-agent -# or -npm start +hax-agent # Ink TUI (default) +npm run dev # Development mode (tsx runs src/cli.ts directly) ``` -On first launch, configure your API keys: +On first launch, configure your API keys from within the session: ```text /api-key anthropic sk-ant-xxxxxxxxxxxx /api-key openai sk-xxxxxxxxxxxx ``` -Or use pre-configured provider profiles: +You can also use environment variables (see [Configuration](#configuration)). + +### 3. Switch Provider Profiles ```text /provider claude # Switch to Anthropic Claude @@ -95,114 +100,89 @@ Or use pre-configured provider profiles: /provider list # List all available profiles ``` -### 3. Configure Provider - -Set up within the Shell at runtime: +Use `/models` to view available models for the current provider and `/model ` to switch at runtime. -```text -/provider anthropic # Switch to Anthropic -/provider openai # Switch to OpenAI -/provider deepseek # Switch to DeepSeek -/model claude-sonnet-4-20250514 -/api-url https://api.anthropic.com -/api-key anthropic sk-ant-xxxxxxxxxxxx -``` - -Or pre-configure via environment variables (see [Configuration](#configuration)). - -## Desktop App - -The desktop app shares the same configuration, session storage, and tool layer as the CLI. +--- -### Start the dev build +## Command Line Usage ```bash -npm run desktop:dev +hax-agent # Interactive session (Ink TUI) +hax-agent "explain this code" # Start with an initial prompt +hax-agent --provider deepseek # Specify a provider +hax-agent --profile opus # Use a profile shortcut +hax-agent -y "fix the bug in main.js" # YOLO mode, auto-approve all tools +hax-agent --sandbox # Docker sandbox for shell commands +hax-agent --legacy # Classic readline interface +hax-agent --batch "explain this project" # Single-turn batch, exits when done +hax-agent --batch --input task.txt --output result.md +hax-agent -v # Show version +hax-agent --help # Full help ``` -### Build the desktop app - -```bash -npm run desktop:build -``` +### All Options + +| Option | Description | +|--------|-------------| +| `-h`, `--help` | Show help | +| `-v`, `--version` | Show version | +| `--provider ` | LLM provider (anthropic, openai, deepseek, groq, mistral, google, moonshot, zhipu, dashscope, openrouter, ollama, vllm) | +| `--model ` | Model identifier | +| `--profile ` | Use a builtin profile (see [Provider Profiles](#provider-profiles)) | +| `--permission-mode ` | Permission mode: normal, yolo, plan, full_auto | +| `-y` | Shorthand for `--permission-mode yolo` | +| `--api-key ` | API key (overrides env var and saved key) | +| `--max-turns ` | Maximum tool execution turns (default: 200) | +| `--sandbox` | Enable Docker sandbox isolation for shell commands | +| `--no-color` | Disable ANSI colors | +| `--legacy`, `--no-ink` | Use the classic readline interface | +| `--ink` | No-op (ink is now the default; kept for compat) | +| `--batch ` | Single non-interactive turn | +| `--input ` | Read prompt from file (with `--batch`) | +| `--output ` | Write response to file (with `--batch`) | --- -## Usage - -```bash -# Start interactive chat (default) -hax-agent -hax-agent chat - -# View help and version -hax-agent help -hax-agent -v - -# List available models for the current provider -hax-agent models - -# Run diagnostics (script-friendly) -hax-agent doctor --json - -# List and resume sessions -hax-agent sessions -hax-agent resume - -# View or edit configuration -hax-agent config -hax-agent config edit - -# Other options -hax-agent --no-color # Disable ANSI color output -hax-agent --debug # Enable verbose debug logging +## Interactive Commands -# Use globally after linking -npm link -hax-agent # Available from any directory -``` +Type these slash commands in a session (typing `/` in the Ink TUI opens the command palette). -### Built-in npm Scripts +### Session Management | Command | Description | |---------|-------------| -| `npm start` | Start the CLI (`node src/cli.js`) | -| `npm run desktop:dev` | Start the Electron + Vue desktop app in development mode | -| `npm run desktop:build` | Build the desktop frontend assets | -| `npm run desktop:start` | Start the Electron desktop app directly | -| `npm run lint` | Run syntax checks for JS files | -| `npm test` | Run the test suite | -| `npm run test:desktop` | Build desktop and run desktop tests | - ---- - -## Interactive Commands - -Type the following slash commands in the Shell: +| `/help` | Show all available commands | +| `/exit` `/quit` `/q` | Exit the session | +| `/clear` | Clear the current context and start a new session | +| `/continue` | Resume the most recent session snapshot | +| `/session` | Manage session snapshots | +| `/summary` | Generate a summary of the current session | +| `/rewind [n]` | Roll back the last n turns (default 2) | +| `/export` | Export the session to a JSON file | +| `/copy` | Copy the last AI reply to the clipboard | +| `/turns` | Show turn statistics | +| `/files` | List files modified in this session | +| `/tag ` / `/tags` | Tag the session / list tags | +| `/version` | Show version information | + +### Model & Provider | Command | Description | |---------|-------------| -| `/help` | View all available commands | -| `/exit` or `/quit` | Exit the Shell | -| `/clear` | Clear the current context and start a new session | -| `/compact` | Compact the current conversation to reduce context usage | -| `/tools` | List available local tools | -| `/skills` | List available skills | -| `/goal [--max n] ` | Set a persistent goal until complete, blocked, or `/goal clear` | | `/models` | List available models for the current provider | -| `/model ` | Switch models | -| `/provider ` | Switch provider profile (`list` to see all) | +| `/model ` | Switch model | +| `/provider ` | Switch provider profile (`list` shows all) | | `/providers` | List all available AI providers | -| `/api-url ` | Set or view the API Base URL | -| `/api-key ` | Set API Key for a provider | -| `/cost` | View token usage and cost for this session | -| `/status` | Show session summary (model, cost, tokens) | -| `/context` | View context window usage | -| `/config` | Show current configuration | -| `/copy` | Copy last AI response to clipboard | -| `/export` | Export session to JSON file | -| `/doctor` | Run diagnostics | -| `/theme ` | Switch terminal color theme (`list` to see all) | +| `/api-url ` | Set or view the API base URL | +| `/api-key ` | Set a provider API key | +| `/status` | Session summary (model, cost, tokens) | +| `/cost` | Token and cost usage for this session | +| `/context` | Context window usage | + +### Permissions & Sandbox + +| Command | Description | +|---------|-------------| | `/yolo` | Toggle YOLO mode (auto-approve all tools) | | `/plan` | Toggle Plan mode (block all mutating tools) | | `/fullauto` | Toggle Full Auto mode (silent auto-approve) | @@ -210,37 +190,67 @@ Type the following slash commands in the Shell: | `/permissions [allow\|deny\|reset\|yolo\|normal] [tool]` | Manage tool permissions | | `/allow ` | Always allow a tool | | `/deny ` | Always deny a tool | -| `/memory [search\|list]` | Manage persistent memories | -| `/lsp def ` | Go to symbol definition | -| `/lsp search ` | Search workspace symbols | -| `/personalize` | Extract environment rules from conversation to rules.md | -| `/init` | Initialize .hax-agent project directory | -| `/version` | Show version info | +| `/sandbox` | View/manage sandbox status | + +### Memory & Context + +| Command | Description | +|---------|-------------| +| `/memory [search\|list]` | Manage persistent memory | +| `/compact` | Compact the conversation to reduce context usage | +| `/think` | Adjust thinking mode | +| `/personalize` | Extract environment rules into rules.md | +| `/dream` | Extract memories from the conversation and continue goals | + +### Tools & Extensions + +| Command | Description | +|---------|-------------| +| `/tools` | List available local tools | +| `/skills` | List skills | +| `/mcp` | View/manage MCP servers | +| `/plugin` | Plugin list and management | +| `/agents` | Sub-agent management (including `stop`) | +| `/goal [--max n] ` | Set a persistent goal until done, blocked, or `/goal clear` | +| `/lsp def ` / `/lsp search ` | Go to definition / search workspace symbols | +| `/config` | Show current configuration | +| `/init` | Initialize the .hax-agent project directory | +| `/doctor` | Run environment diagnostics | +| `/theme ` | Switch terminal color theme (`list` shows all) | +| `/keybindings` | Show keybindings | + +### Git & Workspace + +| Command | Description | +|---------|-------------| +| `/diff` | Show workspace file changes | +| `/branch` | Switch/create a branch | +| `/release-notes` | Show release notes | +| `/reload` | Hot-reload hooks/plugins | +| `/feedback ` | Send feedback | --- ## Skills System -Skills are reusable workflow packages that allow you to save repetitive task processes as SKILL.md files and quickly invoke them in later sessions via slash commands. +Skills are reusable workflow packages: save a repetitive task flow as a SKILL.md file and invoke it as a slash command in later sessions. -### Skills Directory Structure - -Skills are stored in the following locations: +### Directory Layout ```text -~/.hax-agent/skills/ # User-level skills (available across projects) +~/.haxagent/skills/ # User-level skills (available across projects) ├── code-review/ │ └── SKILL.md └── deploy-workflow/ └── SKILL.md -.hax-agent/skills/ # Project-level skills (available only in the current project) +.hax-agent/skills/ # Project-level skills (current project only) ├── run-tests/ │ └── SKILL.md └── ... ``` -Each skill is a directory containing a `SKILL.md` file. +Each skill is a directory containing one `SKILL.md` file. ### SKILL.md Format @@ -252,7 +262,7 @@ allowed-tools: - file.read - file.write - shell.run -when_to_use: Describes when to automatically invoke this skill. Start with "Use when...". +when_to_use: Describe when to invoke this skill. Start with "Use when...". argument-hint: "[arg1] [arg2]" arguments: - arg1 @@ -261,302 +271,299 @@ arguments: # Skill Title -Detailed description of this skill's workflow. - -## Inputs -- `$arg1`: Description of this input - -## Goal -Clearly state the goal of this workflow. +Describe the workflow in detail. ## Steps -### 1. Step Name -What to do in this step. Be specific and actionable. +### 1. Step name +What this step does. -**Success criteria**: Always include! This indicates the step is complete and you can move on. +**Success criteria**: Always include! This signals the step is complete. ``` -### Invoking Skills - -In the Shell, simply type the skill name as a slash command: +### Invoking a Skill ```text /code-review # Invoke the code review skill -/code-review src/index.js # Invoke with arguments +/code-review src/index.ts # With arguments /skills # List all available skills ``` --- +## Plugins & Hooks + +Plugins extend agent behavior through the hook lifecycle. Place them in `~/.haxagent/plugins/` (user-level) or `.hax-agent/plugins/` (project-level); they are discovered automatically at startup. + +Each plugin directory contains a `plugin.json` manifest and may mount hook definitions and a `skills/` subdirectory. Available lifecycle hooks: + +```text +session.start / session.end +pre.compact / post.compact +pre.tool_use / post.tool_use +user.prompt_submit +notification / stop / subagent.stop +``` + +Use `/plugin` to view loaded plugins and `/reload` to hot-reload. + +--- + ## Configuration -### Configuration Priority - -1. **Default Configuration** — Built into `src/config/settings.js` -2. **User Configuration** — `~/.hax-agent/settings.json` -3. **Environment Variables** — All `HAX_AGENT_*` prefixed variables - -> It is recommended not to commit configuration containing API keys to version control. Use environment variables or user configuration instead. - -### Supported Providers - -| Provider | Aliases | Default Model | Environment Variables | -|----------|---------|---------------|----------------------| -| **Anthropic** | `anthropic`, `claude` | `claude-sonnet-4-20250514` | `ANTHROPIC_API_KEY` | -| **OpenAI** | `openai`, `gpt` | `gpt-4o` | `OPENAI_API_KEY` | -| **DeepSeek** | `deepseek` | `deepseek-chat` | `DEEPSEEK_API_KEY` | -| **Groq** | `groq` | `llama-3.3-70b-versatile` | `GROQ_API_KEY` | -| **Mistral** | `mistral` | `mistral-large-latest` | `MISTRAL_API_KEY` | -| **Google** | `google`, `gemini` | `gemini-2.5-pro` | `GOOGLE_API_KEY` | -| **Moonshot** | `moonshot` | `moonshot-v1-8k` | `MOONSHOT_API_KEY` | -| **Zhipu** | `zhipu` | `glm-4-plus` | `ZHIPUAI_API_KEY` | -| **DashScope** | `dashscope` | `qwen-max` | `DASHSCOPE_API_KEY` | -| **OpenRouter** | `openrouter` | `anthropic/claude-sonnet-4` | `OPENROUTER_API_KEY` | -| **Ollama** | `ollama` | `llama3.2` | — (local) | -| **vLLM** | `vllm` | — | — (local) | - -### Key Environment Variables - -| Variable | Description | Default | -|----------|-------------|---------| -| `HAX_AGENT_PROVIDER` | Provider name | `anthropic` | -| `ANTHROPIC_API_KEY` | Anthropic API Key | — | -| `OPENAI_API_KEY` | OpenAI API Key | — | -| `DEEPSEEK_API_KEY` | DeepSeek API Key | — | -| `GROQ_API_KEY` | Groq API Key | — | -| `MISTRAL_API_KEY` | Mistral API Key | — | -| `GOOGLE_API_KEY` | Google API Key | — | -| `HAX_AGENT_MODEL` | Model ID | — | -| `HAX_AGENT_MAX_TURNS` | Maximum conversation turns | `25` | -| `HAX_AGENT_API_URL` | API Base URL | — | -| `HAX_AGENT_PERMISSIONS_MODE` | Default permission mode | `normal` | -| `HAX_AGENT_SHELL_ENABLED` | Enable shell tool | `true` | - -### Configuration File Example +### Configuration Layers + +1. **Defaults** — built into `src/config/settings.ts` +2. **User config** — `~/.haxagent/settings.json` +3. **Environment variables** — provider API keys and path overrides +4. **Runtime overrides** — slash command changes are persisted automatically + +> Do not commit configuration containing API keys. Prefer environment variables or the user-level config file. + +### Config File Example + +Full structure of `~/.haxagent/settings.json` (defaults): ```json { "agent": { "provider": "anthropic", - "model": "claude-sonnet-4-20250514", + "model": "claude-sonnet-4-6", "maxTurns": 25 }, - "permissions": { - "mode": "normal" - }, - "tools": { - "shell": { - "enabled": true - } + "permissions": { "mode": "normal" }, + "tools": { "shell": { "enabled": true } }, + "sandbox": { + "enabled": true, + "backend": "auto", + "image": "node:18-alpine", + "network": "none", + "cpus": 2, + "memory": "512m" }, - "ui": { - "locale": "en", - "autoClearScreen": true - }, - "context": { - "compactionEnabled": false, - "compactionThreshold": 0.85 - } + "ui": { "locale": "en", "autoClearScreen": true }, + "context": { "compactionEnabled": false, "compactionThreshold": 0.85 } } ``` +### Data Directories + +| Path | Purpose | +|------|---------| +| `~/.haxagent/settings.json` | Global configuration | +| `~/.haxagent/skills/` | User-level skills | +| `~/.haxagent/plugins/` | User-level plugins | +| `~/.haxagent/memories/` | Persistent memory | +| `~/.haxagent/sessions/` | Session snapshots | +| `~/.haxagent/data/tasks/` | Background task data | +| `~/.haxagent/data/cron_jobs.json` | Cron job registry | +| `.hax-agent/` | Project-level runtime data (config, skills, plugins, trash) | + +### Environment Variables + +| Variable | Description | +|----------|-------------| +| `HAX_AGENT_PROVIDER` | Default provider name | +| `ANTHROPIC_API_KEY` | Anthropic API key | +| `OPENAI_API_KEY` | OpenAI API key | +| `DEEPSEEK_API_KEY` | DeepSeek API key | +| `GROQ_API_KEY` | Groq API key | +| `MISTRAL_API_KEY` | Mistral API key | +| `GOOGLE_API_KEY` | Google API key | +| `MOONSHOT_API_KEY` | Moonshot API key | +| `ZHIPUAI_API_KEY` | Zhipu API key | +| `DASHSCOPE_API_KEY` | DashScope API key | +| `OPENROUTER_API_KEY` | OpenRouter API key | +| `HAXAGENT_CONFIG_DIR` | Override the global config directory (default `~/.haxagent`) | +| `HAXAGENT_DATA_DIR` | Override the data directory | +| `HAXAGENT_LOGS_DIR` | Override the logs directory | +| `HAXAGENT_LEGACY=1` | Make readline the default interface in all shells | + +Ollama and vLLM run local inference and need no API key. + --- ## Local Tools -The Agent Shell includes a restricted tool registry, with all file operations confined to the workspace root to prevent path traversal attacks. - -| Tool | Description | Security Restriction | -|------|-------------|---------------------| -| `file.read` | Read text files within the workspace | Path restricted to workspace root | -| `file.write` | Write text files within the workspace | Path restricted to workspace root | -| `file.edit` | Precisely replace text in files | Path restricted to workspace root | -| `file.delete` | Delete files (moves to trash by default) | Path restricted to workspace root | -| `file.glob` | List files matching a glob pattern | Path restricted to workspace root | -| `file.search` | Search for content in text files | Supports regex / case sensitivity config | -| `file.readDirectory` | List directory contents | Path restricted to workspace root | -| `shell.run` | Execute local commands | Permission prompt decides in non-yolo mode | -| `web.fetch` | Fetch web pages and convert to plain text | URL fetching | -| `web.search` | Search the web for information | Requires search API config | +The agent has a restricted tool registry; all file operations are confined to the workspace root to prevent path traversal attacks. + +### Core Tools + +| Tool | Description | Safety Constraint | +|------|-------------|-------------------| +| `file.read` | Read a workspace text file (offset/limit pagination) | Path confined to workspace root | +| `file.write` | Write a workspace text file | Path confined to workspace root | +| `file.edit` | Replace exact text in a file | Path confined to workspace root | +| `file.delete` | Delete a file (moved to `.hax-agent/trash` by default) | Path confined to workspace root | +| `file.glob` | Match files by glob pattern | Path confined to workspace root | +| `file.search` | Search file contents (regex/case options) | ReDoS protection | +| `shell.run` | Run a local command | Permission-gated outside yolo mode; `--sandbox` isolation optional | +| `web.fetch` | Fetch a URL as plain text | URL validation | +| `web.search` | DuckDuckGo web search | No API key needed | + +### Extended Tools (auto-registered) + +- **Multi-agent**: `agent` (subtask delegation), `send_message` (inter-agent messaging), `team.create` / `team.delete` +- **Tasks**: `task.create` / `task.get` / `task.list` / `task.output` / `task.stop` / `task.update` +- **Plan mode**: `enter_plan_mode` / `exit_plan_mode` +- **Worktrees**: `enter_worktree` / `exit_worktree` / `list_worktrees` +- **Others**: `todo_write`, `cron.create` / `cron.delete` / `cron.list` / `cron.toggle`, `ask_user`, `grep`, `glob`, `skill`, `lsp`, `notebook_edit` +- **Images**: `image_to_text`, `image_generation` +- **MCP**: `list_mcp_tools`, `list_mcp_resources`, `read_mcp_resource`, `mcp_auth` --- ## Architecture Overview +The codebase is TypeScript + ESM (NodeNext) with a layered architecture: `core/` (typed protocols) → `engine/` (agent runtime) → `api/` / `tools/` / `services/` (implementations). + ``` src/ -├── index.js # Module export entry -├── cli.js # CLI entry + interactive Shell -├── api/ -│ ├── provider.js # 12+ provider clients & registry -│ └── retry.js # Retry logic with backoff -├── commands/ -│ ├── registry.js # ~30 slash commands -│ └── extended-commands.js # Extended command set -├── config/ -│ ├── settings.js # Settings load/save -│ └── profiles.js # Provider profile management -├── core/ # Foundation layer — typed protocols -│ ├── api/ -│ │ ├── errors.js # API error classification -│ │ └── provider-adapter.js # Provider adapter protocol & stream events -│ ├── messages/ -│ │ └── types.js # StandardMessage, ContentBlock types, stream events -│ ├── memory/ -│ │ └── compaction.js # Token estimation & compaction -│ └── permissions/ -│ └── checker.js # Permission checker -├── engine/ # Agent runtime -│ ├── agent.js # AgentEngine, Session, HookExecutor -│ └── query.js # QueryContext state tracking -├── hooks/ -│ └── registry.js # Hook registry -├── memory/ -│ ├── compact.js # Message micro-compaction -│ └── store.js # Persistent memory store -├── plugins/ -│ ├── installer.js # Plugin installer -│ ├── registry.js # Plugin auto-discovery -│ └── schema.js # Plugin manifest validation -├── prompts/ -│ └── manager.js # System prompt assembly -├── services/ # Auxiliary services -│ ├── autodream.js # Auto goal continuation -│ ├── lsp.js # LSP code navigation -│ ├── mcp.js # MCP server integration -│ ├── memory-extract.js # Memory extraction -│ ├── personalization.js # Rule extraction & rules.md -│ └── session-memory.js # Session memory -├── shared/ -│ ├── themes.js # Terminal themes -│ └── utils.js # ANSI codes & style utilities -├── skills/ -│ └── registry.js # Skill auto-discovery & loading -├── tools/ -│ ├── registry.js # 10 built-in tools -│ ├── agent-tool.js # Agent subprocess tool -│ ├── extended.js # Extended tool set -│ ├── image-tools.js # Image processing -│ ├── mcp-tools.js # MCP tool integration -│ ├── plan-mode-tool.js # Plan mode tool -│ ├── send-message-tool.js # Inter-agent messaging -│ └── worktree-tool.js # Git worktree management -└── tui/ - └── index.js # Terminal UI (alt-screen, event rendering, status bar) - -desktop/ -├── main/ # Electron main process -├── preload/ # Preload scripts -└── renderer/ # Vue desktop frontend +├── cli.ts # CLI entry: arg parsing, Ink TUI / readline dispatch +├── index.ts # Library entry: full module barrel export +├── tui-ink/ # Ink TUI (default interface) +│ ├── App.tsx # Root component: three-part layout + Static history +│ ├── reducer.ts # State machine (engine events → UI state) +│ ├── components/ # ToolCall, DiffView, CommandPalette, +│ │ # ApprovalPrompt, StatusBar, ThinkingBlock… +│ └── ui/ # Primitives: Select, Separator, useTerminalSize +├── core/ # Foundation layer — typed protocols +│ ├── api/ # Provider adapter protocol, error classification +│ ├── messages/ # StandardMessage, ContentBlock types +│ ├── memory/ # Token estimation and compaction utilities +│ └── permissions/ # Permission checker +├── engine/ # Agent runtime +│ ├── agent.ts # AgentEngine main loop, Session, HookExecutor +│ ├── query.ts # QueryContext state tracking +│ └── cost-tracker.ts # Cost tracking +├── api/ # Provider clients (12+ providers) and retry +├── tools/ # Tool registry (9 core + extended set) +├── commands/ # 55 slash commands +├── config/ # settings, profiles, paths +├── skills/ plugins/ hooks/ # Extension ecosystem +├── memory/ # Persistent memory (store, compact, relevance) +├── services/ # LSP, MCP, cron, session storage, token estimation +├── sandbox/ # Sandbox backends: docker, bwrap, macos, win +├── swarm/ # Multi-agent collaboration (subprocess / in-process) +├── channels/ # IM channel adapters (Feishu, Slack, Discord, etc. — 11) +├── prompts/ # System prompt assembly +├── auth/ # Authentication management +└── shared/ # Themes, ANSI utilities + +desktop/ # Electron + Vue 3 desktop app +├── main/ # Electron main process (IPC, approval bridge) +├── preload/ # Preload scripts +└── renderer/ # Vue 3 frontend (Vite) ``` -### Core Module Responsibilities - -| Module | Responsibility | -|--------|---------------| -| `api/provider.js` | Unified streaming provider clients, 12+ provider registry | -| `core/api/provider-adapter.js` | Typed provider adapter protocol, stream event types, Anthropic/OpenAI adapters | -| `core/messages/types.js` | StandardMessage class, ContentBlock discriminated union, token estimation, format conversion | -| `core/permissions/checker.js` | Permission checker, four modes, sensitive path detection | -| `engine/agent.js` | AgentEngine main loop, Session management, HookExecutor lifecycle dispatch | -| `engine/query.js` | QueryContext: task focus, file tracking, skill tracking, work log | -| `config/settings.js` | Config load/save from `~/.haxagent/settings.json` | -| `config/profiles.js` | ProfileManager: built-in + custom provider profiles, runtime switching | -| `commands/registry.js` | ~30 slash command registration and dispatch | -| `tools/registry.js` | ToolRegistry: 10 built-in tools, isReadOnly classification, path sandboxing | -| `tui/index.js` | Terminal UI: alt-screen buffer, event-driven rendering, approval prompts | -| `skills/registry.js` | Skill discovery, loading, and system prompt generation | -| `services/lsp.js` | Code navigation: go-to-definition, workspace symbol search | -| `services/personalization.js` | Environment rule extraction and rules.md generation | -| `memory/store.js` | Persistent memory CRUD with search | -| `memory/compact.js` | Token-aware message compaction | +### Core Data Flow + +``` +User input → cli.ts → commands/registry (slash commands) + ↓ chat message + engine/agent.ts (AgentEngine tool loop) + ↓ ↓ + api/provider.ts tools/registry.ts + (LLM streaming) (tool execution + permission checks) + ↓ + tui-ink/reducer.ts (events → state) → terminal rendering +``` + +AgentEngine is an async generator that yields typed events (`message.delta`, `tool.start`, `tool.result`, `turn.completed`, etc.). The TUI consumes these events for incremental rendering; the desktop app forwards the same event stream over IPC. --- ## Sessions & Memory -### Session Storage +### Session Snapshots -All session transcripts are saved as JSONL files in the configuration directory: +Session snapshots are stored in `~/.haxagent/sessions/` as JSON files containing messages, token usage, tool call counts, and timestamps. `/continue` resumes the most recent snapshot; `/session` manages the snapshot list. -```text -.hax-agent/sessions/ -├── 2025-01-15T10-30-00-000Z-a1b2c3d4.jsonl -└── ... -``` - -- Each record is a single line of JSON, containing `timestamp`, `role`, `content`, and other fields. -- The desktop app's "Recent Sessions" list reads from the same transcript files and can resume historical conversations. - -### Memory Storage +### Persistent Memory -Persistent memories are saved as JSON files in: +Memories are stored as Markdown files in `~/.haxagent/memories/` with an auto-generated `MEMORY.md` index: -```text -.hax-agent/memory/ -├── user-preferences-5f8a2b1c.json -└── ... -``` - -- Manage memories via `/memory search ` or `/memory list`. -- `/personalize` extracts environment rules from conversations into `.hax-agent/rules.md`. +- Signature deduplication and TTL expiry cleanup +- `/memory search ` scores matches by title, content, and tags +- `/dream` automatically extracts memories from conversation (LLM extraction, top 3) +- `/personalize` extracts environment rules into rules.md +- Each memory supports category, scope, importance, and tags metadata --- ## Provider Profiles -Pre-configured profiles for quick provider switching via `/provider`: +Use `/provider ` or `--profile `: | Profile | Provider | Model | |---------|----------|-------| -| `claude` | Anthropic | claude-sonnet-4-20250514 | -| `sonnet` | Anthropic | claude-sonnet-4-20250514 | -| `haiku` | Anthropic | claude-haiku-3-5-20241022 | -| `gpt` | OpenAI | gpt-4o | -| `gpt-mini` | OpenAI | gpt-4o-mini | -| `local` | Ollama | (local config) | - -Custom profiles are managed via `~/.haxagent/profiles.json`, switchable with `/provider `. +| `claude` / `sonnet` | Anthropic | claude-sonnet-4-6 | +| `haiku` | Anthropic | claude-haiku-4-5-20251001 | +| `opus` | Anthropic | claude-opus-4-7 | +| `gpt` / `gpt-pro` / `gpt-mini` / `o3` | OpenAI | gpt-5.4-mini etc. | +| `deepseek` / `deepseek-pro` | DeepSeek | deepseek-v4-flash | +| `groq` | Groq | llama-3.3-70b-versatile | +| `mistral` | Mistral | mistral-large-latest | +| `google` / `gemini` / `gemini-pro` | Google | gemini-2.5-pro / gemini-2.5-flash | +| `moonshot` | Moonshot | moonshot-v1-8k | +| `zhipu` | Zhipu | glm-4.5-plus | +| `dashscope` | DashScope | qwen-max-latest | +| `openrouter` | OpenRouter | anthropic/claude-sonnet-4.6 | +| `ollama` | Ollama (local) | llama3.3 | +| `local` | Ollama-compatible endpoint | local config | +| `vllm` | vLLM (local) | default | + +Custom profiles are managed via `~/.haxagent/profiles.json` and switchable with `/provider `. --- -## Development & Testing +## Desktop App -### Running Tests +The desktop app shares the same configuration, session storage, and tool layer as the CLI. ```bash -npm test +npm run desktop:dev # Start dev mode +npm run desktop:build # Build frontend assets +npm run desktop:start # Launch Electron directly ``` -The project uses the Node.js built-in test runner (`node --test`). Test files are in the `test/` directory. +--- + +## Development & Testing + +### Common Commands + +| Command | Description | +|---------|-------------| +| `npm run dev` | Run `src/cli.ts` directly via tsx (development) | +| `npm run build` | Compile TypeScript to `dist/` (tsc) | +| `npm start` | Run the compiled `dist/cli.js` | +| `npm run typecheck` | `tsc --noEmit` type check | +| `npm test` | Run the test suite (node --test + tsx) | +| `npm run desktop:dev` | Desktop development mode | ### Directory Conventions -- `src/` — Source code, following CommonJS module conventions, layered architecture (core -> engine -> api/tools/services) -- `desktop/` — Desktop app source, sharing the same core layer as the CLI -- `test/` — Test files -- `.hax-agent/` — Runtime data (sessions, memories, settings), already in `.gitignore` +- `src/` — TypeScript source (ESM, NodeNext), layered architecture +- `desktop/` — Desktop app source, shares the core layer with the CLI +- `test/` — Test files (must be registered in `scripts/run-tests.js` to run) +- `dist/` — Build output (npm package content) ### Development & Contributing 1. Fork this repository -2. Create your feature branch (`git checkout -b feat/amazing-feature`) +2. Create a feature branch (`git checkout -b feat/amazing-feature`) 3. Commit your changes (`git commit -m 'feat: add amazing feature'`) -4. Push to the branch (`git push origin feat/amazing-feature`) -5. Open a Pull Request +4. Push and open a Pull Request -Issues and PRs are welcome! Please ensure: -- New features include corresponding test cases -- Code style is consistent (follow existing conventions) -- Related documentation is updated +Issues and PRs are welcome. Please include tests for new features and register the test file in the `scripts/run-tests.js` execution list. --- ## License -MIT (c) [IdiotTIQS](https://github.com/IdiotTIQS) +MIT © [IdiotTIQS](https://github.com/IdiotTIQS) --- -*Hax Agent CLI -- Let your AI coding assistant serve you in your terminal.* +*Hax Agent — an AI coding assistant at your service in the terminal.* diff --git a/README.md b/README.md index 3bef81d..8baab31 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ [![PRs](https://img.shields.io/badge/PRs-welcome-brightgreen)](#开发与贡献) [![npm](https://img.shields.io/npm/v/hax-agent-cli)](https://www.npmjs.com/package/hax-agent-cli) -Hax Agent 是一个面向开发者的 AI 编码助手,CLI 仍是一等入口,同时提供 Electron + Vue 桌面端。支持 12+ AI 提供商(Anthropic、OpenAI、DeepSeek、Groq、Mistral、Google、Moonshot、智谱、DashScope、Ollama、vLLM、OpenRouter),支持交互式对话、多 Provider 切换、Provider 配置档案、本地文件工具、会话记忆管理、LSP 代码导航、终端主题切换以及 Hook 生命周期扩展。 +Hax Agent 是一个面向开发者的 AI 编码助手。终端默认运行 Ink TUI(三段式布局、流式输出、菜单式审批),也提供 Electron + Vue 桌面端。支持 12+ AI 提供商(Anthropic、OpenAI、DeepSeek、Groq、Mistral、Google、Moonshot、智谱、DashScope、OpenRouter、Ollama、vLLM),内置文件工具、shell 执行、Web 搜索(DuckDuckGo,无需 API Key)、Skills/Plugins/Hooks 扩展、MCP 集成、Docker 沙箱、多 Agent 协作(swarm)以及持久化记忆。代码库为 TypeScript + ESM。 --- @@ -16,15 +16,16 @@ Hax Agent 是一个面向开发者的 AI 编码助手,CLI 仍是一等入口 - [功能特性](#功能特性) - [环境要求](#环境要求) - [快速开始](#快速开始) -- [桌面端](#桌面端) -- [使用方式](#使用方式) +- [命令行用法](#命令行用法) - [交互式命令](#交互式命令) - [Skills 技能系统](#skills-技能系统) +- [插件与 Hooks](#插件与-hooks) - [配置说明](#配置说明) - [本地工具](#本地工具) - [架构概览](#架构概览) - [会话与记忆](#会话与记忆) - [Provider 档案](#provider-档案) +- [桌面端](#桌面端) - [开发与测试](#开发与测试) - [License](#license) @@ -32,20 +33,22 @@ Hax Agent 是一个面向开发者的 AI 编码助手,CLI 仍是一等入口 ## 功能特性 -- **交互式 Agent Shell** — 默认进入聊天模式,支持持续上下文对话、斜杠命令和流式输出。 +- **Ink TUI 交互界面** — 默认全屏终端 UI:固定三段式布局(历史区 + 活动区 + 输入区)、`` 已完成轮次渲染、斜杠命令面板、菜单式工具审批、富状态栏(模型 / 上下文用量 / 费用),原生 ink 元素渲染,CJK 对齐正确。 +- **经典 readline 备选** — `--legacy` 或 `HAXAGENT_LEGACY=1` 回退到经典 readline 界面,功能等价。 - **桌面 GUI** — Electron + Vue 界面,保留 CLI 工作流,同时提供会话列表、文件树、右侧状态面板和会话恢复。 -- **多 Provider 支持** — 内置 12+ Provider:Anthropic(Claude)、OpenAI(GPT)、Google(Gemini)、DeepSeek、Groq、Mistral、Moonshot、智谱、DashScope、Ollama、vLLM、OpenRouter。 -- **Provider 档案管理** — 预置 claude、gpt、sonnet、haiku、gpt-mini、local 档案,支持自定义档案,运行时一键切换。 -- **模型管理** — 运行时查看可用模型、动态切换模型。 -- **本地工具集** — 文件读写、搜索、Glob 匹配以及带权限确认的 shell 命令执行。 -- **Skills 技能系统** — 支持创建、管理和调用可复用的技能,将重复性工作流封装为 SKILL.md 文件。 -- **Hook 生命周期** — 10 种生命周期钩子(session.start/end、pre/post.compact、pre/post.tool_use 等),支持插件和脚本扩展。 -- **LSP 代码导航** — 内置 `/lsp` 命令,支持 go-to-definition 和 workspace 符号搜索。 -- **终端主题** — 支持多种终端颜色主题,`/theme` 命令实时切换。 -- **会话记忆** — 自动保存对话 transcript,新会话自动加载最近的上下文。 -- **分层配置** — 支持多级优先级配置合并,Provider 档案独立管理。 -- **Cost 追踪** — 统计 token 用量与费用估算。 -- **权限管理** — 四种权限模式:normal(询问)、yolo(全部批准)、plan(阻止写操作)、fullauto(静默批准)。 +- **多 Provider 支持** — 内置 12+ Provider:Anthropic(Claude)、OpenAI(GPT)、Google(Gemini)、DeepSeek、Groq、Mistral、Moonshot、智谱、DashScope、OpenRouter、Ollama、vLLM。 +- **Provider 档案** — 22 个预置档案(claude、sonnet、haiku、opus、gpt、gpt-mini、o3、deepseek、gemini、local 等),支持自定义,运行时一键切换。 +- **本地工具集** — 文件读写/编辑/搜索/Glob、带权限确认的 shell 执行、网页抓取、免 Key 的 DuckDuckGo 网络搜索。 +- **多 Agent 协作** — `agent` 子任务工具、task/team 生命周期管理、git worktree 隔离、swarm 子进程/进程内两种后端。 +- **定时任务** — `cron.create` 等工具与 `/dream` 目标续跑,支持后台任务。 +- **Skills 技能系统** — 将重复性工作流封装为 SKILL.md 文件,用户级与项目级自动发现。 +- **插件与 Hook 生命周期** — 10 种生命周期钩子(session.start/end、pre/post.compact、pre/post.tool_use 等),支持插件与脚本扩展。 +- **MCP 集成** — stdio/http/ws 传输的 MCP 客户端管理,工具与资源自动发现。 +- **沙箱隔离** — Docker / bubblewrap / macOS / Windows 四种后端,`--sandbox` 一键启用 shell 隔离执行。 +- **LSP 代码导航** — `/lsp` 命令支持 go-to-definition、find-references 和 workspace 符号搜索。 +- **会话与记忆** — 会话快照持久化、`/continue` 恢复上下文、持久化记忆(Markdown 文件 + MEMORY.md 索引)、自动记忆提取、上下文压缩。 +- **权限管理** — 四种模式:normal(询问)、yolo(全部批准)、plan(阻止写操作)、full_auto(静默批准)。 +- **Cost 追踪** — token 用量与费用统计,支持缓存命中分析。 --- @@ -53,7 +56,7 @@ Hax Agent 是一个面向开发者的 AI 编码助手,CLI 仍是一等入口 - **Node.js** >= 18 - **npm**(或 pnpm / yarn) -- **API Key**(至少一个 Provider) +- **API Key**(至少一个云 Provider;仅使用 Ollama / vLLM 本地推理时无需) --- @@ -69,24 +72,26 @@ npm install -g hax-agent-cli git clone https://github.com/IdiotTIQS/hax-agent-cli.git cd hax-agent-cli npm install +npm run build ``` -### 2. 启动交互式 Shell +### 2. 启动交互式会话 ```bash -hax-agent -# 或 -npm start +hax-agent # 进入 Ink TUI(默认) +npm run dev # 源码开发模式(tsx 直接运行 src/cli.ts) ``` -首次运行 `hax-agent` 时,如果还没有配置 API Key,可以使用 `/api-key` 命令设置: +首次运行时如果还没有配置 API Key,可以在会话中使用 `/api-key` 命令设置: ```text /api-key anthropic sk-ant-xxxxxxxxxxxx /api-key openai sk-xxxxxxxxxxxx ``` -也可以使用预置的 Provider 档案快速切换: +也可以直接使用环境变量(见[配置说明](#配置说明))。 + +### 3. 切换 Provider 档案 ```text /provider claude # 切换到 Anthropic Claude @@ -95,115 +100,89 @@ npm start /provider list # 查看所有可用档案 ``` -### 3. 配置 Provider - -在 Shell 中运行时设置: - -```text -/provider anthropic # 切换到 Anthropic -/provider openai # 切换到 OpenAI -/provider deepseek # 切换到 DeepSeek -/model claude-sonnet-4-20250514 -/api-url https://api.anthropic.com -/api-key anthropic sk-ant-xxxxxxxxxxxx -``` - -或通过环境变量预配置(见[配置说明](#配置说明))。 - -## 桌面端 - -桌面端与 CLI 共用同一套配置、会话存储和工具层。 - -### 启动开发版 - -```bash -npm run desktop:dev -``` - -### 构建桌面端 - -```bash -npm run desktop:build -``` +运行时还可以用 `/models` 查看当前 Provider 的可用模型,`/model ` 动态切换。 --- -## 使用方式 +## 命令行用法 ```bash -# 启动交互式聊天(默认) -hax-agent -hax-agent chat - -# 查看帮助和版本 -hax-agent help -hax-agent -v - -# 查看当前 Provider 可用模型 -hax-agent models - -# 运行诊断(可用于脚本) -hax-agent doctor --json - -# 查看和管理历史会话 -hax-agent sessions -hax-agent resume - -# 查看或编辑配置 -hax-agent config -hax-agent config edit - -# 其他选项 -hax-agent --no-color # 禁用彩色输出 -hax-agent --debug # 启用详细调试日志 - -# 全局链接后可直接使用 -npm link -hax-agent # 任意目录下可用 +hax-agent # 交互式会话(Ink TUI) +hax-agent "解释这段代码" # 带初始 prompt 启动 +hax-agent --provider deepseek # 指定 Provider +hax-agent --profile opus # 使用档案快捷方式 +hax-agent -y "修复 main.js 的 bug" # YOLO 模式自动批准所有工具 +hax-agent --sandbox # 启用 Docker 沙箱隔离 shell 命令 +hax-agent --legacy # 经典 readline 界面 +hax-agent --batch "解释这个项目" # 单轮批处理,结束即退出 +hax-agent --batch --input task.txt --output result.md +hax-agent -v # 查看版本 +hax-agent --help # 查看完整帮助 ``` -### 内置 npm 脚本 +### 完整参数 -| 命令 | 说明 | +| 参数 | 说明 | |------|------| -| `npm start` | 启动 CLI(`node src/cli.js`) | -| `npm run desktop:dev` | 启动 Electron + Vue 桌面端开发模式 | -| `npm run desktop:build` | 构建桌面端前端资源 | -| `npm run desktop:start` | 直接启动 Electron 桌面端 | -| `npm run auth:team` | 输出认证重构团队计划 | -| `npm run lint` | 对 JS 文件运行语法检查 | -| `npm test` | 运行测试套件 | -| `npm run test:desktop` | 构建桌面端并运行桌面端测试 | +| `-h`, `--help` | 显示帮助 | +| `-v`, `--version` | 显示版本 | +| `--provider ` | 指定 Provider(anthropic、openai、deepseek、groq、mistral、google、moonshot、zhipu、dashscope、openrouter、ollama、vllm) | +| `--model ` | 指定模型 ID | +| `--profile ` | 使用预置档案(见 [Provider 档案](#provider-档案)) | +| `--permission-mode ` | 权限模式:normal、yolo、plan、full_auto | +| `-y` | `--permission-mode yolo` 的简写 | +| `--api-key ` | API Key(覆盖环境变量与已保存的 Key) | +| `--max-turns ` | 最大工具执行轮数(默认 200) | +| `--sandbox` | 为 shell 命令启用 Docker 沙箱隔离 | +| `--no-color` | 禁用 ANSI 颜色 | +| `--legacy`, `--no-ink` | 使用经典 readline 界面 | +| `--ink` | 无操作(Ink 已是默认,保留仅为兼容) | +| `--batch ` | 单轮非交互模式 | +| `--input ` | 从文件读取 prompt(配合 `--batch`) | +| `--output ` | 将回复写入文件(配合 `--batch`) | --- ## 交互式命令 -在 Shell 中输入以下斜杠命令: +会话中输入以下斜杠命令(Ink TUI 中输入 `/` 会弹出命令面板)。 + +### 会话管理 | 命令 | 说明 | |------|------| | `/help` | 查看所有可用命令 | -| `/exit` 或 `/quit` | 退出 Shell | +| `/exit` `/quit` `/q` | 退出会话 | | `/clear` | 清空当前上下文并新建会话 | -| `/compact` | 压缩当前对话,降低上下文占用 | -| `/tools` | 查看可用本地工具列表 | -| `/skills` | 列出 Skills | -| `/goal [--max n] ` | 设置持续目标,直到完成、阻塞或 `/goal clear` | +| `/continue` | 恢复最近的会话快照继续对话 | +| `/session` | 管理会话快照 | +| `/summary` | 生成当前会话摘要 | +| `/rewind [n]` | 回退最近 n 轮对话(默认 2) | +| `/export` | 导出会话到 JSON 文件 | +| `/copy` | 复制最后一条 AI 回复到剪贴板 | +| `/turns` | 查看轮次统计 | +| `/files` | 列出本次会话修改过的文件 | +| `/tag ` / `/tags` | 为会话打标签 / 查看标签 | +| `/version` | 查看版本信息 | + +### 模型与 Provider + +| 命令 | 说明 | +|------|------| | `/models` | 查看当前 Provider 可用模型 | | `/model ` | 切换模型 | | `/provider ` | 切换 Provider 档案(`list` 查看所有) | | `/providers` | 列出所有可用的 AI 提供商 | | `/api-url ` | 设置或查看 API Base URL | | `/api-key ` | 设置 Provider 的 API Key | -| `/cost` | 查看当前会话 token 和费用 | | `/status` | 查看会话摘要(模型、费用、tokens) | +| `/cost` | 查看当前会话 token 和费用 | | `/context` | 查看上下文窗口使用情况 | -| `/config` | 查看当前配置 | -| `/copy` | 复制最后一条 AI 回复到剪贴板 | -| `/export` | 导出会话到 JSON 文件 | -| `/doctor` | 运行环境诊断 | -| `/theme ` | 切换终端颜色主题(`list` 查看所有) | + +### 权限与沙箱 + +| 命令 | 说明 | +|------|------| | `/yolo` | 切换 YOLO 模式(自动批准所有工具) | | `/plan` | 切换 Plan 模式(阻止所有写操作) | | `/fullauto` | 切换 Full Auto 模式(静默批准所有工具) | @@ -211,31 +190,61 @@ hax-agent # 任意目录下可用 | `/permissions [allow\|deny\|reset\|yolo\|normal] [tool]` | 管理工具权限 | | `/allow ` | 始终允许某个工具 | | `/deny ` | 始终拒绝某个工具 | +| `/sandbox` | 查看/管理沙箱状态 | + +### 记忆与上下文 + +| 命令 | 说明 | +|------|------| | `/memory [search\|list]` | 管理持久化记忆 | -| `/lsp def ` | 跳转到符号定义 | -| `/lsp search ` | 搜索工作区符号 | +| `/compact` | 压缩当前对话,降低上下文占用 | +| `/think` | 调整思考模式 | | `/personalize` | 从对话中提取环境规则保存到 rules.md | +| `/dream` | 从当前对话提取记忆并续跑目标 | + +### 工具与扩展 + +| 命令 | 说明 | +|------|------| +| `/tools` | 查看可用本地工具列表 | +| `/skills` | 列出 Skills | +| `/mcp` | 查看/管理 MCP 服务 | +| `/plugin` | 插件列表与管理 | +| `/agents` | 子 Agent 管理(含 `stop`) | +| `/goal [--max n] ` | 设置持续目标,直到完成、阻塞或 `/goal clear` | +| `/lsp def ` / `/lsp search ` | 跳转到符号定义 / 搜索工作区符号 | +| `/config` | 查看当前配置 | | `/init` | 初始化 .hax-agent 项目目录 | -| `/version` | 查看版本信息 | +| `/doctor` | 运行环境诊断 | +| `/theme ` | 切换终端颜色主题(`list` 查看所有) | +| `/keybindings` | 查看键位绑定 | + +### Git 与工作区 + +| 命令 | 说明 | +|------|------| +| `/diff` | 查看工作区文件改动 | +| `/branch` | 切换/创建分支 | +| `/release-notes` | 查看版本发布说明 | +| `/reload` | 热重载 hooks/插件 | +| `/feedback ` | 发送反馈 | --- ## Skills 技能系统 -Skills 是可复用的工作流封装,允许你将重复性的任务流程保存为 SKILL.md 文件,在后续会话中通过斜杠命令快速调用。 +Skills 是可复用的工作流封装,将重复性任务流程保存为 SKILL.md 文件,后续会话中以斜杠命令调用。 ### 技能目录结构 -技能存储在以下位置: - ```text -~/.hax-agent/skills/ # 用户级技能(跨项目可用) +~/.haxagent/skills/ # 用户级技能(跨项目可用) ├── code-review/ │ └── SKILL.md └── deploy-workflow/ └── SKILL.md -.hax-agent/skills/ # 项目级技能(仅当前项目可用) +.hax-agent/skills/ # 项目级技能(仅当前项目可用) ├── run-tests/ │ └── SKILL.md └── ... @@ -264,295 +273,290 @@ arguments: 详细描述此技能的工作流程。 -## Inputs -- `$arg1`: 描述这个输入 - -## Goal -清晰陈述此工作流的目标。 - ## Steps ### 1. 步骤名称 -此步骤要做什么。具体且可操作。 +此步骤要做什么。 **Success criteria**: 始终包含!这表明步骤已完成,可以继续下一步。 ``` ### 调用技能 -在 Shell 中,直接输入技能名作为斜杠命令: - ```text /code-review # 调用代码审查技能 -/code-review src/index.js # 带参数调用 +/code-review src/index.ts # 带参数调用 /skills # 列出所有可用技能 ``` --- +## 插件与 Hooks + +插件通过 Hook 生命周期扩展 Agent 行为。插件放在 `~/.haxagent/plugins/`(用户级)或 `.hax-agent/plugins/`(项目级),启动时自动发现。 + +每个插件目录包含一个 `plugin.json` 清单,可以挂载 hooks 定义和 `skills/` 子目录。可用的生命周期钩子: + +```text +session.start / session.end +pre.compact / post.compact +pre.tool_use / post.tool_use +user.prompt_submit +notification / stop / subagent.stop +``` + +会话中使用 `/plugin` 查看已加载的插件,`/reload` 热重载。 + +--- + ## 配置说明 ### 配置层级 -1. **默认配置** — 内置于 `src/config/settings.js` -2. **用户配置** — `~/.hax-agent/settings.json` -3. **环境变量** — 所有 `HAX_AGENT_*` 前缀变量 - -> ⚠️ 建议不要把包含 API Key 的配置提交到版本库。推荐使用环境变量或用户配置。 - -### 支持的 Provider - -| Provider | 别名 | 默认模型 | 环境变量 | -|----------|------|----------|----------| -| **Anthropic** | `anthropic`, `claude` | `claude-sonnet-4-20250514` | `ANTHROPIC_API_KEY` | -| **OpenAI** | `openai`, `gpt` | `gpt-4o` | `OPENAI_API_KEY` | -| **DeepSeek** | `deepseek` | `deepseek-chat` | `DEEPSEEK_API_KEY` | -| **Groq** | `groq` | `llama-3.3-70b-versatile` | `GROQ_API_KEY` | -| **Mistral** | `mistral` | `mistral-large-latest` | `MISTRAL_API_KEY` | -| **Google** | `google`, `gemini` | `gemini-2.5-pro` | `GOOGLE_API_KEY` | -| **Moonshot** | `moonshot` | `moonshot-v1-8k` | `MOONSHOT_API_KEY` | -| **智谱** | `zhipu` | `glm-4-plus` | `ZHIPUAI_API_KEY` | -| **DashScope** | `dashscope` | `qwen-max` | `DASHSCOPE_API_KEY` | -| **OpenRouter** | `openrouter` | `anthropic/claude-sonnet-4` | `OPENROUTER_API_KEY` | -| **Ollama** | `ollama` | `llama3.2` | — (本地) | -| **vLLM** | `vllm` | — | — (本地) | - -### 完整环境变量 - -| 变量 | 说明 | 默认值 | -|------|------|--------| -| `HAX_AGENT_PROVIDER` | Provider 名称 | `anthropic` | -| `ANTHROPIC_API_KEY` | Anthropic API Key | — | -| `OPENAI_API_KEY` | OpenAI API Key | — | -| `DEEPSEEK_API_KEY` | DeepSeek API Key | — | -| `GROQ_API_KEY` | Groq API Key | — | -| `MISTRAL_API_KEY` | Mistral API Key | — | -| `GOOGLE_API_KEY` | Google API Key | — | -| `HAX_AGENT_MODEL` | 模型 ID | — | -| `HAX_AGENT_MAX_TURNS` | 最大对话轮数 | `25` | -| `HAX_AGENT_API_URL` | API Base URL | — | -| `HAX_AGENT_PERMISSIONS_MODE` | 默认权限模式 | `normal` | -| `HAX_AGENT_SHELL_ENABLED` | 是否启用 shell 工具 | `true` | +1. **默认配置** — 内置于 `src/config/settings.ts` +2. **用户配置** — `~/.haxagent/settings.json` +3. **环境变量** — Provider API Key 及路径覆盖 +4. **运行时覆盖** — 斜杠命令修改后自动持久化 + +> 建议不要把包含 API Key 的配置提交到版本库。推荐使用环境变量或用户级配置文件。 ### 配置文件示例 +`~/.haxagent/settings.json` 的完整结构(默认值): + ```json { "agent": { "provider": "anthropic", - "model": "claude-sonnet-4-20250514", + "model": "claude-sonnet-4-6", "maxTurns": 25 }, - "permissions": { - "mode": "normal" - }, - "tools": { - "shell": { - "enabled": true - } + "permissions": { "mode": "normal" }, + "tools": { "shell": { "enabled": true } }, + "sandbox": { + "enabled": true, + "backend": "auto", + "image": "node:18-alpine", + "network": "none", + "cpus": 2, + "memory": "512m" }, - "ui": { - "locale": "en", - "autoClearScreen": true - }, - "context": { - "compactionEnabled": false, - "compactionThreshold": 0.85 - } + "ui": { "locale": "en", "autoClearScreen": true }, + "context": { "compactionEnabled": false, "compactionThreshold": 0.85 } } ``` +### 数据目录 + +| 路径 | 用途 | +|------|------| +| `~/.haxagent/settings.json` | 全局配置 | +| `~/.haxagent/skills/` | 用户级技能 | +| `~/.haxagent/plugins/` | 用户级插件 | +| `~/.haxagent/memories/` | 持久化记忆 | +| `~/.haxagent/sessions/` | 会话快照 | +| `~/.haxagent/data/tasks/` | 后台任务数据 | +| `~/.haxagent/data/cron_jobs.json` | 定时任务注册表 | +| `.hax-agent/` | 项目级运行时数据(配置、技能、插件、回收站) | + +### 环境变量 + +| 变量 | 说明 | +|------|------| +| `HAX_AGENT_PROVIDER` | 默认 Provider 名称 | +| `ANTHROPIC_API_KEY` | Anthropic API Key | +| `OPENAI_API_KEY` | OpenAI API Key | +| `DEEPSEEK_API_KEY` | DeepSeek API Key | +| `GROQ_API_KEY` | Groq API Key | +| `MISTRAL_API_KEY` | Mistral API Key | +| `GOOGLE_API_KEY` | Google API Key | +| `MOONSHOT_API_KEY` | Moonshot API Key | +| `ZHIPUAI_API_KEY` | 智谱 API Key | +| `DASHSCOPE_API_KEY` | DashScope API Key | +| `OPENROUTER_API_KEY` | OpenRouter API Key | +| `HAXAGENT_CONFIG_DIR` | 覆盖全局配置目录(默认 `~/.haxagent`) | +| `HAXAGENT_DATA_DIR` | 覆盖数据目录 | +| `HAXAGENT_LOGS_DIR` | 覆盖日志目录 | +| `HAXAGENT_LEGACY=1` | 所有 shell 默认使用 readline 界面 | + +Ollama 与 vLLM 为本地推理,无需 API Key。 + --- ## 本地工具 -Agent Shell 内置一个受限制的工具注册表,所有文件操作均限定在工作区根目录内,防止路径穿越攻击。 +Agent 内置一个受限制的工具注册表,所有文件操作均限定在工作区根目录内,防止路径穿越攻击。 + +### 核心工具 | 工具 | 说明 | 安全限制 | |------|------|----------| -| `file.read` | 读取工作区内文本文件 | 路径限制在工作区根目录内 | +| `file.read` | 读取工作区内文本文件(支持 offset/limit 分页) | 路径限制在工作区根目录内 | | `file.write` | 写入工作区内文本文件 | 路径限制在工作区根目录内 | | `file.edit` | 精准替换文件中的指定文本 | 路径限制在工作区根目录内 | -| `file.delete` | 删除文件(默认移到回收站) | 路径限制在工作区根目录内 | +| `file.delete` | 删除文件(默认移到 `.hax-agent/trash` 回收站) | 路径限制在工作区根目录内 | | `file.glob` | 按 Glob 模式匹配文件列表 | 路径限制在工作区根目录内 | -| `file.search` | 在文本文件中搜索内容 | 支持正则/大小写配置 | -| `file.readDirectory` | 列出目录内容 | 路径限制在工作区根目录内 | -| `shell.run` | 执行本地命令 | 非 yolo 模式下由权限确认决定 | -| `web.fetch` | 获取网页内容并转为纯文本 | URL 获取 | -| `web.search` | 搜索互联网信息 | 需配置搜索 API | +| `file.search` | 在文本文件中搜索内容(支持正则/大小写配置) | 支持 ReDoS 防护 | +| `shell.run` | 执行本地命令 | 非 yolo 模式下由权限确认决定;可配合 `--sandbox` 隔离 | +| `web.fetch` | 获取网页内容并转为纯文本 | URL 校验 | +| `web.search` | DuckDuckGo 网络搜索 | 无需 API Key | + +### 扩展工具(自动注册) + +- **多 Agent**:`agent`(子任务委派)、`send_message`(Agent 间消息)、`team.create` / `team.delete` +- **任务**:`task.create` / `task.get` / `task.list` / `task.output` / `task.stop` / `task.update` +- **计划模式**:`enter_plan_mode` / `exit_plan_mode` +- **工作树**:`enter_worktree` / `exit_worktree` / `list_worktrees` +- **其他**:`todo_write`、`cron.create` / `cron.delete` / `cron.list` / `cron.toggle`、`ask_user`、`grep`、`glob`、`skill`、`lsp`、`notebook_edit` +- **图像**:`image_to_text`、`image_generation` +- **MCP**:`list_mcp_tools`、`list_mcp_resources`、`read_mcp_resource`、`mcp_auth` --- ## 架构概览 +代码库为 TypeScript + ESM(NodeNext),分层架构:`core/`(类型协议)→ `engine/`(Agent 运行时)→ `api/` / `tools/` / `services/`(实现层)。 + ``` src/ -├── index.js # 模块导出入口 -├── cli.js # CLI 入口 + 交互式 Shell -├── api/ -│ ├── provider.js # 12+ Provider 客户端与注册表 -│ └── retry.js # 重试逻辑 -├── commands/ -│ ├── registry.js # ~30 个斜杠命令 -│ └── extended-commands.js # 扩展命令 -├── config/ -│ ├── settings.js # 配置加载与持久化 -│ └── profiles.js # Provider 档案管理 -├── core/ # 基础层 — 类型化协议 -│ ├── api/ -│ │ ├── errors.js # API 错误分类 -│ │ └── provider-adapter.js # Provider 适配器协议与流事件类型 -│ ├── messages/ -│ │ └── types.js # StandardMessage、ContentBlock 类型、流事件 -│ ├── memory/ -│ │ └── compaction.js # Token 估算与压缩工具 -│ └── permissions/ -│ └── checker.js # 权限检查器 -├── engine/ # Agent 运行时 -│ ├── agent.js # AgentEngine、Session、HookExecutor -│ └── query.js # QueryContext 状态追踪 -├── hooks/ -│ └── registry.js # Hook 注册表 -├── memory/ -│ ├── compact.js # 消息微压缩 -│ └── store.js # 持久化记忆存储 -├── plugins/ -│ ├── installer.js # 插件安装 -│ ├── registry.js # 插件自动发现 -│ └── schema.js # 插件清单验证 -├── prompts/ -│ └── manager.js # 系统提示词组装 -├── services/ # 辅助服务 -│ ├── autodream.js # 自动目标续跑 -│ ├── lsp.js # LSP 代码导航 -│ ├── mcp.js # MCP 服务集成 -│ ├── memory-extract.js # 记忆提取 -│ ├── personalization.js # 个性化规则提取 -│ └── session-memory.js # 会话记忆 -├── shared/ -│ ├── themes.js # 终端主题 -│ └── utils.js # ANSI 码与样式工具 -├── skills/ -│ └── registry.js # 技能自动发现与加载 -├── tools/ -│ ├── registry.js # 10 个内置工具 -│ ├── agent-tool.js # Agent 子进程工具 -│ ├── extended.js # 扩展工具集 -│ ├── image-tools.js # 图像处理 -│ ├── mcp-tools.js # MCP 工具集成 -│ ├── plan-mode-tool.js # 计划模式工具 -│ ├── send-message-tool.js # Agent 间消息 -│ └── worktree-tool.js # Git worktree 管理 -└── tui/ - └── index.js # 终端 UI(alt-screen、事件渲染、状态栏) - -desktop/ -├── main/ # Electron 主进程 -├── preload/ # 预加载脚本 -└── renderer/ # Vue 桌面端前端 - ├── src/ - └── vite.config.js +├── cli.ts # CLI 入口:参数解析、Ink TUI / readline 分发 +├── index.ts # 库入口:全模块 barrel 导出 +├── tui-ink/ # Ink TUI(默认界面) +│ ├── App.tsx # 根组件:三段式布局 + Static 历史 +│ ├── reducer.ts # 状态机(engine 事件 → UI 状态) +│ ├── components/ # ToolCall、DiffView、CommandPalette、 +│ │ # ApprovalPrompt、StatusBar、ThinkingBlock… +│ └── ui/ # 原语层:Select、Separator、useTerminalSize +├── core/ # 基础层 — 类型化协议 +│ ├── api/ # Provider 适配器协议、错误分类 +│ ├── messages/ # StandardMessage、ContentBlock 类型 +│ ├── memory/ # Token 估算与压缩工具 +│ └── permissions/ # 权限检查器 +├── engine/ # Agent 运行时 +│ ├── agent.ts # AgentEngine 主循环、Session、HookExecutor +│ ├── query.ts # QueryContext 状态追踪 +│ └── cost-tracker.ts # 费用追踪 +├── api/ # Provider 客户端(12+ 提供商)与重试 +├── tools/ # 工具注册表(核心 9 个 + 扩展集) +├── commands/ # 55 个斜杠命令 +├── config/ # settings、profiles、paths +├── skills/ plugins/ hooks/ # 扩展生态 +├── memory/ # 持久化记忆(store、compact、relevance) +├── services/ # LSP、MCP、cron、session 存储、token 估算 +├── sandbox/ # 沙箱后端:docker、bwrap、macos、win +├── swarm/ # 多 Agent 协作(subprocess / in-process) +├── channels/ # IM 通道适配器(飞书、Slack、Discord 等 11 个) +├── prompts/ # 系统提示词组装 +├── auth/ # 认证管理 +└── shared/ # 主题、ANSI 工具 + +desktop/ # Electron + Vue 3 桌面应用 +├── main/ # Electron 主进程(IPC、审批桥) +├── preload/ # 预加载脚本 +└── renderer/ # Vue 3 前端(Vite) ``` -### 核心模块职责 +### 核心数据流 -| 模块 | 职责 | -|------|------| -| `api/provider.js` | 统一流式 Provider 客户端,12+ Provider 注册表 | -| `core/api/provider-adapter.js` | 类型化 Provider 适配器协议,流事件类型,Anthropic/OpenAI 适配器 | -| `core/messages/types.js` | StandardMessage 类,ContentBlock 判别联合,token 估算,格式转换 | -| `core/permissions/checker.js` | 权限检查器,四种模式,敏感路径检测 | -| `engine/agent.js` | AgentEngine 主循环,Session 管理,HookExecutor 生命周期分发 | -| `engine/query.js` | QueryContext:任务焦点、文件追踪、技能调用、工作日志 | -| `config/settings.js` | 配置加载保存,`~/.haxagent/settings.json` | -| `config/profiles.js` | ProfileManager:内置 + 自定义 Provider 档案,运行时切换 | -| `commands/registry.js` | ~30 个斜杠命令的注册与分发 | -| `tools/registry.js` | ToolRegistry:10 个内置工具,isReadOnly 分类,路径沙箱 | -| `tui/index.js` | 终端 UI:alt-screen 缓冲,事件驱动渲染,权限确认提示 | -| `skills/registry.js` | 技能发现、加载与系统提示词生成 | -| `services/lsp.js` | LSP 代码导航:go-to-definition、workspace 符号搜索 | -| `services/personalization.js` | 环境规则提取与 rules.md 生成 | -| `memory/store.js` | 持久化记忆 CRUD 与搜索 | -| `memory/compact.js` | Token 感知的消息压缩 | +``` +用户输入 → cli.ts → commands/registry(斜杠命令) + ↓ 普通消息 + engine/agent.ts(AgentEngine 工具循环) + ↓ ↓ + api/provider.ts tools/registry.ts + (LLM 流式响应) (工具执行 + 权限检查) + ↓ + tui-ink/reducer.ts(事件 → 状态)→ 终端渲染 +``` + +AgentEngine 通过 async generator 产出类型化事件(`message.delta`、`tool.start`、`tool.result`、`turn.completed` 等),TUI 消费这些事件做增量渲染,桌面端通过 IPC 转发同一事件流。 --- ## 会话与记忆 -### 会话存储 - -所有会话 transcript 保存在配置目录中: - -```text -.hax-agent/sessions/ -├── 2025-01-15T10-30-00-000Z-a1b2c3d4.jsonl -└── ... -``` - -- 每条记录一行 JSON,包含 `timestamp`、`role`、`content` 等字段。 -- 桌面端"最近会话"列表直接读取这些 transcript,可恢复历史会话继续对话。 +### 会话快照 -### 记忆存储 +会话快照保存在 `~/.haxagent/sessions/`,每个快照为 JSON 文件,包含消息、token 用量、工具调用计数和时间戳。`/continue` 恢复最近快照,`/session` 管理快照列表。 -持久化记忆保存在: +### 持久化记忆 -```text -.hax-agent/memory/ -├── user-preferences-5f8a2b1c.json -└── ... -``` +记忆以 Markdown 文件保存在 `~/.haxagent/memories/`,自动生成 `MEMORY.md` 索引: -- 每个记忆为独立文件,支持通过 `/memory search ` 或 `/memory list` 管理。 -- `/personalize` 命令从对话中提取环境规则保存到 `.hax-agent/rules.md`。 +- 支持签名去重与 TTL 过期清理 +- `/memory search ` 按标题、内容、标签打分检索 +- `/dream` 从对话中自动提取记忆(LLM 提取,限最重要的 3 条) +- `/personalize` 提取环境规则保存到 rules.md +- 每条记忆支持 category、scope、importance、tags 元数据 --- ## Provider 档案 -通过 `/provider` 命令使用预置档案快速切换 AI 提供商: - -| 档案名 | Provider | 模型 | -|--------|----------|------| -| `claude` | Anthropic | claude-sonnet-4-20250514 | -| `sonnet` | Anthropic | claude-sonnet-4-20250514 | -| `haiku` | Anthropic | claude-haiku-3-5-20241022 | -| `gpt` | OpenAI | gpt-4o | -| `gpt-mini` | OpenAI | gpt-4o-mini | -| `local` | Ollama | (本地配置) | +通过 `/provider ` 或 `--profile ` 使用预置档案: + +| 档案 | Provider | 模型 | +|------|----------|------| +| `claude` / `sonnet` | Anthropic | claude-sonnet-4-6 | +| `haiku` | Anthropic | claude-haiku-4-5-20251001 | +| `opus` | Anthropic | claude-opus-4-7 | +| `gpt` / `gpt-pro` / `gpt-mini` / `o3` | OpenAI | gpt-5.4-mini 等 | +| `deepseek` / `deepseek-pro` | DeepSeek | deepseek-v4-flash | +| `groq` | Groq | llama-3.3-70b-versatile | +| `mistral` | Mistral | mistral-large-latest | +| `google` / `gemini` / `gemini-pro` | Google | gemini-2.5-pro / gemini-2.5-flash | +| `moonshot` | Moonshot | moonshot-v1-8k | +| `zhipu` | 智谱 | glm-4.5-plus | +| `dashscope` | DashScope | qwen-max-latest | +| `openrouter` | OpenRouter | anthropic/claude-sonnet-4.6 | +| `ollama` | Ollama(本地) | llama3.3 | +| `local` | Ollama 兼容端点 | 本地配置 | +| `vllm` | vLLM(本地) | default | 自定义档案通过 `~/.haxagent/profiles.json` 管理,支持 `/provider ` 一键切换。 --- -## 开发与测试 +## 桌面端 -### 运行测试 +桌面端与 CLI 共用同一套配置、会话存储和工具层。 ```bash -npm test +npm run desktop:dev # 启动开发模式 +npm run desktop:build # 构建前端资源 +npm run desktop:start # 直接启动 Electron ``` -项目使用 Node.js 内置 test runner(`node --test`)。测试文件位于 `test/` 目录。 +--- + +## 开发与测试 + +### 常用命令 + +| 命令 | 说明 | +|------|------| +| `npm run dev` | 以 tsx 直接运行 `src/cli.ts`(开发) | +| `npm run build` | TypeScript 编译到 `dist/`(tsc) | +| `npm start` | 运行编译产物 `dist/cli.js` | +| `npm run typecheck` | `tsc --noEmit` 类型检查 | +| `npm test` | 运行测试套件(node --test + tsx) | +| `npm run desktop:dev` | 桌面端开发模式 | ### 目录规范 -- `src/` — 源码,遵循 CommonJS 模块规范,分层架构(core → engine → api/tools/services) +- `src/` — TypeScript 源码(ESM,NodeNext),分层架构 - `desktop/` — 桌面端源码,与 CLI 共用核心层 -- `test/` — 测试文件 -- `.hax-agent/` — 运行时数据(会话、记忆、设置),已加入 `.gitignore` +- `test/` — 测试文件(需登记到 `scripts/run-tests.js` 才会执行) +- `dist/` — 构建产物(npm 发布内容) ### 开发与贡献 1. Fork 本仓库 -2. 创建你的特性分支(`git checkout -b feat/amazing-feature`) -3. 提交你的修改(`git commit -m 'feat: add amazing feature'`) -4. 推送到分支(`git push origin feat/amazing-feature`) -5. 打开一个 Pull Request +2. 创建特性分支(`git checkout -b feat/amazing-feature`) +3. 提交修改(`git commit -m 'feat: add amazing feature'`) +4. 推送并打开 Pull Request -欢迎提交 Issue 和 PR!请确保: -- 新增功能包含对应的测试用例 -- 保持代码风格一致(现有风格) -- 更新相关文档 +欢迎提交 Issue 和 PR。请确保新增功能包含对应测试用例,并将测试文件加入 `scripts/run-tests.js` 的执行列表。 --- @@ -562,4 +566,4 @@ MIT © [IdiotTIQS](https://github.com/IdiotTIQS) --- -*Hax Agent CLI — 让 AI 编码助手在你的终端里为你服务。* +*Hax Agent — 让 AI 编码助手在你的终端里为你服务。* diff --git a/docs/superpowers/specs/2026-08-21-v1.7-quality-and-features-spec.md b/docs/superpowers/specs/2026-08-21-v1.7-quality-and-features-spec.md new file mode 100644 index 0000000..e216691 --- /dev/null +++ b/docs/superpowers/specs/2026-08-21-v1.7-quality-and-features-spec.md @@ -0,0 +1,209 @@ +# 规格:HaxAgent v1.7 — 工程加固与新功能路线 + +- 日期:2026-08-21 +- 基线:v1.6.0 @ `dc1577e`(master) +- 验证基线:`npm test` 179/179 全绿(Node 24.1.0);`npx tsc --noEmit` 0 错误 +- 范围量级:P0 缺陷修复(小)+ P1 质量提升(中)+ 三波次新功能(中大) +- 前置文档:`docs/plans/2026-05-29-haxagent-improvement-plan.md`(v1.5.3 时点的改进计划,其中 P0-1/CI、P1-2/ESLint 至今未落地,本 spec 继承并更新) + +--- + +## 1. 现状体检结论 + +### 1.1 已完成的大迁移(值得肯定) + +| 迁移 | 状态 | 证据 | +|------|------|------| +| 全仓 TypeScript + ESM | ✅ 完成 | `src/` 全 .ts,NodeNext,`"type": "module"` | +| Ink TUI 重构(ux-redesign) | ✅ 完成 | `src/tui-ink/` 三段式布局、Static 历史、命令面板、Select 审批、富状态栏、ui/ 原语层 | +| 分层架构 | ✅ 稳定 | `core/`(类型协议)→ `engine/`(运行时)→ `api/tools/services/` | +| 多 Provider | ✅ 15 个注册名 | `src/api/provider.ts` L402-449,统一流事件 + withRetry 指数退避 | +| 扩展生态 | ✅ 骨架完整 | skills / plugins / hooks(10 生命周期)/ MCP / swarm / channels(11 IM)/ sandbox(4 后端)| + +### 1.2 短板总览(本次检查验证) + +| # | 问题 | 严重度 | 位置 | +|---|------|--------|------| +| 1 | CI 测试失败仍标绿(`continue-on-error`) | **P0** | `.github/workflows/ci.yml` L22, L24 | +| 2 | `test:desktop` 跑的是幽灵目录(`test/desktop` 不存在) | **P0** | `package.json` scripts + `scripts/run-tests.js` | +| 3 | 测试列表硬编码,新测试不进列表就不会被执行 | **P0** | `scripts/run-tests.js` L6-23 | +| 4 | `@types/node` 不在 devDependencies(靠传递依赖侥幸可用) | P1 | `package.json` | +| 5 | 文档漂移:README/CLAUDE.md 仍描述 CJS 架构;CHANGELOG 停在 1.5.4 | P1 | `README.md`、`CLAUDE.md`、`CHANGELOG.md` | +| 6 | `npm run lint` 实为 typecheck,无 ESLint | P1 | `package.json`(`.eslintrc.json` 存在但 eslint 未安装) | +| 7 | 测试覆盖缺口:17 个测试文件 vs ~144 模块;tools/memory/skills/plugins/hooks/swarm/channels/sandbox/config/cli/desktop 全部零测试 | P1 | `test/` | +| 8 | CI matrix 仅 Node 18 + ubuntu;主开发环境为 Windows,win/macos 路径无验证 | P1 | `.github/workflows/ci.yml` | +| 9 | `App.vue` 1153 行巨胖组件;`desktop/main/index.js` 551 行手写无类型 IPC | P2 | `desktop/` | +| 10 | 双渲染栈并存(tui-ink + renderer*.ts + --legacy readline) | P2 | `src/renderer*.ts`、`src/tui-ink/` | +| 11 | channels 仅出站单向(feishu 等只实现 `send`,无 webhook 接收) | P2 | `src/channels/impl/` | +| 12 | `@deprecated` 残留 3 处 | P3 | `src/engine/query.ts` L198、`src/core/api/errors.ts` L352、`src/tui-ink/types.ts` L203 | + +--- + +## 2. P0 — 工程缺陷修复(v1.7 第一步,先行合入) + +### 2.1 CI 必须真实拦截失败 + +**问题**:两个测试步骤均 `continue-on-error: true`,测试红了 CI 仍绿,缺陷代码可直达 master 与 npm publish(release.yml 依赖同样的 `npm test`)。 + +**方案**: + +```yaml +# .github/workflows/ci.yml +matrix: + node-version: [18, 20, 22] +steps: + - run: npm ci + - run: npm test + # continue-on-error 全部删除 +``` + +**验收**:故意让任一测试失败 → CI failure;恢复后 CI 绿。 + +### 2.2 修复幽灵桌面端测试 + +**问题**:`npm run test:desktop` = `vite build && node scripts/run-tests.js test/desktop`,但 ① `test/desktop/` 目录不存在;② `run-tests.js` 根本不读 `process.argv`,参数被静默忽略 → 实际把同一批 17 个 CLI 测试又跑一遍,伪装成"桌面端测试"。CI 里 `xvfb-run npm run test:desktop` 因此是无效门禁。 + +**方案**: +1. `run-tests.js` 支持 glob 发现:用 `node:fs` 扫描 `test/*.test.ts`(+ 可选 `test/desktop/*.test.ts`),删除硬编码列表。 +2. 若桌面端确无测试,先在 CI 中移除该步骤并在此记录,随后按 §3.3 补齐真实桌面端测试后再恢复。 + +**验收**:新增一个 `test/foo.test.ts` 无需改脚本即被 `npm test` 执行;`test:desktop` 要么跑真实桌面端测试、要么不存在该脚本。 + +### 2.3 补依赖声明 + +- `package.json` devDependencies 增加 `@types/node`(当前 tsconfig `types: ["node"]` 依赖传递安装,全新环境 `tsc --noEmit` 直接报 TS2688)。 +- CHANGELOG 补 1.6.0 条目(TS/ESM 迁移 + Ink TUI 重构)。 + +### 2.4 文档对齐现实(一次性小 PR) + +- README.md / README.en.md / CLAUDE.md:CommonJS 描述 → TS+ESM;`src/cli.js` → `src/cli.ts`(bin 指 `dist/cli.js`);架构图补 `tui-ink/`、`swarm/`、`channels/`、`sandbox/`、`voice/`、`autopilot/`、`coordinator/` 等缺失目录;统一配置目录写法(代码实际使用 `~/.haxagent/`,见 `src/config/paths.ts`)。 +- 删除或标注 README 中已不存在的行为描述。 + +**验收**:按 README 从零 clone → `npm install && npm test && npm run build` 全部成功;架构图目录与 `ls src/` 一致。 + +--- + +## 3. P1 — 质量提升(v1.7 主体) + +### 3.1 真实 Lint + +- devDeps 加 `eslint` + `@typescript-eslint/*`(flat config),`npm run lint` = `eslint src test scripts`;`typecheck` 保留独立脚本。 +- 首轮先 `--max-warnings` 宽松(如 no-unused-vars 关闭),只拦截真问题(no-explicit-any 逐步收紧)。 + +### 3.2 测试覆盖补齐(按风险排序) + +| 优先级 | 目标模块 | 理由 | +|--------|----------|------| +| 1 | `src/tools/registry.ts`(路径沙箱、isReadOnly、权限分类) | 安全边界,零测试 | +| 2 | `src/engine/agent.ts` 主循环(tool loop、compact/retry、中断) | 核心路径,仅有 system-prompt/tool-result 两块局部测试 | +| 3 | `src/memory/`(store CRUD/TTL/signature 去重、compact 阈值、relevance 打分) | 纯逻辑、易测、影响上下文行为 | +| 4 | `src/config/`(settings 合并优先级、profiles 切换) | 配置错误=全局限障 | +| 5 | `src/skills/registry.ts`、`src/plugins/registry.ts`、`src/hooks/registry.ts` | 扩展生态入口,frontmatter/manifest 解析易回归 | +| 6 | `src/api/retry.ts`、`src/api/provider.ts`(mock fetch,覆盖 15 provider 的注册与错误分类) | 已有 2 个测试,补齐 | +| 7 | `src/channels/adapter.ts` + 1 个 impl(mock fetch) | 双向化(F5)的前置 | + +不追求行覆盖率数字,追求"每个 P0 行为至少 1 条断言"。配合 `c8`(或 node --test 内置 coverage)输出报告,先观察后设门禁(建议初始门禁:核心目录 `src/core`、`src/engine`、`src/tools` ≥ 60%)。 + +### 3.3 桌面端最小测试闭环 + +- `desktop/main/index.js` 的 IPC handler 提炼为可注入依赖的纯模块(approval 队列、session 生命周期),用 node:test 直接测。 +- Vue 组件用已有 `@vue/test-utils` + `jsdom` 对 `ChatArea.vue` / `ApprovalModal.vue` 写 3-5 条渲染断言,恢复 `test:desktop` 真实门禁。 + +### 3.4 跨平台 CI + +- matrix 增加 `windows-latest`、`macos-latest`(仅跑 `npm test`,桌面端测试只在 ubuntu + xvfb 跑)。 +- `src/sandbox/win-sandbox.ts`、`macos-sandbox.ts`、`src/utils/shell-utils.ts` 至少有平台条件编译的 smoke 测试。 + +### 3.5 桌面端重构(可在 1.7 内做小半步) + +- `App.vue`(1153 行)按组件域拆分:`useSession` / `useWorkspace` / `useAgentEvents` composables(沿用已有 `composables/` 目录习惯)。 +- `desktop/main/index.js` 渐进 TS 化:preload 的 `haxAgent` API 先补 `.d.ts`,渲染进程获得类型提示。 + +### 3.6 清理 + +- 删除 3 处 `@deprecated`(`query.ts` L198、`errors.ts` L352、`tui-ink/types.ts` L203)及其兼容层。 +- 评估 `--legacy` readline 路径退役:Ink TUI 已稳定,legacy 的维护成本>收益。1.7 先打 deprecation 警告,1.8 移除(README 已承诺"始终保留"则改为"1.9 前保留",在 CHANGELOG 明示)。 + +--- + +## 4. 新功能展望(三波次) + +### Wave 1(v1.7)— 上下文工程与可靠性 + +#### F1 语义记忆检索 +- **现状**:`src/memory/relevance.ts` 仅关键词/title/tags 打分;`store.search()` 关键词匹配。 +- **方案**:默认实现 BM25(零依赖、纯 TS,建倒排索引于 `.haxagent/memories`);可选配置 embedding provider(复用现有 15 provider 注册表,新增 `embedding` 能力位)。`rankMemories()` 保持签名不变,内部切换策略。 +- **验收**:`/memory search "登录鉴权"` 能命中不含该关键词但语义相关的记忆;无 embedding 配置时自动降级 BM25;新增 `test/memory-bm25.test.ts`。 + +#### F2 Prompt Caching 与成本可视化 +- **方案**:Anthropic adapter 注入 `cache_control`(system prompt + 最近 N 轮工具定义打 breakpoint);`/cost` 输出 cache hit/miss token 与节省金额(`src/engine/cost-tracker.ts` 已有底座,`src/pricing.ts` 已有价格表)。 +- **验收**:连续两轮对话第二轮 usage 出现 cache_read tokens;`/cost` 显示"缓存节省 $x.xx"。 + +#### F3 Checkpoint / Undo 自动快照 +- **动机**:`file.write`/`file.edit`/`shell.run` 均为破坏性操作,出错后无一键回滚。 +- **方案**:`src/tools/registry.ts` 写类工具执行前将原文件快照到 `.hax-agent/checkpoints///`(复用文件回收站思路);新增 `/undo [n]` 与 `/checkpoint list` 命令;快照自动清理(保留最近 N=50)。 +- **验收**:让 agent 改坏文件后 `/undo 1` 恢复原内容;快照目录有上限不膨胀。 + +#### F4 后台任务与完成通知 +- **方案**:`src/tasks/manager.ts` 扩展后台运行( detached agent task + 轮询/事件回调);完成时经 `node-notifier`(已是 optionalDependency)+ channels 通知(打通 F5 前先用系统通知)。 +- **验收**:`/goal` 长任务切到后台,终端继续可用;任务完成弹通知并写会话记录。 + +### Wave 2(v1.8)— 通道双向化与多端对齐 + +#### F5 Channels 双向网关(远程指挥入口) +- **现状**:11 个 channel 全部只有出站 `send()`(如 `feishu.ts` 仅发消息),本质是通知器。 +- **方案**:新增 `src/channels/gateway.ts`——按 channel 配置拉起轻量 HTTP webhook receiver(飞书/钉钉/Slack 事件回调),消息经 allowFrom 鉴权后注入 AgentEngine 会话,回复走既有 `adapter.send()` 回投。与 F4 组合实现"IM 里远程指挥本地 agent"。 +- **验收**:在飞书群里 @bot 发"跑一下测试",agent 执行并把结果摘要回发到群;未授权用户消息被拒并记录。 + +#### F6 桌面端功能对齐 +- 审批队列(多工具审批排队而非阻塞单条)、内联 diff 视图(CLI 已有 DiffView,桌面端复用逻辑)、skills/plugins 管理面板、swarm 任务监控面板。 +- 依赖 §3.5 的 composables 拆分。 + +#### F7 Web Search 默认可用 +- **现状**:`web.search` 需用户自配搜索 API。 +- **方案**:内置默认 provider(DuckDuckGo HTML 免 key 兜底 + 可配置付费源),`/config web.search.provider` 切换。 + +### Wave 3(v1.9+)— Agent 编排深化 + +#### F8 子 Agent 并行执行 +- `agent` tool 支持同一 turn 内并行 fan-out(Promise.all + 独立 QueryContext),结果汇总渲染;swarm in-process 后端复用该能力。 + +#### F9 Plan Mode 工程化 +- todo 清单持久化(跨 compact 保留)、计划文件落盘可 diff、`/plan approve` 后按清单逐项执行并打勾(对接 F3 快照兜底)。 + +#### F10 生态分发 +- `hax-agent skill install ` / `hax-agent mcp add `(installer.ts 已有插件安装雏形,扩展到 skills/MCP registry 清单格式)。 + +#### F11 Opt-in Telemetry +- 匿名 usage 事件(provider/model/工具调用次数/失败率),`HAX_AGENT_TELEMETRY=0` 一键关闭;产出 `/stats` 本地 dashboard(桌面端优先展示)。 + +--- + +## 5. 实施顺序与门禁 + +``` +v1.7.0 +├─ Sprint A(先行小 PR,1 天内) +│ ├─ P0-1 CI 修复 + matrix 扩展 §2.1 +│ ├─ P0-2 run-tests glob + test:desktop §2.2 +│ ├─ P0-3 @types/node + CHANGELOG §2.3 +│ └─ P0-4 文档对齐 §2.4 +├─ Sprint B(质量) +│ ├─ ESLint 接入 §3.1 +│ ├─ 核心测试补齐(§3.2 前 4 项) +│ └─ deprecated 清理 §3.6 +├─ Sprint C(Wave 1 功能) +│ ├─ F2 prompt caching(最小改动先做) +│ ├─ F3 checkpoint/undo +│ ├─ F1 BM25 记忆检索 +│ └─ F4 后台任务通知 +└─ 发布门禁:npm test 全绿(CI 真实拦截)+ tsc 0 错误 + eslint 0 error + 新功能各带测试 +``` + +## 6. 明确不做(本 spec 排除) + +- 全屏 alt-screen / 自实现 scrollback(继承 ux-redesign 的排除项) +- legacy readline 路径的新功能开发(只维护,1.8 起评估移除) +- 语音模式(voice/)与 vim 模式的新投入(保留现状,待生态功能落地后评估) +- channels 全部 11 个后端的双向化(F5 只做飞书 + Slack 两个样板,其余按需复制) +- 向量数据库/外部存储依赖(F1 坚持"零新依赖默认 + 可选增强") diff --git a/examples/batch/README.md b/examples/batch/README.md index 9829d5b..d455d68 100644 --- a/examples/batch/README.md +++ b/examples/batch/README.md @@ -1,18 +1,36 @@ # Batch Mode +> [!WARNING] +> **Parts of this document have drifted from the current codebase** (v1.6.0). +> - The standalone `src/batch.js` module no longer exists; batch mode is now +> implemented directly in `src/cli.ts` (`runBatch`). +> - **Stdin piping is no longer supported.** `--batch` takes the prompt as a +> CLI argument, or pairs with `--input `. `echo "..." | hax-agent --batch` +> will exit with an error asking for a prompt string or `--input`. +> - The multi-turn markers (`---multi---` / `@@@multi@@@`) described below are +> **not handled** by the current implementation — the whole input is sent as a +> single turn. +> +> Verified current usage: +> +> ```bash +> hax-agent --batch "explain this code" # prompt as argument +> hax-agent --batch --input task.txt # prompt from file +> ``` + Batch mode lets you run HaxAgent non-interactively from scripts, CI pipelines, and automated workflows. ## Quick start ```bash -# Pipe a single prompt -echo "Explain the src/batch.js file" | hax-agent --batch +# Pass a single prompt as an argument (stdin piping is NOT supported) +hax-agent --batch "Explain the src/cli.ts file" -# Read prompts from a file +# Read the prompt from a file hax-agent --batch --input example-prompts.txt --output result.md # Choose a different model -cat tasks.txt | hax-agent --batch --model claude-sonnet-4-20250514 +hax-agent --batch --input tasks.txt --model claude-sonnet-4-20250514 ``` ## CLI flags diff --git a/examples/hub-minimal.js b/examples/hub-minimal.js index 49265cd..5ffd915 100644 --- a/examples/hub-minimal.js +++ b/examples/hub-minimal.js @@ -5,6 +5,13 @@ * Good for understanding the basics of the hub API. * * Run: node examples/hub-minimal.js + * + * ⚠️ DRIFT WARNING (v1.6.0): `../src/hub` was REMOVED in the layered + * architecture rewrite — this example no longer runs as-is. The equivalent + * programmatic entry point is now the package root `src/index.ts` (default + * export with `engine`, `tools`, `api`, `config`, `skills`, `memory`, + * `commands`, `swarm`, … namespaces). The repo is also ESM + TypeScript now, + * so migrate to `import hax from "hax-agent"` style code. */ "use strict"; diff --git a/examples/hub-usage.js b/examples/hub-usage.js index 15735d8..300d9a4 100644 --- a/examples/hub-usage.js +++ b/examples/hub-usage.js @@ -9,6 +9,13 @@ * - Proper cleanup * * Run: node examples/hub-usage.js + * + * ⚠️ DRIFT WARNING (v1.6.0): `../src/hub` was REMOVED in the layered + * architecture rewrite — this example no longer runs as-is. The equivalent + * programmatic entry point is now the package root `src/index.ts` (default + * export with `engine`, `tools`, `api`, `config`, `skills`, `memory`, + * `commands`, `swarm`, … namespaces). The repo is also ESM + TypeScript now, + * so migrate to `import hax from "hax-agent"` style code. */ "use strict"; diff --git a/examples/memory/README.md b/examples/memory/README.md index b331eec..fe3a9d8 100644 --- a/examples/memory/README.md +++ b/examples/memory/README.md @@ -1,5 +1,26 @@ # Memory System +> [!WARNING] +> **This document describes the OLD memory system and has drifted significantly** +> from the current codebase (v1.6.0). The memory subsystem was rewritten +> (see `src/memory/store.ts`, ported from OpenHarness): +> - **Storage location:** memories are now Markdown files (`.md`) under +> `~/.haxagent/memories/` (user home), **not** JSON files in a per-project +> `.haxagent/memories/` directory. A `MEMORY.md` index is maintained +> automatically. +> - **Record model:** the namespace/tag JSON records below were replaced by +> entries with `title`, `content`, `category`, `scope`, `importance`, `tags`, +> plus signature-based dedup and TTL expiry. +> - **Programmatic API:** the free functions (`writeMemory`, `readMemory`, +> `listMemories`, `deleteMemory`, `searchMemories`) were replaced by the +> `MemoryStore` class — `save(title, content, opts)`, `search(query, limit)`, +> `list(opts)`, `delete(id)` — and `require()` imports no longer work in this +> ESM repo. +> +> The CLI command and best-practice guidance below may still partially apply, +> but verify every command against the current `/memory` implementation before +> relying on it. + HaxAgent's memory system persists key-value records to disk, with **namespace** and **tag** support for organizing knowledge across projects and contexts. --- diff --git a/examples/plugins/README.md b/examples/plugins/README.md index 2f5c63d..84ee913 100644 --- a/examples/plugins/README.md +++ b/examples/plugins/README.md @@ -1,5 +1,22 @@ # HaxAgent Plugins +> [!WARNING] +> **Parts of this document have drifted from the current codebase** (v1.6.0, TypeScript + ESM). +> - The repo is now ESM — `require('./src/plugins')` does not work. Import from +> the package entry (`src/index.ts`) or the compiled `dist/` output instead. +> - **Hook names have changed.** The camelCase hooks documented below +> (`beforeToolCall`, `afterChat`, `onError`, …) were replaced by 10 lifecycle +> events in `src/hooks/registry.ts`: `session.start`, `session.end`, +> `pre.compact`, `post.compact`, `pre.tool_use`, `post.tool_use`, +> `user.prompt_submit`, `notification`, `stop`, `subagent.stop`. +> - Hooks now come in 4 types — `command` (shell), `http` (POST), `prompt` (LLM +> check), `agent` (deep verification) — and plugins may contribute tools, +> skills, commands, hooks, or providers (see `src/plugins/types.ts`). +> +> The example plugin files in this directory still use the old hook shape and +> are kept for reference only. Verify against `src/hooks/` and `src/plugins/` +> before writing new plugins. + Plugins let you extend HaxAgent's behavior by hooking into its lifecycle. Each plugin is a **CommonJS module** that exports an object describing which events it cares about and what to do when those events fire. diff --git a/examples/workflows/README.md b/examples/workflows/README.md index 264779d..309310b 100644 --- a/examples/workflows/README.md +++ b/examples/workflows/README.md @@ -1,5 +1,19 @@ # Agent Workflows +> [!WARNING] +> **This document has drifted from the current codebase** (v1.6.0, TypeScript + ESM). +> - The `src/teams/runtime` module (`createTeamRuntime`) shown below **no longer +> exists**. Multi-agent collaboration now lives in `src/swarm/` (in-process and +> subprocess backends, mailbox, team lifecycle, worktrees). +> - The `require(...)` snippets are CommonJS; the repo is now ESM + TypeScript. +> Import from the package entry (`src/index.ts`, namespaces `engine`, `tools`, +> `api`, `config`, `skills`, `memory`, `commands`, `swarm`, …) or run via `tsx`. +> - The `.js` example files in this directory are kept for pattern reference and +> will not run as-is. +> +> Treat the six patterns below as conceptual guidance; verify API details against +> `src/swarm/` and `src/index.ts` before writing code. + HaxAgent supports composing multiple specialized agents into **teams** that collaborate on complex coding tasks. Each agent has a distinct role, a scoped set of tools, and a natural-language prompt that guides its behavior.