@kirosnn/mosaic 0.0.7
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/.mosaic/mosaic.local.jsonc +0 -0
- package/MOSAIC.md +188 -0
- package/README.md +127 -0
- package/docs/mosaic.png +0 -0
- package/package.json +42 -0
- package/src/agent/Agent.ts +131 -0
- package/src/agent/context.ts +96 -0
- package/src/agent/index.ts +2 -0
- package/src/agent/prompts/systemPrompt.ts +138 -0
- package/src/agent/prompts/toolsPrompt.ts +139 -0
- package/src/agent/provider/anthropic.ts +122 -0
- package/src/agent/provider/google.ts +124 -0
- package/src/agent/provider/mistral.ts +117 -0
- package/src/agent/provider/ollama.ts +531 -0
- package/src/agent/provider/openai.ts +220 -0
- package/src/agent/provider/xai.ts +122 -0
- package/src/agent/tools/bash.ts +20 -0
- package/src/agent/tools/definitions.ts +27 -0
- package/src/agent/tools/edit.ts +23 -0
- package/src/agent/tools/executor.ts +751 -0
- package/src/agent/tools/explore.ts +18 -0
- package/src/agent/tools/exploreExecutor.ts +320 -0
- package/src/agent/tools/glob.ts +16 -0
- package/src/agent/tools/grep.ts +19 -0
- package/src/agent/tools/index.ts +4 -0
- package/src/agent/tools/list.ts +20 -0
- package/src/agent/tools/question.ts +20 -0
- package/src/agent/tools/read.ts +15 -0
- package/src/agent/tools/write.ts +21 -0
- package/src/agent/types.ts +155 -0
- package/src/components/App.tsx +174 -0
- package/src/components/CommandsModal.tsx +77 -0
- package/src/components/CustomInput.tsx +328 -0
- package/src/components/Main.tsx +1112 -0
- package/src/components/Notification.tsx +91 -0
- package/src/components/SelectList.tsx +47 -0
- package/src/components/Setup.tsx +528 -0
- package/src/components/ShortcutsModal.tsx +67 -0
- package/src/components/Welcome.tsx +39 -0
- package/src/components/main/ApprovalPanel.tsx +134 -0
- package/src/components/main/ChatPage.tsx +516 -0
- package/src/components/main/HomePage.tsx +111 -0
- package/src/components/main/QuestionPanel.tsx +85 -0
- package/src/components/main/ThinkingIndicator.tsx +101 -0
- package/src/components/main/types.ts +55 -0
- package/src/components/main/wrapText.ts +41 -0
- package/src/index.tsx +212 -0
- package/src/utils/approvalBridge.ts +129 -0
- package/src/utils/commands/echo.ts +22 -0
- package/src/utils/commands/help.ts +25 -0
- package/src/utils/commands/index.ts +68 -0
- package/src/utils/commands/init.ts +68 -0
- package/src/utils/commands/redo.ts +74 -0
- package/src/utils/commands/registry.ts +29 -0
- package/src/utils/commands/sessions.ts +129 -0
- package/src/utils/commands/types.ts +20 -0
- package/src/utils/commands/undo.ts +75 -0
- package/src/utils/commands/web.ts +77 -0
- package/src/utils/config.ts +357 -0
- package/src/utils/diff.ts +201 -0
- package/src/utils/diffRendering.tsx +62 -0
- package/src/utils/exploreBridge.ts +87 -0
- package/src/utils/fileChangeTracker.ts +98 -0
- package/src/utils/fileChangesBridge.ts +18 -0
- package/src/utils/history.ts +106 -0
- package/src/utils/markdown.tsx +232 -0
- package/src/utils/models.ts +304 -0
- package/src/utils/questionBridge.ts +122 -0
- package/src/utils/terminalUtils.ts +25 -0
- package/src/utils/toolFormatting.ts +384 -0
- package/src/utils/undoRedo.ts +429 -0
- package/src/utils/undoRedoBridge.ts +45 -0
- package/src/utils/undoRedoDb.ts +338 -0
- package/src/utils/uninstall.ts +45 -0
- package/src/utils/version.ts +3 -0
- package/src/web/app.tsx +606 -0
- package/src/web/assets/css/ChatPage.css +212 -0
- package/src/web/assets/css/FileExplorer.css +202 -0
- package/src/web/assets/css/HomePage.css +119 -0
- package/src/web/assets/css/Markdown.css +178 -0
- package/src/web/assets/css/MessageItem.css +160 -0
- package/src/web/assets/css/Sidebar.css +208 -0
- package/src/web/assets/css/SidebarModal.css +137 -0
- package/src/web/assets/css/ThinkingIndicator.css +47 -0
- package/src/web/assets/css/ToolMessage.css +148 -0
- package/src/web/assets/css/global.css +226 -0
- package/src/web/assets/fonts/Geist-Black.woff2 +0 -0
- package/src/web/assets/fonts/Geist-BlackItalic.woff2 +0 -0
- package/src/web/assets/fonts/Geist-Bold.woff2 +0 -0
- package/src/web/assets/fonts/Geist-BoldItalic.woff2 +0 -0
- package/src/web/assets/fonts/Geist-ExtraBold.woff2 +0 -0
- package/src/web/assets/fonts/Geist-ExtraBoldItalic.woff2 +0 -0
- package/src/web/assets/fonts/Geist-ExtraLight.woff2 +0 -0
- package/src/web/assets/fonts/Geist-ExtraLightItalic.woff2 +0 -0
- package/src/web/assets/fonts/Geist-Italic[wght].woff2 +0 -0
- package/src/web/assets/fonts/Geist-Light.woff2 +0 -0
- package/src/web/assets/fonts/Geist-LightItalic.woff2 +0 -0
- package/src/web/assets/fonts/Geist-Medium.woff2 +0 -0
- package/src/web/assets/fonts/Geist-MediumItalic.woff2 +0 -0
- package/src/web/assets/fonts/Geist-Regular.woff2 +0 -0
- package/src/web/assets/fonts/Geist-RegularItalic.woff2 +0 -0
- package/src/web/assets/fonts/Geist-SemiBold.woff2 +0 -0
- package/src/web/assets/fonts/Geist-SemiBoldItalic.woff2 +0 -0
- package/src/web/assets/fonts/Geist-Thin.woff2 +0 -0
- package/src/web/assets/fonts/Geist-ThinItalic.woff2 +0 -0
- package/src/web/assets/fonts/GeistMono-Black.woff2 +0 -0
- package/src/web/assets/fonts/GeistMono-BlackItalic.woff2 +0 -0
- package/src/web/assets/fonts/GeistMono-Bold.woff2 +0 -0
- package/src/web/assets/fonts/GeistMono-BoldItalic.woff2 +0 -0
- package/src/web/assets/fonts/GeistMono-ExtraBold.woff2 +0 -0
- package/src/web/assets/fonts/GeistMono-ExtraBoldItalic.woff2 +0 -0
- package/src/web/assets/fonts/GeistMono-ExtraLight.woff2 +0 -0
- package/src/web/assets/fonts/GeistMono-ExtraLightItalic.woff2 +0 -0
- package/src/web/assets/fonts/GeistMono-Italic.woff2 +0 -0
- package/src/web/assets/fonts/GeistMono-Italic[wght].woff2 +0 -0
- package/src/web/assets/fonts/GeistMono-Light.woff2 +0 -0
- package/src/web/assets/fonts/GeistMono-LightItalic.woff2 +0 -0
- package/src/web/assets/fonts/GeistMono-Medium.woff2 +0 -0
- package/src/web/assets/fonts/GeistMono-MediumItalic.woff2 +0 -0
- package/src/web/assets/fonts/GeistMono-Regular.woff2 +0 -0
- package/src/web/assets/fonts/GeistMono-SemiBold.woff2 +0 -0
- package/src/web/assets/fonts/GeistMono-SemiBoldItalic.woff2 +0 -0
- package/src/web/assets/fonts/GeistMono-Thin.woff2 +0 -0
- package/src/web/assets/fonts/GeistMono-ThinItalic.woff2 +0 -0
- package/src/web/assets/fonts/GeistMono[wght].woff2 +0 -0
- package/src/web/assets/fonts/Geist[wght].woff2 +0 -0
- package/src/web/assets/fonts/blauer-nue-regular.woff2 +0 -0
- package/src/web/assets/fonts/neue-montreal-regular.woff2 +0 -0
- package/src/web/assets/images/favicon-v2.svg +6 -0
- package/src/web/assets/images/favicon.png +0 -0
- package/src/web/assets/images/foruse.svg +5 -0
- package/src/web/assets/images/logo_black.svg +5 -0
- package/src/web/assets/images/logo_white.svg +5 -0
- package/src/web/assets/images/logoblack.png +0 -0
- package/src/web/assets/images/logowhite.png +0 -0
- package/src/web/build.ts +23 -0
- package/src/web/components/ApprovalPanel.tsx +191 -0
- package/src/web/components/ChatPage.tsx +273 -0
- package/src/web/components/FileExplorer.tsx +162 -0
- package/src/web/components/HomePage.tsx +121 -0
- package/src/web/components/MessageItem.tsx +178 -0
- package/src/web/components/Modal.tsx +30 -0
- package/src/web/components/QuestionPanel.tsx +149 -0
- package/src/web/components/Setup.tsx +211 -0
- package/src/web/components/Sidebar.tsx +292 -0
- package/src/web/components/ThinkingIndicator.tsx +85 -0
- package/src/web/logo_black.svg +5 -0
- package/src/web/logo_white.svg +5 -0
- package/src/web/router.ts +46 -0
- package/src/web/server.tsx +662 -0
- package/src/web/storage.ts +92 -0
- package/src/web/types.ts +17 -0
- package/src/web/utils.ts +61 -0
- package/tsconfig.json +33 -0
|
File without changes
|
package/MOSAIC.md
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
# MOSAIC.md - Mosaic CLI Context File
|
|
2
|
+
|
|
3
|
+
This file provides contextual information about the Mosaic CLI project to help AI agents understand the codebase structure, patterns, and conventions.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
**Mosaic CLI** is an open-source AI-powered coding agent built with Bun and React. It provides a terminal-based interface using OpenTUI to render React components directly in the terminal, offering seamless interaction with AI coding assistants.
|
|
8
|
+
|
|
9
|
+
**Key Features:**
|
|
10
|
+
- Multi-provider AI support (OpenAI, Anthropic, Google, Mistral, XAI, Ollama)
|
|
11
|
+
- Terminal-first UI with React components rendered via OpenTUI
|
|
12
|
+
- Web interface option on http://127.0.0.1:8192
|
|
13
|
+
- Built-in tools for file operations, code search, and terminal commands
|
|
14
|
+
- Slash commands for quick operations
|
|
15
|
+
- Workspace context via MOSAIC.md files
|
|
16
|
+
|
|
17
|
+
## Architecture
|
|
18
|
+
|
|
19
|
+
### Core Architecture Patterns
|
|
20
|
+
|
|
21
|
+
1. **Modular Design**: The codebase is organized into clear modules:
|
|
22
|
+
- `src/agent/` - AI agent core logic and tools
|
|
23
|
+
- `src/components/` - React UI components
|
|
24
|
+
- `src/utils/` - Utility functions and helpers
|
|
25
|
+
- `src/web/` - Web interface components
|
|
26
|
+
|
|
27
|
+
2. **Tool-Based System**: The AI agent uses a tool-based approach where each capability is implemented as a separate tool (read, write, edit, bash, grep, etc.)
|
|
28
|
+
|
|
29
|
+
3. **Provider Abstraction**: AI providers are abstracted behind a common interface, allowing easy switching between different AI models
|
|
30
|
+
|
|
31
|
+
4. **Event-Driven UI**: The terminal interface uses React with OpenTUI for rendering, creating a responsive terminal experience
|
|
32
|
+
|
|
33
|
+
### Key Design Decisions
|
|
34
|
+
|
|
35
|
+
- **Bun Runtime**: Uses Bun for fast execution and modern JavaScript features
|
|
36
|
+
- **TypeScript**: Entire codebase is written in TypeScript for type safety
|
|
37
|
+
- **Functional Components**: React components use functional style with hooks
|
|
38
|
+
- **Tool Registry**: Tools are registered and managed through a central registry system
|
|
39
|
+
- **Context Management**: MOSAIC.md files provide project-specific context to AI agents
|
|
40
|
+
|
|
41
|
+
## Development Guidelines
|
|
42
|
+
|
|
43
|
+
### Coding Standards
|
|
44
|
+
|
|
45
|
+
- **TypeScript**: All code must be TypeScript with strict type checking
|
|
46
|
+
- **React Functional Components**: Use functional components with hooks
|
|
47
|
+
- **File Organization**: Group related files in subdirectories (e.g., agent tools, web components)
|
|
48
|
+
- **Error Handling**: Comprehensive error handling with user-friendly messages
|
|
49
|
+
- **Async/Await**: Use async/await for asynchronous operations
|
|
50
|
+
|
|
51
|
+
### Naming Conventions
|
|
52
|
+
|
|
53
|
+
- **Files**: PascalCase for components (App.tsx), camelCase for utilities (config.ts)
|
|
54
|
+
- **Variables**: camelCase for variables and functions
|
|
55
|
+
- **Constants**: UPPER_CASE for constants
|
|
56
|
+
- **Types/Interfaces**: PascalCase for type names
|
|
57
|
+
- **Components**: PascalCase component names (e.g., `<App />`)
|
|
58
|
+
|
|
59
|
+
### Best Practices
|
|
60
|
+
|
|
61
|
+
- **Tool Development**: New tools should follow the existing pattern in `src/agent/tools/`
|
|
62
|
+
- **Provider Integration**: New AI providers should implement the standard interface
|
|
63
|
+
- **Error Filtering**: Filter out common React/terminal errors in stderr/stdout
|
|
64
|
+
- **Configuration**: Use the config system for persistent settings
|
|
65
|
+
- **Undo/Redo**: Implement undo/redo functionality for file operations
|
|
66
|
+
|
|
67
|
+
## Key Files & Directories
|
|
68
|
+
|
|
69
|
+
### Root Files
|
|
70
|
+
|
|
71
|
+
- `package.json` - Project configuration and dependencies
|
|
72
|
+
- `tsconfig.json` - TypeScript configuration
|
|
73
|
+
- `README.md` - User documentation
|
|
74
|
+
- `MOSAIC.md` - This context file for AI agents
|
|
75
|
+
|
|
76
|
+
### Source Structure
|
|
77
|
+
|
|
78
|
+
#### `src/`
|
|
79
|
+
- **index.tsx** - Main entry point and CLI parser
|
|
80
|
+
- **components/` - React UI components for terminal interface
|
|
81
|
+
- **agent/` - AI agent core functionality
|
|
82
|
+
- **utils/` - Utility functions and helpers
|
|
83
|
+
- **web/` - Web interface components and server
|
|
84
|
+
|
|
85
|
+
#### `src/agent/`
|
|
86
|
+
- **Agent.ts** - Main agent class
|
|
87
|
+
- **context.ts** - Context management
|
|
88
|
+
- **types.ts** - Type definitions
|
|
89
|
+
- **prompts/` - Prompt templates
|
|
90
|
+
- **provider/` - AI provider implementations
|
|
91
|
+
- **tools/` - Tool implementations (file operations, bash, etc.)
|
|
92
|
+
|
|
93
|
+
#### `src/components/`
|
|
94
|
+
- **App.tsx** - Main application component
|
|
95
|
+
- **Main.tsx** - Main UI container
|
|
96
|
+
- **CustomInput.tsx** - Custom input component
|
|
97
|
+
- **main/` - Main page components (ChatPage, HomePage, etc.)
|
|
98
|
+
|
|
99
|
+
#### `src/utils/`
|
|
100
|
+
- **config.ts** - Configuration management
|
|
101
|
+
- **history.ts** - Chat history
|
|
102
|
+
- **undoRedo.ts** - Undo/redo functionality
|
|
103
|
+
- **commands/` - Slash command implementations
|
|
104
|
+
|
|
105
|
+
#### `src/web/`
|
|
106
|
+
- **app.tsx** - Web application entry point
|
|
107
|
+
- **server.tsx** - Web server implementation
|
|
108
|
+
- **components/` - Web UI components
|
|
109
|
+
- **assets/` - Static assets (CSS, fonts, images)
|
|
110
|
+
|
|
111
|
+
## Common Tasks
|
|
112
|
+
|
|
113
|
+
### Adding a New Tool
|
|
114
|
+
|
|
115
|
+
1. Create a new file in `src/agent/tools/` following the existing pattern
|
|
116
|
+
2. Implement the tool function with proper TypeScript types
|
|
117
|
+
3. Register the tool in the tool registry
|
|
118
|
+
4. Add appropriate error handling and validation
|
|
119
|
+
|
|
120
|
+
### Adding a New AI Provider
|
|
121
|
+
|
|
122
|
+
1. Create a new provider file in `src/agent/provider/`
|
|
123
|
+
2. Implement the standard provider interface
|
|
124
|
+
3. Add provider-specific configuration options
|
|
125
|
+
4. Update the provider selection logic
|
|
126
|
+
|
|
127
|
+
### Creating a New Slash Command
|
|
128
|
+
|
|
129
|
+
1. Create a new command file in `src/utils/commands/`
|
|
130
|
+
2. Implement the command handler function
|
|
131
|
+
3. Register the command in the command registry
|
|
132
|
+
4. Add command documentation
|
|
133
|
+
|
|
134
|
+
### Building the Web Interface
|
|
135
|
+
|
|
136
|
+
1. Develop components in `src/web/components/`
|
|
137
|
+
2. Add styles in `src/web/assets/css/`
|
|
138
|
+
3. Update the web app entry point in `src/web/app.tsx`
|
|
139
|
+
4. Ensure the server handles new routes in `src/web/server.tsx`
|
|
140
|
+
|
|
141
|
+
### Running the Project
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
# Development mode with auto-reload
|
|
145
|
+
bun run dev
|
|
146
|
+
|
|
147
|
+
# Production mode
|
|
148
|
+
bun run start
|
|
149
|
+
|
|
150
|
+
# Web interface
|
|
151
|
+
mosaic web
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Testing Tools
|
|
155
|
+
|
|
156
|
+
The project includes various tools that can be tested:
|
|
157
|
+
- File operations (read, write, edit)
|
|
158
|
+
- Directory listing and filtering
|
|
159
|
+
- Code search with grep
|
|
160
|
+
- Terminal command execution
|
|
161
|
+
- User interaction via questions
|
|
162
|
+
|
|
163
|
+
## Technical Stack
|
|
164
|
+
|
|
165
|
+
- **Runtime**: Bun
|
|
166
|
+
- **Language**: TypeScript
|
|
167
|
+
- **UI Framework**: React with OpenTUI
|
|
168
|
+
- **AI Integration**: Vercel AI SDK
|
|
169
|
+
- **Database**: Better SQLite 3
|
|
170
|
+
- **Build System**: Bun
|
|
171
|
+
|
|
172
|
+
## AI Provider Support
|
|
173
|
+
|
|
174
|
+
Mosaic supports multiple AI providers:
|
|
175
|
+
- OpenAI (GPT models)
|
|
176
|
+
- Anthropic (Claude models)
|
|
177
|
+
- Google (Gemini models)
|
|
178
|
+
- Mistral (Mistral/Mixtral models)
|
|
179
|
+
- XAI (Grok models)
|
|
180
|
+
- Ollama (local/cloud models)
|
|
181
|
+
|
|
182
|
+
## Important Notes
|
|
183
|
+
|
|
184
|
+
- The project uses a custom error filtering system to suppress common React/terminal errors
|
|
185
|
+
- Configuration is stored in `~/.mosaic/` directory
|
|
186
|
+
- MOSAIC.md files are automatically created/updated in project directories
|
|
187
|
+
- The system includes comprehensive undo/redo functionality for file operations
|
|
188
|
+
- Web interface runs on port 8192 by default
|
package/README.md
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="docs/mosaic.png" width="200" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
# Mosaic CLI
|
|
6
|
+
|
|
7
|
+
**Version 0.0.6.03**
|
|
8
|
+
|
|
9
|
+
Mosaic is an open-source, AI-powered coding agent for the terminal. It combines a React-based TUI (OpenTUI) with a tool-driven agent architecture to deliver a fast, context-aware development workflow. A web UI is also available for those who prefer a browser experience.
|
|
10
|
+
|
|
11
|
+
## Highlights
|
|
12
|
+
|
|
13
|
+
- Multi-provider AI support (OpenAI, Anthropic, Google, Mistral, xAI, Ollama)
|
|
14
|
+
- Terminal-first UI powered by React + OpenTUI
|
|
15
|
+
- Optional web interface on http://127.0.0.1:8192
|
|
16
|
+
- Built-in tools for file operations, search, and shell commands
|
|
17
|
+
- Slash commands for quick actions
|
|
18
|
+
- Project context via `MOSAIC.md` files
|
|
19
|
+
|
|
20
|
+
## Requirements
|
|
21
|
+
|
|
22
|
+
- [Bun](https://bun.sh)
|
|
23
|
+
|
|
24
|
+
## Installation (from source)
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
git clone https://github.com/kirosnn/mosaic.git
|
|
28
|
+
cd mosaic
|
|
29
|
+
bun install
|
|
30
|
+
bun link
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
After linking, run Mosaic from any directory:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
mosaic
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
If you prefer not to link globally:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
bun run mosaic
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Quick Start
|
|
46
|
+
|
|
47
|
+
1. Run `mosaic` in a project directory.
|
|
48
|
+
2. On first run, Mosaic creates `~/.mosaic/` and guides you through provider setup.
|
|
49
|
+
3. Initialize project context with:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
/init
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
This creates:
|
|
56
|
+
- `MOSAIC.md` with project context and conventions
|
|
57
|
+
- `.mosaic/` for project-specific settings
|
|
58
|
+
|
|
59
|
+
## CLI Usage
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
mosaic # Start in current directory
|
|
63
|
+
mosaic ./my-project # Start in a specific directory
|
|
64
|
+
mosaic run "fix the bug" # Launch with a task
|
|
65
|
+
mosaic --help # Show help
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Web Interface
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
mosaic web
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Open http://127.0.0.1:8192 in your browser.
|
|
75
|
+
|
|
76
|
+
## Configuration
|
|
77
|
+
|
|
78
|
+
Mosaic stores global settings in `~/.mosaic/`:
|
|
79
|
+
- `mosaic.jsonc` includes first-run status and version metadata
|
|
80
|
+
|
|
81
|
+
Project-specific settings live in `.mosaic/` at the repository root.
|
|
82
|
+
|
|
83
|
+
## Project Structure
|
|
84
|
+
|
|
85
|
+
- `src/index.tsx` - CLI entry point and routing
|
|
86
|
+
- `src/agent/` - Agent core, tools, and providers
|
|
87
|
+
- `src/components/` - TUI components
|
|
88
|
+
- `src/web/` - Web UI and server
|
|
89
|
+
- `src/utils/` - Helpers, config, and commands
|
|
90
|
+
|
|
91
|
+
## How It Works
|
|
92
|
+
|
|
93
|
+
Mosaic relies on a tool registry that exposes safe, focused capabilities to the agent:
|
|
94
|
+
|
|
95
|
+
- File operations (read, write, edit)
|
|
96
|
+
- Directory listing and navigation
|
|
97
|
+
- Code search with regex
|
|
98
|
+
- Terminal command execution
|
|
99
|
+
- Interactive questions for clarification
|
|
100
|
+
|
|
101
|
+
The `MOSAIC.md` file helps the agent adapt to each repository by describing conventions and structure.
|
|
102
|
+
|
|
103
|
+
## AI Providers
|
|
104
|
+
|
|
105
|
+
Mosaic uses the Vercel AI SDK and currently supports:
|
|
106
|
+
|
|
107
|
+
- OpenAI (GPT family)
|
|
108
|
+
- Anthropic (Claude family)
|
|
109
|
+
- Google (Gemini family)
|
|
110
|
+
- Mistral (Mistral, Mixtral)
|
|
111
|
+
- xAI (Grok family)
|
|
112
|
+
- Ollama (local or cloud models)
|
|
113
|
+
|
|
114
|
+
## Development
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
bun run dev # Watch mode
|
|
118
|
+
bun run start # Normal run
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Contributing
|
|
122
|
+
|
|
123
|
+
Issues and pull requests are welcome. Please include clear reproduction steps and context for behavior changes.
|
|
124
|
+
|
|
125
|
+
## License
|
|
126
|
+
|
|
127
|
+
MIT
|
package/docs/mosaic.png
ADDED
|
Binary file
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@kirosnn/mosaic",
|
|
3
|
+
"module": "src/index.tsx",
|
|
4
|
+
"version": "0.0.7",
|
|
5
|
+
"description": "The open source coding agent.",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"mosaic": "src/index.tsx"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"dev": "bun run --watch src/index.tsx",
|
|
12
|
+
"mosaic": "bun run src/index.tsx",
|
|
13
|
+
"start": "bun run src/index.tsx"
|
|
14
|
+
},
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"@types/bun": "latest",
|
|
17
|
+
"@types/react": "^19.0.0",
|
|
18
|
+
"@types/react-dom": "^19.2.3"
|
|
19
|
+
},
|
|
20
|
+
"peerDependencies": {
|
|
21
|
+
"typescript": "^5"
|
|
22
|
+
},
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@ai-sdk/anthropic": "^1.0.0",
|
|
25
|
+
"@ai-sdk/google": "^1.0.0",
|
|
26
|
+
"@ai-sdk/mistral": "^1.0.0",
|
|
27
|
+
"@ai-sdk/openai": "^1.0.0",
|
|
28
|
+
"@ai-sdk/xai": "^1.0.0",
|
|
29
|
+
"@opentui/core": "^0.1.69",
|
|
30
|
+
"@opentui/react": "^0.1.69",
|
|
31
|
+
"@types/react-syntax-highlighter": "^15.5.13",
|
|
32
|
+
"ai": "^4.0.0",
|
|
33
|
+
"better-sqlite3": "^12.6.0",
|
|
34
|
+
"ollama": "^0.5.0",
|
|
35
|
+
"react": "^19.2.3",
|
|
36
|
+
"react-dom": "^19.2.3",
|
|
37
|
+
"react-markdown": "^10.1.0",
|
|
38
|
+
"react-syntax-highlighter": "^16.1.0",
|
|
39
|
+
"remark-gfm": "^4.0.1",
|
|
40
|
+
"zod": "^3.23.8"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { CoreMessage, CoreTool } from 'ai';
|
|
2
|
+
import {
|
|
3
|
+
AgentEvent,
|
|
4
|
+
AgentMessage,
|
|
5
|
+
ProviderConfig,
|
|
6
|
+
Provider,
|
|
7
|
+
ProviderSendOptions,
|
|
8
|
+
} from './types';
|
|
9
|
+
import { readConfig } from '../utils/config';
|
|
10
|
+
import { DEFAULT_SYSTEM_PROMPT, processSystemPrompt } from './prompts/systemPrompt';
|
|
11
|
+
import { getTools } from './tools/definitions';
|
|
12
|
+
import { AnthropicProvider } from './provider/anthropic';
|
|
13
|
+
import { OpenAIProvider } from './provider/openai';
|
|
14
|
+
import { GoogleProvider } from './provider/google';
|
|
15
|
+
import { MistralProvider } from './provider/mistral';
|
|
16
|
+
import { XaiProvider } from './provider/xai';
|
|
17
|
+
import { OllamaProvider, checkAndStartOllama } from './provider/ollama';
|
|
18
|
+
|
|
19
|
+
export class Agent {
|
|
20
|
+
private messageHistory: CoreMessage[] = [];
|
|
21
|
+
private provider: Provider;
|
|
22
|
+
private config: ProviderConfig;
|
|
23
|
+
private static ollamaChecked = false;
|
|
24
|
+
|
|
25
|
+
static async ensureProviderReady(): Promise<{ ready: boolean; started?: boolean; error?: string }> {
|
|
26
|
+
const userConfig = readConfig();
|
|
27
|
+
|
|
28
|
+
if (userConfig.provider === 'ollama') {
|
|
29
|
+
if (Agent.ollamaChecked) {
|
|
30
|
+
return { ready: true };
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const result = await checkAndStartOllama();
|
|
34
|
+
Agent.ollamaChecked = true;
|
|
35
|
+
|
|
36
|
+
if (!result.running) {
|
|
37
|
+
return { ready: false, error: result.error };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return { ready: true, started: result.started };
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return { ready: true };
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
constructor() {
|
|
47
|
+
const userConfig = readConfig();
|
|
48
|
+
|
|
49
|
+
if (!userConfig.provider || !userConfig.model) {
|
|
50
|
+
throw new Error('No provider or model configured. Please run setup first.');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const rawSystemPrompt = userConfig.systemPrompt || DEFAULT_SYSTEM_PROMPT;
|
|
54
|
+
const systemPrompt = processSystemPrompt(rawSystemPrompt, true);
|
|
55
|
+
const tools = getTools();
|
|
56
|
+
|
|
57
|
+
this.config = {
|
|
58
|
+
provider: userConfig.provider,
|
|
59
|
+
model: userConfig.model,
|
|
60
|
+
apiKey: userConfig.apiKey,
|
|
61
|
+
systemPrompt,
|
|
62
|
+
tools,
|
|
63
|
+
maxSteps: 60,
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
this.provider = this.createProvider(userConfig.provider);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
private createProvider(providerName: string): Provider {
|
|
70
|
+
switch (providerName) {
|
|
71
|
+
case 'openai':
|
|
72
|
+
return new OpenAIProvider();
|
|
73
|
+
case 'anthropic':
|
|
74
|
+
return new AnthropicProvider();
|
|
75
|
+
case 'google':
|
|
76
|
+
return new GoogleProvider();
|
|
77
|
+
case 'mistral':
|
|
78
|
+
return new MistralProvider();
|
|
79
|
+
case 'xai':
|
|
80
|
+
return new XaiProvider();
|
|
81
|
+
case 'ollama':
|
|
82
|
+
return new OllamaProvider();
|
|
83
|
+
default:
|
|
84
|
+
throw new Error(`Unknown provider: ${providerName}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
async *sendMessage(userMessage: string, options?: ProviderSendOptions): AsyncGenerator<AgentEvent> {
|
|
89
|
+
this.messageHistory.push({
|
|
90
|
+
role: 'user',
|
|
91
|
+
content: userMessage,
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
try {
|
|
95
|
+
yield* this.provider.sendMessage(this.messageHistory, this.config, options);
|
|
96
|
+
} catch (error) {
|
|
97
|
+
yield {
|
|
98
|
+
type: 'error',
|
|
99
|
+
error: error instanceof Error ? error.message : 'Unknown error occurred',
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
async *streamMessages(messages: AgentMessage[], options?: ProviderSendOptions): AsyncGenerator<AgentEvent> {
|
|
105
|
+
this.messageHistory = messages.map(msg => ({
|
|
106
|
+
role: msg.role,
|
|
107
|
+
content: msg.content,
|
|
108
|
+
}));
|
|
109
|
+
|
|
110
|
+
try {
|
|
111
|
+
yield* this.provider.sendMessage(this.messageHistory, this.config, options);
|
|
112
|
+
} catch (error) {
|
|
113
|
+
yield {
|
|
114
|
+
type: 'error',
|
|
115
|
+
error: error instanceof Error ? error.message : 'Unknown error occurred',
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
getHistory(): CoreMessage[] {
|
|
121
|
+
return [...this.messageHistory];
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
clearHistory(): void {
|
|
125
|
+
this.messageHistory = [];
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
updateConfig(updates: Partial<ProviderConfig>): void {
|
|
129
|
+
this.config = { ...this.config, ...updates };
|
|
130
|
+
}
|
|
131
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { CoreMessage, CoreTool } from 'ai';
|
|
2
|
+
import { AgentConfig, AgentContext } from './types';
|
|
3
|
+
|
|
4
|
+
export class AgentContextManager {
|
|
5
|
+
private messages: CoreMessage[] = [];
|
|
6
|
+
private systemPrompt: string;
|
|
7
|
+
private tools: Record<string, CoreTool>;
|
|
8
|
+
private config: AgentConfig;
|
|
9
|
+
private currentStep: number = 0;
|
|
10
|
+
|
|
11
|
+
constructor(
|
|
12
|
+
systemPrompt: string,
|
|
13
|
+
tools: Record<string, CoreTool>,
|
|
14
|
+
config: AgentConfig,
|
|
15
|
+
initialMessages: CoreMessage[] = []
|
|
16
|
+
) {
|
|
17
|
+
this.systemPrompt = systemPrompt;
|
|
18
|
+
this.tools = tools;
|
|
19
|
+
this.config = config;
|
|
20
|
+
this.messages = [...initialMessages];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
addMessage(message: CoreMessage): void {
|
|
24
|
+
this.messages.push(message);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
addUserMessage(content: string): void {
|
|
28
|
+
this.messages.push({
|
|
29
|
+
role: 'user',
|
|
30
|
+
content,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
addAssistantMessage(content: string): void {
|
|
35
|
+
this.messages.push({
|
|
36
|
+
role: 'assistant',
|
|
37
|
+
content,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
addToolResult(toolCallId: string, toolName: string, result: unknown): void {
|
|
42
|
+
this.messages.push({
|
|
43
|
+
role: 'tool',
|
|
44
|
+
content: [
|
|
45
|
+
{
|
|
46
|
+
type: 'tool-result',
|
|
47
|
+
toolCallId,
|
|
48
|
+
toolName,
|
|
49
|
+
result,
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
getMessages(): CoreMessage[] {
|
|
56
|
+
return [...this.messages];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
getContext(): AgentContext {
|
|
60
|
+
return {
|
|
61
|
+
messages: this.getMessages(),
|
|
62
|
+
systemPrompt: this.systemPrompt,
|
|
63
|
+
tools: this.tools,
|
|
64
|
+
config: this.config,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
incrementStep(): void {
|
|
69
|
+
this.currentStep++;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
getCurrentStep(): number {
|
|
73
|
+
return this.currentStep;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
getMaxSteps(): number {
|
|
77
|
+
return this.config.maxSteps || 10;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
canContinue(): boolean {
|
|
81
|
+
return this.currentStep < this.getMaxSteps();
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
reset(): void {
|
|
85
|
+
this.messages = [];
|
|
86
|
+
this.currentStep = 0;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
getLastMessage(): CoreMessage | undefined {
|
|
90
|
+
return this.messages[this.messages.length - 1];
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
getMessageCount(): number {
|
|
94
|
+
return this.messages.length;
|
|
95
|
+
}
|
|
96
|
+
}
|