@khaentertainment/grok-swarm 1.3.3 → 1.3.5

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/README.md CHANGED
@@ -113,8 +113,9 @@ npm install -g @khaentertainment/grok-swarm
113
113
  /plugin install grok-swarm@khaentertainment
114
114
  ```
115
115
 
116
- Then run `/grok-swarm:setup` inside Claude Code an OAuth browser flow will
117
- authorize your OpenRouter account without exposing your API key in-context.
116
+ Then run `/grok-swarm` or `/grok-swarm-setup` inside Claude Code. That bootstraps
117
+ the plugin-local runtime, registers the Grok MCP server, and launches OAuth if
118
+ your OpenRouter key is not configured yet.
118
119
 
119
120
  ### Option 3: ClawHub (OpenClaw)
120
121
 
@@ -146,10 +147,10 @@ For detailed instructions for each method, see [INSTALL.md](INSTALL.md).
146
147
  ### For Claude Code
147
148
 
148
149
  ```
149
- /grok-swarm:analyze Review the security of my auth module
150
- /grok-swarm:refactor Convert these callbacks to async/await
151
- /grok-swarm:code Write a FastAPI endpoint for user registration
152
- /grok-swarm:reason Compare microservices vs monolith for this project
150
+ /grok-swarm-analyze Review the security of my auth module
151
+ /grok-swarm-refactor Convert these callbacks to async/await
152
+ /grok-swarm-code Write a FastAPI endpoint for user registration
153
+ /grok-swarm-reason Compare microservices vs monolith for this project
153
154
  ```
154
155
 
155
156
  ### For OpenClaw
@@ -177,10 +178,10 @@ const result = await tools.grok_swarm({
177
178
  ### Claude Code
178
179
 
179
180
  ```
180
- /grok-swarm:analyze Review the security of my auth module
181
- /grok-swarm:refactor Convert this to async/await
182
- /grok-swarm:code Write a FastAPI user registration endpoint
183
- /grok-swarm:reason Compare these two architectural approaches
181
+ /grok-swarm-analyze Review the security of my auth module
182
+ /grok-swarm-refactor Convert this to async/await
183
+ /grok-swarm-code Write a FastAPI user registration endpoint
184
+ /grok-swarm-reason Compare these two architectural approaches
184
185
  ```
185
186
 
186
187
  ### OpenClaw
@@ -244,9 +245,10 @@ unset OPENROUTER_API_KEY
244
245
 
245
246
  ## Release Note
246
247
 
247
- `1.3.3` is the first npm release after the failed `1.3.0`-`1.3.2` publish attempts.
248
- If you previously installed `1.0.0`, upgrade directly to `1.3.3` to get the MCP server,
249
- OAuth helper, autonomous agent runtime, and the rest of the Claude/OpenClaw stabilization fixes.
248
+ `1.3.4` fixes the Claude command surface after `1.3.3`.
249
+ If you previously installed `1.3.3`, upgrade to `1.3.4` to get searchable
250
+ `/grok-swarm-*` commands plus first-use bootstrap that repairs missing MCP
251
+ registration from inside Claude Code itself.
250
252
 
251
253
  ## Morph LLM Integration
252
254
 
package/dist/README.md CHANGED
@@ -113,8 +113,9 @@ npm install -g @khaentertainment/grok-swarm
113
113
  /plugin install grok-swarm@khaentertainment
114
114
  ```
115
115
 
116
- Then run `/grok-swarm:setup` inside Claude Code an OAuth browser flow will
117
- authorize your OpenRouter account without exposing your API key in-context.
116
+ Then run `/grok-swarm` or `/grok-swarm-setup` inside Claude Code. That bootstraps
117
+ the plugin-local runtime, registers the Grok MCP server, and launches OAuth if
118
+ your OpenRouter key is not configured yet.
118
119
 
119
120
  ### Option 3: ClawHub (OpenClaw)
120
121
 
@@ -146,10 +147,10 @@ For detailed instructions for each method, see [INSTALL.md](INSTALL.md).
146
147
  ### For Claude Code
147
148
 
148
149
  ```
149
- /grok-swarm:analyze Review the security of my auth module
150
- /grok-swarm:refactor Convert these callbacks to async/await
151
- /grok-swarm:code Write a FastAPI endpoint for user registration
152
- /grok-swarm:reason Compare microservices vs monolith for this project
150
+ /grok-swarm-analyze Review the security of my auth module
151
+ /grok-swarm-refactor Convert these callbacks to async/await
152
+ /grok-swarm-code Write a FastAPI endpoint for user registration
153
+ /grok-swarm-reason Compare microservices vs monolith for this project
153
154
  ```
