@desplega.ai/agent-swarm 1.110.0 → 1.112.0

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.
Files changed (119) hide show
  1. package/README.md +1 -1
  2. package/dist/{actions-837ktebk.js → actions-eckb4g8r.js} +6 -6
  3. package/dist/{app-85h97pg2.js → app-b05sgm02.js} +3 -3
  4. package/dist/{assistant-yhrta0c5.js → assistant-7255sbyw.js} +9 -9
  5. package/dist/{boot-reembed-5sd1t9r4.js → boot-reembed-y1bt3ttn.js} +4 -4
  6. package/dist/{boot-reembed-8xmfv2pq.js → boot-reembed-yv7awg4y.js} +3 -3
  7. package/dist/{boot-scrub-logs-fdw8wbtq.js → boot-scrub-logs-ddyaeqar.js} +2 -2
  8. package/dist/{claude-managed-setup-yhbcx0bz.js → claude-managed-setup-cm05wtek.js} +1 -1
  9. package/dist/{cli-8ps5wsk9.js → cli-0c3n0eba.js} +1 -1
  10. package/dist/{cli-kna0r84e.js → cli-15598a4k.js} +599 -51
  11. package/dist/{cli-8s0swp2t.js → cli-30d2ct3k.js} +3 -3
  12. package/dist/{cli-2h86bsfe.js → cli-3r5y6ayj.js} +2 -2
  13. package/dist/{cli-6ttdv68b.js → cli-52tbq17n.js} +1 -1
  14. package/dist/{cli-k6ssh5dk.js → cli-56s4ehzw.js} +1 -1
  15. package/dist/{cli-m3enfr8q.js → cli-6wscj9z0.js} +4 -4
  16. package/dist/{cli-5kav4x1a.js → cli-709t753c.js} +7 -2
  17. package/dist/{cli-g44ffxk5.js → cli-76d1vtvq.js} +11 -2
  18. package/dist/{cli-gb7dqnna.js → cli-7xkwgkrs.js} +1 -1
  19. package/dist/{cli-kg9v8h1w.js → cli-8f0dwca2.js} +1 -1
  20. package/dist/{cli-zw3cmjh6.js → cli-94vzr3nq.js} +4 -4
  21. package/dist/{cli-d8vmtyyr.js → cli-951w7c79.js} +1 -1
  22. package/dist/{cli-dhph6q98.js → cli-9p0qhead.js} +1 -1
  23. package/dist/{cli-vfyhrk9k.js → cli-a5e8n5hg.js} +1 -1
  24. package/dist/{cli-w6zp4qcx.js → cli-ceewqajw.js} +37 -39
  25. package/dist/{cli-r19ttke3.js → cli-h9jx5mag.js} +4 -4
  26. package/dist/{cli-4trfcacj.js → cli-hm27prrc.js} +5 -5
  27. package/dist/{cli-gtt1f14h.js → cli-pt7c7qxz.js} +3 -3
  28. package/dist/{cli-sjm0e1pa.js → cli-r1btc895.js} +2 -2
  29. package/dist/{cli-3baz70yp.js → cli-rp8pca98.js} +1 -1
  30. package/dist/{cli-dy01kwxk.js → cli-s9pj3c7z.js} +2 -2
  31. package/dist/{cli-0pzg1f8z.js → cli-tch0ypp6.js} +71 -24
  32. package/dist/{cli-3t97r3y1.js → cli-tg0f2wmz.js} +5 -5
  33. package/dist/{cli-amncg1dq.js → cli-tk9vyqzh.js} +66 -9
  34. package/dist/{cli-cwety9qq.js → cli-tp7e60s3.js} +4 -2
  35. package/dist/cli.js +11 -11
  36. package/dist/{codex-adapter-ebs12jef.js → codex-adapter-5cmy858w.js} +3 -3
  37. package/dist/{codex-login-4sywkz6v.js → codex-login-0h18cy3e.js} +1 -1
  38. package/dist/{codex-session-runner-3bx0b1hn.js → codex-session-runner-46q8mrba.js} +3 -3
  39. package/dist/{commands-3fh75nzv.js → commands-14g7taf4.js} +2 -2
  40. package/dist/{db-kwfxkhpw.js → db-3tge4jrn.js} +2 -2
  41. package/dist/{handlers-jj8rzetb.js → handlers-sy64egg6.js} +9 -9
  42. package/dist/{hook-1b45zzz1.js → hook-rnkzw8vp.js} +3 -3
  43. package/dist/{http-71964f7a.js → http-xx9xptcs.js} +234 -37
  44. package/dist/{index-e01wmtj0.js → index-3wr6v2mm.js} +7 -7
  45. package/dist/{index-464v93y6.js → index-brma88d4.js} +9 -9
  46. package/dist/{index-c35g752k.js → index-ha8e9xn2.js} +7 -11
  47. package/dist/{index-zm0x6vmf.js → index-zfx5p959.js} +8 -8
  48. package/dist/{keepalive-2gxqjgrx.js → keepalive-rbz05zad.js} +4 -4
  49. package/dist/{lead-twm4zp8y.js → lead-s790v7r0.js} +20 -20
  50. package/dist/{maintenance-1htsnyz6.js → maintenance-420rmadb.js} +4 -4
  51. package/dist/{onboard-1y1pdzt5.js → onboard-jgqamqnw.js} +2 -2
  52. package/dist/{otel-impl-pw9tnc80.js → otel-impl-ch3n3783.js} +1 -1
  53. package/dist/{pi-mono-adapter-ayr3akk8.js → pi-mono-adapter-kxjxpfgy.js} +2 -2
  54. package/dist/{pricing-refresh-tqvvrk7a.js → pricing-refresh-rmtrby6h.js} +4 -4
  55. package/dist/{seed-pricing-f23sehzq.js → seed-pricing-1szjzfj1.js} +3 -3
  56. package/dist/{setup-jtw9rz9t.js → setup-8jfzkyzv.js} +2 -2
  57. package/dist/{worker-jxrmzwb9.js → worker-40vq0pm8.js} +20 -20
  58. package/openapi.json +1010 -2
  59. package/package.json +1 -1
  60. package/src/be/memory/constants.ts +7 -0
  61. package/src/be/memory/graph-expansion.ts +167 -0
  62. package/src/be/memory/link-resolver.ts +81 -17
  63. package/src/be/memory/links-store.ts +208 -0
  64. package/src/be/memory/providers/sqlite-store.ts +2 -2
  65. package/src/be/memory/raters/retrieval.ts +2 -1
  66. package/src/be/memory/types.ts +1 -1
  67. package/src/be/memory/usefulness-stats.ts +259 -0
  68. package/src/be/migrations/107_memory_usefulness_indexes.sql +12 -0
  69. package/src/be/scripts/typecheck.ts +2 -0
  70. package/src/be/seed-scripts/catalog/smart-recall.ts +1 -5
  71. package/src/commands/runner.ts +154 -8
  72. package/src/github/handlers.ts +128 -25
  73. package/src/github/mentions-aliases.test.ts +4 -3
  74. package/src/http/codex-oauth-keep-warm.ts +107 -0
  75. package/src/http/index.ts +2 -0
  76. package/src/http/memory.ts +73 -6
  77. package/src/providers/codex-adapter.ts +66 -2
  78. package/src/providers/codex-oauth/auth-json.ts +18 -9
  79. package/src/providers/codex-oauth/flow.ts +1 -1
  80. package/src/providers/codex-oauth/storage.ts +88 -6
  81. package/src/providers/codex-oauth/types.ts +1 -1
  82. package/src/scripts-runtime/sdk-allowlist.ts +2 -0
  83. package/src/scripts-runtime/types/swarm-sdk.d.ts +2 -0
  84. package/src/server.ts +4 -0
  85. package/src/slack/message-text.ts +25 -0
  86. package/src/tests/codex-adapter-pool-auth-revalidate.test.ts +113 -11
  87. package/src/tests/codex-adapter.test.ts +27 -0
  88. package/src/tests/codex-oauth-keep-warm.test.ts +268 -0
  89. package/src/tests/codex-oauth-refresh-lock.test.ts +4 -4
  90. package/src/tests/codex-oauth-storage.test.ts +149 -6
  91. package/src/tests/codex-oauth.test.ts +12 -0
  92. package/src/tests/create-page-tool.test.ts +7 -0
  93. package/src/tests/entrypoint-codex-oauth-seed.test.ts +124 -0
  94. package/src/tests/github-event-filter.test.ts +3 -2
  95. package/src/tests/github-handlers-inline-comments.test.ts +114 -24
  96. package/src/tests/jira-webhook-lifecycle.test.ts +7 -0
  97. package/src/tests/memory-edit.test.ts +95 -0
  98. package/src/tests/memory-get-tool.test.ts +138 -0
  99. package/src/tests/memory-graph-expansion.test.ts +421 -0
  100. package/src/tests/memory-http-recall-gating.test.ts +13 -0
  101. package/src/tests/memory-link-resolver.test.ts +228 -2
  102. package/src/tests/memory-usefulness-endpoint.test.ts +392 -0
  103. package/src/tests/runner-repo-autostash.test.ts +168 -1
  104. package/src/tests/script-workflows-runtime-e2e.test.ts +1 -0
  105. package/src/tests/slack-delete.test.ts +157 -0
  106. package/src/tests/slack-message-text.test.ts +37 -1
  107. package/src/tests/slack-update.test.ts +167 -0
  108. package/src/tests/slack-upload-file.test.ts +135 -0
  109. package/src/tests/tool-annotations.test.ts +3 -0
  110. package/src/tools/inject-learning.ts +1 -0
  111. package/src/tools/memory-edit.ts +3 -2
  112. package/src/tools/memory-get.ts +66 -1
  113. package/src/tools/memory-search.ts +13 -3
  114. package/src/tools/slack-delete.ts +102 -0
  115. package/src/tools/slack-reply.ts +11 -3
  116. package/src/tools/slack-start-thread.ts +2 -0
  117. package/src/tools/slack-update.ts +127 -0
  118. package/src/tools/slack-upload-file.ts +11 -1
  119. package/src/tools/tool-config.ts +3 -1
