@kb-labs/rest-api-app 1.3.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 (255) hide show
  1. package/.kb/agents/sessions/session-1771531145393-ws3uh6q/turns.json +42 -0
  2. package/.kb/agents/sessions/session-1771548930486-ui6rtvm/turns.json +33 -0
  3. package/.kb/agents/sessions/session-1771549691485-nibqroq/turns.json +133 -0
  4. package/.kb/agents/sessions/session-1771550943182-dkwqdjc/turns.json +130 -0
  5. package/.kb/agents/sessions/session-1771551564182-cr4bwzn/turns.json +349 -0
  6. package/.kb/agents/sessions/session-1771552401370-g4ztwd1/turns.json +206 -0
  7. package/.kb/commit/current/plan.json +248 -0
  8. package/.kb/commit/current/status.json +472 -0
  9. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/commands/health.d.ts +10 -0
  10. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/commands/health.js +215 -0
  11. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/commands/health.js.map +1 -0
  12. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/commands/list.d.ts +10 -0
  13. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/commands/list.js +271 -0
  14. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/commands/list.js.map +1 -0
  15. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/commands/logs.d.ts +10 -0
  16. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/commands/logs.js +230 -0
  17. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/commands/logs.js.map +1 -0
  18. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/commands/metrics.d.ts +10 -0
  19. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/commands/metrics.js +228 -0
  20. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/commands/metrics.js.map +1 -0
  21. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/commands/run.d.ts +11 -0
  22. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/commands/run.js +281 -0
  23. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/commands/run.js.map +1 -0
  24. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/commands/status.d.ts +10 -0
  25. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/commands/status.js +266 -0
  26. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/commands/status.js.map +1 -0
  27. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/commands/workflow-run.d.ts +11 -0
  28. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/commands/workflow-run.js +284 -0
  29. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/commands/workflow-run.js.map +1 -0
  30. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/flags-WLdpSZl4.d.ts +77 -0
  31. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/index.d.ts +2 -0
  32. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/index.js +441 -0
  33. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/index.js.map +1 -0
  34. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/manifest.d.ts +196 -0
  35. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/manifest.js +441 -0
  36. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/manifest.js.map +1 -0
  37. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/cron-list-handler.d.ts +19 -0
  38. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/cron-list-handler.js +48 -0
  39. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/cron-list-handler.js.map +1 -0
  40. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/index.d.ts +6 -0
  41. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/index.js +170 -0
  42. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/index.js.map +1 -0
  43. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/job-cancel-handler.d.ts +12 -0
  44. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/job-cancel-handler.js +52 -0
  45. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/job-cancel-handler.js.map +1 -0
  46. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/job-detail-handler.d.ts +22 -0
  47. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/job-detail-handler.js +52 -0
  48. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/job-detail-handler.js.map +1 -0
  49. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/job-logs-handler.d.ts +13 -0
  50. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/job-logs-handler.js +52 -0
  51. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/job-logs-handler.js.map +1 -0
  52. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/job-steps-handler.d.ts +9 -0
  53. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/job-steps-handler.js +43 -0
  54. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/job-steps-handler.js.map +1 -0
  55. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/jobs-list-handler.d.ts +26 -0
  56. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/jobs-list-handler.js +63 -0
  57. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/jobs-list-handler.js.map +1 -0
  58. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/pending-approvals-handler.d.ts +9 -0
  59. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/pending-approvals-handler.js +46 -0
  60. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/pending-approvals-handler.js.map +1 -0
  61. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/resolve-approval-handler.d.ts +16 -0
  62. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/resolve-approval-handler.js +58 -0
  63. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/resolve-approval-handler.js.map +1 -0
  64. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/run-detail-handler.d.ts +9 -0
  65. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/run-detail-handler.js +46 -0
  66. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/run-detail-handler.js.map +1 -0
  67. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/runs-list-handler.d.ts +11 -0
  68. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/runs-list-handler.js +50 -0
  69. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/runs-list-handler.js.map +1 -0
  70. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/stats-handler.d.ts +7 -0
  71. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/stats-handler.js +39 -0
  72. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/stats-handler.js.map +1 -0
  73. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/workflow-detail-handler.d.ts +10 -0
  74. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/workflow-detail-handler.js +46 -0
  75. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/workflow-detail-handler.js.map +1 -0
  76. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/workflow-run-cancel-handler.d.ts +13 -0
  77. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/workflow-run-cancel-handler.js +47 -0
  78. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/workflow-run-cancel-handler.js.map +1 -0
  79. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/workflow-run-handler.d.ts +14 -0
  80. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/workflow-run-handler.js +53 -0
  81. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/workflow-run-handler.js.map +1 -0
  82. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/workflow-runs-handler.d.ts +13 -0
  83. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/workflow-runs-handler.js +54 -0
  84. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/workflow-runs-handler.js.map +1 -0
  85. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/workflows-list-handler.d.ts +12 -0
  86. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/workflows-list-handler.js +51 -0
  87. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/rest/workflows-list-handler.js.map +1 -0
  88. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/ws/logs-channel.d.ts +17 -0
  89. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/ws/logs-channel.js +133 -0
  90. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/ws/logs-channel.js.map +1 -0
  91. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/ws/progress-channel.d.ts +11 -0
  92. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/ws/progress-channel.js +46 -0
  93. package/.kb/runtime/workspaces/ws_94c2deab-4cf9-49cb-94ac-3958062754a1/ws/progress-channel.js.map +1 -0
  94. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/commands/health.d.ts +10 -0
  95. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/commands/health.js +215 -0
  96. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/commands/health.js.map +1 -0
  97. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/commands/list.d.ts +10 -0
  98. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/commands/list.js +271 -0
  99. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/commands/list.js.map +1 -0
  100. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/commands/logs.d.ts +10 -0
  101. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/commands/logs.js +230 -0
  102. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/commands/logs.js.map +1 -0
  103. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/commands/metrics.d.ts +10 -0
  104. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/commands/metrics.js +228 -0
  105. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/commands/metrics.js.map +1 -0
  106. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/commands/run.d.ts +11 -0
  107. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/commands/run.js +281 -0
  108. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/commands/run.js.map +1 -0
  109. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/commands/status.d.ts +10 -0
  110. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/commands/status.js +266 -0
  111. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/commands/status.js.map +1 -0
  112. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/commands/workflow-run.d.ts +11 -0
  113. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/commands/workflow-run.js +284 -0
  114. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/commands/workflow-run.js.map +1 -0
  115. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/flags-WLdpSZl4.d.ts +77 -0
  116. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/index.d.ts +2 -0
  117. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/index.js +441 -0
  118. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/index.js.map +1 -0
  119. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/manifest.d.ts +196 -0
  120. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/manifest.js +441 -0
  121. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/manifest.js.map +1 -0
  122. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/cron-list-handler.d.ts +19 -0
  123. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/cron-list-handler.js +48 -0
  124. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/cron-list-handler.js.map +1 -0
  125. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/index.d.ts +6 -0
  126. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/index.js +170 -0
  127. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/index.js.map +1 -0
  128. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/job-cancel-handler.d.ts +12 -0
  129. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/job-cancel-handler.js +52 -0
  130. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/job-cancel-handler.js.map +1 -0
  131. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/job-detail-handler.d.ts +22 -0
  132. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/job-detail-handler.js +52 -0
  133. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/job-detail-handler.js.map +1 -0
  134. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/job-logs-handler.d.ts +13 -0
  135. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/job-logs-handler.js +52 -0
  136. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/job-logs-handler.js.map +1 -0
  137. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/job-steps-handler.d.ts +9 -0
  138. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/job-steps-handler.js +43 -0
  139. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/job-steps-handler.js.map +1 -0
  140. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/jobs-list-handler.d.ts +26 -0
  141. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/jobs-list-handler.js +63 -0
  142. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/jobs-list-handler.js.map +1 -0
  143. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/pending-approvals-handler.d.ts +9 -0
  144. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/pending-approvals-handler.js +46 -0
  145. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/pending-approvals-handler.js.map +1 -0
  146. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/resolve-approval-handler.d.ts +16 -0
  147. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/resolve-approval-handler.js +58 -0
  148. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/resolve-approval-handler.js.map +1 -0
  149. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/run-detail-handler.d.ts +9 -0
  150. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/run-detail-handler.js +46 -0
  151. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/run-detail-handler.js.map +1 -0
  152. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/runs-list-handler.d.ts +11 -0
  153. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/runs-list-handler.js +50 -0
  154. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/runs-list-handler.js.map +1 -0
  155. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/stats-handler.d.ts +7 -0
  156. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/stats-handler.js +39 -0
  157. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/stats-handler.js.map +1 -0
  158. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/workflow-detail-handler.d.ts +10 -0
  159. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/workflow-detail-handler.js +46 -0
  160. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/workflow-detail-handler.js.map +1 -0
  161. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/workflow-run-cancel-handler.d.ts +13 -0
  162. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/workflow-run-cancel-handler.js +47 -0
  163. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/workflow-run-cancel-handler.js.map +1 -0
  164. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/workflow-run-handler.d.ts +14 -0
  165. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/workflow-run-handler.js +53 -0
  166. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/workflow-run-handler.js.map +1 -0
  167. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/workflow-runs-handler.d.ts +13 -0
  168. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/workflow-runs-handler.js +54 -0
  169. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/workflow-runs-handler.js.map +1 -0
  170. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/workflows-list-handler.d.ts +12 -0
  171. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/workflows-list-handler.js +51 -0
  172. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/rest/workflows-list-handler.js.map +1 -0
  173. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/ws/logs-channel.d.ts +17 -0
  174. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/ws/logs-channel.js +133 -0
  175. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/ws/logs-channel.js.map +1 -0
  176. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/ws/progress-channel.d.ts +11 -0
  177. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/ws/progress-channel.js +46 -0
  178. package/.kb/runtime/workspaces/ws_f0f301b8-388d-4dc4-b301-475f2bc95f02/ws/progress-channel.js.map +1 -0
  179. package/README.md +54 -0
  180. package/eslint.config.js +23 -0
  181. package/package.json +72 -0
  182. package/src/.kb/agents/sessions/session-1773470583796-ximqnfk/kpi-baseline.json +17 -0
  183. package/src/.kb/memory/sessions/session-1773470583796-ximqnfk/fact-sheet.json +1 -0
  184. package/src/bootstrap.ts +233 -0
  185. package/src/diagnostics/header-debug.ts +37 -0
  186. package/src/events/hub.ts +60 -0
  187. package/src/events/index.ts +1 -0
  188. package/src/index.ts +13 -0
  189. package/src/manifest.ts +21 -0
  190. package/src/middleware/__tests__/cache.spec.ts +184 -0
  191. package/src/middleware/__tests__/envelope.spec.ts +268 -0
  192. package/src/middleware/__tests__/metrics.redis.spec.ts +64 -0
  193. package/src/middleware/__tests__/rate-limit.spec.ts +283 -0
  194. package/src/middleware/__tests__/request-id.spec.ts +160 -0
  195. package/src/middleware/cache.ts +67 -0
  196. package/src/middleware/envelope.ts +136 -0
  197. package/src/middleware/error-guard.ts +69 -0
  198. package/src/middleware/index.ts +37 -0
  199. package/src/middleware/metrics.ts +810 -0
  200. package/src/middleware/mock-mode.ts +44 -0
  201. package/src/middleware/prom-metrics.ts +284 -0
  202. package/src/middleware/rate-limit-routes.ts +73 -0
  203. package/src/middleware/rate-limit.ts +72 -0
  204. package/src/middleware/request-id.ts +41 -0
  205. package/src/middleware/request-timeout.ts +69 -0
  206. package/src/middleware/security-headers.ts +24 -0
  207. package/src/middleware/startup-guard.ts +107 -0
  208. package/src/observability/service-contract.ts +192 -0
  209. package/src/plugins/index.ts +118 -0
  210. package/src/routes/__tests__/adapters-date-helpers.spec.ts +332 -0
  211. package/src/routes/__tests__/adapters.spec.ts +680 -0
  212. package/src/routes/__tests__/cache.spec.ts +264 -0
  213. package/src/routes/__tests__/events.spec.ts +434 -0
  214. package/src/routes/__tests__/health.spec.ts +414 -0
  215. package/src/routes/__tests__/logs.spec.ts +494 -0
  216. package/src/routes/__tests__/observability.spec.ts +392 -0
  217. package/src/routes/__tests__/plugins.spec.ts +931 -0
  218. package/src/routes/__tests__/workflow-management.spec.ts +698 -0
  219. package/src/routes/__tests__/workflows.spec.ts +204 -0
  220. package/src/routes/adapter-call.ts +220 -0
  221. package/src/routes/adapters.ts +1206 -0
  222. package/src/routes/analytics.ts +328 -0
  223. package/src/routes/cache.ts +104 -0
  224. package/src/routes/debug-routes.ts +95 -0
  225. package/src/routes/events.ts +115 -0
  226. package/src/routes/health.ts +348 -0
  227. package/src/routes/hello.ts +47 -0
  228. package/src/routes/index.ts +395 -0
  229. package/src/routes/jobs.ts +253 -0
  230. package/src/routes/logs.ts +718 -0
  231. package/src/routes/metrics.ts +120 -0
  232. package/src/routes/observability.ts +1388 -0
  233. package/src/routes/openapi.ts +101 -0
  234. package/src/routes/platform.ts +143 -0
  235. package/src/routes/plugins.ts +998 -0
  236. package/src/routes/readiness.ts +83 -0
  237. package/src/routes/workflow-management.ts +469 -0
  238. package/src/routes/workflows.ts +256 -0
  239. package/src/server.ts +203 -0
  240. package/src/services/historical-metrics.ts +496 -0
  241. package/src/services/incident-analyzer.ts +289 -0
  242. package/src/services/incident-detector.ts +691 -0
  243. package/src/services/incident-schema.sql +76 -0
  244. package/src/services/incident-storage.ts +593 -0
  245. package/src/services/system-metrics-collector.ts +244 -0
  246. package/src/types/fastify.d.ts +58 -0
  247. package/src/utils/__tests__/sse-auth.spec.ts +113 -0
  248. package/src/utils/path-helpers.ts +15 -0
  249. package/src/utils/repo.ts +42 -0
  250. package/src/utils/schema.ts +20 -0
  251. package/src/utils/sse-auth.ts +81 -0
  252. package/test-sandbox.sh +105 -0
  253. package/tsconfig.build.json +15 -0
  254. package/tsconfig.json +9 -0
  255. package/tsup.config.ts +18 -0
