@swarmclawai/swarmclaw 1.9.24 → 1.9.25

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
@@ -151,12 +151,13 @@ clawhub install swarmclaw
151
151
 
152
152
  [Browse on ClawHub](https://clawhub.ai/skills/swarmclaw)
153
153
 
154
- ## v1.9.24 Highlights
154
+ ## v1.9.25 Highlights
155
155
 
156
156
  Gateway lifecycle controls and Slack peer-agent collaboration are now safer for multi-agent operations.
157
157
 
158
158
  - **Gateway lifecycle controls.** Providers can activate, drain, cordon, or request restart for saved OpenClaw gateways.
159
159
  - **Routing guardrails.** New OpenClaw work skips draining or cordoned gateway profiles, and Operations Pulse flags unavailable gateways.
160
+ - **CLI lifecycle access.** `swarmclaw gateways activate`, `drain`, `cordon`, and `restart` now reach the same lifecycle control endpoint as the provider UI.
160
161
  - **Slack peer messages.** Peer bot messages now reach the existing connector policy gates while self-loop messages are still blocked.
161
162
 
162
163
  ## Hosted Deploys
@@ -409,13 +410,14 @@ Operational docs: https://swarmclaw.ai/docs/observability
409
410
 
410
411
  ## Releases
411
412
 
412
- ### v1.9.24 Highlights
413
+ ### v1.9.25 Highlights
413
414
 
414
415
  Gateway lifecycle release: saved OpenClaw gateways now have explicit operator lifecycle controls, automatic routing avoids gateways that should not receive new work, and Slack peer-agent messages flow through the existing connector policy gates.
415
416
 
416
417
  - **Gateway lifecycle controls.** Providers can activate, drain, cordon, and request restart for saved OpenClaw gateway profiles.
417
418
  - **Routing guardrails.** OpenClaw route selection skips draining and cordoned profiles, including default, preferred, and pinned gateway paths.
418
419
  - **Operations Pulse awareness.** Cordoned and draining gateways now appear as operator attention items before they surprise a handoff or release check.
420
+ - **CLI lifecycle access.** `swarmclaw gateways activate`, `drain`, `cordon`, and `restart` now post the matching lifecycle action for automation and release scripts.
419
421
  - **Slack peer collaboration.** Slack peer-bot messages are no longer dropped before group policy, mention, and self-loop protections run.
420
422
 
421
423
  ### v1.9.23 Highlights
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swarmclawai/swarmclaw",
3
- "version": "1.9.24",
3
+ "version": "1.9.25",
4
4
  "description": "Build and run autonomous AI agents with OpenClaw, Hermes, multiple model providers, orchestration, delegation, memory, skills, schedules, and chat connectors.",
5
5
  "main": "electron-dist/main.js",
6
6
  "license": "MIT",
@@ -39,7 +39,7 @@
39
39
  "node": ">=22.6.0"
40
40
  },
41
41
  "bin": {
42
- "swarmclaw": "./bin/swarmclaw.js"
42
+ "swarmclaw": "bin/swarmclaw.js"
43
43
  },