package/openapi.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "openapi": "3.1.0",
3
3
  "info": {
4
4
  "title": "Agent Swarm API",
5
- "version": "1.110.0",
5
+ "version": "1.112.0",
6
6
  "description": "Multi-agent orchestration API for Claude Code, Codex, and Gemini CLI. Enables task distribution, agent communication, and service discovery.\n\nMCP tools are documented separately in [MCP.md](./MCP.md)."
7
7
  },
8
8
  "servers": [
@@ -1947,6 +1947,25 @@
1947
1947
  }
1948
1948
  }
1949
1949
  },
1950
+ "/api/oauth/keep-warm/codex": {
1951
+ "post": {
1952
+ "summary": "Locked keep-warm refresh sweep across all Codex OAuth pool slots",
1953
+ "description": "Enumerates codex_oauth_* slots and refreshes any older than ~7 days through the same locked getValidCodexOAuth path used at task time. Skips slots already benched by codex-auth-expiry-watch.",
1954
+ "tags": [
1955
+ "OAuth"
1956
+ ],
1957
+ "security": [
1958
+ {
1959
+ "bearerAuth": []
1960
+ }
1961
+ ],
1962
+ "responses": {
1963
+ "200": {
1964
+ "description": "Per-slot keep-warm outcomes"
1965
+ }
1966
+ }
1967
+ }
1968
+ },
1950
1969
  "/api/config/resolved": {
1951
1970
  "get": {
1952
1971
  "summary": "Get resolved config (merged global + agent + repo scopes)",
@@ -4940,6 +4959,58 @@
4940
4959
  }
4941
4960
  }
