codebot-ai 1.0.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.
Files changed (58) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +247 -0
  3. package/bin/codebot +5 -0
  4. package/dist/agent.d.ts +31 -0
  5. package/dist/agent.js +256 -0
  6. package/dist/banner.d.ts +19 -0
  7. package/dist/banner.js +148 -0
  8. package/dist/browser/cdp.d.ts +29 -0
  9. package/dist/browser/cdp.js +292 -0
  10. package/dist/cli.d.ts +2 -0
  11. package/dist/cli.js +518 -0
  12. package/dist/context/manager.d.ts +27 -0
  13. package/dist/context/manager.js +139 -0
  14. package/dist/context/repo-map.d.ts +5 -0
  15. package/dist/context/repo-map.js +100 -0
  16. package/dist/history.d.ts +27 -0
  17. package/dist/history.js +146 -0
  18. package/dist/index.d.ts +13 -0
  19. package/dist/index.js +42 -0
  20. package/dist/memory.d.ts +39 -0
  21. package/dist/memory.js +168 -0
  22. package/dist/parser.d.ts +8 -0
  23. package/dist/parser.js +79 -0
  24. package/dist/providers/anthropic.d.ts +9 -0
  25. package/dist/providers/anthropic.js +288 -0
  26. package/dist/providers/index.d.ts +5 -0
  27. package/dist/providers/index.js +13 -0
  28. package/dist/providers/openai.d.ts +11 -0
  29. package/dist/providers/openai.js +173 -0
  30. package/dist/providers/registry.d.ts +15 -0
  31. package/dist/providers/registry.js +115 -0
  32. package/dist/setup.d.ts +17 -0
  33. package/dist/setup.js +243 -0
  34. package/dist/tools/browser.d.ts +43 -0
  35. package/dist/tools/browser.js +329 -0
  36. package/dist/tools/edit.d.ts +26 -0
  37. package/dist/tools/edit.js +73 -0
  38. package/dist/tools/execute.d.ts +26 -0
  39. package/dist/tools/execute.js +52 -0
  40. package/dist/tools/glob.d.ts +24 -0
  41. package/dist/tools/glob.js +102 -0
  42. package/dist/tools/grep.d.ts +29 -0
  43. package/dist/tools/grep.js +125 -0
  44. package/dist/tools/index.d.ts +10 -0
  45. package/dist/tools/index.js +49 -0
  46. package/dist/tools/memory.d.ts +36 -0
  47. package/dist/tools/memory.js +114 -0
  48. package/dist/tools/read.d.ts +26 -0
  49. package/dist/tools/read.js +75 -0
  50. package/dist/tools/think.d.ts +18 -0
  51. package/dist/tools/think.js +20 -0
  52. package/dist/tools/web-fetch.d.ts +36 -0
  53. package/dist/tools/web-fetch.js +83 -0
  54. package/dist/tools/write.d.ts +22 -0
  55. package/dist/tools/write.js +65 -0
  56. package/dist/types.d.ts +82 -0
  57. package/dist/types.js +3 -0
  58. package/package.json +57 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Ascendral Software Development & Innovation
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,247 @@
1
+ # CodeBot AI
2
+
3
+ Local-first AI coding assistant. Zero runtime dependencies. Works with Ollama, LM Studio, vLLM, Claude, GPT, Gemini, DeepSeek, Groq, Mistral, and Grok.
4
+
5
+ ## Quick Start
6
+
7
+ ```bash
8
+ # Install globally
9
+ npm install -g codebot-ai
10
+
11
+ # Run — setup wizard launches automatically on first use
12
+ codebot
13
+ ```
14
+
15
+ Or run without installing:
16
+
17
+ ```bash
18
+ npx codebot-ai
19
+ ```
20
+
21
+ Or from source:
22
+
23
+ ```bash
24
+ git clone https://github.com/AscendralSoftware/codebot-ai.git
25
+ cd codebot-ai
26
+ npm install && npm run build
27
+ ./bin/codebot
28
+ ```
29
+
30
+ ## Setup
31
+
32
+ On first run, CodeBot detects your environment and walks you through configuration:
33
+
34
+ - Scans for local LLM servers (Ollama, LM Studio, vLLM)
35
+ - Detects API keys from environment variables
36
+ - Lets you pick a provider and model
37
+ - Saves config to `~/.codebot/config.json`
38
+
39
+ To reconfigure anytime: `codebot --setup`
40
+
41
+ ### Environment Variables
42
+
43
+ Set an API key for your preferred cloud provider:
44
+
45
+ ```bash
46
+ export ANTHROPIC_API_KEY="sk-ant-..." # Claude
47
+ export OPENAI_API_KEY="sk-..." # GPT
48
+ export GEMINI_API_KEY="..." # Gemini
49
+ export DEEPSEEK_API_KEY="sk-..." # DeepSeek
50
+ export GROQ_API_KEY="gsk_..." # Groq
51
+ export MISTRAL_API_KEY="..." # Mistral
52
+ export XAI_API_KEY="xai-..." # Grok
53
+ ```
54
+
55
+ For local models, just have Ollama/LM Studio/vLLM running — CodeBot auto-detects them.
56
+
57
+ ## Usage
58
+
59
+ ### Interactive Mode
60
+
61
+ ```bash
62
+ codebot
63
+ ```
64
+
65
+ ### Single Message
66
+
67
+ ```bash
68
+ codebot "fix the bug in app.ts"
69
+ codebot --model claude-sonnet-4-6 "explain this codebase"
70
+ ```
71
+
72
+ ### Pipe Mode
73
+
74
+ ```bash
75
+ echo "write a function that sorts by date" | codebot
76
+ cat error.log | codebot "what's causing this?"
77
+ ```
78
+
79
+ ### Autonomous Mode
80
+
81
+ Skip all permission prompts — full auto:
82
+
83
+ ```bash
84
+ codebot --autonomous "refactor the auth module and run tests"
85
+ ```
86
+
87
+ ### Session Resume
88
+
89
+ CodeBot auto-saves every conversation. Resume anytime:
90
+
91
+ ```bash
92
+ codebot --continue # Resume last session
93
+ codebot --resume <session-id> # Resume specific session
94
+ ```
95
+
96
+ ## CLI Options
97
+
98
+ ```
99
+ --setup Run the setup wizard
100
+ --model <name> Model to use (default: qwen2.5-coder:32b)
101
+ --provider <name> Provider: openai, anthropic, gemini, deepseek, groq, mistral, xai
102
+ --base-url <url> LLM API base URL
103
+ --api-key <key> API key (or use env vars)
104
+ --autonomous Skip all permission prompts
105
+ --resume <id> Resume a session by ID
106
+ --continue, -c Resume the most recent session
107
+ --max-iterations <n> Max agent loop iterations (default: 50)
108
+ ```
109
+
110
+ ## Interactive Commands
111
+
112
+ ```
113
+ /help Show commands
114
+ /model Show or change model
115
+ /models List all supported models
116
+ /sessions List saved sessions
117
+ /auto Toggle autonomous mode
118
+ /clear Clear conversation
119
+ /compact Force context compaction
120
+ /config Show configuration
121
+ /quit Exit
122
+ ```
123
+
124
+ ## Tools
125
+
126
+ CodeBot has 10 built-in tools:
127
+
128
+ | Tool | Description | Permission |
129
+ |------|-------------|-----------|
130
+ | `read_file` | Read files with line numbers | auto |
131
+ | `write_file` | Create or overwrite files | prompt |
132
+ | `edit_file` | Find-and-replace edits | prompt |
133
+ | `execute` | Run shell commands | always-ask |
134
+ | `glob` | Find files by pattern | auto |
135
+ | `grep` | Search file contents with regex | auto |
136
+ | `think` | Internal reasoning scratchpad | auto |
137
+ | `memory` | Persistent memory across sessions | auto |
138
+ | `web_fetch` | HTTP requests and API calls | prompt |
139
+ | `browser` | Chrome automation via CDP | prompt |
140
+
141
+ ### Permission Levels
142
+
143
+ - **auto** — Runs without asking
144
+ - **prompt** — Asks for approval (skipped in `--autonomous` mode)
145
+ - **always-ask** — Always asks, even in autonomous mode
146
+
147
+ ### Browser Tool
148
+
149
+ Controls Chrome via the Chrome DevTools Protocol. Actions:
150
+
151
+ - `navigate` — Go to a URL
152
+ - `content` — Read page text
153
+ - `screenshot` — Capture the page
154
+ - `click` — Click an element by CSS selector
155
+ - `type` — Type into an input field
156
+ - `evaluate` — Run JavaScript on the page
157
+ - `tabs` — List open tabs
158
+ - `close` — Close browser connection
159
+
160
+ Chrome is auto-launched with `--remote-debugging-port` if not already running.
161
+
162
+ ### Memory
163
+
164
+ CodeBot has persistent memory that survives across sessions:
165
+
166
+ - **Global memory** (`~/.codebot/memory/`) — preferences, patterns
167
+ - **Project memory** (`.codebot/memory/`) — project-specific context
168
+ - Memory is automatically injected into the system prompt
169
+ - The agent can read/write its own memory using the `memory` tool
170
+
171
+ ## Supported Models
172
+
173
+ ### Local (Ollama / LM Studio / vLLM)
174
+
175
+ qwen2.5-coder (3b/7b/14b/32b), qwen3, deepseek-coder, codellama, llama3.x, mistral, mixtral, phi-3/4, starcoder2, granite-code, gemma2, command-r
176
+
177
+ ### Cloud
178
+
179
+ - **Anthropic**: claude-opus-4-6, claude-sonnet-4-6, claude-haiku-4-5
180
+ - **OpenAI**: gpt-4o, gpt-4.1, o1, o3, o4-mini
181
+ - **Google**: gemini-2.5-pro, gemini-2.5-flash, gemini-2.0-flash
182
+ - **DeepSeek**: deepseek-chat, deepseek-reasoner
183
+ - **Groq**: llama-3.3-70b, mixtral-8x7b (fast inference)
184
+ - **Mistral**: mistral-large, codestral
185
+ - **xAI**: grok-3, grok-3-mini
186
+
187
+ ## Architecture
188
+
189
+ ```
190
+ src/
191
+ agent.ts Agent loop with streaming, tool execution, permissions
192
+ cli.ts CLI interface, REPL, slash commands
193
+ types.ts TypeScript interfaces
194
+ parser.ts XML/JSON tool call parser (for models without native tool support)
195
+ history.ts Session persistence (JSONL)
196
+ memory.ts Persistent memory system
197
+ setup.ts Interactive setup wizard
198
+ context/
199
+ manager.ts Context window management, LLM-powered compaction
200
+ repo-map.ts Project structure scanner
201
+ providers/
202
+ openai.ts OpenAI-compatible provider (covers most cloud APIs)
203
+ anthropic.ts Native Anthropic Messages API provider
204
+ registry.ts Model registry, provider detection
205
+ browser/
206
+ cdp.ts Chrome DevTools Protocol client (zero-dep WebSocket)
207
+ tools/
208
+ read.ts, write.ts, edit.ts, execute.ts
209
+ glob.ts, grep.ts, think.ts
210
+ memory.ts, web-fetch.ts, browser.ts
211
+ ```
212
+
213
+ ## Programmatic API
214
+
215
+ CodeBot can be used as a library:
216
+
217
+ ```typescript
218
+ import { Agent, OpenAIProvider, AnthropicProvider } from 'codebot-ai';
219
+
220
+ const provider = new AnthropicProvider({
221
+ baseUrl: 'https://api.anthropic.com',
222
+ apiKey: process.env.ANTHROPIC_API_KEY,
223
+ model: 'claude-sonnet-4-6',
224
+ });
225
+
226
+ const agent = new Agent({
227
+ provider,
228
+ model: 'claude-sonnet-4-6',
229
+ autoApprove: true,
230
+ });
231
+
232
+ for await (const event of agent.run('list all TypeScript files')) {
233
+ if (event.type === 'text') process.stdout.write(event.text || '');
234
+ }
235
+ ```
236
+
237
+ ## Configuration
238
+
239
+ Config is loaded in this order (later values win):
240
+
241
+ 1. `~/.codebot/config.json` (saved by setup wizard)
242
+ 2. Environment variables (`CODEBOT_MODEL`, `CODEBOT_PROVIDER`, etc.)
243
+ 3. CLI flags (`--model`, `--provider`, etc.)
244
+
245
+ ## License
246
+
247
+ MIT - Ascendral Software Development & Innovation
package/bin/codebot ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+ require('../dist/cli.js').main().catch(err => {
3
+ console.error(err.message);
4
+ process.exit(1);
5
+ });
@@ -0,0 +1,31 @@
1
+ import { Message, AgentEvent, LLMProvider } from './types';
2
+ export declare class Agent {
3
+ private provider;
4
+ private tools;
5
+ private context;
6
+ private messages;
7
+ private maxIterations;
8
+ private autoApprove;
9
+ private model;
10
+ private askPermission;
11
+ private onMessage?;
12
+ constructor(opts: {
13
+ provider: LLMProvider;
14
+ model: string;
15
+ maxIterations?: number;
16
+ autoApprove?: boolean;
17
+ askPermission?: (tool: string, args: Record<string, unknown>) => Promise<boolean>;
18
+ onMessage?: (message: Message) => void;
19
+ });
20
+ /** Load messages from a previous session for resume */
21
+ loadMessages(messages: Message[]): void;
22
+ run(userMessage: string): AsyncGenerator<AgentEvent>;
23
+ clearHistory(): void;
24
+ forceCompact(): {
25
+ before: number;
26
+ after: number;
27
+ };
28
+ getMessages(): Message[];
29
+ private buildSystemPrompt;
30
+ }
31
+ //# sourceMappingURL=agent.d.ts.map
package/dist/agent.js ADDED
@@ -0,0 +1,256 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.Agent = void 0;
37
+ const readline = __importStar(require("readline"));
38
+ const tools_1 = require("./tools");
39
+ const parser_1 = require("./parser");
40
+ const manager_1 = require("./context/manager");
41
+ const repo_map_1 = require("./context/repo-map");
42
+ const memory_1 = require("./memory");
43
+ const registry_1 = require("./providers/registry");
44
+ class Agent {
45
+ provider;
46
+ tools;
47
+ context;
48
+ messages = [];
49
+ maxIterations;
50
+ autoApprove;
51
+ model;
52
+ askPermission;
53
+ onMessage;
54
+ constructor(opts) {
55
+ this.provider = opts.provider;
56
+ this.model = opts.model;
57
+ this.tools = new tools_1.ToolRegistry(process.cwd());
58
+ this.context = new manager_1.ContextManager(opts.model, opts.provider);
59
+ this.maxIterations = opts.maxIterations || 25;
60
+ this.autoApprove = opts.autoApprove || false;
61
+ this.askPermission = opts.askPermission || defaultAskPermission;
62
+ this.onMessage = opts.onMessage;
63
+ const supportsTools = (0, registry_1.getModelInfo)(opts.model).supportsToolCalling;
64
+ this.messages.push({
65
+ role: 'system',
66
+ content: this.buildSystemPrompt(supportsTools),
67
+ });
68
+ }
69
+ /** Load messages from a previous session for resume */
70
+ loadMessages(messages) {
71
+ this.messages = messages;
72
+ }
73
+ async *run(userMessage) {
74
+ const userMsg = { role: 'user', content: userMessage };
75
+ this.messages.push(userMsg);
76
+ this.onMessage?.(userMsg);
77
+ if (!this.context.fitsInBudget(this.messages)) {
78
+ const result = await this.context.compactWithSummary(this.messages);
79
+ this.messages = result.messages;
80
+ yield { type: 'compaction', text: result.summary || 'Context compacted to fit budget.' };
81
+ }
82
+ for (let i = 0; i < this.maxIterations; i++) {
83
+ const supportsTools = (0, registry_1.getModelInfo)(this.model).supportsToolCalling;
84
+ const toolSchemas = supportsTools ? this.tools.getSchemas() : undefined;
85
+ let fullText = '';
86
+ let toolCalls = [];
87
+ // Stream LLM response
88
+ for await (const event of this.provider.chat(this.messages, toolSchemas)) {
89
+ switch (event.type) {
90
+ case 'text':
91
+ fullText += event.text || '';
92
+ yield { type: 'text', text: event.text };
93
+ break;
94
+ case 'thinking':
95
+ yield { type: 'thinking', text: event.text };
96
+ break;
97
+ case 'tool_call_end':
98
+ if (event.toolCall) {
99
+ toolCalls.push(event.toolCall);
100
+ }
101
+ break;
102
+ case 'usage':
103
+ yield { type: 'usage', usage: event.usage };
104
+ break;
105
+ case 'error':
106
+ yield { type: 'error', error: event.error };
107
+ return;
108
+ }
109
+ }
110
+ // If no native tool calls, try parsing from text
111
+ if (toolCalls.length === 0 && fullText) {
112
+ toolCalls = (0, parser_1.parseToolCalls)(fullText);
113
+ }
114
+ // Save assistant message
115
+ const assistantMsg = { role: 'assistant', content: fullText };
116
+ if (toolCalls.length > 0) {
117
+ assistantMsg.tool_calls = toolCalls;
118
+ }
119
+ this.messages.push(assistantMsg);
120
+ this.onMessage?.(assistantMsg);
121
+ // No tool calls = conversation turn done
122
+ if (toolCalls.length === 0) {
123
+ yield { type: 'done' };
124
+ return;
125
+ }
126
+ // Execute each tool call
127
+ for (const tc of toolCalls) {
128
+ const toolName = tc.function.name;
129
+ const tool = this.tools.get(toolName);
130
+ if (!tool) {
131
+ const errResult = `Error: Unknown tool "${toolName}"`;
132
+ const toolMsg = { role: 'tool', content: errResult, tool_call_id: tc.id };
133
+ this.messages.push(toolMsg);
134
+ this.onMessage?.(toolMsg);
135
+ yield { type: 'tool_result', toolResult: { name: toolName, result: errResult, is_error: true } };
136
+ continue;
137
+ }
138
+ let args;
139
+ try {
140
+ args = JSON.parse(tc.function.arguments);
141
+ }
142
+ catch {
143
+ const errResult = `Error: Invalid JSON arguments for ${toolName}`;
144
+ const toolMsg = { role: 'tool', content: errResult, tool_call_id: tc.id };
145
+ this.messages.push(toolMsg);
146
+ this.onMessage?.(toolMsg);
147
+ yield { type: 'tool_result', toolResult: { name: toolName, result: errResult, is_error: true } };
148
+ continue;
149
+ }
150
+ yield { type: 'tool_call', toolCall: { name: toolName, args } };
151
+ // Permission check
152
+ const needsPermission = tool.permission === 'always-ask' ||
153
+ (tool.permission === 'prompt' && !this.autoApprove);
154
+ if (needsPermission) {
155
+ const approved = await this.askPermission(toolName, args);
156
+ if (!approved) {
157
+ const toolMsg = { role: 'tool', content: 'Permission denied by user.', tool_call_id: tc.id };
158
+ this.messages.push(toolMsg);
159
+ this.onMessage?.(toolMsg);
160
+ yield { type: 'tool_result', toolResult: { name: toolName, result: 'Permission denied.' } };
161
+ continue;
162
+ }
163
+ }
164
+ // Execute
165
+ try {
166
+ const output = await tool.execute(args);
167
+ const toolMsg = { role: 'tool', content: output, tool_call_id: tc.id };
168
+ this.messages.push(toolMsg);
169
+ this.onMessage?.(toolMsg);
170
+ yield { type: 'tool_result', toolResult: { name: toolName, result: output } };
171
+ }
172
+ catch (err) {
173
+ const errMsg = err instanceof Error ? err.message : String(err);
174
+ const toolMsg = { role: 'tool', content: `Error: ${errMsg}`, tool_call_id: tc.id };
175
+ this.messages.push(toolMsg);
176
+ this.onMessage?.(toolMsg);
177
+ yield { type: 'tool_result', toolResult: { name: toolName, result: errMsg, is_error: true } };
178
+ }
179
+ }
180
+ // Compact after tool results if needed
181
+ if (!this.context.fitsInBudget(this.messages)) {
182
+ const result = await this.context.compactWithSummary(this.messages);
183
+ this.messages = result.messages;
184
+ yield { type: 'compaction', text: result.summary || 'Context compacted.' };
185
+ }
186
+ }
187
+ yield { type: 'error', error: `Max iterations (${this.maxIterations}) reached.` };
188
+ }
189
+ clearHistory() {
190
+ const system = this.messages[0];
191
+ this.messages = system?.role === 'system' ? [system] : [];
192
+ }
193
+ forceCompact() {
194
+ const before = this.messages.length;
195
+ this.messages = this.context.compact(this.messages, true);
196
+ return { before, after: this.messages.length };
197
+ }
198
+ getMessages() {
199
+ return [...this.messages];
200
+ }
201
+ buildSystemPrompt(supportsTools) {
202
+ let repoMap = '';
203
+ try {
204
+ repoMap = (0, repo_map_1.buildRepoMap)(process.cwd());
205
+ }
206
+ catch {
207
+ repoMap = 'Project structure: (unable to scan)';
208
+ }
209
+ // Load persistent memory
210
+ let memoryBlock = '';
211
+ try {
212
+ const memory = new memory_1.MemoryManager(process.cwd());
213
+ memoryBlock = memory.getContextBlock();
214
+ }
215
+ catch {
216
+ // memory unavailable
217
+ }
218
+ let prompt = `You are CodeBot, an AI coding assistant. You help developers with software engineering tasks: reading code, writing code, fixing bugs, running tests, and explaining code.
219
+
220
+ Rules:
221
+ - Always read files before editing them.
222
+ - Prefer editing over rewriting entire files.
223
+ - Be concise and direct.
224
+ - Explain what you're doing and why.
225
+ - Use the memory tool to save important context, user preferences, and patterns you learn. Memory persists across sessions.
226
+
227
+ ${repoMap}${memoryBlock}`;
228
+ if (!supportsTools) {
229
+ prompt += `
230
+
231
+ To use tools, wrap calls in XML tags:
232
+ <tool_call>{"name": "tool_name", "arguments": {"arg1": "value1"}}</tool_call>
233
+
234
+ Available tools:
235
+ ${this.tools.all().map(t => `- ${t.name}: ${t.description}`).join('\n')}`;
236
+ }
237
+ return prompt;
238
+ }
239
+ }
240
+ exports.Agent = Agent;
241
+ async function defaultAskPermission(tool, args) {
242
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
243
+ const summary = Object.entries(args)
244
+ .map(([k, v]) => {
245
+ const val = typeof v === 'string' ? (v.length > 80 ? v.substring(0, 80) + '...' : v) : JSON.stringify(v);
246
+ return ` ${k}: ${val}`;
247
+ })
248
+ .join('\n');
249
+ return new Promise(resolve => {
250
+ rl.question(`\n⚡ ${tool}\n${summary}\nAllow? [y/N] `, answer => {
251
+ rl.close();
252
+ resolve(answer.toLowerCase().startsWith('y'));
253
+ });
254
+ });
255
+ }
256
+ //# sourceMappingURL=agent.js.map
@@ -0,0 +1,19 @@
1
+ /**
2
+ * CodeBot AI mascot and CLI banner.
3
+ *
4
+ * Mascot name: Codi
5
+ * Three designs: Pixel Bot, Monitor Bot, Visor Helmet
6
+ */
7
+ export declare const MASCOT_1 = "\n \u2588\u2588\n \u2584\u2584\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2584\u2584\n \u2588 \u2588\n \u2588 \u2584\u2588\u2588\u2584 \u2584\u2588\u2588\u2584 \u2588\n \u2588 \u2580\u2588\u2588\u2580 \u2580\u2588\u2588\u2580 \u2588\n \u2588 \u2588\n \u2588 \u2580\u2588\u2588\u2588\u2588\u2588\u2588\u2580 \u2588\n \u2580\u2580\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2580\u2580\n";
8
+ export declare const BANNER_1: (version: string, model: string, provider: string, session: string, autonomous: boolean) => string;
9
+ export declare const MASCOT_2 = "\n \u2554\u2557 \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557 \u2554\u2557\n \u2551\u2551 \u2551 \u2551 \u2551\u2551\n \u2551\u2551 \u2551 \u25CF \u25CF \u2551 \u2551\u2551\n \u2551\u2551 \u2551 \u2551 \u2551\u2551\n \u2551\u2551 \u2551 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2551 \u2551\u2551\n \u2551\u2551 \u2551 \u2551 \u2551\u2551\n \u255A\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u255D\n";
10
+ export declare const BANNER_2: (version: string, model: string, provider: string, session: string, autonomous: boolean) => string;
11
+ export declare const MASCOT_3 = "\n \u2584\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2584\n \u2588\u2580 \u2580\u2588\n \u2588 \u2591\u2591\u2588\u2588\u2588\u2588\u2588\u2588\u2591\u2591 \u2588\n \u2588 \u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591 \u2588\n \u2588\u2584 \u2584\u2588\n \u2580\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2580\n";
12
+ export declare const BANNER_3: (version: string, model: string, provider: string, session: string, autonomous: boolean) => string;
13
+ export declare const banner: (version: string, model: string, provider: string, session: string, autonomous: boolean) => string;
14
+ export declare function randomGreeting(): string;
15
+ /**
16
+ * Compact single-line startup for non-TTY / piped usage.
17
+ */
18
+ export declare function compactBanner(version: string, model: string): string;
19
+ //# sourceMappingURL=banner.d.ts.map