prab-cli 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.
package/LICENSE ADDED
@@ -0,0 +1,15 @@
1
+ ISC License
2
+
3
+ Copyright (c) 2024 Prabhanjan Sharma
4
+
5
+ Permission to use, copy, modify, and/or distribute this software for any
6
+ purpose with or without fee is hereby granted, provided that the above
7
+ copyright notice and this permission notice appear in all copies.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
10
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
12
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
14
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15
+ PERFORMANCE OF THIS SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,272 @@
1
+ # Prab CLI
2
+
3
+ An AI-powered coding assistant for your terminal. Built with Groq's lightning-fast LLMs, featuring autonomous tool execution, syntax-highlighted output, and seamless git integration.
4
+
5
+ ![Version](https://img.shields.io/npm/v/prab-cli)
6
+ ![License](https://img.shields.io/npm/l/prab-cli)
7
+
8
+ ## Features
9
+
10
+ - **AI-Powered Coding Assistant** - Chat with AI that understands your codebase
11
+ - **Autonomous Tool Execution** - AI can read, write, and edit files directly
12
+ - **Git Integration** - Built-in git status, diff, commit, push, and more
13
+ - **Syntax Highlighting** - Beautiful colored output for code blocks and diffs
14
+ - **Multiple Models** - Switch between Groq models on the fly
15
+ - **Task Tracking** - Built-in todo management for complex tasks
16
+ - **Safety Checks** - Confirmation prompts for destructive operations
17
+ - **Session Logging** - Debug and track all AI interactions
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ npm install -g prab-cli
23
+ ```
24
+
25
+ ## Quick Start
26
+
27
+ 1. **Get a Groq API Key** from [console.groq.com](https://console.groq.com)
28
+
29
+ 2. **Configure your API key:**
30
+ ```bash
31
+ groq-cli config
32
+ ```
33
+
34
+ 3. **Start chatting:**
35
+ ```bash
36
+ groq-cli
37
+ ```
38
+
39
+ ## Usage
40
+
41
+ ### Interactive Mode
42
+
43
+ Simply run `groq-cli` to start an interactive session:
44
+
45
+ ```bash
46
+ groq-cli
47
+ ```
48
+
49
+ You'll see the welcome banner and can start chatting with the AI:
50
+
51
+ ```
52
+ ____ __ ________ ____
53
+ / __ \_________ _/ /_ / ____/ / / _/
54
+ / /_/ / ___/ __ `/ __ \ / / / / / /
55
+ / ____/ / / /_/ / /_/ / / /___/ /____/ /
56
+ /_/ /_/ \__,_/_.___/ \____/_____/___/
57
+
58
+ Active Model: llama-3.3-70b-versatile
59
+ Available Tools: 14
60
+
61
+ > Help me refactor the authentication module
62
+ ```
63
+
64
+ ### Slash Commands
65
+
66
+ Type `/` during a session to access the command menu:
67
+
68
+ | Command | Description |
69
+ |---------|-------------|
70
+ | `/` | Open command menu |
71
+ | `/exit` | Exit the CLI |
72
+ | `/clear` | Clear chat history |
73
+ | `/context` | Show loaded file context |
74
+ | `/tools` | List available tools |
75
+ | `/todos` | Show current todo list |
76
+
77
+ ### Command Menu Options
78
+
79
+ 1. **Select Model** - Switch between available Groq models
80
+ 2. **Usage** - View current model and session stats
81
+ 3. **Tools** - List all available tools
82
+ 4. **Todos** - View task list
83
+ 5. **Clear Todos** - Reset task list
84
+ 6. **Context** - Show file context
85
+ 7. **Clear History** - Reset conversation
86
+ 8. **API Key** - Update your API key
87
+ 9. **Exit** - Quit the CLI
88
+
89
+ ## Available Tools
90
+
91
+ The AI has access to these tools for autonomous coding:
92
+
93
+ ### File Operations
94
+ | Tool | Description |
95
+ |------|-------------|
96
+ | `read_file` | Read file contents with line numbers |
97
+ | `write_file` | Create or overwrite files |
98
+ | `edit_file` | Make targeted edits to existing files |
99
+ | `glob` | Find files matching patterns |
100
+ | `grep` | Search file contents with regex |
101
+
102
+ ### Git Operations
103
+ | Tool | Description |
104
+ |------|-------------|
105
+ | `git_status` | Show working tree status |
106
+ | `git_diff` | Show changes between commits |
107
+ | `git_log` | View commit history |
108
+ | `git_add` | Stage files for commit |
109
+ | `git_commit` | Create a commit |
110
+ | `git_branch` | List or create branches |
111
+ | `git_push` | Push commits to remote |
112
+
113
+ ### System
114
+ | Tool | Description |
115
+ |------|-------------|
116
+ | `bash` | Execute shell commands |
117
+ | `manage_todos` | Track tasks and progress |
118
+
119
+ ## Colorized Output
120
+
121
+ The CLI provides rich, colorized output for better readability:
122
+
123
+ ### Git Diff
124
+ - Added lines in **green**
125
+ - Removed lines in **red**
126
+ - Hunk headers in **cyan**
127
+ - File headers in **bold**
128
+
129
+ ### Code Blocks
130
+ - Keywords highlighted in **magenta**
131
+ - Strings in **green**
132
+ - Numbers in **yellow**
133
+ - Comments in **gray**
134
+ - Function calls in **cyan**
135
+
136
+ ### Markdown
137
+ - Headers in **cyan bold**
138
+ - Inline code with **gray background**
139
+ - Bullet points with **yellow** markers
140
+ - Bold and italic text styling
141
+
142
+ ## Configuration
143
+
144
+ ### API Key
145
+
146
+ Set your Groq API key:
147
+
148
+ ```bash
149
+ # Interactive prompt
150
+ groq-cli config
151
+
152
+ # Or directly
153
+ groq-cli config YOUR_API_KEY
154
+ ```
155
+
156
+ ### Reset API Key
157
+
158
+ ```bash
159
+ groq-cli reset
160
+ ```
161
+
162
+ ### Model Management
163
+
164
+ ```bash
165
+ groq-cli model
166
+ ```
167
+
168
+ Options:
169
+ - List available models
170
+ - Show current model
171
+ - Switch to a different model
172
+
173
+ ## Supported Models
174
+
175
+ The CLI supports all Groq models including:
176
+
177
+ - `llama-3.3-70b-versatile` (default)
178
+ - `llama-3.1-70b-versatile`
179
+ - `llama-3.1-8b-instant`
180
+ - `mixtral-8x7b-32768`
181
+ - `gemma2-9b-it`
182
+ - And more...
183
+
184
+ Models are fetched dynamically from the Groq API.
185
+
186
+ ## Session Logging
187
+
188
+ Debug logs are stored in `~/.prab-cli/logs/`. View them with:
189
+
190
+ ```bash
191
+ # View latest log
192
+ npm run log
193
+
194
+ # List all logs
195
+ npm run log:list
196
+ ```
197
+
198
+ ## Examples
199
+
200
+ ### Read and Edit a File
201
+
202
+ ```
203
+ > Read the package.json and update the version to 2.0.0
204
+ ```
205
+
206
+ The AI will:
207
+ 1. Use `read_file` to view package.json
208
+ 2. Use `edit_file` to update the version
209
+ 3. Show you the diff of changes
210
+
211
+ ### Git Workflow
212
+
213
+ ```
214
+ > Check the git status and commit all changes with a descriptive message
215
+ ```
216
+
217
+ The AI will:
218
+ 1. Run `git_status` to see changes
219
+ 2. Use `git_add` to stage files
220
+ 3. Create a commit with `git_commit`
221
+
222
+ ### Code Search
223
+
224
+ ```
225
+ > Find all files that import the 'express' module
226
+ ```
227
+
228
+ The AI will use `grep` to search for import statements.
229
+
230
+ ## Safety Features
231
+
232
+ - **Confirmation Prompts** - Destructive operations require approval
233
+ - **Session Memory** - Remember choices for similar operations
234
+ - **Read-Only by Default** - Tools like `read_file` and `git_status` run without confirmation
235
+
236
+ ## Requirements
237
+
238
+ - Node.js 18+
239
+ - npm or yarn
240
+ - Groq API key
241
+
242
+ ## Development
243
+
244
+ ```bash
245
+ # Clone the repo
246
+ git clone https://github.com/prab002/prab-cli.git
247
+ cd prab-cli
248
+
249
+ # Install dependencies
250
+ npm install
251
+
252
+ # Run in development mode
253
+ npm run dev
254
+
255
+ # Build
256
+ npm run build
257
+
258
+ # Run production build
259
+ npm start
260
+ ```
261
+
262
+ ## License
263
+
264
+ ISC
265
+
266
+ ## Author
267
+
268
+ Prabhanjan Sharma
269
+
270
+ ---
271
+
272
+ Built with [Groq](https://groq.com) | [LangChain](https://langchain.com) | [Chalk](https://github.com/chalk/chalk)
package/dist/index.js ADDED
@@ -0,0 +1,374 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ const commander_1 = require("commander");
8
+ const inquirer_1 = __importDefault(require("inquirer"));
9
+ const config_1 = require("./lib/config");
10
+ const context_1 = require("./lib/context");
11
+ const ui_1 = require("./lib/ui");
12
+ const config_2 = require("./lib/config");
13
+ const ora_1 = __importDefault(require("ora"));
14
+ // Import tool system
15
+ const base_1 = require("./lib/tools/base");
16
+ const executor_1 = require("./lib/tools/executor");
17
+ const file_tools_1 = require("./lib/tools/file-tools");
18
+ const shell_tools_1 = require("./lib/tools/shell-tools");
19
+ const git_tools_1 = require("./lib/tools/git-tools");
20
+ const todo_tool_1 = require("./lib/tools/todo-tool");
21
+ // Import model system
22
+ const groq_provider_1 = require("./lib/models/groq-provider");
23
+ const registry_1 = require("./lib/models/registry");
24
+ const groq_models_1 = require("./lib/groq-models");
25
+ // Import chat handler and safety
26
+ const chat_handler_1 = require("./lib/chat-handler");
27
+ const safety_1 = require("./lib/safety");
28
+ const tracker_1 = require("./lib/tracker");
29
+ // Cache for available models
30
+ let cachedModels = [];
31
+ const program = new commander_1.Command();
32
+ program
33
+ .name("prab-cli")
34
+ .description("An AI coding assistant with autonomous tool capabilities")
35
+ .version("2.0.0");
36
+ // Config command
37
+ program
38
+ .command("config [key]")
39
+ .description("Set your Groq API Key")
40
+ .action(async (key) => {
41
+ if (key) {
42
+ (0, config_1.setApiKey)(key.trim());
43
+ ui_1.log.success("API Key saved successfully!");
44
+ return;
45
+ }
46
+ const { inputKey } = await inquirer_1.default.prompt([
47
+ {
48
+ type: "password",
49
+ name: "inputKey",
50
+ message: "Enter your Groq API Key:",
51
+ mask: "*",
52
+ },
53
+ ]);
54
+ (0, config_1.setApiKey)(inputKey.trim());
55
+ ui_1.log.success("API Key saved successfully!");
56
+ });
57
+ // Reset command
58
+ program
59
+ .command("reset")
60
+ .description("Clear your stored API Key")
61
+ .action(() => {
62
+ (0, config_1.clearApiKey)();
63
+ ui_1.log.success("API Key cleared!");
64
+ });
65
+ // Model management commands
66
+ program
67
+ .command("model")
68
+ .description("Manage AI models")
69
+ .action(async () => {
70
+ const { action } = await inquirer_1.default.prompt([
71
+ {
72
+ type: "list",
73
+ name: "action",
74
+ message: "Model Management:",
75
+ choices: [
76
+ { name: "List available models", value: "list" },
77
+ { name: "Show current model", value: "current" },
78
+ { name: "Switch model", value: "switch" },
79
+ { name: "Cancel", value: "cancel" },
80
+ ],
81
+ },
82
+ ]);
83
+ if (action === "list") {
84
+ console.log("\nAvailable Models:\n");
85
+ console.log((0, registry_1.getModelList)());
86
+ }
87
+ else if (action === "current") {
88
+ const config = (0, config_1.getModelConfig)();
89
+ ui_1.log.info(`Current model: ${config.modelId}`);
90
+ ui_1.log.info(`Temperature: ${config.temperature}`);
91
+ }
92
+ else if (action === "switch") {
93
+ const { modelId } = await inquirer_1.default.prompt([
94
+ {
95
+ type: "input",
96
+ name: "modelId",
97
+ message: "Enter model ID:",
98
+ },
99
+ ]);
100
+ const validation = (0, registry_1.validateModelId)(modelId);
101
+ if (validation.valid) {
102
+ (0, config_1.setActiveModel)(modelId);
103
+ ui_1.log.success(`Switched to model: ${modelId}`);
104
+ }
105
+ else {
106
+ ui_1.log.error(validation.error || "Invalid model");
107
+ if (validation.suggested) {
108
+ ui_1.log.info(`Did you mean: ${validation.suggested}?`);
109
+ }
110
+ }
111
+ }
112
+ });
113
+ // Main interactive mode
114
+ program.action(async () => {
115
+ // Check API Key
116
+ let apiKey = (0, config_1.getApiKey)();
117
+ if (!apiKey) {
118
+ ui_1.log.warning("No API Key found.");
119
+ const { key } = await inquirer_1.default.prompt([
120
+ {
121
+ type: "password",
122
+ name: "key",
123
+ message: "Please enter your Groq API Key to get started:",
124
+ mask: "*",
125
+ },
126
+ ]);
127
+ (0, config_1.setApiKey)(key.trim());
128
+ apiKey = key.trim();
129
+ }
130
+ // Initialize tool registry
131
+ const toolRegistry = new base_1.ToolRegistry();
132
+ toolRegistry.register(new file_tools_1.ReadFileTool());
133
+ toolRegistry.register(new file_tools_1.WriteFileTool());
134
+ toolRegistry.register(new file_tools_1.EditFileTool());
135
+ toolRegistry.register(new file_tools_1.GlobTool());
136
+ toolRegistry.register(new file_tools_1.GrepTool());
137
+ toolRegistry.register(new shell_tools_1.BashTool());
138
+ toolRegistry.register(new git_tools_1.GitStatusTool());
139
+ toolRegistry.register(new git_tools_1.GitAddTool());
140
+ toolRegistry.register(new git_tools_1.GitDiffTool());
141
+ toolRegistry.register(new git_tools_1.GitLogTool());
142
+ toolRegistry.register(new git_tools_1.GitCommitTool());
143
+ toolRegistry.register(new git_tools_1.GitBranchTool());
144
+ toolRegistry.register(new git_tools_1.GitPushTool());
145
+ toolRegistry.register(new todo_tool_1.TodoTool());
146
+ // Initialize safety checker and tool executor
147
+ const safetyChecker = new safety_1.SafetyChecker();
148
+ const toolExecutor = new executor_1.ToolExecutor(toolRegistry, safetyChecker);
149
+ // Initialize model provider
150
+ const modelConfig = (0, config_1.getModelConfig)();
151
+ const modelProvider = new groq_provider_1.GroqProvider(modelConfig.modelId, modelConfig.temperature);
152
+ try {
153
+ modelProvider.initialize(apiKey, modelConfig.modelId);
154
+ tracker_1.tracker.modelInit(modelConfig.modelId, "groq", true);
155
+ tracker_1.tracker.sessionStart(modelConfig.modelId, toolRegistry.count());
156
+ }
157
+ catch (e) {
158
+ ui_1.log.error("Failed to initialize model.");
159
+ tracker_1.tracker.modelInit(modelConfig.modelId, "groq", false, e.message);
160
+ process.exit(1);
161
+ }
162
+ // Display banner
163
+ (0, ui_1.banner)(modelConfig.modelId, toolRegistry.count());
164
+ // Context Gathering
165
+ const spinner = (0, ora_1.default)("Checking context...").start();
166
+ const isRepo = await (0, context_1.isGitRepo)();
167
+ let contextMessage = "";
168
+ if (isRepo) {
169
+ spinner.text = "Git repository detected. Gathering file structure...";
170
+ const files = await (0, context_1.getFileTree)();
171
+ contextMessage = `\n\nCurrent Working Directory Context:\nFile List:\n${files.join("\n")}`;
172
+ spinner.succeed(`Context loaded (${files.length} files detected).`);
173
+ }
174
+ else {
175
+ spinner.succeed("No Git repository detected. Running in standalone mode.");
176
+ }
177
+ // Initialize chat handler
178
+ const chatHandler = new chat_handler_1.ChatHandler(toolRegistry, toolExecutor, modelProvider, contextMessage);
179
+ ui_1.log.info('Type "/" for commands menu, or start chatting!');
180
+ // Display any existing todos
181
+ const session = (0, config_2.getSessionData)();
182
+ if (session.todos && session.todos.length > 0) {
183
+ (0, ui_1.showTodoList)(session.todos);
184
+ }
185
+ // Chat Loop
186
+ while (true) {
187
+ const { userInput } = await inquirer_1.default.prompt([
188
+ {
189
+ type: "input",
190
+ name: "userInput",
191
+ message: ">",
192
+ },
193
+ ]);
194
+ // Handle Slash Commands Menu
195
+ if (userInput.trim() === "/") {
196
+ const currentModel = modelProvider.modelId;
197
+ console.log("\n┌────────────────────────────────────────┐");
198
+ console.log("│ AVAILABLE COMMANDS │");
199
+ console.log("└────────────────────────────────────────┘\n");
200
+ const { action } = await inquirer_1.default.prompt([
201
+ {
202
+ type: "list",
203
+ name: "action",
204
+ message: "Choose an option:",
205
+ choices: [
206
+ "1. Select Model",
207
+ "2. Usage",
208
+ "3. Tools",
209
+ "4. Todos",
210
+ "5. Clear Todos",
211
+ "6. Context",
212
+ "7. Clear History",
213
+ "8. API Key",
214
+ "9. Exit",
215
+ ],
216
+ },
217
+ ]);
218
+ // Select Model - Toggle between different models
219
+ if (action === "1. Select Model") {
220
+ // Fetch models from Groq API if not cached
221
+ if (cachedModels.length === 0) {
222
+ const spinner = (0, ora_1.default)("Fetching available models from Groq...").start();
223
+ cachedModels = await (0, groq_models_1.fetchGroqModels)(apiKey);
224
+ spinner.succeed(`Found ${cachedModels.length} models`);
225
+ }
226
+ // Group models by owner
227
+ const grouped = (0, groq_models_1.groupModelsByOwner)(cachedModels);
228
+ const modelChoices = [];
229
+ // Build choices grouped by owner
230
+ for (const [owner, models] of grouped) {
231
+ modelChoices.push(new inquirer_1.default.Separator(`─── ${owner} ───`));
232
+ for (const model of models) {
233
+ const isCurrent = model.id === currentModel;
234
+ const ctx = (0, groq_models_1.formatContextWindow)(model.context_window);
235
+ modelChoices.push({
236
+ name: `${isCurrent ? "✓ " : " "}${model.id} (${ctx} ctx)`,
237
+ value: model.id,
238
+ short: model.id,
239
+ });
240
+ }
241
+ }
242
+ const { selectedModel } = await inquirer_1.default.prompt([
243
+ {
244
+ type: "list",
245
+ name: "selectedModel",
246
+ message: `Select a model (current: ${currentModel}):`,
247
+ choices: modelChoices,
248
+ pageSize: 15,
249
+ loop: false,
250
+ },
251
+ ]);
252
+ if (selectedModel && selectedModel !== currentModel) {
253
+ const oldModel = currentModel;
254
+ (0, config_1.setActiveModel)(selectedModel);
255
+ modelProvider.setModel(selectedModel);
256
+ ui_1.log.success(`Switched to model: ${selectedModel}`);
257
+ tracker_1.tracker.modelSwitch(oldModel, selectedModel, true);
258
+ }
259
+ else if (selectedModel === currentModel) {
260
+ ui_1.log.info(`Already using ${selectedModel}`);
261
+ }
262
+ continue;
263
+ }
264
+ // Usage - Show model usage and stats
265
+ if (action === "2. Usage") {
266
+ console.log("\n┌─────────────────────────────────────┐");
267
+ console.log("│ MODEL USAGE │");
268
+ console.log("└─────────────────────────────────────┘\n");
269
+ console.log(` Current Model: ${currentModel}`);
270
+ // Find model in cache and show details
271
+ if (cachedModels.length === 0) {
272
+ const spinner = (0, ora_1.default)("Fetching model info...").start();
273
+ cachedModels = await (0, groq_models_1.fetchGroqModels)(apiKey);
274
+ spinner.stop();
275
+ }
276
+ const modelInfo = cachedModels.find((m) => m.id === currentModel);
277
+ if (modelInfo) {
278
+ console.log(` Provider: ${modelInfo.owned_by}`);
279
+ console.log(` Context: ${(0, groq_models_1.formatContextWindow)(modelInfo.context_window)} tokens`);
280
+ console.log(` Status: ${modelInfo.active ? "Active" : "Inactive"}`);
281
+ }
282
+ console.log("\n┌─────────────────────────────────────┐");
283
+ console.log("│ SESSION STATS │");
284
+ console.log("└─────────────────────────────────────┘\n");
285
+ console.log(` Messages: ${chatHandler.getMessageCount()}`);
286
+ console.log(` Tools: ${toolRegistry.count()} available`);
287
+ console.log(` Session ID: ${tracker_1.tracker.getSessionId()}`);
288
+ console.log("");
289
+ continue;
290
+ }
291
+ if (action === "3. Tools") {
292
+ console.log("\n┌─────────────────────────────────────┐");
293
+ console.log("│ AVAILABLE TOOLS │");
294
+ console.log("└─────────────────────────────────────┘\n");
295
+ console.log(toolRegistry.getToolDescriptions());
296
+ console.log("");
297
+ continue;
298
+ }
299
+ if (action === "4. Todos") {
300
+ const session = (0, config_2.getSessionData)();
301
+ (0, ui_1.showTodoList)(session.todos);
302
+ continue;
303
+ }
304
+ if (action === "5. Clear Todos") {
305
+ (0, config_1.clearSessionData)();
306
+ ui_1.log.success("Todos cleared.");
307
+ continue;
308
+ }
309
+ if (action === "6. Context") {
310
+ console.log("\n┌─────────────────────────────────────┐");
311
+ console.log("│ FILE CONTEXT │");
312
+ console.log("└─────────────────────────────────────┘\n");
313
+ console.log(contextMessage || " No context loaded.");
314
+ console.log("");
315
+ continue;
316
+ }
317
+ if (action === "7. Clear History") {
318
+ chatHandler.clearHistory();
319
+ ui_1.log.success("Chat history cleared.");
320
+ continue;
321
+ }
322
+ if (action === "8. API Key") {
323
+ const { key } = await inquirer_1.default.prompt([
324
+ {
325
+ type: "password",
326
+ name: "key",
327
+ message: "Enter new API Key:",
328
+ mask: "*",
329
+ },
330
+ ]);
331
+ (0, config_1.setApiKey)(key.trim());
332
+ apiKey = key.trim();
333
+ modelProvider.initialize(key.trim(), modelConfig.modelId);
334
+ cachedModels = []; // Clear model cache
335
+ ui_1.log.success("API Key updated.");
336
+ continue;
337
+ }
338
+ if (action === "9. Exit")
339
+ process.exit(0);
340
+ continue;
341
+ }
342
+ // Handle direct slash commands
343
+ if (userInput.startsWith("/")) {
344
+ const cmd = userInput.trim().toLowerCase();
345
+ if (cmd === "/exit" || cmd === "/quit")
346
+ process.exit(0);
347
+ if (cmd === "/clear") {
348
+ chatHandler.clearHistory();
349
+ ui_1.log.success("History cleared.");
350
+ continue;
351
+ }
352
+ if (cmd === "/context") {
353
+ ui_1.log.info(contextMessage || "No context.");
354
+ continue;
355
+ }
356
+ if (cmd === "/tools") {
357
+ console.log("\n📦 Available Tools:\n");
358
+ console.log(toolRegistry.getToolDescriptions());
359
+ console.log("");
360
+ continue;
361
+ }
362
+ if (cmd === "/todos") {
363
+ const session = (0, config_2.getSessionData)();
364
+ (0, ui_1.showTodoList)(session.todos);
365
+ continue;
366
+ }
367
+ ui_1.log.warning(`Unknown command: ${cmd}. Type "/" for menu.`);
368
+ continue;
369
+ }
370
+ // Process user input with chat handler
371
+ await chatHandler.processUserInput(userInput);
372
+ }
373
+ });
374
+ program.parse(process.argv);