4942
4961
  },
4962
+ "/api/memory/usefulness": {
4963
+ "get": {
4964
+ "summary": "Windowed memory usefulness analytics: retrieval volume, per-arm breakdown, citation rate per source, posterior movement",
4965
+ "tags": [
4966
+ "Memory"
4967
+ ],
4968
+ "security": [
4969
+ {
4970
+ "bearerAuth": []
4971
+ }
4972
+ ],
4973
+ "parameters": [
4974
+ {
4975
+ "schema": {
4976
+ "type": "integer",
4977
+ "minimum": 1,
4978
+ "maximum": 365,
4979
+ "default": 30,
4980
+ "description": "Analysis window in days (default 30)"
4981
+ },
4982
+ "required": false,
4983
+ "description": "Analysis window in days (default 30)",
4984
+ "name": "days",
4985
+ "in": "query"
4986
+ },
4987
+ {
4988
+ "schema": {
4989
+ "type": [
4990
+ "number",
4991
+ "null"
4992
+ ],
4993
+ "minimum": 0,
4994
+ "maximum": 1,
4995
+ "default": 0.6,
4996
+ "description": "Posterior-mean threshold for the aboveThreshold count (default 0.6)"
4997
+ },
4998
+ "required": false,
4999
+ "description": "Posterior-mean threshold for the aboveThreshold count (default 0.6)",
5000
+ "name": "threshold",
5001
+ "in": "query"
5002
+ }
5003
+ ],
5004
+ "responses": {
5005
+ "200": {
5006
+ "description": "Usefulness stats for the window"
5007
+ },
5008
+ "400": {
5009
+ "description": "Validation error"
5010
+ }
5011
+ }
5012
+ }
5013
+ },
4943
5014
  "/api/memory/{id}": {
4944
5015
  "delete": {
4945
5016
  "summary": "Delete a single memory by ID (debug/admin)",
@@ -5005,7 +5076,7 @@
5005
5076
  ],
5006
5077
  "responses": {
5007
5078
  "200": {
5008
- "description": "Memory details"
5079
+ "description": "Memory details, plus `links` (outgoing memory_link rows; memory-kind targets carry `resolved` + ACL-filtered `target` metadata) and `backlinks` (inbound links from other memories, ACL-filtered)"
5009
5080
  },
5010
5081
  "404": {
5011
5082
  "description": "Memory not found"
@@ -5174,6 +5245,943 @@
5174
5245
  }
5175
5246
  }
5176
5247
  },
