nova-terminal-assistant 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +358 -0
- package/bin/nova +38 -0
- package/bin/nova.js +12 -0
- package/package.json +67 -0
- package/src/cli/commands/SmartCompletion.ts +458 -0
- package/src/cli/index.ts +5 -0
- package/src/cli/startup/IFlowRepl.ts +212 -0
- package/src/cli/startup/InkBasedRepl.ts +1056 -0
- package/src/cli/startup/InteractiveRepl.ts +2833 -0
- package/src/cli/startup/NovaApp.ts +1861 -0
- package/src/cli/startup/index.ts +4 -0
- package/src/cli/startup/parseArgs.ts +293 -0
- package/src/cli/test-modules.ts +27 -0
- package/src/cli/ui/IFlowDropdown.ts +425 -0
- package/src/cli/ui/ModernReplUI.ts +276 -0
- package/src/cli/ui/SimpleSelector2.ts +215 -0
- package/src/cli/ui/components/ConfirmDialog.ts +176 -0
- package/src/cli/ui/components/ErrorPanel.ts +364 -0
- package/src/cli/ui/components/InkAppRunner.tsx +67 -0
- package/src/cli/ui/components/InkComponents.tsx +613 -0
- package/src/cli/ui/components/NovaInkApp.tsx +312 -0
- package/src/cli/ui/components/ProgressBar.ts +177 -0
- package/src/cli/ui/components/ProgressIndicator.ts +298 -0
- package/src/cli/ui/components/QuickActions.ts +396 -0
- package/src/cli/ui/components/SimpleErrorPanel.ts +231 -0
- package/src/cli/ui/components/StatusBar.ts +194 -0
- package/src/cli/ui/components/ThinkingBlockRenderer.ts +401 -0
- package/src/cli/ui/components/index.ts +27 -0
- package/src/cli/ui/ink-prototype.tsx +347 -0
- package/src/cli/utils/CliUI.ts +336 -0
- package/src/cli/utils/CompletionHelper.ts +388 -0
- package/src/cli/utils/EnhancedCompleter.test.ts +226 -0
- package/src/cli/utils/EnhancedCompleter.ts +513 -0
- package/src/cli/utils/ErrorEnhancer.ts +429 -0
- package/src/cli/utils/OutputFormatter.ts +193 -0
- package/src/cli/utils/index.ts +9 -0
- package/src/core/agents/AgentOrchestrator.ts +515 -0
- package/src/core/agents/index.ts +17 -0
- package/src/core/audit/AuditLogger.ts +509 -0
- package/src/core/audit/index.ts +11 -0
- package/src/core/auth/AuthManager.d.ts.map +1 -0
- package/src/core/auth/AuthManager.ts +138 -0
- package/src/core/auth/index.d.ts.map +1 -0
- package/src/core/auth/index.ts +2 -0
- package/src/core/config/ConfigManager.d.ts.map +1 -0
- package/src/core/config/ConfigManager.test.ts +183 -0
- package/src/core/config/ConfigManager.ts +1219 -0
- package/src/core/config/index.d.ts.map +1 -0
- package/src/core/config/index.ts +1 -0
- package/src/core/context/ContextBuilder.d.ts.map +1 -0
- package/src/core/context/ContextBuilder.ts +171 -0
- package/src/core/context/ContextCompressor.d.ts.map +1 -0
- package/src/core/context/ContextCompressor.ts +642 -0
- package/src/core/context/LayeredMemoryManager.ts +657 -0
- package/src/core/context/MemoryDiscovery.d.ts.map +1 -0
- package/src/core/context/MemoryDiscovery.ts +175 -0
- package/src/core/context/defaultSystemPrompt.d.ts.map +1 -0
- package/src/core/context/defaultSystemPrompt.ts +35 -0
- package/src/core/context/index.d.ts.map +1 -0
- package/src/core/context/index.ts +22 -0
- package/src/core/extensions/SkillGenerator.ts +421 -0
- package/src/core/extensions/SkillInstaller.d.ts.map +1 -0
- package/src/core/extensions/SkillInstaller.ts +257 -0
- package/src/core/extensions/SkillRegistry.d.ts.map +1 -0
- package/src/core/extensions/SkillRegistry.ts +361 -0
- package/src/core/extensions/SkillValidator.ts +525 -0
- package/src/core/extensions/index.ts +15 -0
- package/src/core/index.d.ts.map +1 -0
- package/src/core/index.ts +42 -0
- package/src/core/mcp/McpManager.d.ts.map +1 -0
- package/src/core/mcp/McpManager.ts +632 -0
- package/src/core/mcp/index.d.ts.map +1 -0
- package/src/core/mcp/index.ts +2 -0
- package/src/core/model/ModelClient.d.ts.map +1 -0
- package/src/core/model/ModelClient.ts +217 -0
- package/src/core/model/ModelConnectionTester.ts +363 -0
- package/src/core/model/ModelValidator.ts +348 -0
- package/src/core/model/index.d.ts.map +1 -0
- package/src/core/model/index.ts +6 -0
- package/src/core/model/providers/AnthropicProvider.d.ts.map +1 -0
- package/src/core/model/providers/AnthropicProvider.ts +279 -0
- package/src/core/model/providers/CodingPlanProvider.d.ts.map +1 -0
- package/src/core/model/providers/CodingPlanProvider.ts +210 -0
- package/src/core/model/providers/OllamaCloudProvider.d.ts.map +1 -0
- package/src/core/model/providers/OllamaCloudProvider.ts +405 -0
- package/src/core/model/providers/OllamaManager.d.ts.map +1 -0
- package/src/core/model/providers/OllamaManager.ts +201 -0
- package/src/core/model/providers/OllamaProvider.d.ts.map +1 -0
- package/src/core/model/providers/OllamaProvider.ts +73 -0
- package/src/core/model/providers/OpenAICompatibleProvider.d.ts.map +1 -0
- package/src/core/model/providers/OpenAICompatibleProvider.ts +327 -0
- package/src/core/model/providers/OpenAIProvider.d.ts.map +1 -0
- package/src/core/model/providers/OpenAIProvider.ts +29 -0
- package/src/core/model/providers/index.d.ts.map +1 -0
- package/src/core/model/providers/index.ts +12 -0
- package/src/core/model/types.d.ts.map +1 -0
- package/src/core/model/types.ts +77 -0
- package/src/core/security/ApprovalManager.d.ts.map +1 -0
- package/src/core/security/ApprovalManager.ts +174 -0
- package/src/core/security/FileFilter.d.ts.map +1 -0
- package/src/core/security/FileFilter.ts +141 -0
- package/src/core/security/HookExecutor.d.ts.map +1 -0
- package/src/core/security/HookExecutor.ts +178 -0
- package/src/core/security/SandboxExecutor.ts +447 -0
- package/src/core/security/index.d.ts.map +1 -0
- package/src/core/security/index.ts +8 -0
- package/src/core/session/AgentLoop.d.ts.map +1 -0
- package/src/core/session/AgentLoop.ts +501 -0
- package/src/core/session/SessionManager.d.ts.map +1 -0
- package/src/core/session/SessionManager.test.ts +183 -0
- package/src/core/session/SessionManager.ts +460 -0
- package/src/core/session/index.d.ts.map +1 -0
- package/src/core/session/index.ts +3 -0
- package/src/core/telemetry/Telemetry.d.ts.map +1 -0
- package/src/core/telemetry/Telemetry.ts +90 -0
- package/src/core/telemetry/TelemetryService.ts +531 -0
- package/src/core/telemetry/index.d.ts.map +1 -0
- package/src/core/telemetry/index.ts +12 -0
- package/src/core/testing/AutoFixer.ts +385 -0
- package/src/core/testing/ErrorAnalyzer.ts +499 -0
- package/src/core/testing/TestRunner.ts +265 -0
- package/src/core/testing/agent-cli-tests.ts +538 -0
- package/src/core/testing/index.ts +11 -0
- package/src/core/tools/ToolRegistry.d.ts.map +1 -0
- package/src/core/tools/ToolRegistry.test.ts +206 -0
- package/src/core/tools/ToolRegistry.ts +260 -0
- package/src/core/tools/impl/EditFileTool.d.ts.map +1 -0
- package/src/core/tools/impl/EditFileTool.ts +97 -0
- package/src/core/tools/impl/ListDirectoryTool.d.ts.map +1 -0
- package/src/core/tools/impl/ListDirectoryTool.ts +142 -0
- package/src/core/tools/impl/MemoryTool.d.ts.map +1 -0
- package/src/core/tools/impl/MemoryTool.ts +102 -0
- package/src/core/tools/impl/ReadFileTool.d.ts.map +1 -0
- package/src/core/tools/impl/ReadFileTool.ts +58 -0
- package/src/core/tools/impl/SearchContentTool.d.ts.map +1 -0
- package/src/core/tools/impl/SearchContentTool.ts +94 -0
- package/src/core/tools/impl/SearchFileTool.d.ts.map +1 -0
- package/src/core/tools/impl/SearchFileTool.ts +61 -0
- package/src/core/tools/impl/ShellTool.d.ts.map +1 -0
- package/src/core/tools/impl/ShellTool.ts +118 -0
- package/src/core/tools/impl/TaskTool.d.ts.map +1 -0
- package/src/core/tools/impl/TaskTool.ts +207 -0
- package/src/core/tools/impl/TodoTool.d.ts.map +1 -0
- package/src/core/tools/impl/TodoTool.ts +122 -0
- package/src/core/tools/impl/WebFetchTool.d.ts.map +1 -0
- package/src/core/tools/impl/WebFetchTool.ts +103 -0
- package/src/core/tools/impl/WebSearchTool.d.ts.map +1 -0
- package/src/core/tools/impl/WebSearchTool.ts +89 -0
- package/src/core/tools/impl/WriteFileTool.d.ts.map +1 -0
- package/src/core/tools/impl/WriteFileTool.ts +49 -0
- package/src/core/tools/impl/index.d.ts.map +1 -0
- package/src/core/tools/impl/index.ts +16 -0
- package/src/core/tools/index.d.ts.map +1 -0
- package/src/core/tools/index.ts +7 -0
- package/src/core/tools/schemas/execution.d.ts.map +1 -0
- package/src/core/tools/schemas/execution.ts +42 -0
- package/src/core/tools/schemas/file.d.ts.map +1 -0
- package/src/core/tools/schemas/file.ts +119 -0
- package/src/core/tools/schemas/index.d.ts.map +1 -0
- package/src/core/tools/schemas/index.ts +11 -0
- package/src/core/tools/schemas/memory.d.ts.map +1 -0
- package/src/core/tools/schemas/memory.ts +52 -0
- package/src/core/tools/schemas/orchestration.d.ts.map +1 -0
- package/src/core/tools/schemas/orchestration.ts +44 -0
- package/src/core/tools/schemas/search.d.ts.map +1 -0
- package/src/core/tools/schemas/search.ts +112 -0
- package/src/core/tools/schemas/todo.d.ts.map +1 -0
- package/src/core/tools/schemas/todo.ts +32 -0
- package/src/core/tools/schemas/web.d.ts.map +1 -0
- package/src/core/tools/schemas/web.ts +86 -0
- package/src/core/types/config.d.ts.map +1 -0
- package/src/core/types/config.ts +200 -0
- package/src/core/types/errors.d.ts.map +1 -0
- package/src/core/types/errors.ts +204 -0
- package/src/core/types/index.d.ts.map +1 -0
- package/src/core/types/index.ts +8 -0
- package/src/core/types/session.d.ts.map +1 -0
- package/src/core/types/session.ts +216 -0
- package/src/core/types/tools.d.ts.map +1 -0
- package/src/core/types/tools.ts +157 -0
- package/src/core/utils/CheckpointManager.d.ts.map +1 -0
- package/src/core/utils/CheckpointManager.ts +327 -0
- package/src/core/utils/Logger.d.ts.map +1 -0
- package/src/core/utils/Logger.ts +98 -0
- package/src/core/utils/RetryManager.ts +471 -0
- package/src/core/utils/TokenCounter.d.ts.map +1 -0
- package/src/core/utils/TokenCounter.ts +414 -0
- package/src/core/utils/VectorMemoryStore.ts +440 -0
- package/src/core/utils/helpers.d.ts.map +1 -0
- package/src/core/utils/helpers.ts +89 -0
- package/src/core/utils/index.d.ts.map +1 -0
- package/src/core/utils/index.ts +19 -0
package/README.md
ADDED
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
# Nova CLI
|
|
2
|
+
|
|
3
|
+
> Next-generation CLI agent framework — more efficient, more multimodal, more intelligent.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@nova-cli/cli)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
Nova CLI is a production-grade terminal AI agent that combines the best ideas from Claude Code, iFlow CLI, and other tools into a unified, extensible framework. It provides a complete conversation loop with tool use, multi-provider LLM support, MCP integration, and a security-first architecture.
|
|
9
|
+
|
|
10
|
+
## 快速安装
|
|
11
|
+
|
|
12
|
+
### 1. 安装 Node.js
|
|
13
|
+
|
|
14
|
+
访问 [https://nodejs.org/zh-cn/download](https://nodejs.org/zh-cn/download) 下载最新的 Node.js 安装程序。
|
|
15
|
+
|
|
16
|
+
### 2. 运行安装程序
|
|
17
|
+
|
|
18
|
+
按照安装向导完成 Node.js 的安装。
|
|
19
|
+
|
|
20
|
+
### 3. 重启终端
|
|
21
|
+
|
|
22
|
+
- **Windows**: CMD(按 `Win + R`,输入 `cmd`)或 PowerShell
|
|
23
|
+
- **macOS/Linux**: 打开新的终端窗口
|
|
24
|
+
|
|
25
|
+
### 4. 安装 Nova CLI
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm install -g @nova-cli/cli@latest
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### 5. 启动 Nova CLI
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
nova
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## 配置 API Key
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# 配置 Anthropic Claude
|
|
41
|
+
nova auth set anthropic
|
|
42
|
+
|
|
43
|
+
# 配置 OpenAI
|
|
44
|
+
nova auth set openai
|
|
45
|
+
|
|
46
|
+
# 查看认证状态
|
|
47
|
+
nova auth status
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### 使用本地模型(Ollama)
|
|
51
|
+
|
|
52
|
+
如果你安装了 Ollama,Nova CLI 会自动检测本地模型:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# 查看本地模型
|
|
56
|
+
nova ollama list
|
|
57
|
+
|
|
58
|
+
# 使用本地模型启动
|
|
59
|
+
nova -m llama3.2
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
详细安装指南请参阅 [INSTALLATION.md](./INSTALLATION.md)。
|
|
63
|
+
|
|
64
|
+
## Architecture Overview
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
nova-cli/
|
|
68
|
+
├── packages/
|
|
69
|
+
│ ├── core/ # @nova-cli/core - Engine library
|
|
70
|
+
│ │ └── src/
|
|
71
|
+
│ │ ├── types/ # Branded types, session, tools, config, errors
|
|
72
|
+
│ │ ├── tools/ # ToolRegistry, JSON schemas, 11 built-in tools
|
|
73
|
+
│ │ ├── model/ # Unified LLM client + Anthropic/OpenAI providers
|
|
74
|
+
│ │ ├── session/ # SessionManager + AgentLoop (execution engine)
|
|
75
|
+
│ │ ├── context/ # MemoryDiscovery + ContextBuilder + compression
|
|
76
|
+
│ │ ├── security/ # ApprovalManager + HookExecutor + FileFilter
|
|
77
|
+
│ │ ├── mcp/ # Model Context Protocol server management
|
|
78
|
+
│ │ ├── config/ # ConfigManager (YAML/JSON/env layered config)
|
|
79
|
+
│ │ ├── auth/ # Credential management (file + env vars)
|
|
80
|
+
│ │ ├── telemetry/ # Anonymous usage tracking
|
|
81
|
+
│ │ └── utils/ # Logger, helpers (retry, format, debounce)
|
|
82
|
+
│ └── cli/ # @nova-cli/cli - Terminal interface
|
|
83
|
+
│ └── src/
|
|
84
|
+
│ ├── bin/nova.js # Entry point
|
|
85
|
+
│ └── startup/ # NovaApp, InteractiveRepl, CLI argument parser
|
|
86
|
+
├── extensions/ # Skills and agents
|
|
87
|
+
├── __tests__/ # Unit and integration tests
|
|
88
|
+
└── scripts/ # Build and utility scripts
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Key Features
|
|
92
|
+
|
|
93
|
+
### Multi-Provider LLM Support
|
|
94
|
+
- **Anthropic** — Claude 3.5 Sonnet, Claude 3 Opus, Claude 3 Haiku (streaming, tools, vision)
|
|
95
|
+
- **OpenAI** — GPT-4o, GPT-4o Mini, GPT-4 Turbo (streaming, function calling)
|
|
96
|
+
- Unified `ModelClient` interface — swap providers without code changes
|
|
97
|
+
- Automatic message format conversion between Anthropic and OpenAI formats
|
|
98
|
+
|
|
99
|
+
### 11 Built-in Tools
|
|
100
|
+
|
|
101
|
+
| Category | Tools | Description |
|
|
102
|
+
|----------|-------|-------------|
|
|
103
|
+
| **File** | `read_file`, `write_file`, `edit_file`, `list_directory` | File operations with offset/limit, occurrence-safe editing, recursive listing |
|
|
104
|
+
| **Search** | `search_file`, `search_content` | Glob-based file search, ripgrep-powered content search with context lines |
|
|
105
|
+
| **Execution** | `execute_command` | Shell command execution with PowerShell/bash auto-detection, timeout, abort |
|
|
106
|
+
| **Web** | `web_search`, `web_fetch` | Serper.dev API search, URL fetching with HTML-to-text conversion |
|
|
107
|
+
| **Memory** | `memory_read`, `memory_write` | Key-value store with session/project/global scopes and TTL |
|
|
108
|
+
|
|
109
|
+
### Agent Execution Loop
|
|
110
|
+
The `AgentLoop` is the heart of Nova CLI — a multi-turn conversation loop that:
|
|
111
|
+
1. Sends messages to the LLM with tool definitions
|
|
112
|
+
2. Processes tool use responses from the model
|
|
113
|
+
3. Executes tools through the `ToolRegistry` (with approval checks)
|
|
114
|
+
4. Feeds tool results back to the model
|
|
115
|
+
5. Repeats until the model stops calling tools or max turns reached
|
|
116
|
+
|
|
117
|
+
Supports both **blocking** (`run()`) and **streaming** (`runStream()`) modes.
|
|
118
|
+
|
|
119
|
+
### Approval System
|
|
120
|
+
Five approval modes for different use cases:
|
|
121
|
+
|
|
122
|
+
| Mode | Behavior |
|
|
123
|
+
|------|----------|
|
|
124
|
+
| `yolo` | Auto-approve everything (dangerous but fast) |
|
|
125
|
+
| `default` | Ask for high/critical risk tools only |
|
|
126
|
+
| `accepting_edits` | Auto-approve file edits, ask for the rest |
|
|
127
|
+
| `plan` | Always ask before any tool execution |
|
|
128
|
+
| `smart` | AI-assisted approval decisions |
|
|
129
|
+
|
|
130
|
+
Custom approval rules with glob patterns and input field conditions.
|
|
131
|
+
|
|
132
|
+
### MCP (Model Context Protocol) Integration
|
|
133
|
+
- Connect to external MCP servers via stdio JSON-RPC
|
|
134
|
+
- Automatically discover and register MCP tools
|
|
135
|
+
- Each MCP server's tools become native Nova tools
|
|
136
|
+
|
|
137
|
+
### Security
|
|
138
|
+
- **FileFilter**: Path-based access control, ignore patterns, size limits
|
|
139
|
+
- **HookExecutor**: Lifecycle hooks (PreToolUse, PostToolUse, SessionStart, etc.)
|
|
140
|
+
- **ApprovalManager**: Risk-based approval workflow
|
|
141
|
+
- Credential files stored with `chmod 600` permissions
|
|
142
|
+
|
|
143
|
+
### Context & Memory System
|
|
144
|
+
- **MemoryDiscovery**: Auto-discovers project context files (CLAUDE.md, .cursor/rules, ARCHITECTURE.md, etc.)
|
|
145
|
+
- **ContextBuilder**: Builds optimized system prompts from discovered memory
|
|
146
|
+
- **Context Compression**: Automatic conversation truncation when approaching token limits
|
|
147
|
+
|
|
148
|
+
## Getting Started
|
|
149
|
+
|
|
150
|
+
### Prerequisites
|
|
151
|
+
- Node.js >= 18.0.0
|
|
152
|
+
- npm (or pnpm >= 9.0.0)
|
|
153
|
+
- An Anthropic or OpenAI API key
|
|
154
|
+
|
|
155
|
+
### Installation
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
# Clone and install
|
|
159
|
+
git clone <your-repo>
|
|
160
|
+
cd nova-cli
|
|
161
|
+
npm install --workspaces=false
|
|
162
|
+
|
|
163
|
+
# Install core dependencies
|
|
164
|
+
cd packages/core && npm install
|
|
165
|
+
|
|
166
|
+
# Install CLI dependencies
|
|
167
|
+
cd ../cli && npm install
|
|
168
|
+
|
|
169
|
+
# Build core first
|
|
170
|
+
cd ../core && npx tsc -p tsconfig.json
|
|
171
|
+
|
|
172
|
+
# Build CLI (includes core source for local references)
|
|
173
|
+
cd ../cli && npx tsc -p tsconfig.json
|
|
174
|
+
|
|
175
|
+
# Or use the build script (requires pnpm)
|
|
176
|
+
cd ../.. && pnpm install && pnpm build
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Configuration
|
|
180
|
+
|
|
181
|
+
Set your API key:
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
# Via CLI
|
|
185
|
+
nova auth set anthropic
|
|
186
|
+
# Enter your API key when prompted
|
|
187
|
+
|
|
188
|
+
# Or via environment variable
|
|
189
|
+
export ANTHROPIC_API_KEY=sk-ant-...
|
|
190
|
+
export OPENAI_API_KEY=sk-...
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Create a config file at `~/.nova/config.yaml`:
|
|
194
|
+
|
|
195
|
+
```yaml
|
|
196
|
+
core:
|
|
197
|
+
defaultModel: claude-3-sonnet-20240229
|
|
198
|
+
defaultApprovalMode: default
|
|
199
|
+
maxTurns: 100
|
|
200
|
+
maxTokens: 4096
|
|
201
|
+
temperature: 0.7
|
|
202
|
+
logLevel: info
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Project-level config at `.nova/config.yaml` overrides global settings.
|
|
206
|
+
|
|
207
|
+
### Usage
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
# Start interactive session
|
|
211
|
+
nova
|
|
212
|
+
|
|
213
|
+
# Single prompt
|
|
214
|
+
nova -p "Explain this codebase"
|
|
215
|
+
|
|
216
|
+
# Use a specific model
|
|
217
|
+
nova -m gpt-4o
|
|
218
|
+
|
|
219
|
+
# YOLO mode (auto-approve all tools)
|
|
220
|
+
nova --approval-mode yolo
|
|
221
|
+
|
|
222
|
+
# Set working directory
|
|
223
|
+
nova -d /path/to/project
|
|
224
|
+
|
|
225
|
+
# Show current config
|
|
226
|
+
nova config show
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Interactive Commands
|
|
230
|
+
|
|
231
|
+
Inside the REPL:
|
|
232
|
+
|
|
233
|
+
```
|
|
234
|
+
/help Show all commands
|
|
235
|
+
/quit Exit
|
|
236
|
+
/clear Clear conversation
|
|
237
|
+
/model <name> Switch model
|
|
238
|
+
/approval <mode> Change approval mode
|
|
239
|
+
/tools List available tools
|
|
240
|
+
/sessions Show session stats
|
|
241
|
+
/compact Compress context
|
|
242
|
+
/reset Start new session
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
## Development
|
|
246
|
+
|
|
247
|
+
### Project Structure (Monorepo)
|
|
248
|
+
|
|
249
|
+
```
|
|
250
|
+
nova-cli/ # pnpm workspace + Turborepo
|
|
251
|
+
├── packages/core/ # @nova-cli/core — reusable engine library
|
|
252
|
+
├── packages/cli/ # @nova-cli/cli — terminal application
|
|
253
|
+
├── extensions/ # Pluggable skills and agents
|
|
254
|
+
└── __tests__/ # Test suites
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### Building
|
|
258
|
+
|
|
259
|
+
```bash
|
|
260
|
+
pnpm build # Build all packages
|
|
261
|
+
pnpm dev # Watch mode
|
|
262
|
+
pnpm test # Run tests
|
|
263
|
+
pnpm lint # Lint
|
|
264
|
+
pnpm typecheck # Type check
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### Adding a New Tool
|
|
268
|
+
|
|
269
|
+
1. Create a JSON schema in `packages/core/src/tools/schemas/my-tool.ts`
|
|
270
|
+
2. Export from `packages/core/src/tools/schemas/index.ts`
|
|
271
|
+
3. Create a handler in `packages/core/src/tools/impl/MyTool.ts`
|
|
272
|
+
4. Register in `NovaApp.ts`:
|
|
273
|
+
|
|
274
|
+
```typescript
|
|
275
|
+
this.toolRegistry.register({
|
|
276
|
+
name: 'my_tool',
|
|
277
|
+
description: 'What this tool does',
|
|
278
|
+
category: 'file',
|
|
279
|
+
inputSchema: myToolSchema,
|
|
280
|
+
requiresApproval: false,
|
|
281
|
+
riskLevel: 'low',
|
|
282
|
+
}, myToolHandler);
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### Adding a New Model Provider
|
|
286
|
+
|
|
287
|
+
1. Create `packages/core/src/model/providers/MyProvider.ts`
|
|
288
|
+
2. Implement the `ModelProvider` interface
|
|
289
|
+
3. Add to `ModelClient.ts` constructor switch
|
|
290
|
+
4. Register models in `ConfigManager.ts` default config
|
|
291
|
+
|
|
292
|
+
### Type System
|
|
293
|
+
|
|
294
|
+
Nova CLI uses **branded TypeScript types** for compile-time safety:
|
|
295
|
+
|
|
296
|
+
```typescript
|
|
297
|
+
type SessionId = string & { readonly __brand: 'SessionId' };
|
|
298
|
+
type MessageId = string & { readonly __brand: 'MessageId' };
|
|
299
|
+
type ToolCallId = string & { readonly __brand: 'ToolCallId' };
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
### Error Handling
|
|
303
|
+
|
|
304
|
+
Hierarchical error classes:
|
|
305
|
+
|
|
306
|
+
```
|
|
307
|
+
NovaError (base)
|
|
308
|
+
├── ConfigError
|
|
309
|
+
├── ModelError
|
|
310
|
+
│ └── RateLimitError (retryable)
|
|
311
|
+
├── ToolError
|
|
312
|
+
│ └── ToolValidationError
|
|
313
|
+
├── SessionError
|
|
314
|
+
├── ApprovalError
|
|
315
|
+
├── HookError
|
|
316
|
+
├── McpError
|
|
317
|
+
├── SecurityError
|
|
318
|
+
├── ContextOverflowError
|
|
319
|
+
├── CancelledError
|
|
320
|
+
├── TimeoutError
|
|
321
|
+
└── AggregateError
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
## Design Decisions
|
|
325
|
+
|
|
326
|
+
### Why Monorepo?
|
|
327
|
+
Separation between `core` (library) and `cli` (application) allows:
|
|
328
|
+
- Reusing the engine in other projects (IDE plugins, web UIs)
|
|
329
|
+
- Independent versioning and testing
|
|
330
|
+
- Clean dependency boundaries
|
|
331
|
+
|
|
332
|
+
### Why Custom Tool System Instead of Raw MCP?
|
|
333
|
+
- Built-in tools work without external server dependencies
|
|
334
|
+
- Fine-grained approval control per tool
|
|
335
|
+
- Consistent error handling and streaming
|
|
336
|
+
- MCP tools are wrapped and exposed through the same registry
|
|
337
|
+
|
|
338
|
+
### Why Both Blocking and Streaming?
|
|
339
|
+
- Blocking mode (`run()`): simpler, good for scripts and testing
|
|
340
|
+
- Streaming mode (`runStream()`): better UX for interactive sessions
|
|
341
|
+
|
|
342
|
+
## Comparison with Alternatives
|
|
343
|
+
|
|
344
|
+
| Feature | Nova CLI | Claude Code | iFlow CLI |
|
|
345
|
+
|---------|----------|-------------|-----------|
|
|
346
|
+
| Multi-provider | Anthropic + OpenAI | Anthropic only | Multiple |
|
|
347
|
+
| Tool approval modes | 5 modes | 2 modes | 2 modes |
|
|
348
|
+
| MCP integration | Yes | Yes | Yes |
|
|
349
|
+
| Custom hooks | Shell-based | Limited | Limited |
|
|
350
|
+
| Context compression | Auto | Auto | Auto |
|
|
351
|
+
| Memory system | 3 scopes | Session only | File-based |
|
|
352
|
+
| Streaming | Yes | Yes | Yes |
|
|
353
|
+
| Extensible | Yes (extensions) | No | Limited |
|
|
354
|
+
| Open source | Yes | No | Yes |
|
|
355
|
+
|
|
356
|
+
## License
|
|
357
|
+
|
|
358
|
+
MIT
|
package/bin/nova
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// Nova CLI Entry Point - Cross-platform launcher
|
|
4
|
+
// Automatically uses tsx if available, falls back to direct node if compiled
|
|
5
|
+
|
|
6
|
+
import { spawn } from 'node:child_process';
|
|
7
|
+
import { fileURLToPath } from 'node:url';
|
|
8
|
+
import { dirname, join } from 'node:path';
|
|
9
|
+
import { existsSync } from 'node:fs';
|
|
10
|
+
|
|
11
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
12
|
+
const __dirname = dirname(__filename);
|
|
13
|
+
|
|
14
|
+
const mainScript = join(__dirname, 'nova.js');
|
|
15
|
+
|
|
16
|
+
// Check if running from compiled dist
|
|
17
|
+
const isCompiled = !existsSync(join(__dirname, '../src'));
|
|
18
|
+
|
|
19
|
+
if (isCompiled) {
|
|
20
|
+
// Running compiled version
|
|
21
|
+
import(mainScript).catch((err) => {
|
|
22
|
+
console.error('Fatal error:', err.message);
|
|
23
|
+
process.exit(1);
|
|
24
|
+
});
|
|
25
|
+
} else {
|
|
26
|
+
// Running from source, need tsx
|
|
27
|
+
const tsxPath = join(__dirname, '../node_modules/.bin/tsx');
|
|
28
|
+
const tsxCmd = existsSync(tsxPath + '.cmd') ? tsxPath + '.cmd' : tsxPath;
|
|
29
|
+
|
|
30
|
+
const child = spawn(tsxCmd, [mainScript, ...process.argv.slice(2)], {
|
|
31
|
+
stdio: 'inherit',
|
|
32
|
+
shell: process.platform === 'win32',
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
child.on('exit', (code) => {
|
|
36
|
+
process.exit(code ?? 0);
|
|
37
|
+
});
|
|
38
|
+
}
|
package/bin/nova.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// Nova CLI Entry Point
|
|
4
|
+
// Uses tsx to run TypeScript directly (handles ESM + cross-package imports)
|
|
5
|
+
|
|
6
|
+
import { NovaApp } from '../src/startup/NovaApp.ts';
|
|
7
|
+
|
|
8
|
+
const app = new NovaApp();
|
|
9
|
+
app.run().catch((err) => {
|
|
10
|
+
console.error('Fatal error:', err.message);
|
|
11
|
+
process.exit(1);
|
|
12
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "nova-terminal-assistant",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Nova CLI - Next-generation AI-powered terminal assistant",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"nova": "./bin/nova.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin/",
|
|
11
|
+
"src/",
|
|
12
|
+
"README.md"
|
|
13
|
+
],
|
|
14
|
+
"keywords": [
|
|
15
|
+
"ai",
|
|
16
|
+
"cli",
|
|
17
|
+
"assistant",
|
|
18
|
+
"code",
|
|
19
|
+
"terminal",
|
|
20
|
+
"llm",
|
|
21
|
+
"anthropic",
|
|
22
|
+
"openai",
|
|
23
|
+
"ollama"
|
|
24
|
+
],
|
|
25
|
+
"author": "Nova CLI Team",
|
|
26
|
+
"license": "MIT",
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "https://github.com/nova-cli/nova-cli"
|
|
30
|
+
},
|
|
31
|
+
"engines": {
|
|
32
|
+
"node": ">=18.0.0"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@anthropic-ai/sdk": "^0.25.0",
|
|
36
|
+
"@inquirer/prompts": "^5.3.0",
|
|
37
|
+
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
38
|
+
"chalk": "^5.3.0",
|
|
39
|
+
"commander": "^12.1.0",
|
|
40
|
+
"diff": "^5.2.0",
|
|
41
|
+
"glob": "^10.3.0",
|
|
42
|
+
"ignore": "^5.3.0",
|
|
43
|
+
"ink": "^4.4.1",
|
|
44
|
+
"ink-spinner": "^5.0.0",
|
|
45
|
+
"ink-text-input": "^5.0.1",
|
|
46
|
+
"json-schema": "^0.4.0",
|
|
47
|
+
"mime-types": "^2.1.35",
|
|
48
|
+
"open": "^10.1.0",
|
|
49
|
+
"openai": "^4.28.0",
|
|
50
|
+
"p-limit": "^4.0.0",
|
|
51
|
+
"react": "^18.2.0",
|
|
52
|
+
"semver": "^7.6.0",
|
|
53
|
+
"uuid": "^9.0.0",
|
|
54
|
+
"yaml": "^2.4.0",
|
|
55
|
+
"yargs": "^17.7.0",
|
|
56
|
+
"zod": "^3.22.0"
|
|
57
|
+
},
|
|
58
|
+
"devDependencies": {
|
|
59
|
+
"@types/node": "^20.11.0",
|
|
60
|
+
"@types/react": "^18.2.0",
|
|
61
|
+
"tsx": "^4.21.0",
|
|
62
|
+
"typescript": "^5.9.3"
|
|
63
|
+
},
|
|
64
|
+
"peerDependencies": {
|
|
65
|
+
"tsx": ">=4.0.0"
|
|
66
|
+
}
|
|
67
|
+
}
|