grok-cli-acp 0.1.2
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/.env.example +42 -0
- package/.github/workflows/ci.yml +30 -0
- package/.github/workflows/rust.yml +22 -0
- package/.grok/.env.example +85 -0
- package/.grok/COMPLETE_FIX_SUMMARY.md +466 -0
- package/.grok/ENV_CONFIG_GUIDE.md +173 -0
- package/.grok/QUICK_REFERENCE.md +180 -0
- package/.grok/README.md +104 -0
- package/.grok/TESTING_GUIDE.md +393 -0
- package/CHANGELOG.md +465 -0
- package/CODE_REVIEW_SUMMARY.md +414 -0
- package/COMPLETE_FIX_SUMMARY.md +415 -0
- package/CONFIGURATION.md +489 -0
- package/CONTEXT_FILES_GUIDE.md +419 -0
- package/CONTRIBUTING.md +55 -0
- package/CURSOR_POSITION_FIX.md +206 -0
- package/Cargo.toml +88 -0
- package/ERROR_HANDLING_REPORT.md +361 -0
- package/FINAL_FIX_SUMMARY.md +462 -0
- package/FIXES.md +37 -0
- package/FIXES_SUMMARY.md +87 -0
- package/GROK_API_MIGRATION_SUMMARY.md +111 -0
- package/LICENSE +22 -0
- package/MIGRATION_TO_GROK_API.md +223 -0
- package/README.md +504 -0
- package/REVIEW_COMPLETE.md +416 -0
- package/REVIEW_QUICK_REFERENCE.md +173 -0
- package/SECURITY.md +463 -0
- package/SECURITY_AUDIT.md +661 -0
- package/SETUP.md +287 -0
- package/TESTING_TOOLS.md +88 -0
- package/TESTING_TOOL_EXECUTION.md +239 -0
- package/TOOL_EXECUTION_FIX.md +491 -0
- package/VERIFICATION_CHECKLIST.md +419 -0
- package/docs/API.md +74 -0
- package/docs/CHAT_LOGGING.md +39 -0
- package/docs/CURSOR_FIX_DEMO.md +306 -0
- package/docs/ERROR_HANDLING_GUIDE.md +547 -0
- package/docs/FILE_OPERATIONS.md +449 -0
- package/docs/INTERACTIVE.md +401 -0
- package/docs/PROJECT_CREATION_GUIDE.md +570 -0
- package/docs/QUICKSTART.md +378 -0
- package/docs/QUICK_REFERENCE.md +691 -0
- package/docs/RELEASE_NOTES_0.1.2.md +240 -0
- package/docs/TOOLS.md +459 -0
- package/docs/TOOLS_QUICK_REFERENCE.md +210 -0
- package/docs/ZED_INTEGRATION.md +371 -0
- package/docs/extensions.md +464 -0
- package/docs/settings.md +293 -0
- package/examples/extensions/logging-hook/README.md +91 -0
- package/examples/extensions/logging-hook/extension.json +22 -0
- package/package.json +30 -0
- package/scripts/test_acp.py +252 -0
- package/scripts/test_acp.sh +143 -0
- package/scripts/test_acp_simple.sh +72 -0
- package/src/acp/mod.rs +741 -0
- package/src/acp/protocol.rs +323 -0
- package/src/acp/security.rs +298 -0
- package/src/acp/tools.rs +697 -0
- package/src/bin/banner_demo.rs +216 -0
- package/src/bin/docgen.rs +18 -0
- package/src/bin/installer.rs +217 -0
- package/src/cli/app.rs +310 -0
- package/src/cli/commands/acp.rs +721 -0
- package/src/cli/commands/chat.rs +485 -0
- package/src/cli/commands/code.rs +513 -0
- package/src/cli/commands/config.rs +394 -0
- package/src/cli/commands/health.rs +442 -0
- package/src/cli/commands/history.rs +421 -0
- package/src/cli/commands/mod.rs +14 -0
- package/src/cli/commands/settings.rs +1384 -0
- package/src/cli/mod.rs +166 -0
- package/src/config/mod.rs +2212 -0
- package/src/display/ascii_art.rs +139 -0
- package/src/display/banner.rs +289 -0
- package/src/display/components/input.rs +323 -0
- package/src/display/components/mod.rs +2 -0
- package/src/display/components/settings_list.rs +306 -0
- package/src/display/interactive.rs +1255 -0
- package/src/display/mod.rs +62 -0
- package/src/display/terminal.rs +42 -0
- package/src/display/tips.rs +316 -0
- package/src/grok_client_ext.rs +177 -0
- package/src/hooks/loader.rs +407 -0
- package/src/hooks/mod.rs +158 -0
- package/src/lib.rs +174 -0
- package/src/main.rs +65 -0
- package/src/mcp/client.rs +195 -0
- package/src/mcp/config.rs +20 -0
- package/src/mcp/mod.rs +6 -0
- package/src/mcp/protocol.rs +67 -0
- package/src/utils/auth.rs +41 -0
- package/src/utils/chat_logger.rs +568 -0
- package/src/utils/context.rs +390 -0
- package/src/utils/mod.rs +16 -0
- package/src/utils/network.rs +320 -0
- package/src/utils/rate_limiter.rs +166 -0
- package/src/utils/session.rs +73 -0
- package/src/utils/shell_permissions.rs +389 -0
- package/src/utils/telemetry.rs +41 -0
package/docs/settings.md
ADDED
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
# Grok CLI Settings (`settings` command)
|
|
2
|
+
|
|
3
|
+
Grok CLI provides a powerful settings system using `.env` files with hierarchical configuration.
|
|
4
|
+
|
|
5
|
+
## Configuration Files
|
|
6
|
+
|
|
7
|
+
- **System settings**: `~/.grok/.env` (Linux/macOS) or `%USERPROFILE%\.grok\.env` (Windows)
|
|
8
|
+
- **Project settings**: `.grok/.env` (in your project directory)
|
|
9
|
+
|
|
10
|
+
Note: Project settings override system settings. Environment variables override all files.
|
|
11
|
+
|
|
12
|
+
## Using the Settings Command
|
|
13
|
+
|
|
14
|
+
### Interactive Settings Browser
|
|
15
|
+
```bash
|
|
16
|
+
# Launch interactive settings browser
|
|
17
|
+
grok settings show
|
|
18
|
+
|
|
19
|
+
# Edit settings interactively
|
|
20
|
+
grok settings edit
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Reset Settings
|
|
24
|
+
```bash
|
|
25
|
+
# Reset all settings to defaults
|
|
26
|
+
grok settings reset
|
|
27
|
+
|
|
28
|
+
# Reset specific category to defaults
|
|
29
|
+
grok settings reset --category ui
|
|
30
|
+
grok settings reset --category general
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Import/Export Settings
|
|
34
|
+
```bash
|
|
35
|
+
# Export current settings to a file
|
|
36
|
+
grok settings export --path my-settings.env
|
|
37
|
+
|
|
38
|
+
# Import settings from a file
|
|
39
|
+
grok settings import --path my-settings.env
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Settings Categories
|
|
43
|
+
|
|
44
|
+
Settings are organized into logical categories for easier management:
|
|
45
|
+
|
|
46
|
+
### General
|
|
47
|
+
Core application settings and preferences.
|
|
48
|
+
|
|
49
|
+
### UI
|
|
50
|
+
User interface appearance, themes, and display options.
|
|
51
|
+
|
|
52
|
+
### Model
|
|
53
|
+
AI model configuration and behavior settings.
|
|
54
|
+
|
|
55
|
+
### Context
|
|
56
|
+
File handling, context discovery, and memory management.
|
|
57
|
+
|
|
58
|
+
### Tools
|
|
59
|
+
Tool execution, shell integration, and external command settings.
|
|
60
|
+
|
|
61
|
+
### Security
|
|
62
|
+
Security policies, trust settings, and access controls.
|
|
63
|
+
|
|
64
|
+
### Experimental
|
|
65
|
+
Preview features and experimental functionality.
|
|
66
|
+
|
|
67
|
+
### ACP
|
|
68
|
+
Agent Client Protocol settings for Zed editor integration.
|
|
69
|
+
|
|
70
|
+
### Network
|
|
71
|
+
Network configuration, timeouts, and Starlink optimizations.
|
|
72
|
+
|
|
73
|
+
### Logging
|
|
74
|
+
Logging levels, file output, and debugging options.
|
|
75
|
+
|
|
76
|
+
## Settings Reference
|
|
77
|
+
|
|
78
|
+
Here is a comprehensive list of all available settings, grouped by category:
|
|
79
|
+
|
|
80
|
+
### General Settings
|
|
81
|
+
|
|
82
|
+
| Setting | Description | Default | Type |
|
|
83
|
+
|---------|-------------|---------|------|
|
|
84
|
+
| `general.preview_features` | Enable preview features and experimental models | `false` | Boolean |
|
|
85
|
+
| `general.vim_mode` | Enable Vim keybindings throughout the interface | `false` | Boolean |
|
|
86
|
+
| `general.disable_auto_update` | Disable automatic updates | `false` | Boolean |
|
|
87
|
+
| `general.disable_update_nag` | Hide update notification messages | `false` | Boolean |
|
|
88
|
+
| `general.enable_prompt_completion` | Enable AI-powered prompt completion while typing | `false` | Boolean |
|
|
89
|
+
| `general.retry_fetch_errors` | Automatically retry failed network requests | `false` | Boolean |
|
|
90
|
+
| `general.debug_keystroke_logging` | Log keystrokes for debugging purposes | `false` | Boolean |
|
|
91
|
+
|
|
92
|
+
### UI Settings
|
|
93
|
+
|
|
94
|
+
| Setting | Description | Default | Type |
|
|
95
|
+
|---------|-------------|---------|------|
|
|
96
|
+
| `ui.theme` | Color theme for the interface | `"default"` | String |
|
|
97
|
+
| `ui.colors` | Enable colored output in terminal | `true` | Boolean |
|
|
98
|
+
| `ui.progress_bars` | Show progress indicators during operations | `true` | Boolean |
|
|
99
|
+
| `ui.verbose_errors` | Display detailed error information | `false` | Boolean |
|
|
100
|
+
| `ui.terminal_width` | Terminal width override (0 = auto-detect) | `0` | Number |
|
|
101
|
+
| `ui.unicode` | Enable Unicode characters and emojis | `true` | Boolean |
|
|
102
|
+
| `ui.hide_window_title` | Hide the window title bar | `false` | Boolean |
|
|
103
|
+
| `ui.show_status_in_title` | Show Grok CLI status in terminal title | `false` | Boolean |
|
|
104
|
+
| `ui.hide_tips` | Hide helpful tips and suggestions | `false` | Boolean |
|
|
105
|
+
| `ui.hide_banner` | Hide the ASCII art startup banner | `false` | Boolean |
|
|
106
|
+
| `ui.hide_context_summary` | Hide context summary above input | `false` | Boolean |
|
|
107
|
+
| `ui.hide_footer` | Hide the status footer | `false` | Boolean |
|
|
108
|
+
| `ui.show_memory_usage` | Display memory usage information | `false` | Boolean |
|
|
109
|
+
| `ui.show_line_numbers` | Show line numbers in chat output | `true` | Boolean |
|
|
110
|
+
| `ui.show_citations` | Show citations for generated content | `false` | Boolean |
|
|
111
|
+
| `ui.show_model_info_in_chat` | Display model name in chat responses | `false` | Boolean |
|
|
112
|
+
| `ui.use_full_width` | Use entire terminal width for output | `true` | Boolean |
|
|
113
|
+
| `ui.use_alternate_buffer` | Use alternate screen buffer (preserves history) | `false` | Boolean |
|
|
114
|
+
| `ui.incremental_rendering` | Enable incremental text rendering | `false` | Boolean |
|
|
115
|
+
|
|
116
|
+
### Footer Settings
|
|
117
|
+
|
|
118
|
+
| Setting | Description | Default | Type |
|
|
119
|
+
|---------|-------------|---------|------|
|
|
120
|
+
| `ui.footer.hide_cwd` | Hide current working directory in footer | `false` | Boolean |
|
|
121
|
+
| `ui.footer.hide_sandbox_status` | Hide sandbox status indicator | `false` | Boolean |
|
|
122
|
+
| `ui.footer.hide_model_info` | Hide model information in footer | `false` | Boolean |
|
|
123
|
+
| `ui.footer.hide_context_percentage` | Hide context usage percentage | `true` | Boolean |
|
|
124
|
+
|
|
125
|
+
### Accessibility Settings
|
|
126
|
+
|
|
127
|
+
| Setting | Description | Default | Type |
|
|
128
|
+
|---------|-------------|---------|------|
|
|
129
|
+
| `ui.accessibility.disable_loading_phrases` | Disable witty loading phrases | `false` | Boolean |
|
|
130
|
+
| `ui.accessibility.screen_reader` | Optimize output for screen readers | `false` | Boolean |
|
|
131
|
+
|
|
132
|
+
### Interactive UI Settings
|
|
133
|
+
|
|
134
|
+
| Setting | Description | Default | Type |
|
|
135
|
+
|---------|-------------|---------|------|
|
|
136
|
+
| `ui.interactive.prompt_style` | Prompt style (simple, rich, minimal) | `"rich"` | String |
|
|
137
|
+
| `ui.interactive.show_context_usage` | Enable context usage display | `true` | Boolean |
|
|
138
|
+
| `ui.interactive.auto_save_sessions` | Auto-save sessions | `false` | Boolean |
|
|
139
|
+
| `ui.interactive.check_directory` | Check for home directory usage | `true` | Boolean |
|
|
140
|
+
| `ui.interactive.startup_animation` | Enable startup animation | `true` | Boolean |
|
|
141
|
+
| `ui.interactive.update_check_hours` | Update check frequency in hours (0 = disabled) | `24` | Number |
|
|
142
|
+
|
|
143
|
+
### Model Settings
|
|
144
|
+
|
|
145
|
+
| Setting | Description | Default | Type |
|
|
146
|
+
|---------|-------------|---------|------|
|
|
147
|
+
| `default_model` | Default Grok model to use | `"grok-3"` | String |
|
|
148
|
+
| `default_temperature` | Default temperature for responses (0.0-2.0) | `0.7` | Number |
|
|
149
|
+
| `default_max_tokens` | Default maximum tokens per response | `4096` | Number |
|
|
150
|
+
| `model.max_session_turns` | Maximum conversation turns (-1 = unlimited) | `-1` | Number |
|
|
151
|
+
| `model.compression_threshold` | Context compression threshold (0.1-1.0) | `0.2` | Number |
|
|
152
|
+
| `model.skip_next_speaker_check` | Skip next speaker validation | `true` | Boolean |
|
|
153
|
+
|
|
154
|
+
### Context Settings
|
|
155
|
+
|
|
156
|
+
| Setting | Description | Default | Type |
|
|
157
|
+
|---------|-------------|---------|------|
|
|
158
|
+
| `context.discovery_max_dirs` | Maximum directories to search for context | `200` | Number |
|
|
159
|
+
| `context.load_memory_from_include_directories` | Load memory from included directories | `false` | Boolean |
|
|
160
|
+
| `context.file_filtering.respect_git_ignore` | Respect .gitignore files | `true` | Boolean |
|
|
161
|
+
| `context.file_filtering.respect_grok_ignore` | Respect .grokignore files | `true` | Boolean |
|
|
162
|
+
| `context.file_filtering.enable_recursive_file_search` | Enable recursive file search | `true` | Boolean |
|
|
163
|
+
| `context.file_filtering.disable_fuzzy_search` | Disable fuzzy file matching | `false` | Boolean |
|
|
164
|
+
|
|
165
|
+
### Tools Settings
|
|
166
|
+
|
|
167
|
+
| Setting | Description | Default | Type |
|
|
168
|
+
|---------|-------------|---------|------|
|
|
169
|
+
| `tools.shell.enable_interactive_shell` | Enable interactive shell mode | `true` | Boolean |
|
|
170
|
+
| `tools.shell.show_color` | Show colors in shell output | `false` | Boolean |
|
|
171
|
+
| `tools.auto_accept` | Automatically accept safe tool executions | `false` | Boolean |
|
|
172
|
+
| `tools.use_ripgrep` | Use ripgrep for faster file searches | `true` | Boolean |
|
|
173
|
+
| `tools.enable_tool_output_truncation` | Truncate large tool outputs | `true` | Boolean |
|
|
174
|
+
| `tools.truncate_tool_output_threshold` | Truncation threshold in characters | `10000` | Number |
|
|
175
|
+
| `tools.truncate_tool_output_lines` | Lines to keep when truncating | `100` | Number |
|
|
176
|
+
| `tools.enable_message_bus_integration` | Enable message bus integration | `true` | Boolean |
|
|
177
|
+
|
|
178
|
+
### Security Settings
|
|
179
|
+
|
|
180
|
+
| Setting | Description | Default | Type |
|
|
181
|
+
|---------|-------------|---------|------|
|
|
182
|
+
| `security.disable_yolo_mode` | Disable YOLO mode even if flagged | `false` | Boolean |
|
|
183
|
+
| `security.enable_permanent_tool_approval` | Allow permanent tool approvals | `false` | Boolean |
|
|
184
|
+
| `security.block_git_extensions` | Block Git-based extensions | `false` | Boolean |
|
|
185
|
+
| `security.folder_trust.enabled` | Enable folder trust system | `false` | Boolean |
|
|
186
|
+
| `security.environment_variable_redaction.enabled` | Enable env var redaction | `false` | Boolean |
|
|
187
|
+
|
|
188
|
+
### Experimental Settings
|
|
189
|
+
|
|
190
|
+
| Setting | Description | Default | Type |
|
|
191
|
+
|---------|-------------|---------|------|
|
|
192
|
+
| `experimental.enable_agents` | Enable experimental agent features | `false` | Boolean |
|
|
193
|
+
| `experimental.extension_management` | Enable extension management | `false` | Boolean |
|
|
194
|
+
| `experimental.jit_context` | Enable just-in-time context loading | `false` | Boolean |
|
|
195
|
+
| `experimental.codebase_investigator_settings.enabled` | Enable codebase investigator | `true` | Boolean |
|
|
196
|
+
| `experimental.codebase_investigator_settings.max_num_turns` | Max investigator turns | `10` | Number |
|
|
197
|
+
|
|
198
|
+
### ACP Settings
|
|
199
|
+
|
|
200
|
+
| Setting | Description | Default | Type |
|
|
201
|
+
|---------|-------------|---------|------|
|
|
202
|
+
| `acp.enabled` | Enable Agent Client Protocol | `true` | Boolean |
|
|
203
|
+
| `acp.bind_host` | ACP server bind address | `"127.0.0.1"` | String |
|
|
204
|
+
| `acp.default_port` | Default ACP server port | `None` | Number |
|
|
205
|
+
| `acp.protocol_version` | ACP protocol version | `"1.0"` | String |
|
|
206
|
+
| `acp.dev_mode` | Enable development mode | `false` | Boolean |
|
|
207
|
+
|
|
208
|
+
### Network Settings
|
|
209
|
+
|
|
210
|
+
| Setting | Description | Default | Type |
|
|
211
|
+
|---------|-------------|---------|------|
|
|
212
|
+
| `network.starlink_optimizations` | Enable Starlink satellite optimizations | `false` | Boolean |
|
|
213
|
+
| `network.base_retry_delay` | Base retry delay in seconds | `1` | Number |
|
|
214
|
+
| `network.max_retry_delay` | Maximum retry delay in seconds | `60` | Number |
|
|
215
|
+
| `network.health_monitoring` | Enable network health monitoring | `true` | Boolean |
|
|
216
|
+
| `network.connect_timeout` | Connection timeout in seconds | `10` | Number |
|
|
217
|
+
| `network.read_timeout` | Read timeout in seconds | `30` | Number |
|
|
218
|
+
|
|
219
|
+
### Logging Settings
|
|
220
|
+
|
|
221
|
+
| Setting | Description | Default | Type |
|
|
222
|
+
|---------|-------------|---------|------|
|
|
223
|
+
| `logging.level` | Log level (trace/debug/info/warn/error) | `"info"` | String |
|
|
224
|
+
| `logging.file_logging` | Enable logging to file | `false` | Boolean |
|
|
225
|
+
| `logging.max_file_size_mb` | Maximum log file size in MB | `10` | Number |
|
|
226
|
+
| `logging.rotation_count` | Number of rotated log files to keep | `5` | Number |
|
|
227
|
+
|
|
228
|
+
## Configuration File Example
|
|
229
|
+
|
|
230
|
+
Here's an example of what your `.env` file might look like:
|
|
231
|
+
|
|
232
|
+
```toml
|
|
233
|
+
api_key = "your-x-api-key-here"
|
|
234
|
+
default_model = "grok-3"
|
|
235
|
+
default_temperature = 0.7
|
|
236
|
+
default_max_tokens = 4096
|
|
237
|
+
timeout_secs = 30
|
|
238
|
+
max_retries = 3
|
|
239
|
+
|
|
240
|
+
[general]
|
|
241
|
+
preview_features = true
|
|
242
|
+
vim_mode = false
|
|
243
|
+
disable_auto_update = false
|
|
244
|
+
|
|
245
|
+
[ui]
|
|
246
|
+
theme = "default"
|
|
247
|
+
colors = true
|
|
248
|
+
hide_banner = false
|
|
249
|
+
hide_tips = false
|
|
250
|
+
show_line_numbers = true
|
|
251
|
+
use_full_width = true
|
|
252
|
+
|
|
253
|
+
[ui.footer]
|
|
254
|
+
hide_cwd = false
|
|
255
|
+
hide_model_info = false
|
|
256
|
+
hide_context_percentage = true
|
|
257
|
+
|
|
258
|
+
[model]
|
|
259
|
+
max_session_turns = -1
|
|
260
|
+
compression_threshold = 0.2
|
|
261
|
+
|
|
262
|
+
[acp]
|
|
263
|
+
enabled = true
|
|
264
|
+
bind_host = "127.0.0.1"
|
|
265
|
+
protocol_version = "1.0"
|
|
266
|
+
|
|
267
|
+
[network]
|
|
268
|
+
starlink_optimizations = true
|
|
269
|
+
base_retry_delay = 2
|
|
270
|
+
max_retry_delay = 60
|
|
271
|
+
|
|
272
|
+
[logging]
|
|
273
|
+
level = "info"
|
|
274
|
+
file_logging = true
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
## Tips
|
|
278
|
+
|
|
279
|
+
1. **Start with defaults**: The interactive settings browser shows current values and defaults for easy comparison.
|
|
280
|
+
|
|
281
|
+
2. **Category-specific resets**: Use `grok settings reset --category <name>` to reset only specific sections.
|
|
282
|
+
|
|
283
|
+
3. **Backup your settings**: Use `grok settings export` to create backups before making major changes.
|
|
284
|
+
|
|
285
|
+
4. **Project-specific configs**: Create a `.grok/.env` file in your project directory for project-specific settings.
|
|
286
|
+
|
|
287
|
+
5. **Restart requirements**: Some settings require restarting Grok CLI to take effect. The settings browser will indicate these.
|
|
288
|
+
|
|
289
|
+
6. **Use .env format**: All configuration now uses environment variable format (KEY=value) instead of TOML.
|
|
290
|
+
|
|
291
|
+
6. **Environment variables**: Many settings can also be overridden with environment variables (e.g., `GROK_API_KEY`).
|
|
292
|
+
|
|
293
|
+
For more information about specific features, see the main [Grok CLI documentation](README.md).
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Logging Hook Extension
|
|
2
|
+
|
|
3
|
+
A sample extension that demonstrates the Grok CLI extension system by logging tool invocations.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This extension provides a simple hook that logs all tool invocations before and after execution, which can be useful for:
|
|
8
|
+
- Debugging tool interactions
|
|
9
|
+
- Monitoring agent behavior
|
|
10
|
+
- Auditing tool usage
|
|
11
|
+
- Performance profiling
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
1. Copy this directory to your Grok extensions folder:
|
|
16
|
+
```bash
|
|
17
|
+
cp -r logging-hook ~/.grok/extensions/
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
2. Enable the extension in your `~/.config/grok-cli/config.toml`:
|
|
21
|
+
```toml
|
|
22
|
+
[experimental.extensions]
|
|
23
|
+
enabled = true
|
|
24
|
+
enabled_extensions = ["logging-hook"]
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
3. Restart Grok CLI to load the extension.
|
|
28
|
+
|
|
29
|
+
## Configuration
|
|
30
|
+
|
|
31
|
+
The extension can be configured in the `extension.json` file:
|
|
32
|
+
|
|
33
|
+
- **log_level**: Set to "debug", "info", "warn", or "error" (default: "debug")
|
|
34
|
+
- **include_args**: Whether to log tool arguments (default: true)
|
|
35
|
+
- **include_results**: Whether to log tool results (default: true)
|
|
36
|
+
- **max_result_length**: Maximum length of result to log, to avoid huge logs (default: 500)
|
|
37
|
+
|
|
38
|
+
## How It Works
|
|
39
|
+
|
|
40
|
+
The logging hook implements both `before_tool` and `after_tool` hooks:
|
|
41
|
+
|
|
42
|
+
1. **before_tool**: Logs when a tool is about to be invoked, including:
|
|
43
|
+
- Tool name
|
|
44
|
+
- Arguments (if enabled)
|
|
45
|
+
- Timestamp
|
|
46
|
+
|
|
47
|
+
2. **after_tool**: Logs after tool execution completes, including:
|
|
48
|
+
- Tool name
|
|
49
|
+
- Result preview (if enabled)
|
|
50
|
+
- Execution duration
|
|
51
|
+
- Timestamp
|
|
52
|
+
|
|
53
|
+
## Example Output
|
|
54
|
+
|
|
55
|
+
When enabled, you'll see log entries like:
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
[DEBUG] Extension 'logging-hook' hook 'tool-logger' executing before tool 'read_file'
|
|
59
|
+
[DEBUG] Tool args: {"path": "src/main.rs"}
|
|
60
|
+
[DEBUG] Extension 'logging-hook' hook 'tool-logger' executing after tool 'read_file'
|
|
61
|
+
[DEBUG] Result length: 1234 bytes
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Extending This Example
|
|
65
|
+
|
|
66
|
+
You can use this as a template to create your own extensions:
|
|
67
|
+
|
|
68
|
+
1. Modify `extension.json` to change the extension name and configuration
|
|
69
|
+
2. Add additional hooks as needed
|
|
70
|
+
3. In a full implementation, you could:
|
|
71
|
+
- Execute external scripts or commands
|
|
72
|
+
- Send metrics to monitoring systems
|
|
73
|
+
- Implement security policies
|
|
74
|
+
- Transform tool inputs/outputs
|
|
75
|
+
- Add custom validation logic
|
|
76
|
+
|
|
77
|
+
## Limitations
|
|
78
|
+
|
|
79
|
+
This is a basic config-based extension. For more advanced functionality, you would need to:
|
|
80
|
+
- Implement dynamic library loading (`.so`, `.dll`, `.dylib`)
|
|
81
|
+
- Add scripting language support (Lua, Python, etc.)
|
|
82
|
+
- Create a proper extension SDK with more hook types
|
|
83
|
+
- Add tool registration capabilities for custom tools
|
|
84
|
+
|
|
85
|
+
## License
|
|
86
|
+
|
|
87
|
+
MIT License - feel free to modify and distribute.
|
|
88
|
+
|
|
89
|
+
## Author
|
|
90
|
+
|
|
91
|
+
john mcconnell <john.microtech@gmail.com>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "logging-hook",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A sample extension that logs tool invocations for debugging and monitoring",
|
|
5
|
+
"author": "john mcconnell <john.microtech@gmail.com>",
|
|
6
|
+
"extension_type": "hook",
|
|
7
|
+
"hooks": [
|
|
8
|
+
{
|
|
9
|
+
"name": "tool-logger",
|
|
10
|
+
"hook_type": "both",
|
|
11
|
+
"script": null,
|
|
12
|
+
"config": {
|
|
13
|
+
"log_level": "debug",
|
|
14
|
+
"include_args": true,
|
|
15
|
+
"include_results": true,
|
|
16
|
+
"max_result_length": 500
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
],
|
|
20
|
+
"dependencies": [],
|
|
21
|
+
"enabled": true
|
|
22
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "grok-cli-acp",
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "grok-cli in rust with acp access",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"Xai",
|
|
7
|
+
"grok",
|
|
8
|
+
"Zed",
|
|
9
|
+
"ACP"
|
|
10
|
+
],
|
|
11
|
+
"homepage": "https://github.com/micro-tech/grok-cli#readme",
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/micro-tech/grok-cli/issues"
|
|
14
|
+
},
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://github.com/micro-tech/grok-cli.git"
|
|
18
|
+
},
|
|
19
|
+
"license": "ISC",
|
|
20
|
+
"author": "john mcconnell",
|
|
21
|
+
"type": "commonjs",
|
|
22
|
+
"main": "H:\\GitHub\\grok-cli\\target\\release\\groke.exe",
|
|
23
|
+
"directories": {
|
|
24
|
+
"doc": "docs",
|
|
25
|
+
"example": "examples"
|
|
26
|
+
},
|
|
27
|
+
"scripts": {
|
|
28
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Test script for ACP (Agent Client Protocol) stdio communication
|
|
4
|
+
This script properly handles the JSON-RPC protocol and session management
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import json
|
|
8
|
+
import subprocess
|
|
9
|
+
import sys
|
|
10
|
+
import time
|
|
11
|
+
from typing import Optional
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def send_message(proc, message: dict) -> None:
|
|
15
|
+
"""Send a JSON-RPC message to the process"""
|
|
16
|
+
msg_str = json.dumps(message)
|
|
17
|
+
print(f">>> Sending: {msg_str}", file=sys.stderr)
|
|
18
|
+
proc.stdin.write(msg_str + "\n")
|
|
19
|
+
proc.stdin.flush()
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def read_response(proc, timeout: float = 5.0) -> Optional[dict]:
|
|
23
|
+
"""Read a JSON-RPC response from the process"""
|
|
24
|
+
proc.stdout.flush()
|
|
25
|
+
line = proc.stdout.readline()
|
|
26
|
+
if not line:
|
|
27
|
+
return None
|
|
28
|
+
|
|
29
|
+
line = line.strip()
|
|
30
|
+
if not line:
|
|
31
|
+
return None
|
|
32
|
+
|
|
33
|
+
print(f"<<< Received: {line}", file=sys.stderr)
|
|
34
|
+
|
|
35
|
+
try:
|
|
36
|
+
return json.loads(line)
|
|
37
|
+
except json.JSONDecodeError as e:
|
|
38
|
+
print(f"Error parsing JSON: {e}", file=sys.stderr)
|
|
39
|
+
print(f"Raw line: {line}", file=sys.stderr)
|
|
40
|
+
return None
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def main():
|
|
44
|
+
print("=" * 60)
|
|
45
|
+
print("Testing ACP Protocol via stdio")
|
|
46
|
+
print("=" * 60)
|
|
47
|
+
print()
|
|
48
|
+
|
|
49
|
+
# Start grok in ACP stdio mode
|
|
50
|
+
proc = subprocess.Popen(
|
|
51
|
+
["./target/release/grok.exe", "acp", "stdio"],
|
|
52
|
+
stdin=subprocess.PIPE,
|
|
53
|
+
stdout=subprocess.PIPE,
|
|
54
|
+
stderr=subprocess.PIPE,
|
|
55
|
+
text=True,
|
|
56
|
+
bufsize=1,
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
try:
|
|
60
|
+
# Give it a moment to start
|
|
61
|
+
time.sleep(0.5)
|
|
62
|
+
|
|
63
|
+
# Step 1: Initialize
|
|
64
|
+
print("Step 1: Initialize")
|
|
65
|
+
print("-" * 60)
|
|
66
|
+
init_msg = {
|
|
67
|
+
"jsonrpc": "2.0",
|
|
68
|
+
"id": 1,
|
|
69
|
+
"method": "initialize",
|
|
70
|
+
"params": {
|
|
71
|
+
"protocolVersion": "1",
|
|
72
|
+
"clientInfo": {"name": "test-client", "version": "1.0.0"},
|
|
73
|
+
},
|
|
74
|
+
}
|
|
75
|
+
send_message(proc, init_msg)
|
|
76
|
+
init_response = read_response(proc)
|
|
77
|
+
|
|
78
|
+
if not init_response:
|
|
79
|
+
print("❌ No initialize response")
|
|
80
|
+
return 1
|
|
81
|
+
|
|
82
|
+
if "error" in init_response:
|
|
83
|
+
print(f"❌ Initialize error: {init_response['error']}")
|
|
84
|
+
return 1
|
|
85
|
+
|
|
86
|
+
print(f"✓ Initialize successful")
|
|
87
|
+
print()
|
|
88
|
+
|
|
89
|
+
# Step 2: Create new session
|
|
90
|
+
print("Step 2: Create Session")
|
|
91
|
+
print("-" * 60)
|
|
92
|
+
new_session_msg = {
|
|
93
|
+
"jsonrpc": "2.0",
|
|
94
|
+
"id": 2,
|
|
95
|
+
"method": "session/new",
|
|
96
|
+
"params": {},
|
|
97
|
+
}
|
|
98
|
+
send_message(proc, new_session_msg)
|
|
99
|
+
session_response = read_response(proc)
|
|
100
|
+
|
|
101
|
+
if not session_response:
|
|
102
|
+
print("❌ No session/new response")
|
|
103
|
+
return 1
|
|
104
|
+
|
|
105
|
+
if "error" in session_response:
|
|
106
|
+
print(f"❌ Session creation error: {session_response['error']}")
|
|
107
|
+
return 1
|
|
108
|
+
|
|
109
|
+
session_id = session_response.get("result", {}).get("sessionId")
|
|
110
|
+
if not session_id:
|
|
111
|
+
print(f"❌ No session ID in response: {session_response}")
|
|
112
|
+
return 1
|
|
113
|
+
|
|
114
|
+
print(f"✓ Session created: {session_id}")
|
|
115
|
+
print()
|
|
116
|
+
|
|
117
|
+
# Step 3: Send prompt
|
|
118
|
+
print("Step 3: Send Prompt")
|
|
119
|
+
print("-" * 60)
|
|
120
|
+
prompt_msg = {
|
|
121
|
+
"jsonrpc": "2.0",
|
|
122
|
+
"id": 3,
|
|
123
|
+
"method": "session/prompt",
|
|
124
|
+
"params": {
|
|
125
|
+
"sessionId": session_id,
|
|
126
|
+
"prompt": [
|
|
127
|
+
{
|
|
128
|
+
"type": "text",
|
|
129
|
+
"text": "Hello! Please respond with exactly: Hello World!",
|
|
130
|
+
}
|
|
131
|
+
],
|
|
132
|
+
},
|
|
133
|
+
}
|
|
134
|
+
send_message(proc, prompt_msg)
|
|
135
|
+
|
|
136
|
+
# Step 4: Read all responses (notifications + final response)
|
|
137
|
+
print()
|
|
138
|
+
print("Step 4: Reading Responses")
|
|
139
|
+
print("-" * 60)
|
|
140
|
+
|
|
141
|
+
notifications = []
|
|
142
|
+
final_response = None
|
|
143
|
+
timeout_counter = 0
|
|
144
|
+
max_timeout = 30 # 30 seconds max
|
|
145
|
+
|
|
146
|
+
while timeout_counter < max_timeout:
|
|
147
|
+
response = read_response(proc, timeout=1.0)
|
|
148
|
+
|
|
149
|
+
if response:
|
|
150
|
+
# Check if it's a notification (no id) or a response (has id)
|
|
151
|
+
if "id" not in response:
|
|
152
|
+
# Notification
|
|
153
|
+
notifications.append(response)
|
|
154
|
+
print(f" 📢 Notification: {response.get('method', 'unknown')}")
|
|
155
|
+
|
|
156
|
+
# Check for session/update with content
|
|
157
|
+
if response.get("method") == "session/update":
|
|
158
|
+
params = response.get("params", {})
|
|
159
|
+
update = params.get("update", {})
|
|
160
|
+
if update.get("sessionUpdate") == "agent_message_chunk":
|
|
161
|
+
content = update.get("content", {})
|
|
162
|
+
if content.get("type") == "text":
|
|
163
|
+
text = content.get("text", "")
|
|
164
|
+
print(f" 💬 Content: {text}")
|
|
165
|
+
elif response.get("id") == 3:
|
|
166
|
+
# Final response to our prompt
|
|
167
|
+
final_response = response
|
|
168
|
+
print(f" ✓ Final response received")
|
|
169
|
+
break
|
|
170
|
+
|
|
171
|
+
timeout_counter = 0
|
|
172
|
+
else:
|
|
173
|
+
timeout_counter += 1
|
|
174
|
+
time.sleep(0.1)
|
|
175
|
+
|
|
176
|
+
print()
|
|
177
|
+
print("=" * 60)
|
|
178
|
+
print("Results")
|
|
179
|
+
print("=" * 60)
|
|
180
|
+
|
|
181
|
+
# Analyze results
|
|
182
|
+
print(f"Notifications received: {len(notifications)}")
|
|
183
|
+
|
|
184
|
+
# Check for session/update notifications
|
|
185
|
+
update_notifications = [
|
|
186
|
+
n for n in notifications if n.get("method") == "session/update"
|
|
187
|
+
]
|
|
188
|
+
print(f"session/update notifications: {len(update_notifications)}")
|
|
189
|
+
|
|
190
|
+
# Extract content
|
|
191
|
+
content_chunks = []
|
|
192
|
+
for notif in update_notifications:
|
|
193
|
+
params = notif.get("params", {})
|
|
194
|
+
update = params.get("update", {})
|
|
195
|
+
if update.get("sessionUpdate") == "agent_message_chunk":
|
|
196
|
+
content = update.get("content", {})
|
|
197
|
+
if content.get("type") == "text":
|
|
198
|
+
text = content.get("text", "")
|
|
199
|
+
content_chunks.append(text)
|
|
200
|
+
|
|
201
|
+
if content_chunks:
|
|
202
|
+
print(f"✓ Content found: {len(content_chunks)} chunk(s)")
|
|
203
|
+
print()
|
|
204
|
+
print("Combined content:")
|
|
205
|
+
print("-" * 60)
|
|
206
|
+
for i, chunk in enumerate(content_chunks, 1):
|
|
207
|
+
print(f"Chunk {i}: {chunk}")
|
|
208
|
+
print("-" * 60)
|
|
209
|
+
else:
|
|
210
|
+
print("❌ No content found in notifications")
|
|
211
|
+
|
|
212
|
+
# Check final response
|
|
213
|
+
if final_response:
|
|
214
|
+
if "error" in final_response:
|
|
215
|
+
print(f"❌ Error in final response: {final_response['error']}")
|
|
216
|
+
return 1
|
|
217
|
+
else:
|
|
218
|
+
result = final_response.get("result", {})
|
|
219
|
+
stop_reason = result.get("stopReason")
|
|
220
|
+
print(f"✓ Stop reason: {stop_reason}")
|
|
221
|
+
else:
|
|
222
|
+
print("❌ No final response received")
|
|
223
|
+
return 1
|
|
224
|
+
|
|
225
|
+
print()
|
|
226
|
+
if content_chunks and final_response and "error" not in final_response:
|
|
227
|
+
print("✅ Test PASSED - ACP protocol working correctly!")
|
|
228
|
+
return 0
|
|
229
|
+
else:
|
|
230
|
+
print("❌ Test FAILED - Missing content or errors")
|
|
231
|
+
return 1
|
|
232
|
+
|
|
233
|
+
except KeyboardInterrupt:
|
|
234
|
+
print("\nTest interrupted")
|
|
235
|
+
return 1
|
|
236
|
+
except Exception as e:
|
|
237
|
+
print(f"❌ Exception: {e}")
|
|
238
|
+
import traceback
|
|
239
|
+
|
|
240
|
+
traceback.print_exc()
|
|
241
|
+
return 1
|
|
242
|
+
finally:
|
|
243
|
+
# Clean shutdown
|
|
244
|
+
try:
|
|
245
|
+
proc.stdin.close()
|
|
246
|
+
proc.wait(timeout=2)
|
|
247
|
+
except:
|
|
248
|
+
proc.kill()
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
if __name__ == "__main__":
|
|
252
|
+
sys.exit(main())
|