44
44
  "files": [
45
45
  "bin/",
package/src/cli/index.js CHANGED
@@ -278,6 +278,23 @@ const COMMAND_GROUPS = [
278
278
  cmd('create', 'POST', '/gateways', 'Create a gateway profile', { expectsJsonBody: true }),
279
279
  cmd('update', 'PUT', '/gateways/:id', 'Update a gateway profile', { expectsJsonBody: true }),
280
280
  cmd('delete', 'DELETE', '/gateways/:id', 'Delete a gateway profile'),
281
+ cmd('control', 'POST', '/gateways/:id/control', 'Run a gateway lifecycle control action', { expectsJsonBody: true }),
282
+ cmd('activate', 'POST', '/gateways/:id/control', 'Return a gateway to active routing', {
283
+ expectsJsonBody: true,
284
+ defaultBody: { action: 'activate' },
285
+ }),
286
+ cmd('drain', 'POST', '/gateways/:id/control', 'Drain a gateway from new automatic work', {
287
+ expectsJsonBody: true,
288
+ defaultBody: { action: 'drain' },
289
+ }),
290
+ cmd('cordon', 'POST', '/gateways/:id/control', 'Cordon a gateway from automatic work', {
291
+ expectsJsonBody: true,
292
+ defaultBody: { action: 'cordon' },
293
+ }),
294
+ cmd('restart', 'POST', '/gateways/:id/control', 'Request a gateway restart', {
295
+ expectsJsonBody: true,
296
+ defaultBody: { action: 'restart' },
297
+ }),
281
298
  cmd('health', 'GET', '/gateways/:id/health', 'Run a gateway health check'),
282
299
  cmd('topology', 'GET', '/gateways/:id/topology', 'Refresh and return one gateway topology snapshot'),
283
300
  cmd('environments', 'GET', '/gateways/:id/environments', 'List OpenClaw gateway execution environments'),
@@ -225,6 +225,36 @@ test('tasks execution-policy-decision posts policy decisions', async () => {
225
225
  assert.equal(stderr.toString(), '')
226
226
  })
227
227
 
228
+ test('gateways drain command posts a lifecycle control action', async () => {
229
+ const stdout = makeWritable()
230
+ const stderr = makeWritable()
231
+ const calls = []
232
+
233
+ const fetchImpl = async (url, init) => {
234
+ calls.push({ url: String(url), init })
235
+ return jsonResponse({ ok: true })
236
+ }
237
+
238
+ const exitCode = await runCli(
239
+ ['gateways', 'drain', 'gateway-1', '--json'],
240
+ {
241
+ fetchImpl,
242
+ stdout,
243
+ stderr,
244
+ env: {
245
+ SWARMCLAW_API_KEY: 'test-key',
246
+ },
247
+ cwd: process.cwd(),
248
+ }
249
+ )
250
+
251
+ assert.equal(exitCode, 0)
252
+ assert.equal(calls.length, 1)
253
+ assert.match(calls[0].url, /\/api\/gateways\/gateway-1\/control$/)
254
+ assert.equal(calls[0].init.method, 'POST')
255
+ assert.deepEqual(JSON.parse(calls[0].init.body), { action: 'drain' })
256
+ })
257
+
228
258
  test('openclaw deploy bundle command merges action with provided JSON body', async () => {
229
259
  const stdout = makeWritable()
230
260
  const stderr = makeWritable()
package/src/cli/spec.js CHANGED
@@ -219,6 +219,11 @@ const COMMAND_GROUPS = {
219
219
  create: { description: 'Create a gateway profile', method: 'POST', path: '/gateways' },
220
220
  update: { description: 'Update a gateway profile', method: 'PUT', path: '/gateways/:id', params: ['id'] },
221
221
  delete: { description: 'Delete a gateway profile', method: 'DELETE', path: '/gateways/:id', params: ['id'] },
222
+ control: { description: 'Run a gateway lifecycle control action', method: 'POST', path: '/gateways/:id/control', params: ['id'] },
223
+ activate: { description: 'Return a gateway to active routing', method: 'POST', path: '/gateways/:id/control', params: ['id'] },
224
+ drain: { description: 'Drain a gateway from new automatic work', method: 'POST', path: '/gateways/:id/control', params: ['id'] },
225
+ cordon: { description: 'Cordon a gateway from automatic work', method: 'POST', path: '/gateways/:id/control', params: ['id'] },
226
+ restart: { description: 'Request a gateway restart', method: 'POST', path: '/gateways/:id/control', params: ['id'] },
222
227
  health: { description: 'Run a gateway health check', method: 'GET', path: '/gateways/:id/health', params: ['id'] },
223
228
  topology: { description: 'Refresh and return one gateway topology snapshot', method: 'GET', path: '/gateways/:id/topology', params: ['id'] },
224
229
  environments: { description: 'List OpenClaw gateway execution environments', method: 'GET', path: '/gateways/:id/environments', params: ['id'] },