154
155
 
155
156
  ### For OpenClaw
@@ -177,10 +178,10 @@ const result = await tools.grok_swarm({
177
178
  ### Claude Code
178
179
 
179
180
  ```
180
- /grok-swarm:analyze Review the security of my auth module
181
- /grok-swarm:refactor Convert this to async/await
182
- /grok-swarm:code Write a FastAPI user registration endpoint
183
- /grok-swarm:reason Compare these two architectural approaches
181
+ /grok-swarm-analyze Review the security of my auth module
182
+ /grok-swarm-refactor Convert this to async/await
183
+ /grok-swarm-code Write a FastAPI user registration endpoint
184
+ /grok-swarm-reason Compare these two architectural approaches
184
185
  ```
185
186
 
186
187
  ### OpenClaw
@@ -244,9 +245,10 @@ unset OPENROUTER_API_KEY
244
245
 
245
246
  ## Release Note
246
247
 
247
- `1.3.3` is the first npm release after the failed `1.3.0`-`1.3.2` publish attempts.
248
- If you previously installed `1.0.0`, upgrade directly to `1.3.3` to get the MCP server,
249
- OAuth helper, autonomous agent runtime, and the rest of the Claude/OpenClaw stabilization fixes.
248
+ `1.3.4` fixes the Claude command surface after `1.3.3`.
249
+ If you previously installed `1.3.3`, upgrade to `1.3.4` to get searchable
250
+ `/grok-swarm-*` commands plus first-use bootstrap that repairs missing MCP
251
+ registration from inside Claude Code itself.
250
252
 
251
253
  ## Morph LLM Integration
252
254
 
package/dist/VERSION CHANGED
@@ -1 +1 @@
1
- 1.3.3
1
+ 1.3.5
@@ -28,7 +28,7 @@ try:
28
28
  except ImportError:
29
29
  print(
30
30
  "ERROR: openai package required for this Grok Swarm runtime. "
31
- "Install from src/requirements.txt or run /grok-swarm:setup to bootstrap the plugin-local environment.",
31
+ "Install from src/requirements.txt or run /grok-swarm-setup to bootstrap the plugin-local environment.",
32
32
  file=sys.stderr,
33
33
  )
34
34
  sys.exit(1)
@@ -330,7 +330,7 @@ def _get_client(api_key=None, timeout=120):
330
330
  "No OpenRouter API key found. "
331
331
  "Tried: OPENROUTER_API_KEY env, ~/.config/grok-swarm/config.json, "
332
332
  "~/.claude/grok-swarm.local.md, OpenClaw auth profiles. "
333
- "Run: python3 src/bridge/oauth_setup.py or /grok-swarm:setup"
333
+ "Run: python3 src/bridge/oauth_setup.py or /grok-swarm-setup"
334
334
  )
335
335
  return OpenAI(base_url=OPENROUTER_BASE, api_key=key, timeout=timeout)
336
336
 
@@ -403,7 +403,7 @@ def call_grok(prompt, mode="reason", context="", system_override=None, tools=Non
403
403
  print(" 2. ~/.config/grok-swarm/config.json", file=sys.stderr)
404
404
  print(" 3. ~/.claude/grok-swarm.local.md", file=sys.stderr)
405
405
  print(" 4. OpenClaw auth profiles (~/.openclaw/)", file=sys.stderr)
406
- print("Run: python3 src/bridge/oauth_setup.py or /grok-swarm:setup", file=sys.stderr)
406
+ print("Run: python3 src/bridge/oauth_setup.py or /grok-swarm-setup", file=sys.stderr)
407
407
  sys.exit(1)
408
408
 
409
409
  # Resolve system prompt
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@khaentertainment/grok-swarm",
3
- "version": "1.3.3",
3
+ "version": "1.3.5",
4
4
  "description": "Multi-agent intelligence powered by Grok 4.20 via OpenRouter. Give any AI coding agent access to a 4-agent swarm with ~2M token context.",
5
5
  "keywords": [
6
6
  "grok",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@khaentertainment/grok-swarm",
3
- "version": "1.3.3",
3
+ "version": "1.3.5",
4
4
  "description": "Multi-agent intelligence powered by Grok 4.20 via OpenRouter. Give any AI coding agent access to a 4-agent swarm with ~2M token context.",
5
5
  "keywords": [
6
6
  "grok",
@@ -28,7 +28,7 @@ try:
28
28
  except ImportError:
29
29
  print(
30
30
  "ERROR: openai package required for this Grok Swarm runtime. "
31
- "Install from src/requirements.txt or run /grok-swarm:setup to bootstrap the plugin-local environment.",
31
+ "Install from src/requirements.txt or run /grok-swarm-setup to bootstrap the plugin-local environment.",
32
32
  file=sys.stderr,
33
33
  )
34
34
  sys.exit(1)
@@ -330,7 +330,7 @@ def _get_client(api_key=None, timeout=120):
330
330
  "No OpenRouter API key found. "
331
331
  "Tried: OPENROUTER_API_KEY env, ~/.config/grok-swarm/config.json, "
332
332
  "~/.claude/grok-swarm.local.md, OpenClaw auth profiles. "
333
- "Run: python3 src/bridge/oauth_setup.py or /grok-swarm:setup"
333
+ "Run: python3 src/bridge/oauth_setup.py or /grok-swarm-setup"
334
334
  )
335
335
  return OpenAI(base_url=OPENROUTER_BASE, api_key=key, timeout=timeout)
336
336
 
@@ -403,7 +403,7 @@ def call_grok(prompt, mode="reason", context="", system_override=None, tools=Non
403
403
  print(" 2. ~/.config/grok-swarm/config.json", file=sys.stderr)
404
404
  print(" 3. ~/.claude/grok-swarm.local.md", file=sys.stderr)
405
405
  print(" 4. OpenClaw auth profiles (~/.openclaw/)", file=sys.stderr)
406
- print("Run: python3 src/bridge/oauth_setup.py or /grok-swarm:setup", file=sys.stderr)
406
+ print("Run: python3 src/bridge/oauth_setup.py or /grok-swarm-setup", file=sys.stderr)
407
407
  sys.exit(1)
408
408
 
409
409
  # Resolve system prompt
@@ -31,6 +31,7 @@ from bridge.grok_bridge import (
31
31
  get_api_key,
32
32
  read_files,
33
33
  strip_pgp_blocks,
34
+ parse_and_write_files,
34
35
  MODE_PROMPTS,
35
36
  AGENT_COUNTS,
36
37
  )
@@ -57,13 +58,28 @@ log = logging.getLogger("grok-mcp")
57
58
  # ---------------------------------------------------------------------------
58
59
 
59
60
  SERVER_NAME = "grok-swarm"
60
- SERVER_VERSION = "1.3.3"
61
+ SERVER_VERSION = "1.3.4"
61
62
  PROTOCOL_VERSION = "2024-11-05"
62
63
 
63
64
  # ---------------------------------------------------------------------------
64
65
  # Tool definitions (JSON Schema format for MCP, NOT OpenAI format)
65
66
  # ---------------------------------------------------------------------------
66
67
 
68
+ # JSON Schema fragments parsed at import time so defaults use lowercase JSON
69
+ # true/false rather than Python True/False literals.
70
+ _WRITE_FILES_SCHEMA = json.loads(
71
+ '{"type": "boolean", "default": false, '
72
+ '"description": "Whether to parse and write code blocks from the response to disk."}'
73
+ )
74
+ _OUTPUT_DIR_SCHEMA = json.loads(
75
+ '{"type": "string", "default": "./grok-output/", '
76
+ '"description": "Output directory for write_files mode."}'
77
+ )
78
+ _BOOL_FALSE_SCHEMA = json.loads(
79
+ '{"type": "boolean", "default": false, '
80
+ '"description": "Whether to actually write changes (default: dry-run preview)."}'
81
+ )
82
+
67
83
  TOOLS = [
68
84
  {
69
85
  "name": "grok_query",
@@ -105,6 +121,8 @@ TOOLS = [
105
121
  "default": 120,
106
122
  "description": "API timeout in seconds.",
107
123
  },
124
+ "write_files": _WRITE_FILES_SCHEMA,
125
+ "output_dir": _OUTPUT_DIR_SCHEMA,
108
126
  },
109
127
  "required": ["prompt"],
110
128
  },
@@ -140,6 +158,16 @@ TOOLS = [
140
158
  "items": {"type": "string"},
141
159
  "description": "File paths to include as initial context.",
142
160
  },
161
+ "write_files": {
162
+ "type": "boolean",
163
+ "default": False,
164
+ "description": "Accepted for API consistency; applies only to grok_session_continue.",
165
+ },
166
+ "output_dir": {
167
+ "type": "string",
168
+ "default": "./grok-output/",
169
+ "description": "Accepted for API consistency; applies only to grok_session_continue.",
170
+ },
143
171
  },
144
172
  "required": [],
145
173
  },
@@ -166,6 +194,8 @@ TOOLS = [
166
194
  "items": {"type": "string"},
167
195
  "description": "Additional file paths to add as context.",
168
196
  },
197
+ "write_files": _WRITE_FILES_SCHEMA,
198
+ "output_dir": _OUTPUT_DIR_SCHEMA,
169
199
  },
170
200
  "required": ["session_id", "message"],
171
201
  },
