on main help sign in
ci: auto generate on changes
9bf42ceCarlos Alexandro Becker
.gitattributes+1
@@ -1 +1,2 @@
1*.golden linguist-generated=true -text
1*.golden linguist-generated=true -text
2+.github/crush-schema.json linguist-generated=true
.github/crush-schema.jsonnew file+397
@@ -0,0 +1,397 @@
1+{
2+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3+ "$id": "https://github.com/charmbracelet/crush/internal/config/config",
4+ "$ref": "#/$defs/Config",
5+ "$defs": {
6+ "Config": {
7+ "properties": {
8+ "models": {
9+ "additionalProperties": {
10+ "$ref": "#/$defs/SelectedModel"
11+ },
12+ "type": "object",
13+ "description": "Model configurations for different model types"
14+ },
15+ "providers": {
16+ "additionalProperties": {
17+ "$ref": "#/$defs/ProviderConfig"
18+ },
19+ "type": "object",
20+ "description": "AI provider configurations"
21+ },
22+ "mcp": {
23+ "$ref": "#/$defs/MCPs",
24+ "description": "Model Context Protocol server configurations"
25+ },
26+ "lsp": {
27+ "$ref": "#/$defs/LSPs",
28+ "description": "Language Server Protocol configurations"
29+ },
30+ "options": {
31+ "$ref": "#/$defs/Options",
32+ "description": "General application options"
33+ },
34+ "permissions": {
35+ "$ref": "#/$defs/Permissions",
36+ "description": "Permission settings for tool usage"
37+ }
38+ },
39+ "additionalProperties": false,
40+ "type": "object"
41+ },
42+ "LSPConfig": {
43+ "properties": {
44+ "enabled": {
45+ "type": "boolean",
46+ "description": "Whether this LSP server is disabled",
47+ "default": false
48+ },
49+ "command": {
50+ "type": "string",
51+ "description": "Command to execute for the LSP server",
52+ "examples": [
53+ "gopls"
54+ ]
55+ },
56+ "args": {
57+ "items": {
58+ "type": "string"
59+ },
60+ "type": "array",
61+ "description": "Arguments to pass to the LSP server command"
62+ },
63+ "options": {
64+ "description": "LSP server-specific configuration options"
65+ }
66+ },
67+ "additionalProperties": false,
68+ "type": "object",
69+ "required": [
70+ "command"
71+ ]
72+ },
73+ "LSPs": {
74+ "additionalProperties": {
75+ "$ref": "#/$defs/LSPConfig"
76+ },
77+ "type": "object"
78+ },
79+ "MCPConfig": {
80+ "properties": {
81+ "command": {
82+ "type": "string",
83+ "description": "Command to execute for stdio MCP servers",
84+ "examples": [
85+ "npx"
86+ ]
87+ },
88+ "env": {
89+ "additionalProperties": {
90+ "type": "string"
91+ },
92+ "type": "object",
93+ "description": "Environment variables to set for the MCP server"
94+ },
95+ "args": {
96+ "items": {
97+ "type": "string"
98+ },
99+ "type": "array",
100+ "description": "Arguments to pass to the MCP server command"
101+ },
102+ "type": {
103+ "$ref": "#/$defs/MCPType",
104+ "description": "Type of MCP connection"
105+ },
106+ "url": {
107+ "type": "string",
108+ "format": "uri",
109+ "description": "URL for HTTP or SSE MCP servers",
110+ "examples": [
111+ "http://localhost:3000/mcp"
112+ ]
113+ },
114+ "disabled": {
115+ "type": "boolean",
116+ "description": "Whether this MCP server is disabled",
117+ "default": false
118+ },
119+ "headers": {
120+ "additionalProperties": {
121+ "type": "string"
122+ },
123+ "type": "object",
124+ "description": "HTTP headers for HTTP/SSE MCP servers"
125+ }
126+ },
127+ "additionalProperties": false,
128+ "type": "object",
129+ "required": [
130+ "type"
131+ ]
132+ },
133+ "MCPType": {
134+ "type": "string",
135+ "enum": [
136+ "stdio",
137+ "sse",
138+ "http"
139+ ],
140+ "description": "Type of MCP connection protocol",
141+ "default": "stdio"
142+ },
143+ "MCPs": {
144+ "additionalProperties": {
145+ "$ref": "#/$defs/MCPConfig"
146+ },
147+ "type": "object"
148+ },
149+ "Model": {
150+ "properties": {
151+ "id": {
152+ "type": "string"
153+ },
154+ "name": {
155+ "type": "string"
156+ },
157+ "cost_per_1m_in": {
158+ "type": "number"
159+ },
160+ "cost_per_1m_out": {
161+ "type": "number"
162+ },
163+ "cost_per_1m_in_cached": {
164+ "type": "number"
165+ },
166+ "cost_per_1m_out_cached": {
167+ "type": "number"
168+ },
169+ "context_window": {
170+ "type": "integer"
171+ },
172+ "default_max_tokens": {
173+ "type": "integer"
174+ },
175+ "can_reason": {
176+ "type": "boolean"
177+ },
178+ "has_reasoning_efforts": {
179+ "type": "boolean"
180+ },
181+ "default_reasoning_effort": {
182+ "type": "string"
183+ },
184+ "supports_attachments": {
185+ "type": "boolean"
186+ }
187+ },
188+ "additionalProperties": false,
189+ "type": "object",
190+ "required": [
191+ "id",
192+ "name",
193+ "cost_per_1m_in",
194+ "cost_per_1m_out",
195+ "cost_per_1m_in_cached",
196+ "cost_per_1m_out_cached",
197+ "context_window",
198+ "default_max_tokens",
199+ "can_reason",
200+ "has_reasoning_efforts",
201+ "supports_attachments"
202+ ]
203+ },
204+ "Options": {
205+ "properties": {
206+ "context_paths": {
207+ "items": {
208+ "type": "string",
209+ "examples": [
210+ ".cursorrules",
211+ "CRUSH.md"
212+ ]
213+ },
214+ "type": "array",
215+ "description": "Paths to files containing context information for the AI"
216+ },
217+ "tui": {
218+ "$ref": "#/$defs/TUIOptions",
219+ "description": "Terminal user interface options"
220+ },
221+ "debug": {
222+ "type": "boolean",
223+ "description": "Enable debug logging",
224+ "default": false
225+ },
226+ "debug_lsp": {
227+ "type": "boolean",
228+ "description": "Enable debug logging for LSP servers",
229+ "default": false
230+ },
231+ "disable_auto_summarize": {
232+ "type": "boolean",
233+ "description": "Disable automatic conversation summarization",
234+ "default": false
235+ },
236+ "data_directory": {
237+ "type": "string",
238+ "description": "Directory for storing application data (relative to working directory)",
239+ "default": ".crush",
240+ "examples": [
241+ ".crush"
242+ ]
243+ }
244+ },
245+ "additionalProperties": false,
246+ "type": "object"
247+ },
248+ "Permissions": {
249+ "properties": {
250+ "allowed_tools": {
251+ "items": {
252+ "type": "string",
253+ "examples": [
254+ "bash",
255+ "view"
256+ ]
257+ },
258+ "type": "array",
259+ "description": "List of tools that don't require permission prompts"
260+ }
261+ },
262+ "additionalProperties": false,
263+ "type": "object"
264+ },
265+ "ProviderConfig": {
266+ "properties": {
267+ "id": {
268+ "type": "string",
269+ "description": "Unique identifier for the provider",
270+ "examples": [
271+ "openai"
272+ ]
273+ },
274+ "name": {
275+ "type": "string",
276+ "description": "Human-readable name for the provider",
277+ "examples": [
278+ "OpenAI"
279+ ]
280+ },
281+ "base_url": {
282+ "type": "string",
283+ "format": "uri",
284+ "description": "Base URL for the provider's API",
285+ "examples": [
286+ "https://api.openai.com/v1"
287+ ]
288+ },
289+ "type": {
290+ "type": "string",
291+ "enum": [
292+ "openai",
293+ "anthropic",
294+ "gemini",
295+ "azure",
296+ "vertexai"
297+ ],
298+ "description": "Provider type that determines the API format",
299+ "default": "openai"
300+ },
301+ "api_key": {
302+ "type": "string",
303+ "description": "API key for authentication with the provider",
304+ "examples": [
305+ "$OPENAI_API_KEY"
306+ ]
307+ },
308+ "disable": {
309+ "type": "boolean",
310+ "description": "Whether this provider is disabled",
311+ "default": false
312+ },
313+ "system_prompt_prefix": {
314+ "type": "string",
315+ "description": "Custom prefix to add to system prompts for this provider"
316+ },
317+ "extra_headers": {
318+ "additionalProperties": {
319+ "type": "string"
320+ },
321+ "type": "object",
322+ "description": "Additional HTTP headers to send with requests"
323+ },
324+ "extra_body": {
325+ "type": "object",
326+ "description": "Additional fields to include in request bodies"
327+ },
328+ "models": {
329+ "items": {
330+ "$ref": "#/$defs/Model"
331+ },
332+ "type": "array",
333+ "description": "List of models available from this provider"
334+ }
335+ },
336+ "additionalProperties": false,
337+ "type": "object"
338+ },
339+ "SelectedModel": {
340+ "properties": {
341+ "model": {
342+ "type": "string",
343+ "description": "The model ID as used by the provider API",
344+ "examples": [
345+ "gpt-4o"
346+ ]
347+ },
348+ "provider": {
349+ "type": "string",
350+ "description": "The model provider ID that matches a key in the providers config",
351+ "examples": [
352+ "openai"
353+ ]
354+ },
355+ "reasoning_effort": {
356+ "type": "string",
357+ "enum": [
358+ "low",
359+ "medium",
360+ "high"
361+ ],
362+ "description": "Reasoning effort level for OpenAI models that support it"
363+ },
364+ "max_tokens": {
365+ "type": "integer",
366+ "maximum": 200000,
367+ "minimum": 1,
368+ "description": "Maximum number of tokens for model responses",
369+ "examples": [
370+ 4096
371+ ]
372+ },
373+ "think": {
374+ "type": "boolean",
375+ "description": "Enable thinking mode for Anthropic models that support reasoning"
376+ }
377+ },
378+ "additionalProperties": false,
379+ "type": "object",
380+ "required": [
381+ "model",
382+ "provider"
383+ ]
384+ },
385+ "TUIOptions": {
386+ "properties": {
387+ "compact_mode": {
388+ "type": "boolean",
389+ "description": "Enable compact mode for the TUI interface",
390+ "default": false
391+ }
392+ },
393+ "additionalProperties": false,
394+ "type": "object"
395+ }
396+ }
397+}
.github/workflows/schema-update.ymlnew file+26
@@ -0,0 +1,26 @@
1+name: Update Schema
2+
3+on:
4+ push:
5+ branches: [main]
6+ paths:
7+ - "internal/config/**"
8+
9+jobs:
10+ update-schema:
11+ runs-on: ubuntu-latest
12+ steps:
13+ - uses: actions/checkout@v4
14+ with:
15+ token: ${{ secrets.GITHUB_TOKEN }}
16+ - uses: actions/setup-go@v5
17+ with:
18+ go-version-file: go.mod
19+ - run: go run . schema > .github/crush-schema.json
20+ - uses: stefanzweifel/git-auto-commit-action@778341af668090896ca464160c2def5d1d1a3eb0 # v5
21+ with:
22+ commit_message: "chore: auto-update generated files"
23+ branch: main
24+ commit_user_name: actions-user
25+ commit_user_email: actions@github.com
26+ commit_author: actions-user <actions@github.com>
README.md+7
@@ -85,6 +85,7 @@ Crush can use LSPs for additional context to help inform its decisions, just lik
85
85
86```json
86```json
87{
87{
88+ "$schema": "https://charm.land/crush.json",
88 "lsp": {
89 "lsp": {
89 "go": {
90 "go": {
90 "command": "gopls"
91 "command": "gopls"
@@ -106,6 +107,7 @@ Crush supports Model Context Protocol (MCP) servers through three transport type
106
107
107```json
108```json
108{
109{
110+ "$schema": "https://charm.land/crush.json",
109 "mcp": {
111 "mcp": {
110 "filesystem": {
112 "filesystem": {
111 "type": "stdio",
113 "type": "stdio",
@@ -136,6 +138,7 @@ Crush supports Model Context Protocol (MCP) servers through three transport type
136### Logging
138### Logging
137
139
138Enable debug logging with the `-d` flag or in config. View logs with `crush logs`. Logs are stored in `.crush/logs/crush.log`.
140Enable debug logging with the `-d` flag or in config. View logs with `crush logs`. Logs are stored in `.crush/logs/crush.log`.
141+
139```bash
142```bash
140# Run with debug logging
143# Run with debug logging
141crush -d
144crush -d
@@ -154,6 +157,7 @@ Add to your `crush.json` config file:
154
157
155```json
158```json
156{
159{
160+ "$schema": "https://charm.land/crush.json",
157 "options": {
161 "options": {
158 "debug": true,
162 "debug": true,
159 "debug_lsp": true
163 "debug_lsp": true
@@ -167,6 +171,7 @@ Crush includes a permission system to control which tools can be executed withou
167
171
168```json
172```json
169{
173{
174+ "$schema": "https://charm.land/crush.json",
170 "permissions": {
175 "permissions": {
171 "allowed_tools": [
176 "allowed_tools": [
172 "view",
177 "view",
@@ -196,6 +201,7 @@ Here's an example configuration for Deepseek, which uses an OpenAI-compatible AP
196
201
197```json
202```json
198{
203{
204+ "$schema": "https://charm.land/crush.json",
199 "providers": {
205 "providers": {
200 "deepseek": {
206 "deepseek": {
201 "type": "openai",
207 "type": "openai",
@@ -224,6 +230,7 @@ You can also configure custom Anthropic-compatible providers:
224
230
225```json
231```json
226{
232{
233+ "$schema": "https://charm.land/crush.json",
227 "providers": {
234 "providers": {
228 "custom-anthropic": {
235 "custom-anthropic": {
229 "type": "anthropic",
236 "type": "anthropic",
internal/cmd/schema.go+39−1
@@ -3,6 +3,7 @@ package cmd
3import (
3import (
4 "encoding/json"
4 "encoding/json"
5 "fmt"
5 "fmt"
6+ "reflect"
6
7
7 "github.com/charmbracelet/crush/internal/config"
8 "github.com/charmbracelet/crush/internal/config"
8 "github.com/invopop/jsonschema"
9 "github.com/invopop/jsonschema"
@@ -15,8 +16,45 @@ var schemaCmd = &cobra.Command{
15 Long: "Generate JSON schema for the crush configuration file",
16 Long: "Generate JSON schema for the crush configuration file",
16 Hidden: true,
17 Hidden: true,
17 RunE: func(cmd *cobra.Command, args []string) error {
18 RunE: func(cmd *cobra.Command, args []string) error {
18− reflector := jsonschema.Reflector{}
19+ reflector := jsonschema.Reflector{
20+ // Custom type mapper to handle csync.Map
21+ Mapper: func(t reflect.Type) *jsonschema.Schema {
22+ // Handle csync.Map[string, ProviderConfig] specifically
23+ if t.String() == "csync.Map[string,github.com/charmbracelet/crush/internal/config.ProviderConfig]" {
24+ return &jsonschema.Schema{
25+ Type: "object",
26+ Description: "AI provider configurations",
27+ AdditionalProperties: &jsonschema.Schema{
28+ Ref: "#/$defs/ProviderConfig",
29+ },
30+ }
31+ }
32+ return nil
33+ },
34+ }
35+
36+ // First reflect the config to get the main schema
19 schema := reflector.Reflect(&config.Config{})
37 schema := reflector.Reflect(&config.Config{})
38+
39+ // Now manually add the ProviderConfig definition that might be missing
40+ providerConfigSchema := reflector.ReflectFromType(reflect.TypeOf(config.ProviderConfig{}))
41+ if schema.Definitions == nil {
42+ schema.Definitions = make(map[string]*jsonschema.Schema)
43+ }
44+
45+ // Extract the actual definition from the nested schema
46+ if providerConfigSchema.Definitions != nil && providerConfigSchema.Definitions["ProviderConfig"] != nil {
47+ schema.Definitions["ProviderConfig"] = providerConfigSchema.Definitions["ProviderConfig"]
48+ // Also add any other definitions from the provider config schema
49+ for k, v := range providerConfigSchema.Definitions {
50+ if k != "ProviderConfig" {
51+ schema.Definitions[k] = v
52+ }
53+ }
54+ } else {
55+ // Fallback: use the schema itself if it's not nested
56+ schema.Definitions["ProviderConfig"] = providerConfigSchema
57+ }
20
58
21 schemaJSON, err := json.MarshalIndent(schema, "", " ")
59 schemaJSON, err := json.MarshalIndent(schema, "", " ")
22 if err != nil {
60 if err != nil {
internal/config/config.go+62−41
@@ -13,6 +13,7 @@ import (
13 "github.com/charmbracelet/catwalk/pkg/catwalk"
13 "github.com/charmbracelet/catwalk/pkg/catwalk"
14 "github.com/charmbracelet/crush/internal/csync"
14 "github.com/charmbracelet/crush/internal/csync"
15 "github.com/charmbracelet/crush/internal/env"
15 "github.com/charmbracelet/crush/internal/env"
16+ "github.com/invopop/jsonschema"
16 "github.com/tidwall/sjson"
17 "github.com/tidwall/sjson"
17)
18)
18
19
@@ -45,51 +46,61 @@ const (
45 SelectedModelTypeSmall SelectedModelType = "small"
46 SelectedModelTypeSmall SelectedModelType = "small"
46)
47)
47
48
49+// JSONSchema returns the JSON schema for SelectedModelType
50+func (SelectedModelType) JSONSchema() *jsonschema.Schema {
51+ return &jsonschema.Schema{
52+ Type: "string",
53+ Description: "Model type selection for different use cases",
54+ Enum: []any{"large", "small"},
55+ Default: "large",
56+ }
57+}
58+
48type SelectedModel struct {
59type SelectedModel struct {
49 // The model id as used by the provider API.
60 // The model id as used by the provider API.
50 // Required.
61 // Required.
51− Model string `json:"model"`
62+ Model string `json:"model" jsonschema:"required,description=The model ID as used by the provider API,example=gpt-4o"`
52 // The model provider, same as the key/id used in the providers config.
63 // The model provider, same as the key/id used in the providers config.
53 // Required.
64 // Required.
54− Provider string `json:"provider"`
65+ Provider string `json:"provider" jsonschema:"required,description=The model provider ID that matches a key in the providers config,example=openai"`
55
66
56 // Only used by models that use the openai provider and need this set.
67 // Only used by models that use the openai provider and need this set.
57− ReasoningEffort string `json:"reasoning_effort,omitempty"`
68+ ReasoningEffort string `json:"reasoning_effort,omitempty" jsonschema:"description=Reasoning effort level for OpenAI models that support it,enum=low,enum=medium,enum=high"`
58
69
59 // Overrides the default model configuration.
70 // Overrides the default model configuration.
60− MaxTokens int64 `json:"max_tokens,omitempty"`
71+ MaxTokens int64 `json:"max_tokens,omitempty" jsonschema:"description=Maximum number of tokens for model responses,minimum=1,maximum=200000,example=4096"`
61
72
62 // Used by anthropic models that can reason to indicate if the model should think.
73 // Used by anthropic models that can reason to indicate if the model should think.
63− Think bool `json:"think,omitempty"`
74+ Think bool `json:"think,omitempty" jsonschema:"description=Enable thinking mode for Anthropic models that support reasoning"`
64}
75}
65
76
66type ProviderConfig struct {
77type ProviderConfig struct {
67 // The provider's id.
78 // The provider's id.
68− ID string `json:"id,omitempty"`
79+ ID string `json:"id,omitempty" jsonschema:"description=Unique identifier for the provider,example=openai"`
69 // The provider's name, used for display purposes.
80 // The provider's name, used for display purposes.
70− Name string `json:"name,omitempty"`
81+ Name string `json:"name,omitempty" jsonschema:"description=Human-readable name for the provider,example=OpenAI"`
71 // The provider's API endpoint.
82 // The provider's API endpoint.
72− BaseURL string `json:"base_url,omitempty"`
83+ BaseURL string `json:"base_url,omitempty" jsonschema:"description=Base URL for the provider's API,format=uri,example=https://api.openai.com/v1"`
73 // The provider type, e.g. "openai", "anthropic", etc. if empty it defaults to openai.
84 // The provider type, e.g. "openai", "anthropic", etc. if empty it defaults to openai.
74− Type catwalk.Type `json:"type,omitempty"`
85+ Type catwalk.Type `json:"type,omitempty" jsonschema:"description=Provider type that determines the API format,enum=openai,enum=anthropic,enum=gemini,enum=azure,enum=vertexai,default=openai"`
75 // The provider's API key.
86 // The provider's API key.
76− APIKey string `json:"api_key,omitempty"`
87+ APIKey string `json:"api_key,omitempty" jsonschema:"description=API key for authentication with the provider,example=$OPENAI_API_KEY"`
77 // Marks the provider as disabled.
88 // Marks the provider as disabled.
78− Disable bool `json:"disable,omitempty"`
89+ Disable bool `json:"disable,omitempty" jsonschema:"description=Whether this provider is disabled,default=false"`
79
90
80 // Custom system prompt prefix.
91 // Custom system prompt prefix.
81− SystemPromptPrefix string `json:"system_prompt_prefix,omitempty"`
92+ SystemPromptPrefix string `json:"system_prompt_prefix,omitempty" jsonschema:"description=Custom prefix to add to system prompts for this provider"`
82
93
83 // Extra headers to send with each request to the provider.
94 // Extra headers to send with each request to the provider.
84− ExtraHeaders map[string]string `json:"extra_headers,omitempty"`
95+ ExtraHeaders map[string]string `json:"extra_headers,omitempty" jsonschema:"description=Additional HTTP headers to send with requests"`
85 // Extra body
96 // Extra body
86− ExtraBody map[string]any `json:"extra_body,omitempty"`
97+ ExtraBody map[string]any `json:"extra_body,omitempty" jsonschema:"description=Additional fields to include in request bodies"`
87
98
88 // Used to pass extra parameters to the provider.
99 // Used to pass extra parameters to the provider.
89 ExtraParams map[string]string `json:"-"`
100 ExtraParams map[string]string `json:"-"`
90
101
91 // The provider models
102 // The provider models
92− Models []catwalk.Model `json:"models,omitempty"`
103+ Models []catwalk.Model `json:"models,omitempty" jsonschema:"description=List of models available from this provider"`
93}
104}
94
105
95type MCPType string
106type MCPType string
@@ -100,42 +111,52 @@ const (
100 MCPHttp MCPType = "http"
111 MCPHttp MCPType = "http"
101)
112)
102
113
114+// JSONSchema returns the JSON schema for MCPType
115+func (MCPType) JSONSchema() *jsonschema.Schema {
116+ return &jsonschema.Schema{
117+ Type: "string",
118+ Description: "Type of MCP connection protocol",
119+ Enum: []any{"stdio", "sse", "http"},
120+ Default: "stdio",
121+ }
122+}
123+
103type MCPConfig struct {
124type MCPConfig struct {
104− Command string `json:"command,omitempty" `
125+ Command string `json:"command,omitempty" jsonschema:"description=Command to execute for stdio MCP servers,example=npx"`
105− Env map[string]string `json:"env,omitempty"`
126+ Env map[string]string `json:"env,omitempty" jsonschema:"description=Environment variables to set for the MCP server"`
106− Args []string `json:"args,omitempty"`
127+ Args []string `json:"args,omitempty" jsonschema:"description=Arguments to pass to the MCP server command"`
107− Type MCPType `json:"type"`
128+ Type MCPType `json:"type" jsonschema:"required,description=Type of MCP connection,enum=stdio,enum=sse,enum=http,default=stdio"`
108− URL string `json:"url,omitempty"`
129+ URL string `json:"url,omitempty" jsonschema:"description=URL for HTTP or SSE MCP servers,format=uri,example=http://localhost:3000/mcp"`
109− Disabled bool `json:"disabled,omitempty"`
130+ Disabled bool `json:"disabled,omitempty" jsonschema:"description=Whether this MCP server is disabled,default=false"`
110
131
111 // TODO: maybe make it possible to get the value from the env
132 // TODO: maybe make it possible to get the value from the env
112− Headers map[string]string `json:"headers,omitempty"`
133+ Headers map[string]string `json:"headers,omitempty" jsonschema:"description=HTTP headers for HTTP/SSE MCP servers"`
113}
134}
114
135
115type LSPConfig struct {
136type LSPConfig struct {
116− Disabled bool `json:"enabled,omitempty"`
137+ Disabled bool `json:"enabled,omitempty" jsonschema:"description=Whether this LSP server is disabled,default=false"`
117− Command string `json:"command"`
138+ Command string `json:"command" jsonschema:"required,description=Command to execute for the LSP server,example=gopls"`
118− Args []string `json:"args,omitempty"`
139+ Args []string `json:"args,omitempty" jsonschema:"description=Arguments to pass to the LSP server command"`
119− Options any `json:"options,omitempty"`
140+ Options any `json:"options,omitempty" jsonschema:"description=LSP server-specific configuration options"`
120}
141}
121
142
122type TUIOptions struct {
143type TUIOptions struct {
123− CompactMode bool `json:"compact_mode,omitempty"`
144+ CompactMode bool `json:"compact_mode,omitempty" jsonschema:"description=Enable compact mode for the TUI interface,default=false"`
124 // Here we can add themes later or any TUI related options
145 // Here we can add themes later or any TUI related options
125}
146}
126
147
127type Permissions struct {
148type Permissions struct {
128− AllowedTools []string `json:"allowed_tools,omitempty"` // Tools that don't require permission prompts
149+ AllowedTools []string `json:"allowed_tools,omitempty" jsonschema:"description=List of tools that don't require permission prompts,example=bash,example=view"` // Tools that don't require permission prompts
129− SkipRequests bool `json:"-"` // Automatically accept all permissions (YOLO mode)
150+ SkipRequests bool `json:"-"` // Automatically accept all permissions (YOLO mode)
130}
151}
131
152
132type Options struct {
153type Options struct {
133− ContextPaths []string `json:"context_paths,omitempty"`
154+ ContextPaths []string `json:"context_paths,omitempty" jsonschema:"description=Paths to files containing context information for the AI,example=.cursorrules,example=CRUSH.md"`
134− TUI *TUIOptions `json:"tui,omitempty"`
155+ TUI *TUIOptions `json:"tui,omitempty" jsonschema:"description=Terminal user interface options"`
135− Debug bool `json:"debug,omitempty"`
156+ Debug bool `json:"debug,omitempty" jsonschema:"description=Enable debug logging,default=false"`
136− DebugLSP bool `json:"debug_lsp,omitempty"`
157+ DebugLSP bool `json:"debug_lsp,omitempty" jsonschema:"description=Enable debug logging for LSP servers,default=false"`
137− DisableAutoSummarize bool `json:"disable_auto_summarize,omitempty"`
158+ DisableAutoSummarize bool `json:"disable_auto_summarize,omitempty" jsonschema:"description=Disable automatic conversation summarization,default=false"`
138− DataDirectory string `json:"data_directory,omitempty"` // Relative to the cwd
159+ DataDirectory string `json:"data_directory,omitempty" jsonschema:"description=Directory for storing application data (relative to working directory),default=.crush,example=.crush"` // Relative to the cwd
139}
160}
140
161
141type MCPs map[string]MCPConfig
162type MCPs map[string]MCPConfig
@@ -241,18 +262,18 @@ type Agent struct {
241// Config holds the configuration for crush.
262// Config holds the configuration for crush.
242type Config struct {
263type Config struct {
243 // We currently only support large/small as values here.
264 // We currently only support large/small as values here.
244− Models map[SelectedModelType]SelectedModel `json:"models,omitempty"`
265+ Models map[SelectedModelType]SelectedModel `json:"models,omitempty" jsonschema:"description=Model configurations for different model types,example={\"large\":{\"model\":\"gpt-4o\",\"provider\":\"openai\"}}"`
245
266
246 // The providers that are configured
267 // The providers that are configured
247− Providers *csync.Map[string, ProviderConfig] `json:"providers,omitempty"`
268+ Providers *csync.Map[string, ProviderConfig] `json:"providers,omitempty" jsonschema:"description=AI provider configurations"`
248
269
249− MCP MCPs `json:"mcp,omitempty"`
270+ MCP MCPs `json:"mcp,omitempty" jsonschema:"description=Model Context Protocol server configurations"`
250
271
251− LSP LSPs `json:"lsp,omitempty"`
272+ LSP LSPs `json:"lsp,omitempty" jsonschema:"description=Language Server Protocol configurations"`
252
273
253− Options *Options `json:"options,omitempty"`
274+ Options *Options `json:"options,omitempty" jsonschema:"description=General application options"`
254
275
255− Permissions *Permissions `json:"permissions,omitempty"`
276+ Permissions *Permissions `json:"permissions,omitempty" jsonschema:"description=Permission settings for tool usage"`
256
277
257 // Internal
278 // Internal
258 workingDir string `json:"-"`
279 workingDir string `json:"-"`