5248
+ "/api/metrics/definitions": {
5249
+ "post": {
5250
+ "summary": "Create a metric definition",
5251
+ "tags": [
5252
+ "Metrics"
5253
+ ],
5254
+ "security": [
5255
+ {
5256
+ "bearerAuth": []
5257
+ }
5258
+ ],
5259
+ "requestBody": {
5260
+ "content": {
5261
+ "application/json": {
5262
+ "schema": {
5263
+ "type": "object",
5264
+ "properties": {
5265
+ "slug": {
5266
+ "type": "string",
5267
+ "minLength": 1
5268
+ },
5269
+ "title": {
5270
+ "type": "string",
5271
+ "minLength": 1
5272
+ },
5273
+ "description": {
5274
+ "type": [
5275
+ "string",
5276
+ "null"
5277
+ ]
5278
+ },
5279
+ "definition": {
5280
+ "type": "object",
5281
+ "properties": {
5282
+ "version": {
5283
+ "type": "number",
5284
+ "enum": [
5285
+ 1
5286
+ ]
5287
+ },
5288
+ "widgets": {
5289
+ "type": "array",
5290
+ "items": {
5291
+ "type": "object",
5292
+ "properties": {
5293
+ "id": {
5294
+ "type": "string",
5295
+ "minLength": 1
5296
+ },
5297
+ "title": {
5298
+ "type": "string",
5299
+ "minLength": 1
5300
+ },
5301
+ "description": {
5302
+ "type": "string"
5303
+ },
5304
+ "query": {
5305
+ "type": "object",
5306
+ "properties": {
5307
+ "sql": {
5308
+ "type": "string",
5309
+ "minLength": 1,
5310
+ "maxLength": 10000
5311
+ },
5312
+ "params": {
5313
+ "type": "array",
5314
+ "items": {
5315
+ "anyOf": [
5316
+ {
5317
+ "type": "string"
5318
+ },
5319
+ {
5320
+ "type": "number"
5321
+ },
5322
+ {
5323
+ "type": "boolean"
5324
+ },
5325
+ {
5326
+ "type": "null"
5327
+ }
5328
+ ]
5329
+ }
5330
+ },
5331
+ "maxRows": {
5332
+ "type": "integer",
5333
+ "minimum": 1,
5334
+ "maximum": 500
5335
+ }
5336
+ },
5337
+ "required": [
5338
+ "sql"
5339
+ ]
5340
+ },
5341
+ "viz": {
5342
+ "type": "object",
5343
+ "properties": {
5344
+ "type": {
5345
+ "type": "string",
5346
+ "enum": [
5347
+ "stat",
5348
+ "table",
5349
+ "bar",
5350
+ "line",
5351
+ "multi-bar",
5352
+ "multi-line"
5353
+ ]
5354
+ },
5355
+ "x": {
5356
+ "type": "string"
5357
+ },
5358
+ "y": {
5359
+ "type": "string"
5360
+ },
5361
+ "series": {
5362
+ "type": "array",
5363
+ "items": {
5364
+ "type": "string"
5365
+ }
5366
+ },
5367
+ "label": {
5368
+ "type": "string"
5369
+ },
5370
+ "value": {
5371
+ "type": "string"
5372
+ },
5373
+ "columns": {
5374
+ "type": "array",
5375
+ "items": {
5376
+ "type": "object",
5377
+ "properties": {
5378
+ "key": {
5379
+ "type": "string"
5380
+ },
5381
+ "label": {
5382
+ "type": "string"
5383
+ },
5384
+ "format": {
5385
+ "type": "string",
5386
+ "enum": [
5387
+ "number",
5388
+ "integer",
5389
+ "currency",
5390
+ "percent",
5391
+ "duration"
5392
+ ]
5393
+ }
5394
+ },
5395
+ "required": [
5396
+ "key"
5397
+ ]
5398
+ }
5399
+ },
5400
+ "format": {
5401
+ "type": "string",
5402
+ "enum": [
5403
+ "number",
5404
+ "integer",
5405
+ "currency",
5406
+ "percent",
5407
+ "duration"
5408
+ ]
5409
+ }
5410
+ },
5411
+ "required": [
5412
+ "type"
5413
+ ]
5414
+ },
5415
+ "colSpan": {
5416
+ "type": "integer",
5417
+ "minimum": 1,
5418
+ "maximum": 4
5419
+ },
5420
+ "rowSpan": {
5421
+ "type": "integer",
5422
+ "minimum": 1,
5423
+ "maximum": 4
5424
+ }
5425
+ },
5426
+ "required": [
5427
+ "id",
5428
+ "title",
5429
+ "query",
5430
+ "viz"
5431
+ ]
5432
+ },
5433
+ "minItems": 1,
5434
+ "maxItems": 24
5435
+ },
5436
+ "variables": {
5437
+ "type": "array",
5438
+ "items": {
5439
+ "type": "object",
5440
+ "properties": {
5441
+ "key": {
5442
+ "type": "string",
5443
+ "minLength": 1,
5444
+ "pattern": "^[a-zA-Z][a-zA-Z0-9_]*$"
5445
+ },
5446
+ "label": {
5447
+ "type": "string",
5448
+ "minLength": 1
5449
+ },
5450
+ "type": {
5451
+ "type": "string",
5452
+ "enum": [
5453
+ "text",
5454
+ "number",
5455
+ "select"
5456
+ ],
5457
+ "default": "text"
5458
+ },
5459
+ "defaultValue": {
5460
+ "anyOf": [
5461
+ {
5462
+ "type": "string"
5463
+ },
5464
+ {
5465
+ "type": "number"
5466
+ },
5467
+ {
5468
+ "type": "boolean"
5469
+ },
5470
+ {
5471
+ "type": "null"
5472
+ }
5473
+ ]
5474
+ },
5475
+ "options": {
5476
+ "type": "array",
5477
+ "items": {
5478
+ "type": "object",
5479
+ "properties": {
5480
+ "label": {
5481
+ "type": "string",
5482
+ "minLength": 1
5483
+ },
5484
+ "value": {
5485
+ "anyOf": [
5486
+ {
5487
+ "type": "string"
5488
+ },
5489
+ {
5490
+ "type": "number"
5491
+ },
5492
+ {
5493
+ "type": "boolean"
5494
+ },
5495
+ {
5496
+ "type": "null"
5497
+ }
5498
+ ]
5499
+ }
5500
+ },
5501
+ "required": [
5502
+ "label",
5503
+ "value"
5504
+ ]
5505
+ }
5506
+ },
5507
+ "optionsQuery": {
5508
+ "type": "object",
5509
+ "properties": {
5510
+ "sql": {
5511
+ "type": "string",
5512
+ "minLength": 1,
5513
+ "maxLength": 10000
5514
+ },
5515
+ "valueKey": {
5516
+ "type": "string",
5517
+ "minLength": 1
5518
+ },
5519
+ "labelKey": {
5520
+ "type": "string",
5521
+ "minLength": 1
5522
+ }
5523
+ },
5524
+ "required": [
5525
+ "sql",
5526
+ "valueKey"
5527
+ ]
5528
+ }
5529
+ },
5530
+ "required": [
5531
+ "key"
5532
+ ]
5533
+ },
5534
+ "maxItems": 12
5535
+ },
5536
+ "layout": {
5537
+ "type": "object",
5538
+ "properties": {
5539
+ "columns": {
5540
+ "type": "integer",
5541
+ "minimum": 1,
5542
+ "maximum": 4
5543
+ }
5544
+ }
5545
+ },
5546
+ "refreshSeconds": {
5547
+ "type": "integer",
5548
+ "minimum": 5,
5549
+ "maximum": 3600
5550
+ }
5551
+ },
5552
+ "required": [
5553
+ "version",
5554
+ "widgets"
5555
+ ]
5556
+ }
5557
+ },
5558
+ "required": [
5559
+ "title",
5560
+ "definition"
5561
+ ]
5562
+ }
5563
+ }
5564
+ }
5565
+ },
5566
+ "responses": {
5567
+ "201": {
5568
+ "description": "Metric created"
5569
+ },
5570
+ "400": {
5571
+ "description": "Invalid metric definition"
5572
+ },
5573
+ "409": {
5574
+ "description": "Slug already exists for this agent"
5575
+ }
5576
+ }
5577
+ },
5578
+ "get": {
5579
+ "summary": "List metric definitions",
5580
+ "tags": [
5581
+ "Metrics"
5582
+ ],
5583
+ "security": [
5584
+ {
5585
+ "bearerAuth": []
5586
+ }
5587
+ ],
5588
+ "parameters": [
5589
+ {
5590
+ "schema": {
5591
+ "type": "string",
5592
+ "minLength": 1
5593
+ },
5594
+ "required": false,
5595
+ "name": "agentId",
5596
+ "in": "query"
5597
+ },
5598
+ {
5599
+ "schema": {
5600
+ "type": "integer",
5601
+ "minimum": 1,
5602
+ "maximum": 500
5603
+ },
5604
+ "required": false,
5605
+ "name": "limit",
5606
+ "in": "query"
5607
+ },
5608
+ {
5609
+ "schema": {
5610
+ "type": [
5611
+ "integer",
5612
+ "null"
5613
+ ],
5614
+ "minimum": 0
5615
+ },
5616
+ "required": false,
5617
+ "name": "offset",
5618
+ "in": "query"
5619
+ },
5620
+ {
5621
+ "schema": {
5622
+ "type": "string",
5623
+ "enum": [
5624
+ "full",
5625
+ "slim"
5626
+ ]
5627
+ },
5628
+ "required": false,
5629
+ "name": "fields",
5630
+ "in": "query"
5631
+ }
5632
+ ],
5633
+ "responses": {
5634
+ "200": {
5635
+ "description": "Metric definitions"
5636
+ }
5637
+ }
5638
+ }
5639
+ },
5640
+ "/api/metrics/definitions/{id}": {
5641
+ "get": {
5642
+ "summary": "Get a metric definition",
5643
+ "tags": [
5644
+ "Metrics"
5645
+ ],
5646
+ "security": [
5647
+ {
5648
+ "bearerAuth": []
5649
+ }
5650
+ ],
5651
+ "parameters": [
5652
+ {
5653
+ "schema": {
5654
+ "type": "string"
5655
+ },
5656
+ "required": true,
5657
+ "name": "id",
5658
+ "in": "path"
5659
+ }
5660
+ ],
5661
+ "responses": {
5662
+ "200": {
5663
+ "description": "Metric definition"
5664
+ },
5665
+ "404": {
5666
+ "description": "Metric not found"
5667
+ }
5668
+ }
5669
+ },
5670
+ "put": {
5671
+ "summary": "Update a metric definition",
5672
+ "tags": [
5673
+ "Metrics"
5674
+ ],
5675
+ "security": [
5676
+ {
5677
+ "bearerAuth": []
5678
+ }
5679
+ ],
5680
+ "parameters": [
5681
+ {
5682
+ "schema": {
5683
+ "type": "string"
5684
+ },
5685
+ "required": true,
5686
+ "name": "id",
5687
+ "in": "path"
5688
+ }
5689
+ ],
5690
+ "requestBody": {
5691
+ "content": {
5692
+ "application/json": {
5693
+ "schema": {
5694
+ "type": "object",
5695
+ "properties": {
5696
+ "slug": {
5697
+ "type": "string",
5698
+ "minLength": 1
5699
+ },
5700
+ "title": {
5701
+ "type": "string",
5702
+ "minLength": 1
5703
+ },
5704
+ "description": {
5705
+ "type": [
5706
+ "string",
5707
+ "null"
5708
+ ]
5709
+ },
5710
+ "definition": {
5711
+ "type": "object",
5712
+ "properties": {
5713
+ "version": {
5714
+ "type": "number",
5715
+ "enum": [
5716
+ 1
5717
+ ]
5718
+ },
5719
+ "widgets": {
5720
+ "type": "array",
5721
+ "items": {
5722
+ "type": "object",
5723
+ "properties": {
5724
+ "id": {
5725
+ "type": "string",
5726
+ "minLength": 1
5727
+ },
5728
+ "title": {
5729
+ "type": "string",
5730
+ "minLength": 1
5731
+ },
5732
+ "description": {
5733
+ "type": "string"
5734
+ },
5735
+ "query": {
5736
+ "type": "object",
5737
+ "properties": {
5738
+ "sql": {
5739
+ "type": "string",
5740
+ "minLength": 1,
5741
+ "maxLength": 10000
5742
+ },
5743
+ "params": {
5744
+ "type": "array",
5745
+ "items": {
5746
+ "anyOf": [
5747
+ {
5748
+ "type": "string"
5749
+ },
5750
+ {
5751
+ "type": "number"
5752
+ },
5753
+ {
5754
+ "type": "boolean"
5755
+ },
5756
+ {
5757
+ "type": "null"
5758
+ }
5759
+ ]
5760
+ }
5761
+ },
5762
+ "maxRows": {
5763
+ "type": "integer",
5764
+ "minimum": 1,
5765
+ "maximum": 500
5766
+ }
5767
+ },
5768
+ "required": [
5769
+ "sql"
5770
+ ]
5771
+ },
5772
+ "viz": {
5773
+ "type": "object",
5774
+ "properties": {
5775
+ "type": {
5776
+ "type": "string",
5777
+ "enum": [
5778
+ "stat",
5779
+ "table",
5780
+ "bar",
5781
+ "line",
5782
+ "multi-bar",
5783
+ "multi-line"
5784
+ ]
5785
+ },
5786
+ "x": {
5787
+ "type": "string"
5788
+ },
5789
+ "y": {
5790
+ "type": "string"
5791
+ },
5792
+ "series": {
5793
+ "type": "array",
5794
+ "items": {
5795
+ "type": "string"
5796
+ }
5797
+ },
5798
+ "label": {
5799
+ "type": "string"
5800
+ },
5801
+ "value": {
5802
+ "type": "string"
5803
+ },
5804
+ "columns": {
5805
+ "type": "array",
5806
+ "items": {
5807
+ "type": "object",
5808
+ "properties": {
5809
+ "key": {
5810
+ "type": "string"
5811
+ },
5812
+ "label": {
5813
+ "type": "string"
5814
+ },
5815
+ "format": {
5816
+ "type": "string",
5817
+ "enum": [
5818
+ "number",
5819
+ "integer",
5820
+ "currency",
5821
+ "percent",
5822
+ "duration"
5823
+ ]
5824
+ }
5825
+ },
5826
+ "required": [
5827
+ "key"
5828
+ ]
5829
+ }
5830
+ },
5831
+ "format": {
5832
+ "type": "string",
5833
+ "enum": [
5834
+ "number",
5835
+ "integer",
5836
+ "currency",
5837
+ "percent",
5838
+ "duration"
5839
+ ]
5840
+ }
5841
+ },
5842
+ "required": [
5843
+ "type"
5844
+ ]
5845
+ },
5846
+ "colSpan": {
5847
+ "type": "integer",
5848
+ "minimum": 1,
5849
+ "maximum": 4
5850
+ },
5851
+ "rowSpan": {
5852
+ "type": "integer",
5853
+ "minimum": 1,
5854
+ "maximum": 4
5855
+ }
5856
+ },
5857
+ "required": [
5858
+ "id",
5859
+ "title",
5860
+ "query",
5861
+ "viz"
5862
+ ]
5863
+ },
5864
+ "minItems": 1,
5865
+ "maxItems": 24
5866
+ },
5867
+ "variables": {
5868
+ "type": "array",
5869
+ "items": {
5870
+ "type": "object",
5871
+ "properties": {
5872
+ "key": {
5873
+ "type": "string",
5874
+ "minLength": 1,
5875
+ "pattern": "^[a-zA-Z][a-zA-Z0-9_]*$"
5876
+ },
5877
+ "label": {
5878
+ "type": "string",
5879
+ "minLength": 1
5880
+ },
5881
+ "type": {
5882
+ "type": "string",
5883
+ "enum": [
5884
+ "text",
5885
+ "number",
5886
+ "select"
5887
+ ],
5888
+ "default": "text"
5889
+ },
5890
+ "defaultValue": {
5891
+ "anyOf": [
5892
+ {
5893
+ "type": "string"
5894
+ },
5895
+ {
5896
+ "type": "number"
5897
+ },
5898
+ {
5899
+ "type": "boolean"
5900
+ },
5901
+ {
5902
+ "type": "null"
5903
+ }
5904
+ ]
5905
+ },
5906
+ "options": {
5907
+ "type": "array",
5908
+ "items": {
5909
+ "type": "object",
5910
+ "properties": {
5911
+ "label": {
5912
+ "type": "string",
5913
+ "minLength": 1
5914
+ },
5915
+ "value": {
5916
+ "anyOf": [
5917
+ {
5918
+ "type": "string"
5919
+ },
5920
+ {
5921
+ "type": "number"
5922
+ },
5923
+ {
5924
+ "type": "boolean"
5925
+ },
5926
+ {
5927
+ "type": "null"
5928
+ }
5929
+ ]
5930
+ }
5931
+ },
5932
+ "required": [
5933
+ "label",
5934
+ "value"
5935
+ ]
5936
+ }
5937
+ },
5938
+ "optionsQuery": {
5939
+ "type": "object",
5940
+ "properties": {
5941
+ "sql": {
5942
+ "type": "string",
5943
+ "minLength": 1,
5944
+ "maxLength": 10000
5945
+ },
5946
+ "valueKey": {
5947
+ "type": "string",
5948
+ "minLength": 1
5949
+ },
5950
+ "labelKey": {
5951
+ "type": "string",
5952
+ "minLength": 1
5953
+ }
5954
+ },
5955
+ "required": [
5956
+ "sql",
5957
+ "valueKey"
5958
+ ]
5959
+ }
5960
+ },
5961
+ "required": [
5962
+ "key"
5963
+ ]
5964
+ },
5965
+ "maxItems": 12
5966
+ },
5967
+ "layout": {
5968
+ "type": "object",
5969
+ "properties": {
5970
+ "columns": {
5971
+ "type": "integer",
5972
+ "minimum": 1,
5973
+ "maximum": 4
5974
+ }
5975
+ }
5976
+ },
5977
+ "refreshSeconds": {
5978
+ "type": "integer",
5979
+ "minimum": 5,
5980
+ "maximum": 3600
5981
+ }
5982
+ },
5983
+ "required": [
5984
+ "version",
5985
+ "widgets"
5986
+ ]
5987
+ }
5988
+ }
5989
+ }
5990
+ }
5991
+ }
5992
+ },
5993
+ "responses": {
5994
+ "200": {
5995
+ "description": "Metric updated"
5996
+ },
5997
+ "404": {
5998
+ "description": "Metric not found"
5999
+ }
6000
+ }
6001
+ },
6002
+ "delete": {
6003
+ "summary": "Delete a metric definition",
6004
+ "tags": [
6005
+ "Metrics"
6006
+ ],
6007
+ "security": [
6008
+ {
6009
+ "bearerAuth": []
6010
+ }
6011
+ ],
6012
+ "parameters": [
6013
+ {
6014
+ "schema": {
6015
+ "type": "string"
6016
+ },
6017
+ "required": true,
6018
+ "name": "id",
6019
+ "in": "path"
6020
+ }
6021
+ ],
6022
+ "responses": {
6023
+ "204": {
6024
+ "description": "Metric deleted"
6025
+ },
6026
+ "404": {
6027
+ "description": "Metric not found"
6028
+ }
6029
+ }
6030
+ }
6031
+ },
6032
+ "/api/metrics/definitions/{id}/run": {
6033
+ "post": {
6034
+ "summary": "Run a metric definition",
6035
+ "tags": [
6036
+ "Metrics"
6037
+ ],
6038
+ "security": [
6039
+ {
6040
+ "bearerAuth": []
6041
+ }
6042
+ ],
6043
+ "parameters": [
6044
+ {
6045
+ "schema": {
6046
+ "type": "string"
6047
+ },
6048
+ "required": true,
6049
+ "name": "id",
6050
+ "in": "path"
6051
+ }
6052
+ ],
6053
+ "requestBody": {
6054
+ "content": {
6055
+ "application/json": {
6056
+ "schema": {
6057
+ "type": "object",
6058
+ "properties": {
6059
+ "variables": {
6060
+ "type": "object",
6061
+ "additionalProperties": {
6062
+ "anyOf": [
6063
+ {
6064
+ "type": "string"
6065
+ },
6066
+ {
6067
+ "type": "number"
6068
+ },
6069
+ {
6070
+ "type": "boolean"
6071
+ },
6072
+ {
6073
+ "type": "null"
6074
+ }
6075
+ ]
6076
+ }
6077
+ }
6078
+ }
6079
+ }
6080
+ }
6081
+ }
6082
+ },
6083
+ "responses": {
6084
+ "200": {
6085
+ "description": "Metric result"
6086
+ },
6087
+ "400": {
6088
+ "description": "Invalid or disallowed query"
6089
+ },
6090
+ "404": {
6091
+ "description": "Metric not found"
6092
+ }
6093
+ }
6094
+ }
6095
+ },
6096
+ "/api/metrics/definitions/{id}/versions": {
6097
+ "get": {
6098
+ "summary": "List metric definition versions",
6099
+ "tags": [
6100
+ "Metrics"
6101
+ ],
6102
+ "security": [
6103
+ {
6104
+ "bearerAuth": []
6105
+ }
6106
+ ],
6107
+ "parameters": [
6108
+ {
6109
+ "schema": {
6110
+ "type": "string"
6111
+ },
6112
+ "required": true,
6113
+ "name": "id",
6114
+ "in": "path"
6115
+ }
6116
+ ],
6117
+ "responses": {
6118
+ "200": {
6119
+ "description": "Metric version list"
6120
+ },
6121
+ "404": {
6122
+ "description": "Metric not found"
6123
+ }
6124
+ }
6125
+ }
6126
+ },
6127
+ "/api/metrics/definitions/{id}/versions/{version}": {
6128
+ "get": {
6129
+ "summary": "Get a metric definition version",
6130
+ "tags": [
6131
+ "Metrics"
6132
+ ],
6133
+ "security": [
6134
+ {
6135
+ "bearerAuth": []
6136
+ }
6137
+ ],
6138
+ "parameters": [
6139
+ {
6140
+ "schema": {
6141
+ "type": "string"
6142
+ },
6143
+ "required": true,
6144
+ "name": "id",
6145
+ "in": "path"
6146
+ },
6147
+ {
6148
+ "schema": {
6149
+ "type": "integer",
6150
+ "minimum": 1
6151
+ },
6152
+ "required": true,
6153
+ "name": "version",
6154
+ "in": "path"
6155
+ }
6156
+ ],
6157
+ "responses": {
6158
+ "200": {
6159
+ "description": "Metric version"
6160
+ },
6161
+ "404": {
6162
+ "description": "Metric or version not found"
6163
+ }
6164
+ }
6165
+ }
6166
+ },
6167
+ "/api/metrics/schema": {
6168
+ "get": {
6169
+ "summary": "Get the metric definition JSON Schema",
6170
+ "tags": [
6171
+ "Metrics"
6172
+ ],
6173
+ "security": [
6174
+ {
6175
+ "bearerAuth": []
6176
+ }
6177
+ ],
6178
+ "responses": {
6179
+ "200": {
6180
+ "description": "Metric definition JSON Schema"
6181
+ }
6182
+ }
6183
+ }
6184
+ },
5177
6185
  "/api/oauth/refresh-locks/{key}": {
5178
6186
  "post": {
5179
6187
  "summary": "Acquire a cross-process OAuth refresh lock",