@@ -0,0 +1,44 @@
1
+ /**
2
+ * @module @kb-labs/rest-api-app/middleware/mock-mode
3
+ * Mock mode middleware (per-request)
4
+ */
5
+
6
+ import type { FastifyInstance } from 'fastify';
7
+ import type { RestApiConfig } from '@kb-labs/rest-api-core';
8
+ import type { IncomingHttpHeaders } from 'http';
9
+
10
+ type MockableRequest = {
11
+ headers: IncomingHttpHeaders;
12
+ mockMode?: boolean;
13
+ };
14
+
15
+ /**
16
+ * Check if mock mode should be enabled for this request
17
+ */
18
+ export function isMockModeEnabled(
19
+ request: MockableRequest,
20
+ config: RestApiConfig
21
+ ): boolean {
22
+ // Check per-request header
23
+ const headerMock = request.headers['kb-mock'];
24
+ if (headerMock === 'true' || headerMock === '1') {
25
+ return true;
26
+ }
27
+
28
+ // Check global config
29
+ return config.mockMode || false;
30
+ }
31
+
32
+ /**
33
+ * Register mock mode middleware
34
+ */
35
+ export function registerMockModeMiddleware(
36
+ server: FastifyInstance,
37
+ config: RestApiConfig
38
+ ): void {
39
+ server.addHook('onRequest', async (request) => {
40
+ const mockableRequest = request as MockableRequest;
41
+ mockableRequest.mockMode = isMockModeEnabled(mockableRequest, config);
42
+ });
43
+ }
44
+
@@ -0,0 +1,284 @@
1
+ /**
2
+ * @module @kb-labs/rest-api-app/middleware/prom-metrics
3
+ * Prometheus metrics using prom-client
4
+ */
5
+
6
+ import { Registry, Histogram, Counter, Gauge } from 'prom-client';
7
+
8
+ /**
9
+ * Prometheus metrics registry
10
+ */
11
+ export const promRegistry = new Registry();
12
+
13
+ /**
14
+ * HTTP request duration histogram with percentiles
15
+ * Automatically calculates p50, p95, p99
16
+ */
17
+ export const httpRequestDuration = new Histogram({
18
+ name: 'http_request_duration_ms',
19
+ help: 'HTTP request duration in milliseconds',
20
+ labelNames: ['method', 'route', 'status_code', 'tenant', 'plugin'],
21
+ buckets: [5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000, 10000], // milliseconds
22
+ registers: [promRegistry],
23
+ });
24
+
25
+ /**
26
+ * HTTP requests total counter
27
+ */
28
+ export const httpRequestsTotal = new Counter({
29
+ name: 'http_requests_total',
30
+ help: 'Total number of HTTP requests',
31
+ labelNames: ['method', 'route', 'status_code', 'tenant', 'plugin'],
32
+ registers: [promRegistry],
33
+ });
34
+
35
+ /**
36
+ * HTTP errors total counter
37
+ */
38
+ export const httpErrorsTotal = new Counter({
39
+ name: 'http_errors_total',
40
+ help: 'Total number of HTTP errors (4xx, 5xx)',
41
+ labelNames: ['status_code', 'error_code', 'tenant'],
42
+ registers: [promRegistry],
43
+ });
44
+
45
+ /**
46
+ * Process uptime gauge
47
+ */
48
+ export const processUptime = new Gauge({
49
+ name: 'process_uptime_seconds',
50
+ help: 'Process uptime in seconds',
51
+ registers: [promRegistry],
52
+ });
53
+
54
+ export const processCpuPercent = new Gauge({
55
+ name: 'process_cpu_percent',
56
+ help: 'Current process CPU usage percentage',
57
+ registers: [promRegistry],
58
+ });
59
+
60
+ export const processRssBytes = new Gauge({
61
+ name: 'process_rss_bytes',
62
+ help: 'Current process resident set size in bytes',
63
+ registers: [promRegistry],
64
+ });
65
+
66
+ export const processHeapUsedBytes = new Gauge({
67
+ name: 'process_heap_used_bytes',
68
+ help: 'Current process heap used in bytes',
69
+ registers: [promRegistry],
70
+ });
71
+
72
+ export const processEventLoopLagMs = new Gauge({
73
+ name: 'process_event_loop_lag_ms',
74
+ help: 'Current event loop lag in milliseconds',
75
+ registers: [promRegistry],
76
+ });
77
+
78
+ export const serviceHealthStatus = new Gauge({
79
+ name: 'service_health_status',
80
+ help: 'Service health status (2=healthy, 1=degraded, 0=unhealthy)',
81
+ registers: [promRegistry],
82
+ });
83
+
84
+ export const serviceRestartsTotal = new Gauge({
85
+ name: 'service_restarts_total',
86
+ help: 'Service restart counter within current process lifetime',
87
+ registers: [promRegistry],
88
+ });
89
+
90
+ export const serviceActiveOperations = new Gauge({
91
+ name: 'service_active_operations',
92
+ help: 'Current number of active operations',
93
+ registers: [promRegistry],
94
+ });
95
+
96
+ export const serviceOperationTotal = new Counter({
97
+ name: 'service_operation_total',
98
+ help: 'Total number of service operations',
99
+ labelNames: ['operation', 'status'],
100
+ registers: [promRegistry],
101
+ });
102
+
103
+ export const serviceOperationDuration = new Histogram({
104
+ name: 'service_operation_duration_ms',
105
+ help: 'Service operation duration in milliseconds',
106
+ labelNames: ['operation', 'status'],
107
+ buckets: [5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000, 10000],
108
+ registers: [promRegistry],
109
+ });
110
+
111
+ /**
112
+ * Header policy metrics
113
+ */
114
+ export const headersFiltered = new Counter({
115
+ name: 'kb_headers_filtered_total',
116
+ help: 'Total headers filtered by policy enforcement',
117
+ labelNames: ['direction', 'plugin'],
118
+ registers: [promRegistry],
119
+ });
120
+
121
+ export const headersSensitiveInbound = new Counter({
122
+ name: 'kb_headers_sensitive_inbound_total',
123
+ help: 'Sensitive inbound headers observed',
124
+ labelNames: ['plugin'],
125
+ registers: [promRegistry],
126
+ });
127
+
128
+ export const headersValidationErrors = new Counter({
129
+ name: 'kb_headers_validation_errors_total',
130
+ help: 'Header validation errors encountered',
131
+ labelNames: ['plugin'],
132
+ registers: [promRegistry],
133
+ });
134
+
135
+ export const headersVaryApplied = new Counter({
136
+ name: 'kb_headers_vary_applied_total',
137
+ help: 'Vary header entries applied by policy',
138
+ labelNames: ['plugin'],
139
+ registers: [promRegistry],
140
+ });
141
+
142
+ export const headersDryRunDecisions = new Counter({
143
+ name: 'kb_headers_dry_run_decisions_total',
144
+ help: 'Header decisions skipped due to dry-run mode',
145
+ registers: [promRegistry],
146
+ });
147
+
148
+ /**
149
+ * Plugin metrics
150
+ */
151
+ export const pluginRequestsTotal = new Counter({
152
+ name: 'kb_plugin_request_total',
153
+ help: 'Total HTTP requests per plugin',
154
+ labelNames: ['plugin'],
155
+ registers: [promRegistry],
156
+ });
157
+
158
+ export const pluginRequestDuration = new Histogram({
159
+ name: 'kb_plugin_request_duration_ms',
160
+ help: 'Plugin request duration metrics',
161
+ labelNames: ['plugin'],
162
+ buckets: [5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000],
163
+ registers: [promRegistry],
164
+ });
165
+
166
+ /**
167
+ * Tenant metrics
168
+ */
169
+ export const tenantRequestsTotal = new Counter({
170
+ name: 'kb_tenant_request_total',
171
+ help: 'Total HTTP requests per tenant',
172
+ labelNames: ['tenant'],
173
+ registers: [promRegistry],
174
+ });
175
+
176
+ export const tenantErrorsTotal = new Counter({
177
+ name: 'kb_tenant_request_errors_total',
178
+ help: 'Total HTTP errors per tenant',
179
+ labelNames: ['tenant'],
180
+ registers: [promRegistry],
181
+ });
182
+
183
+ export const tenantRequestDuration = new Histogram({
184
+ name: 'kb_tenant_request_duration_ms',
185
+ help: 'Tenant request duration',
186
+ labelNames: ['tenant'],
187
+ buckets: [5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000],
188
+ registers: [promRegistry],
189
+ });
190
+
191
+ /**
192
+ * Plugin mount metrics
193
+ */
194
+ export const pluginsMountTotal = new Gauge({
195
+ name: 'kb_plugins_mount_total',
196
+ help: 'Plugins processed during last mount run',
197
+ registers: [promRegistry],
198
+ });
199
+
200
+ export const pluginsMountSucceeded = new Gauge({
201
+ name: 'kb_plugins_mount_succeeded',
202
+ help: 'Plugins successfully mounted',
203
+ registers: [promRegistry],
204
+ });
205
+
206
+ export const pluginsMountFailed = new Gauge({
207
+ name: 'kb_plugins_mount_failed',
208
+ help: 'Plugins failed to mount',
209
+ registers: [promRegistry],
210
+ });
211
+
212
+ export const pluginsMountElapsed = new Gauge({
213
+ name: 'kb_plugins_mount_elapsed_ms',
214
+ help: 'Plugin mount elapsed time in milliseconds',
215
+ registers: [promRegistry],
216
+ });
217
+
218
+ /**
219
+ * Redis metrics
220
+ */
221
+ export const redisStatusUpdates = new Counter({
222
+ name: 'kb_redis_status_updates_total',
223
+ help: 'Redis status updates observed',
224
+ registers: [promRegistry],
225
+ });
226
+
227
+ export const redisStatusTransitions = new Counter({
228
+ name: 'kb_redis_status_transitions_total',
229
+ help: 'Redis health transitions',
230
+ labelNames: ['state'],
231
+ registers: [promRegistry],
232
+ });
233
+
234
+ export const redisHealthy = new Gauge({
235
+ name: 'kb_redis_healthy',
236
+ help: 'Redis healthy flag (1 = healthy)',
237
+ registers: [promRegistry],
238
+ });
239
+
240
+ export const redisRoleState = new Gauge({
241
+ name: 'kb_redis_role_state_total',
242
+ help: 'Redis role state occurrences',
243
+ labelNames: ['role', 'state'],
244
+ registers: [promRegistry],
245
+ });
246
+
247
+ /**
248
+ * Update process uptime metric
249
+ */
250
+ export function updateProcessUptime(startTimeMs: number): void {
251
+ const uptimeSeconds = (Date.now() - startTimeMs) / 1000;
252
+ processUptime.set(uptimeSeconds);
253
+ }
254
+
255
+ export function updateRuntimeObservabilityMetrics(input: {
256
+ cpuPercent: number;
257
+ rssBytes: number;
258
+ heapUsedBytes: number;
259
+ eventLoopLagMs: number;
260
+ activeOperations: number;
261
+ healthStatus?: 'healthy' | 'degraded' | 'unhealthy';
262
+ }): void {
263
+ processCpuPercent.set(input.cpuPercent);
264
+ processRssBytes.set(input.rssBytes);
265
+ processHeapUsedBytes.set(input.heapUsedBytes);
266
+ processEventLoopLagMs.set(input.eventLoopLagMs);
267
+ serviceActiveOperations.set(input.activeOperations);
268
+ serviceRestartsTotal.set(0);
269
+
270
+ if (input.healthStatus) {
271
+ updateServiceHealthStatus(input.healthStatus);
272
+ }
273
+ }
274
+
275
+ export function updateServiceHealthStatus(status: 'healthy' | 'degraded' | 'unhealthy'): void {
276
+ serviceHealthStatus.set(status === 'healthy' ? 2 : status === 'degraded' ? 1 : 0);
277
+ }
278
+
279
+ /**
280
+ * Get all metrics in Prometheus format
281
+ */
282
+ export async function getPrometheusMetrics(): Promise<string> {
283
+ return promRegistry.metrics();
284
+ }
@@ -0,0 +1,73 @@
1
+ /**
2
+ * @module @kb-labs/rest-api-app/middleware/rate-limit-routes
3
+ * Per-route rate limiting middleware
4
+ */
5
+
6
+ import type { FastifyInstance } from 'fastify';
7
+ import type { RestApiConfig } from '@kb-labs/rest-api-core';
8
+
9
+ /**
10
+ * Rate limit configuration per route
11
+ */
12
+ interface RouteRateLimit {
13
+ max: number;
14
+ timeWindow: string;
15
+ }
16
+
17
+ const routeLimits: Record<string, RouteRateLimit> = {
18
+ '/audit/runs': { max: 10, timeWindow: '1 minute' },
19
+ '/release/runs': { max: 5, timeWindow: '1 minute' },
20
+ '/devlink/check': { max: 20, timeWindow: '1 minute' },
21
+ // Health endpoints - higher limits
22
+ '/health': { max: 100, timeWindow: '1 minute' },
23
+ '/ready': { max: 60, timeWindow: '1 minute' },
24
+ '/observability/describe': { max: 60, timeWindow: '1 minute' },
25
+ '/observability/health': { max: 60, timeWindow: '1 minute' },
26
+ // Info endpoints - moderate limits
27
+ '/info': { max: 30, timeWindow: '1 minute' },
28
+ '/info/capabilities': { max: 30, timeWindow: '1 minute' },
29
+ // Jobs endpoints - moderate limits
30
+ '/jobs': { max: 60, timeWindow: '1 minute' },
31
+ };
32
+
33
+ /**
34
+ * Register per-route rate limiting
35
+ */
36
+ export function registerRouteRateLimiting(
37
+ server: FastifyInstance,
38
+ config: RestApiConfig
39
+ ): void {
40
+ // Only apply if rate limiting is enabled globally
41
+ if (!config.rateLimit) {
42
+ return;
43
+ }
44
+
45
+ // Apply route-specific limits
46
+ for (const [route] of Object.entries(routeLimits)) {
47
+ const fullPath = `${config.basePath}${route}`;
48
+
49
+ server.addHook('onRequest', async (request, _reply) => {
50
+ // Check if this route matches
51
+ if (!request.url.startsWith(fullPath)) {
52
+ return;
53
+ }
54
+
55
+ // Apply route-specific rate limit
56
+ // Note: This is a simplified implementation
57
+ // Full implementation would use @fastify/rate-limit with route-specific config
58
+ // For now, we rely on global rate limiting configured in plugins
59
+ });
60
+ }
61
+
62
+ // Apply stricter limits for POST requests to run endpoints
63
+ server.addHook('onRequest', async (request, _reply) => {
64
+ const isRunEndpoint = request.url.includes('/audit/runs') ||
65
+ request.url.includes('/release/runs') ||
66
+ request.url.includes('/devlink/check');
67
+
68
+ if (isRunEndpoint && request.method === 'POST') {
69
+ // These limits are enforced by the queue adapter's concurrency limits
70
+ // Additional rate limiting is handled globally
71
+ }
72
+ });
73
+ }
@@ -0,0 +1,72 @@
1
+ /**
2
+ * @module @kb-labs/rest-api-app/middleware/rate-limit
3
+ * Tenant-aware rate limiting middleware
4
+ */
5
+
6
+ import type { FastifyRequest, FastifyReply } from 'fastify';
7
+
8
+ interface TenantRateLimiter {
9
+ checkLimit(tenantId: string, resource: string): Promise<{
10
+ allowed: boolean;
11
+ limit: number;
12
+ remaining: number;
13
+ resetAt: number;
14
+ }>;
15
+ }
16
+
17
+ /**
18
+ * Extract tenant ID from request
19
+ * Priority order:
20
+ * 1. Header: X-Tenant-ID
21
+ * 2. Environment: KB_TENANT_ID
22
+ * 3. Default: 'default'
23
+ *
24
+ * @param request - Fastify request
25
+ * @returns Tenant ID
26
+ */
27
+ export function extractTenantId(request: FastifyRequest): string {
28
+ return (
29
+ (request.headers['x-tenant-id'] as string) ||
30
+ process.env.KB_TENANT_ID ||
31
+ 'default'
32
+ );
33
+ }
34
+
35
+ /**
36
+ * Create rate limiting middleware
37
+ *
38
+ * @param rateLimiter - Tenant rate limiter instance
39
+ * @returns Fastify preHandler hook
40
+ */
41
+ export function createRateLimitMiddleware(rateLimiter: TenantRateLimiter) {
42
+ return async function rateLimitMiddleware(
43
+ request: FastifyRequest,
44
+ reply: FastifyReply
45
+ ) {
46
+ const tenantId = extractTenantId(request);
47
+
48
+ // Check rate limit for requests
49
+ const result = await rateLimiter.checkLimit(tenantId, 'requests');
50
+
51
+ // Add rate limit headers (standard X-RateLimit-* headers)
52
+ reply.header('X-RateLimit-Limit', result.limit);
53
+ reply.header('X-RateLimit-Remaining', result.remaining);
54
+ reply.header('X-RateLimit-Reset', result.resetAt);
55
+
56
+ if (!result.allowed) {
57
+ const retryAfter = Math.ceil((result.resetAt - Date.now()) / 1000);
58
+ reply.header('Retry-After', retryAfter);
59
+
60
+ return reply.code(429).send({
61
+ error: 'RATE_LIMIT_EXCEEDED',
62
+ message: 'Too many requests. Please try again later.',
63
+ retryAfter,
64
+ limit: result.limit,
65
+ resetAt: new Date(result.resetAt).toISOString(),
66
+ });
67
+ }
68
+
69
+ // Store tenantId in request context for downstream use
70
+ (request as any).tenantId = tenantId;
71
+ };
72
+ }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * @module @kb-labs/rest-api-app/middleware/request-id
3
+ * Request ID generation and correlation middleware
4
+ */
5
+
6
+ import type { FastifyInstance } from 'fastify';
7
+ import { ulid } from 'ulid';
8
+ import { platform } from '@kb-labs/core-runtime';
9
+ import { createCorrelatedLogger } from '@kb-labs/shared-http';
10
+
11
+ /**
12
+ * Register request ID middleware
13
+ */
14
+ export function registerRequestIdMiddleware(server: FastifyInstance): void {
15
+ server.addHook('onRequest', async (request, reply) => {
16
+ const requestId = (request.headers['x-request-id'] as string | undefined) || ulid();
17
+ const traceId = (request.headers['x-trace-id'] as string | undefined) || ulid();
18
+
19
+ request.id = requestId;
20
+ reply.header('X-Request-Id', requestId);
21
+ reply.header('X-Trace-Id', traceId);
22
+
23
+ // Store logger metadata on request for metrics middleware to use
24
+ (request as any).kbLogger = createCorrelatedLogger(platform.logger, {
25
+ serviceId: 'rest',
26
+ logsSource: 'rest',
27
+ layer: 'rest',
28
+ service: 'request',
29
+ requestId,
30
+ traceId,
31
+ method: request.method,
32
+ url: request.url,
33
+ operation: 'http.request',
34
+ });
35
+
36
+ // Log request received
37
+ const method = request.method.toUpperCase();
38
+ const fullUrl = request.url;
39
+ (request as any).kbLogger.info(`→ ${method} ${fullUrl}`);
40
+ });
41
+ }
@@ -0,0 +1,69 @@
1
+ /**
2
+ * @module @kb-labs/rest-api-app/middleware/request-timeout
3
+ * Enforce route-level request timeouts
4
+ */
5
+
6
+ import type { FastifyInstance } from 'fastify';
7
+ import type { RestApiConfig } from '@kb-labs/rest-api-core';
8
+ import { metricsCollector } from './metrics';
9
+
10
+ type RouteConfig = {
11
+ kbRouteBudgetMs?: number | null;
12
+ };
13
+
14
+ export function registerRequestTimeoutGuard(
15
+ server: FastifyInstance,
16
+ config: RestApiConfig
17
+ ): void {
18
+ const defaultTimeout = config.timeouts?.requestTimeout ?? 30_000;
19
+
20
+ server.addHook('onRequest', (request, reply, done) => {
21
+ const routeConfig = (request.routeOptions?.config || {}) as RouteConfig;
22
+ let budget = typeof routeConfig.kbRouteBudgetMs === 'number' && routeConfig.kbRouteBudgetMs > 0
23
+ ? routeConfig.kbRouteBudgetMs
24
+ : null;
25
+
26
+ if (!budget) {
27
+ const normalized =
28
+ request.routeOptions?.url ??
29
+ request.url;
30
+ const inferred = normalized ? metricsCollector.getRouteBudget(request.method, normalized) : null;
31
+ if (inferred && inferred > 0) {
32
+ budget = inferred;
33
+ }
34
+ }
35
+
36
+ if (!budget || budget <= 0) {
37
+ budget = defaultTimeout;
38
+ }
39
+
40
+ if (!budget || budget <= 0) {
41
+ done();
42
+ return;
43
+ }
44
+
45
+ reply.raw.setTimeout(budget, () => {
46
+ if (reply.sent) {
47
+ return;
48
+ }
49
+ reply
50
+ .code(504)
51
+ .header('Content-Type', 'application/json')
52
+ .send({
53
+ schema: 'kb.errors/timeout/1',
54
+ status: 'error',
55
+ http: 504,
56
+ code: 'E_GATEWAY_TIMEOUT',
57
+ message: 'Request timed out',
58
+ meta: {
59
+ method: request.method,
60
+ route: request.routeOptions?.url ?? request.url,
61
+ timeoutMs: budget,
62
+ },
63
+ });
64
+ });
65
+
66
+ done();
67
+ });
68
+ }
69
+
@@ -0,0 +1,24 @@
1
+ /**
2
+ * @module @kb-labs/rest-api-app/middleware/security-headers
3
+ * Security headers middleware
4
+ */
5
+
6
+ import type { FastifyInstance } from 'fastify';
7
+
8
+ /**
9
+ * Register security headers middleware
10
+ */
11
+ export function registerSecurityHeadersMiddleware(server: FastifyInstance): void {
12
+ server.addHook('onRequest', async (request, reply) => {
13
+ reply.header('X-Content-Type-Options', 'nosniff');
14
+ reply.header('X-Frame-Options', 'DENY');
15
+ reply.header('X-XSS-Protection', '1; mode=block');
16
+ reply.header('Referrer-Policy', 'strict-origin-when-cross-origin');
17
+ reply.header('Permissions-Policy', 'geolocation=(), microphone=(), camera=()');
18
+
19
+ if (request.protocol === 'https') {
20
+ reply.header('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
21
+ }
22
+ });
23
+ }
24
+