@@ -189,11 +219,7 @@ TOOLS = [
189
219
  "default": ".",
190
220
  "description": "Target directory or file to operate on.",
191
221
  },
192
- "apply": {
193
- "type": "boolean",
194
- "default": False,
195
- "description": "Whether to actually write changes (default: dry-run preview).",
196
- },
222
+ "apply": _BOOL_FALSE_SCHEMA,
197
223
  "max_iterations": {
198
224
  "type": "integer",
199
225
  "default": 5,
@@ -222,6 +248,8 @@ def _handle_grok_query(params):
222
248
  system = params.get("system")
223
249
  thinking = params.get("thinking", "low")
224
250
  timeout = params.get("timeout", 120)
251
+ write_files = params.get("write_files", False)
252
+ output_dir = params.get("output_dir", "./grok-output/")
225
253
 
226
254
  if mode == "orchestrate" and not system:
227
255
  return _error_content("orchestrate mode requires the 'system' parameter")
@@ -255,7 +283,19 @@ def _handle_grok_query(params):
255
283
  return _error_content("Empty response from Grok API")
256
284
 
257
285
  content = response.choices[0].message.content or ""
258
- return _text_content(strip_pgp_blocks(content))
286
+ cleaned = strip_pgp_blocks(content)
287
+
288
+ if write_files:
289
+ try:
290
+ written = parse_and_write_files(cleaned, output_dir)
291
+ except (OSError, IOError) as exc:
292
+ log.error("Failed to write files: %s", exc)
293
+ return _error_content(f"Failed to write files: {exc}")
294
+ if written:
295
+ paths = ", ".join(p for p, _ in written)
296
+ return _text_content(f"{len(written)} file(s) written to {output_dir}: {paths}")
297
+ # Fall back to printing the response text if no files were written
298
+ return _text_content(cleaned)
259
299
 
260
300
 
261
301
  def _handle_grok_session_start(params):
@@ -266,6 +306,8 @@ def _handle_grok_session_start(params):
266
306
  system = params.get("system")
267
307
  thinking = params.get("thinking", "low")
268
308
  files = params.get("files", [])
309
+ # write_files and output_dir params are accepted for API consistency
310
+ # but apply to grok_session_continue, not the session start itself
269
311
 
270
312
  # Read initial file context
271
313
  file_context = ""
@@ -296,6 +338,8 @@ def _handle_grok_session_continue(params):
296
338
  session_id = params["session_id"]
297
339
  message = params["message"]
298
340
  files = params.get("files", [])
341
+ write_files = params.get("write_files", False)
342
+ output_dir = params.get("output_dir", "./grok-output/")
299
343
 
300
344
  session = session_mod.get_session(session_id)
301
345
  if session is None:
@@ -312,7 +356,17 @@ def _handle_grok_session_continue(params):
312
356
  log.error("Session %s error: %s", session_id, exc)
313
357
  return _error_content(f"Grok API error: {exc}")
314
358
 
315
- return _text_content(strip_pgp_blocks(response))
359
+ cleaned = strip_pgp_blocks(response)
360
+ if write_files:
361
+ try:
362
+ written = parse_and_write_files(cleaned, output_dir)
363
+ except (OSError, IOError) as exc:
364
+ log.error("Failed to write files to %s: %s", output_dir, exc)
365
+ return _error_content(f"Failed to write files: {exc}")
366
+ if written:
367
+ paths = ", ".join(p for p, _ in written)
368
+ return _text_content(f"{len(written)} file(s) written to {output_dir}: {paths}")
369
+ return _text_content(cleaned)
316
370
 
317
371
 
318
372
  def _handle_grok_agent(params):