/ src / cli / spec.js
spec.js
  1  const COMMAND_GROUPS = {
  2    agents: {
  3      description: 'Manage agents',
  4      commands: {
  5        list: { description: 'List agents', method: 'GET', path: '/agents' },
  6        get: { description: 'Get an agent by id (from list)', virtualGet: true, collectionPath: '/agents', params: ['id'] },
  7        create: { description: 'Create an agent', method: 'POST', path: '/agents' },
  8        update: { description: 'Update an agent', method: 'PUT', path: '/agents/:id', params: ['id'] },
  9        delete: { description: 'Delete an agent', method: 'DELETE', path: '/agents/:id', params: ['id'] },
 10        'bulk-update': { description: 'Bulk update agents', method: 'PATCH', path: '/agents/bulk' },
 11        trash: { description: 'List trashed agents', method: 'GET', path: '/agents/trash' },
 12        restore: { description: 'Restore a trashed agent', method: 'POST', path: '/agents/trash' },
 13        purge: { description: 'Permanently delete a trashed agent', method: 'DELETE', path: '/agents/trash' },
 14        status: { description: 'Get live status for an agent', method: 'GET', path: '/agents/:id/status', params: ['id'] },
 15        dream: { description: 'Get agent dream config and recent cycles', method: 'GET', path: '/agents/:id/dream', params: ['id'] },
 16        'dream-update': { description: 'Update agent dream config', method: 'PATCH', path: '/agents/:id/dream', params: ['id'] },
 17      },
 18    },
 19    activity: {
 20      description: 'Query activity feed events',
 21      commands: {
 22        list: { description: 'List activity events (supports --query limit=50,entityType=task,action=updated)', method: 'GET', path: '/activity' },
 23      },
 24    },
 25    auth: {
 26      description: 'Access-key auth checks',
 27      commands: {
 28        status: { description: 'Get auth setup status', method: 'GET', path: '/auth' },
 29        login: { description: 'Validate an access key', method: 'POST', path: '/auth' },
 30      },
 31    },
 32    autonomy: {
 33      description: 'Autonomy supervisor inspection',
 34      commands: {
 35        incidents: { description: 'List supervisor incidents (supports --query sessionId=..., --query taskId=..., --query limit=50)', method: 'GET', path: '/autonomy/incidents' },
 36        reflections: { description: 'List run reflections (supports --query sessionId=..., --query taskId=..., --query limit=50)', method: 'GET', path: '/autonomy/reflections' },
 37        estop: { description: 'Get autonomy emergency-stop state', method: 'GET', path: '/autonomy/estop' },
 38        'estop-set': { description: 'Engage or resume autonomy emergency-stop state', method: 'POST', path: '/autonomy/estop' },
 39        'guardian-restore': { description: 'Restore the latest guardian checkpoint after approval', method: 'POST', path: '/autonomy/guardian/restore' },
 40      },
 41    },
 42    approvals: {
 43      description: 'List and resolve human-loop approvals',
 44      commands: {
 45        list: { description: 'List pending human-loop approvals', method: 'GET', path: '/approvals' },
 46        resolve: { description: 'Resolve a human-loop approval', method: 'POST', path: '/approvals' },
 47      },
 48    },
 49    chatrooms: {
 50      description: 'Manage multi-agent chatrooms',
 51      commands: {
 52        list: { description: 'List chatrooms', method: 'GET', path: '/chatrooms' },
 53        get: { description: 'Get chatroom by id', method: 'GET', path: '/chatrooms/:id', params: ['id'] },
 54        create: { description: 'Create a chatroom', method: 'POST', path: '/chatrooms' },
 55        update: { description: 'Update a chatroom', method: 'PUT', path: '/chatrooms/:id', params: ['id'] },
 56        delete: { description: 'Delete a chatroom', method: 'DELETE', path: '/chatrooms/:id', params: ['id'] },
 57        chat: { description: 'Post chatroom message and stream agent replies', method: 'POST', path: '/chatrooms/:id/chat', params: ['id'] },
 58        'add-member': { description: 'Add an agent to a chatroom', method: 'POST', path: '/chatrooms/:id/members', params: ['id'] },
 59        'remove-member': { description: 'Remove an agent from a chatroom', method: 'DELETE', path: '/chatrooms/:id/members', params: ['id'] },
 60        react: { description: 'Toggle reaction on a chatroom message', method: 'POST', path: '/chatrooms/:id/reactions', params: ['id'] },
 61        pin: { description: 'Toggle pin on a chatroom message', method: 'POST', path: '/chatrooms/:id/pins', params: ['id'] },
 62      },
 63    },
 64    connectors: {
 65      description: 'Manage chat connectors',
 66      commands: {
 67        list: { description: 'List connectors', method: 'GET', path: '/connectors' },
 68        get: { description: 'Get connector details', method: 'GET', path: '/connectors/:id', params: ['id'] },
 69        create: { description: 'Create a connector', method: 'POST', path: '/connectors' },
 70        update: { description: 'Update connector config', method: 'PUT', path: '/connectors/:id', params: ['id'] },
 71        delete: { description: 'Delete connector', method: 'DELETE', path: '/connectors/:id', params: ['id'] },
 72        'access-get': { description: 'Get connector access and ownership state', method: 'GET', path: '/connectors/:id/access', params: ['id'] },
 73        'access-set': { description: 'Update connector access and ownership state', method: 'PUT', path: '/connectors/:id/access', params: ['id'] },
 74        start: {
 75          description: 'Start connector runtime',
 76          method: 'PUT',
 77          path: '/connectors/:id',
 78          params: ['id'],
 79          staticBody: { action: 'start' },
 80        },
 81        stop: {
 82          description: 'Stop connector runtime',
 83          method: 'PUT',
 84          path: '/connectors/:id',
 85          params: ['id'],
 86          staticBody: { action: 'stop' },
 87        },
 88        repair: {
 89          description: 'Repair connector runtime',
 90          method: 'PUT',
 91          path: '/connectors/:id',
 92          params: ['id'],
 93          staticBody: { action: 'repair' },
 94        },
 95      },
 96    },
 97    clawhub: {
 98      description: 'Browse and install ClawHub skills',
 99      commands: {
100        search: { description: 'Search ClawHub skills catalog', method: 'GET', path: '/clawhub/search' },
101        preview: { description: 'Preview a ClawHub skill install without writing files', method: 'POST', path: '/clawhub/preview' },
102        install: { description: 'Install a skill from ClawHub', method: 'POST', path: '/clawhub/install' },
103      },
104    },
105    credentials: {
106      description: 'Manage encrypted provider credentials',
107      commands: {
108        list: { description: 'List credentials', method: 'GET', path: '/credentials' },
109        get: { description: 'Get credential metadata by id (from list)', virtualGet: true, collectionPath: '/credentials', params: ['id'] },
110        create: { description: 'Create credential', method: 'POST', path: '/credentials' },
111        delete: { description: 'Delete credential', method: 'DELETE', path: '/credentials/:id', params: ['id'] },
112      },
113    },
114    daemon: {
115      description: 'Daemon lifecycle controls',
116      commands: {
117        status: { description: 'Get daemon status', method: 'GET', path: '/daemon' },
118        start: { description: 'Start daemon', method: 'POST', path: '/daemon', staticBody: { action: 'start' } },
119        stop: { description: 'Stop daemon', method: 'POST', path: '/daemon', staticBody: { action: 'stop' } },
120        'health-check': { description: 'Run daemon health checks immediately', method: 'POST', path: '/daemon/health-check' },
121      },
122    },
123    'delegation-jobs': {
124      description: 'Delegation job status',
125      commands: {
126        list: { description: 'List active and recent delegation jobs', method: 'GET', path: '/delegation-jobs' },
127      },
128    },
129    dirs: {
130      description: 'Directory browsing helpers',
131      commands: {
132        list: { description: 'List directories (supports --query path=/some/dir)', method: 'GET', path: '/dirs' },
133        pick: { description: 'Open native picker (body: {"mode":"file|folder"})', method: 'POST', path: '/dirs/pick' },
134      },
135    },
136    perf: {
137      description: 'Inspect or control runtime perf tracing',
138      commands: {
139        status: { description: 'Get current perf tracing status and recent entries', method: 'GET', path: '/perf' },
140        enable: { description: 'Enable perf tracing and clear existing entries', method: 'POST', path: '/perf', staticBody: { action: 'enable' } },
141        disable: { description: 'Disable perf tracing', method: 'POST', path: '/perf', staticBody: { action: 'disable' } },
142        clear: { description: 'Clear recent perf entries', method: 'POST', path: '/perf', staticBody: { action: 'clear' } },
143      },
144    },
145    documents: {
146      description: 'File uploads/downloads and TTS audio',
147      commands: {
148        upload: {
149          description: 'Upload a file (requires --file)',
150          method: 'POST',
151          path: '/upload',
152          upload: true,
153        },
154        fetch: {
155          description: 'Download an uploaded file by filename',
156          method: 'GET',
157          path: '/uploads/:filename',
158          params: ['filename'],
159          binary: true,
160        },
161        tts: {
162          description: 'Generate TTS audio (body: {"text":"..."})',
163          method: 'POST',
164          path: '/tts',
165          binary: true,
166        },
167      },
168    },
169    'external-agents': {
170      description: 'Manage external agent runtimes',
171      commands: {
172        list: { description: 'List external agent runtimes', method: 'GET', path: '/external-agents' },
173        create: { description: 'Register an external agent runtime', method: 'POST', path: '/external-agents' },
174        update: { description: 'Update an external agent runtime', method: 'PUT', path: '/external-agents/:id', params: ['id'] },
175        delete: { description: 'Delete an external agent runtime', method: 'DELETE', path: '/external-agents/:id', params: ['id'] },
176        heartbeat: { description: 'Record an external agent heartbeat', method: 'POST', path: '/external-agents/:id/heartbeat', params: ['id'] },
177      },
178    },
179    a2a: {
180      description: 'A2A Protocol gateway',
181      commands: {
182        send: { description: 'Send a JSON-RPC request to the A2A endpoint', method: 'POST', path: '/a2a' },
183        'agent-card': { description: 'Get agent card for a SwarmClaw agent', method: 'GET', path: '/.well-known/agent-card' },
184        'task-status': { description: 'Check A2A task status', method: 'GET', path: '/a2a/tasks/:taskId/status', params: ['taskId'] },
185      },
186    },
187    uploads: {
188      description: 'Manage uploaded artifacts',
189      commands: {
190        list: { description: 'List uploaded artifacts', method: 'GET', path: '/uploads' },
191        get: { description: 'Download uploaded artifact by filename', method: 'GET', path: '/uploads/:filename', params: ['filename'], binary: true },
192        delete: { description: 'Delete uploaded artifact by filename', method: 'DELETE', path: '/uploads/:filename', params: ['filename'] },
193        'delete-many': { description: 'Delete uploads by filter/body (filenames, olderThanDays, category, or all)', method: 'DELETE', path: '/uploads' },
194      },
195    },
196    files: {
197      description: 'Serve/open local files',
198      commands: {
199        serve: { description: 'Serve a local file (supports --query path=/some/file)', method: 'GET', path: '/files/serve' },
200        open: { description: 'Open a local file path via host default app/browser', method: 'POST', path: '/files/open' },
201      },
202    },
203    gateways: {
204      description: 'Manage named OpenClaw gateway profiles',
205      commands: {
206        list: { description: 'List configured gateway profiles', method: 'GET', path: '/gateways' },
207        create: { description: 'Create a gateway profile', method: 'POST', path: '/gateways' },
208        update: { description: 'Update a gateway profile', method: 'PUT', path: '/gateways/:id', params: ['id'] },
209        delete: { description: 'Delete a gateway profile', method: 'DELETE', path: '/gateways/:id', params: ['id'] },
210        health: { description: 'Run a gateway health check', method: 'GET', path: '/gateways/:id/health', params: ['id'] },
211      },
212    },
213    logs: {
214      description: 'Application logs',
215      commands: {
216        list: { description: 'Fetch logs (supports --query lines=200,level=INFO)', method: 'GET', path: '/logs' },
217        clear: { description: 'Clear log file', method: 'DELETE', path: '/logs' },
218        report: { description: 'Write a client/browser error entry to the application log', method: 'POST', path: '/logs' },
219      },
220    },
221  
222    memory: {
223      description: 'Agent memory entries',
224      commands: {
225        list: { description: 'List memory entries (supports --query q=term,agentId=id)', method: 'GET', path: '/memory' },
226        get: { description: 'Get memory entry by id', method: 'GET', path: '/memory/:id', params: ['id'] },
227        create: { description: 'Create memory entry', method: 'POST', path: '/memory' },
228        update: { description: 'Update memory entry', method: 'PUT', path: '/memory/:id', params: ['id'] },
229        delete: { description: 'Delete memory entry', method: 'DELETE', path: '/memory/:id', params: ['id'] },
230        maintenance: { description: 'Analyze memory dedupe/prune candidates', method: 'GET', path: '/memory/maintenance' },
231        'maintenance-run': { description: 'Run memory dedupe/prune maintenance', method: 'POST', path: '/memory/maintenance' },
232        dream: { description: 'List dream cycles', method: 'GET', path: '/memory/dream' },
233        'dream-trigger': { description: 'Trigger a dream cycle', method: 'POST', path: '/memory/dream' },
234        'dream-get': { description: 'Get dream cycle by id', method: 'GET', path: '/memory/dream/:id', params: ['id'] },
235      },
236    },
237    'memory-images': {
238      description: 'Stored memory image assets',
239      commands: {
240        get: { description: 'Download memory image by filename', method: 'GET', path: '/memory-images/:filename', params: ['filename'], binary: true },
241      },
242    },
243    notifications: {
244      description: 'In-app notification center',
245      commands: {
246        list: { description: 'List notifications (supports --query unreadOnly=true,limit=100)', method: 'GET', path: '/notifications' },
247        create: { description: 'Create notification', method: 'POST', path: '/notifications' },
248        clear: { description: 'Clear read notifications', method: 'DELETE', path: '/notifications' },
249        'mark-read': { description: 'Mark notification as read', method: 'PUT', path: '/notifications/:id', params: ['id'] },
250        delete: { description: 'Delete notification by id', method: 'DELETE', path: '/notifications/:id', params: ['id'] },
251      },
252    },
253    openclaw: {
254      description: 'OpenClaw discovery, gateway control, and runtime APIs',
255      commands: {
256        discover: { description: 'Discover OpenClaw gateways', method: 'GET', path: '/openclaw/discover' },
257        'deploy-status': { description: 'Get managed OpenClaw deploy status', method: 'GET', path: '/openclaw/deploy' },
258        'deploy-local-start': {
259          description: 'Start a managed local OpenClaw deployment (use --data JSON for port/token overrides)',
260          method: 'POST',
261          path: '/openclaw/deploy',
262          staticBody: { action: 'start-local' },
263        },
264        'deploy-local-stop': {
265          description: 'Stop the managed local OpenClaw deployment',
266          method: 'POST',
267          path: '/openclaw/deploy',
268          staticBody: { action: 'stop-local' },
269        },
270        'deploy-local-restart': {
271          description: 'Restart the managed local OpenClaw deployment (use --data JSON for port/token overrides)',
272          method: 'POST',
273          path: '/openclaw/deploy',
274          staticBody: { action: 'restart-local' },
275        },
276        'deploy-bundle': {
277          description: 'Generate an OpenClaw remote deployment bundle (use --data JSON for template/target/token)',
278          method: 'POST',
279          path: '/openclaw/deploy',
280          staticBody: { action: 'bundle' },
281        },
282        'deploy-ssh': {
283          description: 'Push the official-image OpenClaw bundle to a remote host over SSH (use --data JSON for target/ssh/provider)',
284          method: 'POST',
285          path: '/openclaw/deploy',
286          staticBody: { action: 'ssh-deploy' },
287        },
288        'deploy-verify': {
289          description: 'Verify an OpenClaw endpoint/token pair (use --data JSON for endpoint/token)',
290          method: 'POST',
291          path: '/openclaw/deploy',
292          staticBody: { action: 'verify' },
293        },
294        'remote-start': {
295          description: 'Start a remote SSH-managed OpenClaw stack',
296          method: 'POST',
297          path: '/openclaw/deploy',
298          staticBody: { action: 'remote-start' },
299        },
300        'remote-stop': {
301          description: 'Stop a remote SSH-managed OpenClaw stack',
302          method: 'POST',
303          path: '/openclaw/deploy',
304          staticBody: { action: 'remote-stop' },
305        },
306        'remote-restart': {
307          description: 'Restart a remote SSH-managed OpenClaw stack',
308          method: 'POST',
309          path: '/openclaw/deploy',
310          staticBody: { action: 'remote-restart' },
311        },
312        'remote-upgrade': {
313          description: 'Upgrade a remote SSH-managed OpenClaw stack',
314          method: 'POST',
315          path: '/openclaw/deploy',
316          staticBody: { action: 'remote-upgrade' },
317        },
318        'remote-backup': {
319          description: 'Create a remote backup on an SSH-managed OpenClaw host',
320          method: 'POST',
321          path: '/openclaw/deploy',
322          staticBody: { action: 'remote-backup' },
323        },
324        'remote-restore': {
325          description: 'Restore a remote backup on an SSH-managed OpenClaw host',
326          method: 'POST',
327          path: '/openclaw/deploy',
328          staticBody: { action: 'remote-restore' },
329        },
330        'remote-rotate-token': {
331          description: 'Rotate the gateway token on an SSH-managed OpenClaw host',
332          method: 'POST',
333          path: '/openclaw/deploy',
334          staticBody: { action: 'remote-rotate-token' },
335        },
336        directory: { description: 'List directory entries from running OpenClaw connectors', method: 'GET', path: '/openclaw/directory' },
337        'gateway-status': { description: 'Check OpenClaw gateway connection status', method: 'GET', path: '/openclaw/gateway' },
338        gateway: { description: 'Call OpenClaw gateway RPC/control action', method: 'POST', path: '/openclaw/gateway' },
339        'config-sync': { description: 'Detect OpenClaw gateway config issues', method: 'GET', path: '/openclaw/config-sync' },
340        'config-sync-repair': { description: 'Repair a detected OpenClaw config issue', method: 'POST', path: '/openclaw/config-sync' },
341        approvals: { description: 'List pending OpenClaw execution approvals', method: 'GET', path: '/openclaw/approvals' },
342        'approvals-resolve': { description: 'Resolve an OpenClaw execution approval', method: 'POST', path: '/openclaw/approvals' },
343        cron: { description: 'List OpenClaw cron jobs', method: 'GET', path: '/openclaw/cron' },
344        'cron-action': { description: 'Create/run/remove OpenClaw cron jobs', method: 'POST', path: '/openclaw/cron' },
345        'agent-files': { description: 'Fetch OpenClaw agent files', method: 'GET', path: '/openclaw/agent-files' },
346        'agent-files-set': { description: 'Save an OpenClaw agent file', method: 'PUT', path: '/openclaw/agent-files' },
347        'dotenv-keys': { description: 'List gateway .env keys', method: 'GET', path: '/openclaw/dotenv-keys' },
348        'exec-config': { description: 'Fetch OpenClaw exec approval config', method: 'GET', path: '/openclaw/exec-config' },
349        'exec-config-set': { description: 'Save OpenClaw exec approval config', method: 'PUT', path: '/openclaw/exec-config' },
350        'history-preview': { description: 'Preview OpenClaw session history', method: 'GET', path: '/openclaw/history' },
351        'history-merge': { description: 'Merge OpenClaw session history into local session', method: 'POST', path: '/openclaw/history' },
352        media: { description: 'Proxy OpenClaw media/file content', method: 'GET', path: '/openclaw/media' },
353        models: { description: 'List allowed OpenClaw models', method: 'GET', path: '/openclaw/models' },
354        permissions: { description: 'Get OpenClaw permission preset/config', method: 'GET', path: '/openclaw/permissions' },
355        'permissions-set': { description: 'Apply OpenClaw permission preset', method: 'PUT', path: '/openclaw/permissions' },
356        'sandbox-env': { description: 'List OpenClaw sandbox env allowlist', method: 'GET', path: '/openclaw/sandbox-env' },
357        'sandbox-env-set': { description: 'Update OpenClaw sandbox env allowlist', method: 'PUT', path: '/openclaw/sandbox-env' },
358        skills: { description: 'List OpenClaw skills and eligibility', method: 'GET', path: '/openclaw/skills' },
359        'skills-update': { description: 'Update OpenClaw skill state/config', method: 'PATCH', path: '/openclaw/skills' },
360        'skills-save': { description: 'Save OpenClaw skill allowlist mode/config', method: 'PUT', path: '/openclaw/skills' },
361        'skills-install': { description: 'Install OpenClaw skill dependencies', method: 'POST', path: '/openclaw/skills/install' },
362        'skills-remove': { description: 'Remove OpenClaw skill', method: 'POST', path: '/openclaw/skills/remove' },
363        sync: { description: 'Run OpenClaw sync action', method: 'POST', path: '/openclaw/sync' },
364      },
365    },
366    extensions: {
367      description: 'Extension listing/config/install',
368      commands: {
369        list: { description: 'List installed extensions', method: 'GET', path: '/extensions' },
370        update: { description: 'Enable or disable an extension (body: {"filename":"x.js","enabled":true})', method: 'POST', path: '/extensions' },
371        marketplace: { description: 'Get extension marketplace registry', method: 'GET', path: '/extensions/marketplace' },
372        install: { description: 'Install extension by URL', method: 'POST', path: '/extensions/install' },
373        'settings-get': { description: 'Read extension settings (supports --query extensionId=...)', method: 'GET', path: '/extensions/settings' },
374        'settings-set': { description: 'Write extension settings (supports --query extensionId=... and --data JSON)', method: 'PUT', path: '/extensions/settings' },
375      },
376    },
377    providers: {
378      description: 'Provider configs and model overrides',
379      commands: {
380        list: { description: 'List providers', method: 'GET', path: '/providers' },
381        create: { description: 'Create custom provider', method: 'POST', path: '/providers' },
382        get: { description: 'Get provider by id', method: 'GET', path: '/providers/:id', params: ['id'] },
383        update: { description: 'Update provider config', method: 'PUT', path: '/providers/:id', params: ['id'] },
384        delete: { description: 'Delete custom provider', method: 'DELETE', path: '/providers/:id', params: ['id'] },
385        configs: { description: 'List provider configs only', method: 'GET', path: '/providers/configs' },
386        ollama: { description: 'List local Ollama models', method: 'GET', path: '/providers/ollama' },
387        'openclaw-health': { description: 'Probe OpenClaw endpoint and auth status', method: 'GET', path: '/providers/openclaw/health' },
388        'models-get': { description: 'Get provider model overrides', method: 'GET', path: '/providers/:id/models', params: ['id'] },
389        'models-set': { description: 'Set provider model overrides', method: 'PUT', path: '/providers/:id/models', params: ['id'] },
390        'models-reset': { description: 'Delete provider model overrides', method: 'DELETE', path: '/providers/:id/models', params: ['id'] },
391      },
392    },
393    search: {
394      description: 'Global search across app resources',
395      commands: {
396        query: { description: 'Search agents/tasks/chats/schedules/webhooks/skills (supports --query q=term)', method: 'GET', path: '/search' },
397      },
398    },
399    schedules: {
400      description: 'Scheduled task automation',
401      commands: {
402        list: { description: 'List schedules', method: 'GET', path: '/schedules' },
403        create: { description: 'Create schedule', method: 'POST', path: '/schedules' },
404        get: { description: 'Get schedule by id (from list)', virtualGet: true, collectionPath: '/schedules', params: ['id'] },
405        update: { description: 'Update schedule', method: 'PUT', path: '/schedules/:id', params: ['id'] },
406        delete: { description: 'Delete schedule', method: 'DELETE', path: '/schedules/:id', params: ['id'] },
407        run: { description: 'Trigger schedule immediately', method: 'POST', path: '/schedules/:id/run', params: ['id'] },
408      },
409    },
410    secrets: {
411      description: 'Encrypted secret vault',
412      commands: {
413        list: { description: 'List secret metadata', method: 'GET', path: '/secrets' },
414        get: { description: 'Get secret metadata by id (from list)', virtualGet: true, collectionPath: '/secrets', params: ['id'] },
415        create: { description: 'Create secret', method: 'POST', path: '/secrets' },
416        update: { description: 'Update secret metadata', method: 'PUT', path: '/secrets/:id', params: ['id'] },
417        delete: { description: 'Delete secret', method: 'DELETE', path: '/secrets/:id', params: ['id'] },
418      },
419    },
420    chats: {
421      description: 'Agent chats',
422      commands: {
423        list: { description: 'List chats', method: 'GET', path: '/chats' },
424        create: { description: 'Create chat', method: 'POST', path: '/chats' },
425        get: { description: 'Get chat by id', method: 'GET', path: '/chats/:id', params: ['id'] },
426        update: { description: 'Update chat fields', method: 'PUT', path: '/chats/:id', params: ['id'] },
427        delete: { description: 'Delete one chat', method: 'DELETE', path: '/chats/:id', params: ['id'] },
428        'delete-many': { description: 'Delete multiple chats (body: {"ids":[...]})', method: 'DELETE', path: '/chats' },
429        'heartbeat-disable-all': { description: 'Disable all chat heartbeats and cancel queued heartbeat runs', method: 'POST', path: '/chats/heartbeat' },
430        'migrate-messages': { description: 'Migrate messages from session blobs to relational table', method: 'POST', path: '/chats/migrate-messages' },
431        messages: { description: 'Get chat message history', method: 'GET', path: '/chats/:id/messages', params: ['id'] },
432        'messages-update': { description: 'Update chat message metadata (e.g. bookmark)', method: 'PUT', path: '/chats/:id/messages', params: ['id'] },
433        'messages-send': { description: 'Append a user/system message to a chat', method: 'POST', path: '/chats/:id/messages', params: ['id'] },
434        'messages-delete': { description: 'Delete a message from a chat', method: 'DELETE', path: '/chats/:id/messages', params: ['id'] },
435        'edit-resend': { description: 'Edit and resend from a specific message index', method: 'POST', path: '/chats/:id/edit-resend', params: ['id'] },
436        chat: { description: 'Send chat message (SSE stream)', method: 'POST', path: '/chats/:id/chat', params: ['id'], stream: true, waitable: true },
437        stop: { description: 'Cancel active/running chat work', method: 'POST', path: '/chats/:id/stop', params: ['id'] },
438        clear: { description: 'Clear chat history (returns undoToken with 30s TTL)', method: 'POST', path: '/chats/:id/clear', params: ['id'] },
439        'clear-undo': { description: 'Restore a cleared chat via its undoToken', method: 'POST', path: '/chats/:id/clear/undo', params: ['id'] },
440        compact: { description: 'Summarize and compact chat history', method: 'POST', path: '/chats/:id/compact', params: ['id'] },
441        'context-status': { description: 'Report token usage and context-window status', method: 'GET', path: '/chats/:id/context-status', params: ['id'] },
442        mailbox: { description: 'List mailbox envelopes for a chat', method: 'GET', path: '/chats/:id/mailbox', params: ['id'] },
443        'mailbox-action': { description: 'Send/ack/clear mailbox envelopes', method: 'POST', path: '/chats/:id/mailbox', params: ['id'] },
444        queue: { description: 'List queued follow-up turns for a chat', method: 'GET', path: '/chats/:id/queue', params: ['id'] },
445        'queue-add': { description: 'Enqueue a follow-up turn for a busy chat', method: 'POST', path: '/chats/:id/queue', params: ['id'] },
446        'queue-clear': { description: 'Remove queued follow-up turns from a chat', method: 'DELETE', path: '/chats/:id/queue', params: ['id'] },
447        deploy: { description: 'Deploy chat workspace git changes', method: 'POST', path: '/chats/:id/deploy', params: ['id'] },
448        devserver: { description: 'Start/stop/status dev server (body: {"action":"start|stop|status"})', method: 'POST', path: '/chats/:id/devserver', params: ['id'] },
449        browser: { description: 'Check browser runtime for chat', method: 'GET', path: '/chats/:id/browser', params: ['id'] },
450        'browser-clear': { description: 'Close browser runtime for chat', method: 'DELETE', path: '/chats/:id/browser', params: ['id'] },
451      },
452    },
453    settings: {
454      description: 'Global app settings',
455      commands: {
456        get: { description: 'Get settings', method: 'GET', path: '/settings' },
457        update: { description: 'Update settings', method: 'PUT', path: '/settings' },
458      },
459    },
460    setup: {
461      description: 'Setup and provider validation helpers',
462      commands: {
463        'check-provider': { description: 'Validate provider credentials/endpoint', method: 'POST', path: '/setup/check-provider' },
464        doctor: { description: 'Run local setup diagnostics', method: 'GET', path: '/setup/doctor' },
465      },
466    },
467    'learned-skills': {
468      description: 'Inspect agent-scoped learned skills',
469      commands: {
470        list: { description: 'List learned skills', method: 'GET', path: '/learned-skills' },
471        promote: { description: 'Promote a review-ready skill to active', method: 'POST', path: '/learned-skills/:id?action=promote', params: ['id'] },
472        dismiss: { description: 'Dismiss a learned skill', method: 'POST', path: '/learned-skills/:id?action=dismiss', params: ['id'] },
473        delete: { description: 'Delete a learned skill', method: 'DELETE', path: '/learned-skills/:id', params: ['id'] },
474        'review-counts': { description: 'Show pending review counts', method: 'GET', path: '/skill-review-counts' },
475      },
476    },
477    skills: {
478      description: 'SwarmClaw and Claude skills',
479      commands: {
480        list: { description: 'List SwarmClaw skills', method: 'GET', path: '/skills' },
481        get: { description: 'Get SwarmClaw skill by id', method: 'GET', path: '/skills/:id', params: ['id'] },
482        create: { description: 'Create SwarmClaw skill', method: 'POST', path: '/skills' },
483        update: { description: 'Update SwarmClaw skill', method: 'PUT', path: '/skills/:id', params: ['id'] },
484        delete: { description: 'Delete SwarmClaw skill', method: 'DELETE', path: '/skills/:id', params: ['id'] },
485        import: { description: 'Import skill from URL', method: 'POST', path: '/skills/import' },
486        claude: { description: 'List local ~/.claude/skills', method: 'GET', path: '/claude-skills' },
487      },
488    },
489    'skill-suggestions': {
490      description: 'Conversation-derived skill draft review',
491      commands: {
492        list: { description: 'List generated skill suggestions', method: 'GET', path: '/skill-suggestions' },
493        draft: { description: 'Generate or refresh a skill suggestion from a session', method: 'POST', path: '/skill-suggestions' },
494        approve: { description: 'Approve a skill suggestion and materialize it', method: 'POST', path: '/skill-suggestions/:id/approve', params: ['id'] },
495        reject: { description: 'Reject a skill suggestion draft', method: 'POST', path: '/skill-suggestions/:id/reject', params: ['id'] },
496      },
497    },
498    system: {
499      description: 'System and version endpoints',
500      commands: {
501        ip: { description: 'Get local bind IP/port', method: 'GET', path: '/ip' },
502        status: { description: 'Get lightweight system health summary (safe for external monitors)', method: 'GET', path: '/system/status' },
503        usage: { description: 'Get usage summary', method: 'GET', path: '/usage' },
504        version: { description: 'Get local/remote git version info', method: 'GET', path: '/version' },
505        update: { description: 'Update to latest stable release tag (fallback: main)', method: 'POST', path: '/version/update' },
506      },
507    },
508    tasks: {
509      description: 'Task board operations',
510      commands: {
511        list: { description: 'List tasks', method: 'GET', path: '/tasks' },
512        get: { description: 'Get task by id', method: 'GET', path: '/tasks/:id', params: ['id'] },
513        create: { description: 'Create task', method: 'POST', path: '/tasks' },
514        bulk: { description: 'Bulk update tasks (status/agent/project)', method: 'POST', path: '/tasks/bulk' },
515        update: { description: 'Update task', method: 'PUT', path: '/tasks/:id', params: ['id'] },
516        delete: { description: 'Archive task', method: 'DELETE', path: '/tasks/:id', params: ['id'] },
517        archive: { description: 'Archive task', method: 'DELETE', path: '/tasks/:id', params: ['id'] },
518        approve: { description: 'Approve or reject a pending tool execution', method: 'POST', path: '/tasks/:id/approve', params: ['id'] },
519        'import-github': { description: 'Import GitHub issues into tasks', method: 'POST', path: '/tasks/import/github' },
520        metrics: { description: 'Get task board metrics (supports --query range=24h|7d|30d)', method: 'GET', path: '/tasks/metrics' },
521      },
522    },
523    runs: {
524      description: 'Session run queue/history',
525      commands: {
526        list: { description: 'List runs (supports --query sessionId=,status=,limit=)', method: 'GET', path: '/runs' },
527        get: { description: 'Get run by id', method: 'GET', path: '/runs/:id', params: ['id'] },
528        events: { description: 'Get run event history by run id', method: 'GET', path: '/runs/:id/events', params: ['id'] },
529      },
530    },
531    webhooks: {
532      description: 'Inbound webhook triggers',
533      commands: {
534        trigger: { description: 'Trigger webhook by id', method: 'POST', path: '/webhooks/:id', params: ['id'], waitable: true },
535      },
536    },
537    portability: {
538      description: 'Export and import agent configurations',
539      commands: {
540        export: { description: 'Export agents, skills, and schedules as a portable JSON manifest', method: 'GET', path: '/portability/export' },
541        import: { description: 'Import a portable JSON manifest', method: 'POST', path: '/portability/import', body: true },
542      },
543    },
544    wallets: {
545      description: 'Manage agent wallets',
546      commands: {
547        list: { description: 'List wallets', method: 'GET', path: '/wallets' },
548        get: { description: 'Get wallet by id', method: 'GET', path: '/wallets/:id', params: ['id'] },
549        create: { description: 'Create a wallet', method: 'POST', path: '/wallets' },
550        generate: { description: 'Generate a new wallet for an agent', method: 'POST', path: '/wallets/generate', body: true },
551        update: { description: 'Update wallet settings', method: 'PATCH', path: '/wallets/:id', params: ['id'], body: true },
552        delete: { description: 'Delete a wallet', method: 'DELETE', path: '/wallets/:id', params: ['id'] },
553      },
554    },
555    goals: {
556      description: 'Manage goal hierarchy',
557      commands: {
558        list: { description: 'List goals', method: 'GET', path: '/goals' },
559        get: { description: 'Get goal by id', method: 'GET', path: '/goals/:id', params: ['id'] },
560        create: { description: 'Create a goal', method: 'POST', path: '/goals' },
561        update: { description: 'Update a goal', method: 'PATCH', path: '/goals/:id', params: ['id'], body: true },
562        delete: { description: 'Delete a goal', method: 'DELETE', path: '/goals/:id', params: ['id'] },
563      },
564    },
565    workspaces: {
566      description: 'Manage logical workspaces (multi-workspace scaffolding)',
567      commands: {
568        list: { description: 'List workspaces', method: 'GET', path: '/workspaces' },
569        create: { description: 'Create a workspace', method: 'POST', path: '/workspaces' },
570        update: { description: 'Update a workspace', method: 'PATCH', path: '/workspaces' },
571        delete: { description: 'Delete a workspace', method: 'DELETE', path: '/workspaces' },
572        active: { description: 'Get the active workspace', method: 'GET', path: '/workspaces/active' },
573        'set-active': { description: 'Set the active workspace', method: 'POST', path: '/workspaces/active' },
574      },
575    },
576    'workflow-states': {
577      description: 'Manage customizable task workflow states',
578      commands: {
579        list: { description: 'List workflow states', method: 'GET', path: '/task-workflow-states' },
580        create: { description: 'Create or update a workflow state', method: 'POST', path: '/task-workflow-states' },
581        delete: { description: 'Delete a workflow state (or pass --query reset=true to restore defaults)', method: 'DELETE', path: '/task-workflow-states' },
582      },
583    },
584    'config-versions': {
585      description: 'Inspect and restore configuration version history',
586      commands: {
587        list: { description: 'List versions for an entity (--query entityKind=agent,entityId=...)', method: 'GET', path: '/config-versions' },
588        restore: { description: 'Restore an entity to a prior version', method: 'POST', path: '/config-versions/restore' },
589      },
590    },
591    'cost-attribution': {
592      description: 'Aggregate cost by billing-code tags',
593      commands: {
594        'by-code': { description: 'Roll up cost by billing code (--query codes=foo,bar,range=7d)', method: 'GET', path: '/usage/by-code' },
595      },
596    },
597    'chatroom-policy': {
598      description: 'Configure chatroom delegation refusal policies',
599      commands: {
600        set: { description: 'Set onRefusal policy for a chatroom', method: 'POST', path: '/chatrooms/refusal-policy' },
601        simulate: { description: 'Simulate a refusal-handling decision', method: 'PUT', path: '/chatrooms/refusal-policy' },
602      },
603    },
604    missions: {
605      description: 'Manage autonomous missions',
606      commands: {
607        list: { description: 'List autonomous missions', method: 'GET', path: '/missions' },
608        get: { description: 'Get a mission by id', method: 'GET', path: '/missions/:id', params: ['id'] },
609        create: { description: 'Create an autonomous mission', method: 'POST', path: '/missions' },
610        update: { description: 'Update a mission', method: 'PUT', path: '/missions/:id', params: ['id'], body: true },
611        delete: { description: 'Delete a mission', method: 'DELETE', path: '/missions/:id', params: ['id'] },
612        control: { description: 'Start, pause, resume, cancel, complete, or fail a mission', method: 'POST', path: '/missions/:id/control', params: ['id'] },
613        reports: { description: 'List mission reports', method: 'GET', path: '/missions/:id/reports', params: ['id'] },
614        'report-now': { description: 'Force-generate a mission report now', method: 'POST', path: '/missions/:id/reports', params: ['id'] },
615        events: { description: 'List mission events', method: 'GET', path: '/missions/:id/events', params: ['id'] },
616        templates: { description: 'List built-in mission templates', method: 'GET', path: '/missions/templates' },
617        instantiate: { description: 'Create a mission from a template', method: 'POST', path: '/missions/templates/:id/instantiate', params: ['id'], body: true },
618      },
619    },
620  }
621  
622  const GROUP_NAMES = Object.keys(COMMAND_GROUPS)
623  
624  function listCoveredRoutes() {
625    const routes = []
626    for (const group of GROUP_NAMES) {
627      const commands = COMMAND_GROUPS[group].commands
628      for (const action of Object.keys(commands)) {
629        const cmd = commands[action]
630        if (cmd.method && cmd.path) {
631          routes.push(`${cmd.method.toUpperCase()} ${cmd.path.split('?')[0]}`)
632        }
633      }
634    }
635    return routes
636  }
637  
638  module.exports = {
639    COMMAND_GROUPS,
640    GROUP_NAMES,
641    listCoveredRoutes,
642  }