pi-harness-runtime 1.1.398 → 1.1.402

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 (613) hide show
  1. package/AGENTS.md +44 -2
  2. package/CHANGELOG.md +21 -0
  3. package/RULES.md +28 -0
  4. package/harness/agent-handoff.ts +2 -3
  5. package/harness/autonomous-review.ts +1 -1
  6. package/harness/blackboard.ts +2 -3
  7. package/harness/context-compact-orchestrator.ts +1 -1
  8. package/harness/context-window-manager.ts +2 -2
  9. package/harness/e2e/playwright-runner.ts +6 -4
  10. package/harness/herdr-agents.ts +1 -1
  11. package/harness/job-state-machine.ts +1 -1
  12. package/harness/langchain/daemon.ts +3 -3
  13. package/harness/langchain/graph.ts +2 -2
  14. package/harness/langchain/ping-pong-middleware.ts +2 -2
  15. package/harness/loop-code-agent.ts +6 -4
  16. package/harness/loop-controller.ts +1 -1
  17. package/harness/loop-review-agent.ts +1 -1
  18. package/harness/loop-types.ts +1 -1
  19. package/harness/master-planner.ts +1 -1
  20. package/harness/project-detector/detector.ts +1 -2
  21. package/harness/repair-engine.ts +2 -4
  22. package/harness/service-diagnostics.ts +1 -1
  23. package/harness/skill-sync.ts +3 -3
  24. package/index.ts +276 -55
  25. package/mirror.ts +1 -1
  26. package/package.json +5 -3
  27. package/packages/a2a-adapter/dist/discovery.d.ts.map +1 -1
  28. package/packages/a2a-adapter/dist/discovery.js +0 -1
  29. package/packages/a2a-adapter/dist/discovery.js.map +1 -1
  30. package/packages/a2a-adapter/package.json +1 -1
  31. package/packages/a2a-adapter/src/discovery.ts +0 -1
  32. package/packages/agent-policy/package.json +1 -1
  33. package/packages/architecture-generator/package.json +1 -1
  34. package/packages/auth/dist/index.d.ts +9 -0
  35. package/packages/auth/dist/index.d.ts.map +1 -0
  36. package/packages/auth/dist/index.js +9 -0
  37. package/packages/auth/dist/index.js.map +1 -0
  38. package/packages/auth/package.json +1 -1
  39. package/packages/auth/src/index.ts +9 -0
  40. package/packages/autonomous-refactor/package.json +1 -1
  41. package/packages/autonomous-runtime/package.json +1 -1
  42. package/packages/cache-strategy/package.json +1 -1
  43. package/packages/capability-registry/package.json +1 -1
  44. package/packages/checkpoint/package.json +1 -1
  45. package/packages/cli-plugin-sdk/package.json +1 -1
  46. package/packages/clipboard/package.json +1 -1
  47. package/packages/clipboard-plugin/package.json +1 -1
  48. package/packages/code-generation/package.json +1 -1
  49. package/packages/code-review/package.json +1 -1
  50. package/packages/codex-adapter/package.json +1 -1
  51. package/packages/codex-watcher/package.json +1 -1
  52. package/packages/config-capture/dist/index.d.ts +52 -0
  53. package/packages/config-capture/dist/index.d.ts.map +1 -0
  54. package/packages/config-capture/dist/index.js +261 -0
  55. package/packages/config-capture/dist/index.js.map +1 -0
  56. package/packages/config-capture/package.json +1 -1
  57. package/packages/connection-runtime/package.json +1 -1
  58. package/packages/context-compiler/package.json +1 -1
  59. package/packages/context-discovery/package.json +1 -1
  60. package/packages/context-manager/package.json +1 -1
  61. package/packages/contracts/package.json +1 -1
  62. package/packages/cookie-sanitizer/package.json +1 -1
  63. package/packages/cost-optimizer/package.json +1 -1
  64. package/packages/dependency-analyzer/package.json +1 -1
  65. package/packages/django-plugin/package.json +1 -1
  66. package/packages/doc-generator/package.json +1 -1
  67. package/packages/durable-review/package.json +1 -1
  68. package/packages/e2e-tester/package.json +1 -1
  69. package/packages/evaluation-engine/package.json +1 -1
  70. package/packages/evaluation-runner/package.json +1 -1
  71. package/packages/event-bus/package.json +1 -1
  72. package/packages/event-sink/package.json +1 -1
  73. package/packages/event-store/package.json +1 -1
  74. package/packages/experience-replay/package.json +1 -1
  75. package/packages/feedback-collector/package.json +1 -1
  76. package/packages/file-copy-helper/dist/extension.d.ts +15 -0
  77. package/packages/file-copy-helper/dist/extension.d.ts.map +1 -0
  78. package/packages/file-copy-helper/dist/extension.debug.d.ts +15 -0
  79. package/packages/file-copy-helper/dist/extension.debug.d.ts.map +1 -0
  80. package/packages/file-copy-helper/dist/extension.debug.js +215 -0
  81. package/packages/file-copy-helper/dist/extension.debug.js.map +1 -0
  82. package/packages/file-copy-helper/dist/extension.js +222 -0
  83. package/packages/file-copy-helper/dist/extension.js.map +1 -0
  84. package/packages/file-copy-helper/dist/index.d.ts +3 -0
  85. package/packages/file-copy-helper/dist/index.d.ts.map +1 -0
  86. package/packages/file-copy-helper/dist/index.js +3 -0
  87. package/packages/file-copy-helper/dist/index.js.map +1 -0
  88. package/packages/file-copy-helper/dist/intent-detector.d.ts +21 -0
  89. package/packages/file-copy-helper/dist/intent-detector.d.ts.map +1 -0
  90. package/packages/file-copy-helper/dist/intent-detector.js +348 -0
  91. package/packages/file-copy-helper/dist/intent-detector.js.map +1 -0
  92. package/packages/file-copy-helper/package.json +1 -1
  93. package/packages/framework-detector/package.json +1 -1
  94. package/packages/framework-plugin-sdk/package.json +1 -1
  95. package/packages/frappe-plugin/package.json +1 -1
  96. package/packages/generic-web-plugin/package.json +1 -1
  97. package/packages/health-monitor/package.json +1 -1
  98. package/packages/intent-analyzer/package.json +1 -1
  99. package/packages/jev-judge/dist/auto-continue.d.ts +161 -2
  100. package/packages/jev-judge/dist/auto-continue.d.ts.map +1 -1
  101. package/packages/jev-judge/dist/auto-continue.js +267 -22
  102. package/packages/jev-judge/dist/auto-continue.js.map +1 -1
  103. package/packages/jev-judge/dist/index.d.ts +2 -0
  104. package/packages/jev-judge/dist/index.d.ts.map +1 -1
  105. package/packages/jev-judge/dist/index.js +2 -0
  106. package/packages/jev-judge/dist/index.js.map +1 -1
  107. package/packages/jev-judge/dist/question-risk.d.ts +50 -0
  108. package/packages/jev-judge/dist/question-risk.d.ts.map +1 -0
  109. package/packages/jev-judge/dist/question-risk.js +100 -0
  110. package/packages/jev-judge/dist/question-risk.js.map +1 -0
  111. package/packages/jev-judge/package.json +1 -1
  112. package/packages/jev-judge/src/auto-continue.ts +426 -29
  113. package/packages/jev-judge/src/index.ts +4 -0
  114. package/packages/jev-judge/src/question-risk.ts +151 -0
  115. package/packages/jev-judge/tests/auto-continue-context.test.ts +221 -0
  116. package/packages/jev-judge/tests/outcome-application.test.ts +132 -0
  117. package/packages/jev-judge/tests/question-risk.test.ts +116 -0
  118. package/packages/knowledge-graph/package.json +1 -1
  119. package/packages/knowledge-retrieval/package.json +1 -1
  120. package/packages/laravel-plugin/package.json +1 -1
  121. package/packages/learning-engine/package.json +1 -1
  122. package/packages/logging/README.md +36 -3
  123. package/packages/logging/dist/config.d.ts +7 -0
  124. package/packages/logging/dist/config.d.ts.map +1 -1
  125. package/packages/logging/dist/config.js +14 -0
  126. package/packages/logging/dist/config.js.map +1 -1
  127. package/packages/logging/dist/incidents/schema.d.ts +111 -0
  128. package/packages/logging/dist/incidents/schema.d.ts.map +1 -0
  129. package/packages/logging/dist/incidents/schema.js +0 -0
  130. package/packages/logging/dist/incidents/schema.js.map +1 -0
  131. package/packages/logging/dist/index.d.ts +2 -0
  132. package/packages/logging/dist/index.d.ts.map +1 -1
  133. package/packages/logging/dist/index.js +2 -0
  134. package/packages/logging/dist/index.js.map +1 -1
  135. package/packages/logging/dist/server/http.d.ts +4 -3
  136. package/packages/logging/dist/server/http.d.ts.map +1 -1
  137. package/packages/logging/dist/server/http.js +35 -3
  138. package/packages/logging/dist/server/http.js.map +1 -1
  139. package/packages/logging/dist/server/incident-qdrant.d.ts +83 -0
  140. package/packages/logging/dist/server/incident-qdrant.d.ts.map +1 -0
  141. package/packages/logging/dist/server/incident-qdrant.js +129 -0
  142. package/packages/logging/dist/server/incident-qdrant.js.map +1 -0
  143. package/packages/logging/dist/server/incident-store.d.ts +76 -0
  144. package/packages/logging/dist/server/incident-store.d.ts.map +1 -0
  145. package/packages/logging/dist/server/incident-store.js +157 -0
  146. package/packages/logging/dist/server/incident-store.js.map +1 -0
  147. package/packages/logging/dist/server/index.d.ts +4 -0
  148. package/packages/logging/dist/server/index.d.ts.map +1 -1
  149. package/packages/logging/dist/server/index.js +2 -0
  150. package/packages/logging/dist/server/index.js.map +1 -1
  151. package/packages/logging/dist/server/service.d.ts +33 -0
  152. package/packages/logging/dist/server/service.d.ts.map +1 -1
  153. package/packages/logging/dist/server/service.js +63 -0
  154. package/packages/logging/dist/server/service.js.map +1 -1
  155. package/packages/logging/dist/shipper.d.ts +74 -3
  156. package/packages/logging/dist/shipper.d.ts.map +1 -1
  157. package/packages/logging/dist/shipper.js +88 -5
  158. package/packages/logging/dist/shipper.js.map +1 -1
  159. package/packages/logging/dist/singleton.d.ts.map +1 -1
  160. package/packages/logging/dist/singleton.js +1 -0
  161. package/packages/logging/dist/singleton.js.map +1 -1
  162. package/packages/logging/package.json +1 -1
  163. package/packages/logging/src/config.ts +22 -0
  164. package/packages/logging/src/incidents/schema.ts +0 -0
  165. package/packages/logging/src/index.ts +17 -0
  166. package/packages/logging/src/server/http.ts +42 -3
  167. package/packages/logging/src/server/incident-qdrant.ts +177 -0
  168. package/packages/logging/src/server/incident-store.ts +192 -0
  169. package/packages/logging/src/server/index.ts +21 -0
  170. package/packages/logging/src/server/service.ts +79 -0
  171. package/packages/logging/src/shipper.ts +120 -5
  172. package/packages/logging/src/singleton.ts +1 -0
  173. package/packages/logging/test/fanout.test.ts +186 -0
  174. package/packages/logging/test/incidents.test.ts +404 -0
  175. package/packages/mcp-adapter/package.json +1 -1
  176. package/packages/memory-engine/package.json +1 -1
  177. package/packages/milestone-manager/package.json +1 -1
  178. package/packages/model-registry/package.json +1 -1
  179. package/packages/nextjs-plugin/package.json +1 -1
  180. package/packages/notification/dist/adapters/detail-format.d.ts +10 -2
  181. package/packages/notification/dist/adapters/detail-format.d.ts.map +1 -1
  182. package/packages/notification/dist/adapters/detail-format.js +39 -0
  183. package/packages/notification/dist/adapters/detail-format.js.map +1 -1
  184. package/packages/notification/dist/adapters/line-adapter.d.ts +33 -0
  185. package/packages/notification/dist/adapters/line-adapter.d.ts.map +1 -1
  186. package/packages/notification/dist/adapters/line-adapter.js +84 -7
  187. package/packages/notification/dist/adapters/line-adapter.js.map +1 -1
  188. package/packages/notification/dist/adapters/telegram-adapter.d.ts.map +1 -1
  189. package/packages/notification/dist/adapters/telegram-adapter.js +6 -2
  190. package/packages/notification/dist/adapters/telegram-adapter.js.map +1 -1
  191. package/packages/notification/dist/notification-center.d.ts.map +1 -1
  192. package/packages/notification/dist/notification-center.js +59 -7
  193. package/packages/notification/dist/notification-center.js.map +1 -1
  194. package/packages/notification/dist/pending-question.d.ts +69 -2
  195. package/packages/notification/dist/pending-question.d.ts.map +1 -1
  196. package/packages/notification/dist/pending-question.js +88 -2
  197. package/packages/notification/dist/pending-question.js.map +1 -1
  198. package/packages/notification/dist/types.d.ts +18 -0
  199. package/packages/notification/dist/types.d.ts.map +1 -1
  200. package/packages/notification/package.json +1 -1
  201. package/packages/notification/src/adapters/detail-format.ts +42 -2
  202. package/packages/notification/src/adapters/line-adapter.ts +94 -7
  203. package/packages/notification/src/adapters/telegram-adapter.ts +6 -2
  204. package/packages/notification/src/notification-center.ts +65 -8
  205. package/packages/notification/src/pending-question.ts +160 -8
  206. package/packages/notification/src/types.ts +18 -0
  207. package/packages/notification/test/approval-payload.test.ts +269 -0
  208. package/packages/notification/test/pending-question-lifecycle.test.ts +195 -0
  209. package/packages/observability/package.json +1 -1
  210. package/packages/okf-indexer/dist/index.d.ts +9 -0
  211. package/packages/okf-indexer/dist/index.d.ts.map +1 -0
  212. package/packages/okf-indexer/dist/index.js +9 -0
  213. package/packages/okf-indexer/dist/index.js.map +1 -0
  214. package/packages/okf-indexer/package.json +1 -1
  215. package/packages/okf-indexer/src/index.ts +9 -0
  216. package/packages/paperclip-integration/package.json +1 -1
  217. package/packages/performance-optimizer/package.json +1 -1
  218. package/packages/permission-mode/package.json +1 -1
  219. package/packages/privilege-broker/package.json +1 -1
  220. package/packages/project-analyzer/package.json +1 -1
  221. package/packages/project-bootstrap/package.json +1 -1
  222. package/packages/projection-engine/package.json +1 -1
  223. package/packages/prompt-compiler/package.json +1 -1
  224. package/packages/prompt-versioning/package.json +1 -1
  225. package/packages/provider-adapter-sdk/package.json +1 -1
  226. package/packages/provider-router/dist/provider-router.d.ts.map +1 -1
  227. package/packages/provider-router/dist/types.d.ts +2 -2
  228. package/packages/provider-router/dist/types.d.ts.map +1 -1
  229. package/packages/provider-router/dist/types.js +1 -1
  230. package/packages/provider-router/package.json +1 -1
  231. package/packages/provider-router/src/types.ts +2 -2
  232. package/packages/provider-selector/package.json +1 -1
  233. package/packages/providers/package.json +1 -1
  234. package/packages/qdrant-skills/package.json +1 -1
  235. package/packages/quota-manager/package.json +1 -1
  236. package/packages/rate-limiter/package.json +1 -1
  237. package/packages/react-vite-plugin/package.json +1 -1
  238. package/packages/relay/package.json +1 -1
  239. package/packages/release-manager/package.json +1 -1
  240. package/packages/requirement-compiler/package.json +1 -1
  241. package/packages/runtime/package.json +1 -1
  242. package/packages/scheduler/dist/index.d.ts +9 -0
  243. package/packages/scheduler/dist/index.d.ts.map +1 -0
  244. package/packages/scheduler/dist/index.js +9 -0
  245. package/packages/scheduler/dist/index.js.map +1 -0
  246. package/packages/scheduler/dist/scheduler.d.ts +17 -0
  247. package/packages/scheduler/dist/scheduler.d.ts.map +1 -0
  248. package/packages/scheduler/dist/scheduler.js +41 -0
  249. package/packages/scheduler/dist/scheduler.js.map +1 -0
  250. package/packages/scheduler/package.json +1 -1
  251. package/packages/scheduler/src/index.ts +9 -0
  252. package/packages/scheduler-adapter/package.json +1 -1
  253. package/packages/session/package.json +1 -1
  254. package/packages/session-api/package.json +1 -1
  255. package/packages/session-export/package.json +1 -1
  256. package/packages/shared-context/dist/index.d.ts +7 -0
  257. package/packages/shared-context/dist/index.d.ts.map +1 -0
  258. package/packages/shared-context/dist/index.js +7 -0
  259. package/packages/shared-context/dist/index.js.map +1 -0
  260. package/packages/shared-context/dist/shared-context.d.ts +12 -0
  261. package/packages/shared-context/dist/shared-context.d.ts.map +1 -0
  262. package/packages/shared-context/dist/shared-context.js +39 -0
  263. package/packages/shared-context/dist/shared-context.js.map +1 -0
  264. package/packages/shared-context/package.json +1 -1
  265. package/packages/skill-mcp-client/dist/client.d.ts +56 -0
  266. package/packages/skill-mcp-client/dist/client.d.ts.map +1 -0
  267. package/packages/skill-mcp-client/dist/client.js +101 -0
  268. package/packages/skill-mcp-client/dist/client.js.map +1 -0
  269. package/packages/skill-mcp-client/dist/errors.d.ts +44 -0
  270. package/packages/skill-mcp-client/dist/errors.d.ts.map +1 -0
  271. package/packages/skill-mcp-client/dist/errors.js +68 -0
  272. package/packages/skill-mcp-client/dist/errors.js.map +1 -0
  273. package/packages/skill-mcp-client/dist/index.d.ts +9 -0
  274. package/packages/skill-mcp-client/dist/index.d.ts.map +1 -0
  275. package/packages/skill-mcp-client/dist/index.js +9 -0
  276. package/packages/skill-mcp-client/dist/index.js.map +1 -0
  277. package/packages/skill-mcp-client/dist/types.d.ts +106 -0
  278. package/packages/skill-mcp-client/dist/types.d.ts.map +1 -0
  279. package/packages/skill-mcp-client/dist/types.js +14 -0
  280. package/packages/skill-mcp-client/dist/types.js.map +1 -0
  281. package/packages/skill-mcp-client/package.json +1 -1
  282. package/packages/skill-registry/package.json +1 -1
  283. package/packages/skills/package.json +1 -5
  284. package/packages/sprint-planner/package.json +1 -1
  285. package/packages/subscription-engine/package.json +1 -1
  286. package/packages/task-compiler/package.json +1 -1
  287. package/packages/telegram/package.json +1 -1
  288. package/packages/telegram/src/agent-messages.d.ts +28 -0
  289. package/packages/telegram/src/agent-messages.js +90 -0
  290. package/packages/telegram/src/bindings.d.ts +296 -0
  291. package/packages/telegram/src/bindings.js +1086 -0
  292. package/packages/telegram/src/bus.d.ts +759 -0
  293. package/packages/telegram/src/bus.js +2732 -0
  294. package/packages/telegram/src/commands.d.ts +761 -0
  295. package/packages/telegram/src/commands.js +2622 -0
  296. package/packages/telegram/src/config.d.ts +222 -0
  297. package/packages/telegram/src/config.js +844 -0
  298. package/packages/telegram/src/delivery.d.ts +161 -0
  299. package/packages/telegram/src/delivery.js +550 -0
  300. package/packages/telegram/src/extension.d.ts +7 -0
  301. package/packages/telegram/src/extension.js +2444 -0
  302. package/packages/telegram/src/inbound.d.ts +94 -0
  303. package/packages/telegram/src/inbound.js +478 -0
  304. package/packages/telegram/src/index.d.ts +6 -0
  305. package/packages/telegram/src/index.js +6 -0
  306. package/packages/telegram/src/keyboard.d.ts +21 -0
  307. package/packages/telegram/src/keyboard.js +37 -0
  308. package/packages/telegram/src/lifecycle.d.ts +210 -0
  309. package/packages/telegram/src/lifecycle.js +538 -0
  310. package/packages/telegram/src/pi.d.ts +76 -0
  311. package/packages/telegram/src/pi.js +130 -0
  312. package/packages/telegram/src/polling.d.ts +332 -0
  313. package/packages/telegram/src/polling.js +1219 -0
  314. package/packages/telegram/src/replies.d.ts +210 -0
  315. package/packages/telegram/src/replies.js +752 -0
  316. package/packages/telegram/src/routing.d.ts +388 -0
  317. package/packages/telegram/src/routing.js +7886 -0
  318. package/packages/telegram/src/runtime.d.ts +159 -0
  319. package/packages/telegram/src/runtime.js +351 -0
  320. package/packages/telegram/src/telegram-api.d.ts +564 -0
  321. package/packages/telegram/src/telegram-api.js +1332 -0
  322. package/packages/telegram/src/turns.d.ts +108 -0
  323. package/packages/telegram/src/turns.js +482 -0
  324. package/packages/telegram/src/updates.d.ts +1545 -0
  325. package/packages/telegram/src/updates.js +6420 -0
  326. package/packages/tencentdb-memory/package.json +1 -1
  327. package/packages/tencentdb-sync/package.json +1 -1
  328. package/packages/test-data-generator/package.json +1 -1
  329. package/packages/test-generator/package.json +1 -1
  330. package/packages/todo-bd-sync/dist/detector.d.ts +54 -0
  331. package/packages/todo-bd-sync/dist/detector.d.ts.map +1 -0
  332. package/packages/todo-bd-sync/dist/detector.js +132 -0
  333. package/packages/todo-bd-sync/dist/detector.js.map +1 -0
  334. package/packages/todo-bd-sync/dist/extension.d.ts +30 -0
  335. package/packages/todo-bd-sync/dist/extension.d.ts.map +1 -0
  336. package/packages/todo-bd-sync/dist/extension.js +35 -0
  337. package/packages/todo-bd-sync/dist/extension.js.map +1 -0
  338. package/packages/todo-bd-sync/dist/index.d.ts +87 -0
  339. package/packages/todo-bd-sync/dist/index.d.ts.map +1 -0
  340. package/packages/todo-bd-sync/dist/index.js +296 -0
  341. package/packages/todo-bd-sync/dist/index.js.map +1 -0
  342. package/packages/todo-bd-sync/dist/sync.d.ts +72 -0
  343. package/packages/todo-bd-sync/dist/sync.d.ts.map +1 -0
  344. package/packages/todo-bd-sync/dist/sync.js +290 -0
  345. package/packages/todo-bd-sync/dist/sync.js.map +1 -0
  346. package/packages/todo-bd-sync/dist/task-analyzer.d.ts +49 -0
  347. package/packages/todo-bd-sync/dist/task-analyzer.d.ts.map +1 -0
  348. package/packages/todo-bd-sync/dist/task-analyzer.js +240 -0
  349. package/packages/todo-bd-sync/dist/task-analyzer.js.map +1 -0
  350. package/packages/todo-bd-sync/dist/todo-reminder.d.ts +126 -0
  351. package/packages/todo-bd-sync/dist/todo-reminder.d.ts.map +1 -0
  352. package/packages/todo-bd-sync/dist/todo-reminder.js +329 -0
  353. package/packages/todo-bd-sync/dist/todo-reminder.js.map +1 -0
  354. package/packages/todo-bd-sync/dist/types.d.ts +65 -0
  355. package/packages/todo-bd-sync/dist/types.d.ts.map +1 -0
  356. package/packages/todo-bd-sync/dist/types.js +67 -0
  357. package/packages/todo-bd-sync/dist/types.js.map +1 -0
  358. package/packages/todo-bd-sync/package.json +1 -1
  359. package/packages/token-estimation/dist/index.d.ts +94 -0
  360. package/packages/token-estimation/dist/index.d.ts.map +1 -0
  361. package/packages/token-estimation/dist/index.js +115 -0
  362. package/packages/token-estimation/dist/index.js.map +1 -0
  363. package/packages/token-estimation/package.json +1 -1
  364. package/packages/token-optimizer/package.json +1 -1
  365. package/packages/trajectory/package.json +1 -1
  366. package/packages/tui/package.json +1 -1
  367. package/packages/types/dist/ai-providers.d.ts +36 -0
  368. package/packages/types/dist/ai-providers.d.ts.map +1 -0
  369. package/packages/types/dist/ai-providers.js +66 -0
  370. package/packages/types/dist/ai-providers.js.map +1 -0
  371. package/packages/types/dist/index.d.ts +12 -0
  372. package/packages/types/dist/index.d.ts.map +1 -0
  373. package/packages/types/dist/index.js +12 -0
  374. package/packages/types/dist/index.js.map +1 -0
  375. package/packages/types/package.json +5 -5
  376. package/packages/types/src/index.ts +12 -0
  377. package/packages/voice-api/package.json +1 -1
  378. package/packages/webmcp-tester/package.json +1 -1
  379. package/packages/wiki/package.json +1 -1
  380. package/packages/workflow-events/package.json +1 -1
  381. package/packages/workspace-scanner/package.json +1 -1
  382. package/packages/worktree/package.json +1 -1
  383. package/packages/worktree/worktree.ts +1 -1
  384. package/packages/write-review/package.json +1 -1
  385. package/renderer.ts +1 -1
  386. package/scripts/build-packages.ts +162 -0
  387. package/scripts/relay-client.ts +2 -2
  388. package/scripts/typecheck-packages.mjs +3 -3
  389. package/scripts/unified-webhook-server.ts +22 -10
  390. package/scripts/verify-package-contents.ts +345 -0
  391. package/scripts/ws-server.ts +1 -1
  392. package/tracker.ts +1 -1
  393. package/harness/browser-scrapers/base-browser-scraper.d.ts +0 -91
  394. package/harness/browser-scrapers/chrome-profile-manager.d.ts +0 -80
  395. package/harness/browser-scrapers/codex-browser-scraper.d.ts +0 -60
  396. package/harness/browser-scrapers/index.d.ts +0 -29
  397. package/harness/browser-scrapers/zai-browser-scraper.d.ts +0 -79
  398. package/harness/e2e/browser-scrapers/base-browser-scraper.d.ts +0 -92
  399. package/harness/e2e/browser-scrapers/chrome-profile-manager.d.ts +0 -81
  400. package/harness/e2e/browser-scrapers/codex-browser-scraper.d.ts +0 -61
  401. package/harness/e2e/browser-scrapers/index.d.ts +0 -30
  402. package/harness/e2e/browser-scrapers/zai-browser-scraper.d.ts +0 -80
  403. package/harness/langchain/agents.d.ts +0 -143
  404. package/harness/langchain/agents.test.d.ts +0 -2
  405. package/harness/langchain/checkpointer.d.ts +0 -48
  406. package/harness/langchain/checkpointer.test.d.ts +0 -8
  407. package/harness/langchain/cron-cli.d.ts +0 -12
  408. package/harness/langchain/daemon.d.ts +0 -161
  409. package/harness/langchain/daemon.test.d.ts +0 -11
  410. package/harness/langchain/file-tools.d.ts +0 -97
  411. package/harness/langchain/graph.d.ts +0 -706
  412. package/harness/langchain/model-router.d.ts +0 -63
  413. package/harness/langchain/model-router.test.d.ts +0 -2
  414. package/harness/langchain/models.d.ts +0 -72
  415. package/harness/langchain/ping-pong-middleware.d.ts +0 -28
  416. package/harness/langchain/ping-pong-middleware.test.d.ts +0 -2
  417. package/harness/langchain/run.d.ts +0 -15
  418. package/harness/langchain/scoreboard.test.d.ts +0 -13
  419. package/harness/langchain/status-line.d.ts +0 -91
  420. package/harness/langchain/status-line.test.d.ts +0 -8
  421. package/harness/langchain/surge.d.ts +0 -111
  422. package/harness/langchain/surge.test.d.ts +0 -10
  423. package/harness/langchain/widget.d.ts +0 -105
  424. package/harness/langchain/widget.test.d.ts +0 -8
  425. package/packages/autonomous-runtime/dist/worker.d.ts +0 -63
  426. package/packages/autonomous-runtime/dist/worker.js +0 -133
  427. package/packages/capability-registry/src/types.d.ts +0 -47
  428. package/packages/clipboard/dist/clipboard.d.ts +0 -11
  429. package/packages/clipboard/dist/clipboard.js +0 -40
  430. package/packages/clipboard/dist/index.d.ts +0 -2
  431. package/packages/clipboard/dist/index.js +0 -2
  432. package/packages/clipboard/dist/types.d.ts +0 -13
  433. package/packages/clipboard/dist/types.js +0 -5
  434. package/packages/context-discovery/dist/discover.d.ts +0 -3
  435. package/packages/context-discovery/dist/discover.js +0 -42
  436. package/packages/context-discovery/dist/discovery.d.ts +0 -28
  437. package/packages/context-discovery/dist/discovery.js +0 -21
  438. package/packages/context-discovery/dist/index.d.ts +0 -3
  439. package/packages/context-discovery/dist/index.js +0 -2
  440. package/packages/context-discovery/dist/types.d.ts +0 -16
  441. package/packages/context-discovery/dist/types.js +0 -2
  442. package/packages/event-bus/dist/bus.d.ts +0 -15
  443. package/packages/event-bus/dist/bus.js +0 -90
  444. package/packages/event-bus/dist/index.d.ts +0 -4
  445. package/packages/event-bus/dist/index.js +0 -3
  446. package/packages/event-bus/dist/test/bus.test.js +0 -52
  447. package/packages/event-bus/dist/types.d.ts +0 -27
  448. package/packages/event-bus/dist/types.js +0 -10
  449. package/packages/event-store/dist/index.d.ts +0 -3
  450. package/packages/event-store/dist/index.js +0 -2
  451. package/packages/event-store/dist/store.d.ts +0 -15
  452. package/packages/event-store/dist/store.js +0 -131
  453. package/packages/event-store/dist/test/store.test.js +0 -57
  454. package/packages/event-store/dist/types.d.ts +0 -48
  455. package/packages/event-store/dist/types.js +0 -5
  456. package/packages/event-store/src/types.d.ts +0 -48
  457. package/packages/file-copy-helper/dist/src/extension.js +0 -186
  458. package/packages/model-registry/src/types.d.ts +0 -63
  459. package/packages/notification/dist/src/adapters/email-adapter.d.ts +0 -17
  460. package/packages/notification/dist/src/adapters/email-adapter.d.ts.map +0 -1
  461. package/packages/notification/dist/src/adapters/email-adapter.js +0 -89
  462. package/packages/notification/dist/src/adapters/email-adapter.js.map +0 -1
  463. package/packages/notification/dist/src/adapters/line-adapter.d.ts +0 -17
  464. package/packages/notification/dist/src/adapters/line-adapter.d.ts.map +0 -1
  465. package/packages/notification/dist/src/adapters/line-adapter.js +0 -99
  466. package/packages/notification/dist/src/adapters/line-adapter.js.map +0 -1
  467. package/packages/notification/dist/src/adapters/ntfy-adapter.d.ts +0 -17
  468. package/packages/notification/dist/src/adapters/ntfy-adapter.d.ts.map +0 -1
  469. package/packages/notification/dist/src/adapters/ntfy-adapter.js +0 -84
  470. package/packages/notification/dist/src/adapters/ntfy-adapter.js.map +0 -1
  471. package/packages/notification/dist/src/adapters/telegram-adapter.d.ts +0 -56
  472. package/packages/notification/dist/src/adapters/telegram-adapter.d.ts.map +0 -1
  473. package/packages/notification/dist/src/adapters/telegram-adapter.js +0 -251
  474. package/packages/notification/dist/src/adapters/telegram-adapter.js.map +0 -1
  475. package/packages/notification/dist/src/adapters/webhook-adapter.d.ts +0 -15
  476. package/packages/notification/dist/src/adapters/webhook-adapter.d.ts.map +0 -1
  477. package/packages/notification/dist/src/adapters/webhook-adapter.js +0 -64
  478. package/packages/notification/dist/src/adapters/webhook-adapter.js.map +0 -1
  479. package/packages/notification/dist/src/base-adapter.d.ts +0 -36
  480. package/packages/notification/dist/src/base-adapter.d.ts.map +0 -1
  481. package/packages/notification/dist/src/base-adapter.js +0 -39
  482. package/packages/notification/dist/src/base-adapter.js.map +0 -1
  483. package/packages/notification/dist/src/index.d.ts +0 -12
  484. package/packages/notification/dist/src/index.d.ts.map +0 -1
  485. package/packages/notification/dist/src/index.js +0 -12
  486. package/packages/notification/dist/src/index.js.map +0 -1
  487. package/packages/notification/dist/src/notification-center.d.ts +0 -89
  488. package/packages/notification/dist/src/notification-center.d.ts.map +0 -1
  489. package/packages/notification/dist/src/notification-center.js +0 -356
  490. package/packages/notification/dist/src/notification-center.js.map +0 -1
  491. package/packages/notification/dist/src/notification-policy.d.ts +0 -66
  492. package/packages/notification/dist/src/notification-policy.d.ts.map +0 -1
  493. package/packages/notification/dist/src/notification-policy.js +0 -153
  494. package/packages/notification/dist/src/notification-policy.js.map +0 -1
  495. package/packages/notification/dist/src/telegram-webhook-handler.d.ts +0 -86
  496. package/packages/notification/dist/src/telegram-webhook-handler.d.ts.map +0 -1
  497. package/packages/notification/dist/src/telegram-webhook-handler.js +0 -149
  498. package/packages/notification/dist/src/telegram-webhook-handler.js.map +0 -1
  499. package/packages/notification/dist/src/types.d.ts +0 -106
  500. package/packages/notification/dist/src/types.d.ts.map +0 -1
  501. package/packages/notification/dist/src/types.js +0 -7
  502. package/packages/notification/dist/src/types.js.map +0 -1
  503. package/packages/projection-engine/dist/engine.d.ts +0 -61
  504. package/packages/projection-engine/dist/engine.js +0 -76
  505. package/packages/projection-engine/dist/index.d.ts +0 -2
  506. package/packages/projection-engine/dist/index.js +0 -2
  507. package/packages/projection-engine/dist/project.d.ts +0 -3
  508. package/packages/projection-engine/dist/project.js +0 -24
  509. package/packages/projection-engine/dist/types.d.ts +0 -55
  510. package/packages/projection-engine/dist/types.js +0 -5
  511. package/packages/projection-engine/src/types.d.ts +0 -55
  512. package/packages/provider-adapter-sdk/dist/src/builder.d.ts +0 -140
  513. package/packages/provider-adapter-sdk/dist/src/builder.d.ts.map +0 -1
  514. package/packages/provider-adapter-sdk/dist/src/builder.js +0 -332
  515. package/packages/provider-adapter-sdk/dist/src/builder.js.map +0 -1
  516. package/packages/provider-adapter-sdk/dist/src/errors.d.ts +0 -71
  517. package/packages/provider-adapter-sdk/dist/src/errors.d.ts.map +0 -1
  518. package/packages/provider-adapter-sdk/dist/src/errors.js +0 -111
  519. package/packages/provider-adapter-sdk/dist/src/errors.js.map +0 -1
  520. package/packages/provider-adapter-sdk/dist/src/index.d.ts +0 -15
  521. package/packages/provider-adapter-sdk/dist/src/index.d.ts.map +0 -1
  522. package/packages/provider-adapter-sdk/dist/src/index.js +0 -19
  523. package/packages/provider-adapter-sdk/dist/src/index.js.map +0 -1
  524. package/packages/provider-adapter-sdk/dist/src/registry.d.ts +0 -108
  525. package/packages/provider-adapter-sdk/dist/src/registry.d.ts.map +0 -1
  526. package/packages/provider-adapter-sdk/dist/src/registry.js +0 -301
  527. package/packages/provider-adapter-sdk/dist/src/registry.js.map +0 -1
  528. package/packages/provider-adapter-sdk/dist/src/tester.d.ts +0 -71
  529. package/packages/provider-adapter-sdk/dist/src/tester.d.ts.map +0 -1
  530. package/packages/provider-adapter-sdk/dist/src/tester.js +0 -392
  531. package/packages/provider-adapter-sdk/dist/src/tester.js.map +0 -1
  532. package/packages/provider-adapter-sdk/dist/src/types.d.ts +0 -182
  533. package/packages/provider-adapter-sdk/dist/src/types.d.ts.map +0 -1
  534. package/packages/provider-adapter-sdk/dist/src/types.js +0 -11
  535. package/packages/provider-adapter-sdk/dist/src/types.js.map +0 -1
  536. package/packages/provider-router/dist/capability-registry/src/types.d.ts +0 -47
  537. package/packages/provider-router/dist/capability-registry/src/types.d.ts.map +0 -1
  538. package/packages/provider-router/dist/capability-registry/src/types.js +0 -10
  539. package/packages/provider-router/dist/capability-registry/src/types.js.map +0 -1
  540. package/packages/provider-router/dist/provider-router/src/index.d.ts +0 -23
  541. package/packages/provider-router/dist/provider-router/src/index.d.ts.map +0 -1
  542. package/packages/provider-router/dist/provider-router/src/index.js +0 -25
  543. package/packages/provider-router/dist/provider-router/src/index.js.map +0 -1
  544. package/packages/provider-router/dist/provider-router/src/policy.d.ts +0 -10
  545. package/packages/provider-router/dist/provider-router/src/policy.d.ts.map +0 -1
  546. package/packages/provider-router/dist/provider-router/src/policy.js +0 -45
  547. package/packages/provider-router/dist/provider-router/src/policy.js.map +0 -1
  548. package/packages/provider-router/dist/provider-router/src/provider-router.d.ts +0 -56
  549. package/packages/provider-router/dist/provider-router/src/provider-router.d.ts.map +0 -1
  550. package/packages/provider-router/dist/provider-router/src/provider-router.js +0 -222
  551. package/packages/provider-router/dist/provider-router/src/provider-router.js.map +0 -1
  552. package/packages/provider-router/dist/provider-router/src/strategies.d.ts +0 -19
  553. package/packages/provider-router/dist/provider-router/src/strategies.d.ts.map +0 -1
  554. package/packages/provider-router/dist/provider-router/src/strategies.js +0 -110
  555. package/packages/provider-router/dist/provider-router/src/strategies.js.map +0 -1
  556. package/packages/provider-router/dist/provider-router/src/types.d.ts +0 -91
  557. package/packages/provider-router/dist/provider-router/src/types.d.ts.map +0 -1
  558. package/packages/provider-router/dist/provider-router/src/types.js +0 -10
  559. package/packages/provider-router/dist/provider-router/src/types.js.map +0 -1
  560. package/packages/provider-router/dist/src/index.d.ts +0 -23
  561. package/packages/provider-router/dist/src/index.d.ts.map +0 -1
  562. package/packages/provider-router/dist/src/index.js +0 -25
  563. package/packages/provider-router/dist/src/index.js.map +0 -1
  564. package/packages/provider-router/dist/src/policy.d.ts +0 -10
  565. package/packages/provider-router/dist/src/policy.d.ts.map +0 -1
  566. package/packages/provider-router/dist/src/policy.js +0 -45
  567. package/packages/provider-router/dist/src/policy.js.map +0 -1
  568. package/packages/provider-router/dist/src/provider-router.d.ts +0 -56
  569. package/packages/provider-router/dist/src/provider-router.d.ts.map +0 -1
  570. package/packages/provider-router/dist/src/provider-router.js +0 -222
  571. package/packages/provider-router/dist/src/provider-router.js.map +0 -1
  572. package/packages/provider-router/dist/src/strategies.d.ts +0 -19
  573. package/packages/provider-router/dist/src/strategies.d.ts.map +0 -1
  574. package/packages/provider-router/dist/src/strategies.js +0 -110
  575. package/packages/provider-router/dist/src/strategies.js.map +0 -1
  576. package/packages/provider-router/dist/src/types.d.ts +0 -91
  577. package/packages/provider-router/dist/src/types.d.ts.map +0 -1
  578. package/packages/provider-router/dist/src/types.js +0 -10
  579. package/packages/provider-router/dist/src/types.js.map +0 -1
  580. package/packages/provider-router/dist/types/src/runtime-types.d.ts +0 -412
  581. package/packages/provider-router/dist/types/src/runtime-types.d.ts.map +0 -1
  582. package/packages/provider-router/dist/types/src/runtime-types.js +0 -2
  583. package/packages/provider-router/dist/types/src/runtime-types.js.map +0 -1
  584. package/packages/session-api/dist/api.d.ts +0 -83
  585. package/packages/session-api/dist/api.js +0 -35
  586. package/packages/session-api/dist/index.d.ts +0 -2
  587. package/packages/session-api/dist/index.js +0 -2
  588. package/packages/session-api/dist/types.d.ts +0 -22
  589. package/packages/session-api/dist/types.js +0 -5
  590. package/packages/session-export/dist/exporter.d.ts +0 -28
  591. package/packages/session-export/dist/exporter.js +0 -38
  592. package/packages/session-export/dist/index.d.ts +0 -2
  593. package/packages/session-export/dist/index.js +0 -2
  594. package/packages/session-export/dist/types.d.ts +0 -20
  595. package/packages/session-export/dist/types.js +0 -5
  596. package/packages/subscription-engine/dist/engine.d.ts +0 -13
  597. package/packages/subscription-engine/dist/engine.js +0 -40
  598. package/packages/subscription-engine/dist/index.d.ts +0 -2
  599. package/packages/subscription-engine/dist/index.js +0 -2
  600. package/packages/subscription-engine/dist/subscriptions.d.ts +0 -19
  601. package/packages/subscription-engine/dist/subscriptions.js +0 -32
  602. package/packages/subscription-engine/dist/types.d.ts +0 -24
  603. package/packages/subscription-engine/dist/types.js +0 -5
  604. package/packages/trajectory/test/store.test.d.ts +0 -2
  605. package/packages/workflow-events/dist/events.d.ts +0 -38
  606. package/packages/workflow-events/dist/events.js +0 -46
  607. package/packages/workflow-events/dist/index.d.ts +0 -2
  608. package/packages/workflow-events/dist/index.js +0 -2
  609. package/packages/workflow-events/dist/pipeline.d.ts +0 -21
  610. package/packages/workflow-events/dist/pipeline.js +0 -27
  611. package/packages/workflow-events/dist/types.d.ts +0 -110
  612. package/packages/workflow-events/dist/types.js +0 -5
  613. package/packages/workflow-events/src/types.d.ts +0 -110
@@ -0,0 +1,192 @@
1
+ /**
2
+ * Durable incident storage.
3
+ *
4
+ * The log index answers "which records exist"; the incident store answers
5
+ * "what is actually broken". It keeps the derived incidents of a tenant in
6
+ * plain NDJSON files, one per tenant and day:
7
+ *
8
+ * <dir>/<tenant>/incidents-<day>.ndjson
9
+ *
10
+ * The store is tenant scoped by construction: the tenant is a parameter of
11
+ * every method and the server fills it from the authenticated credential.
12
+ * A caller can therefore never read or write another tenant's incidents.
13
+ */
14
+
15
+ import { appendFileSync, existsSync, mkdirSync, readFileSync, readdirSync } from "node:fs";
16
+ import { join } from "node:path";
17
+ import {
18
+ INCIDENT_SCHEMA_VERSION,
19
+ mergeIncident,
20
+ type LogIncident,
21
+ } from "../incidents/schema.js";
22
+ import { safeSegment } from "./outbox.js";
23
+
24
+ export interface IncidentQueryParams {
25
+ /** Tenant of the authenticated caller. Required. */
26
+ tenantId: string;
27
+ /** Only incidents of this severity. */
28
+ severity?: "warn" | "error";
29
+ /** Only incidents of this component. */
30
+ source?: string;
31
+ /** Only incidents of this event. */
32
+ event?: string;
33
+ /** ISO timestamp, inclusive lower bound on `lastSeen`. */
34
+ since?: string;
35
+ /** ISO timestamp, exclusive upper bound on `lastSeen`. */
36
+ until?: string;
37
+ /** Maximum number of incidents. Default 50, hard maximum 200. */
38
+ limit?: number;
39
+ }
40
+
41
+ export interface IncidentQueryResult {
42
+ incidents: LogIncident[];
43
+ /** True when the scan hit its day budget. */
44
+ truncated: boolean;
45
+ /** Number of day files that were read. */
46
+ scannedFiles: number;
47
+ }
48
+
49
+ export interface IncidentStoreOptions {
50
+ dir: string;
51
+ /** Days a query may scan back. Default 7, hard maximum 31. */
52
+ maxScanDays?: number;
53
+ /** Incidents per page by default. */
54
+ defaultLimit?: number;
55
+ /** Hard maximum of incidents per page. */
56
+ maxLimit?: number;
57
+ }
58
+
59
+ function toIsoDay(value: Date): string {
60
+ return value.toISOString().slice(0, 10);
61
+ }
62
+
63
+ export class IncidentStore {
64
+ private readonly dir: string;
65
+ private readonly maxScanDays: number;
66
+ private readonly defaultLimit: number;
67
+ private readonly maxLimit: number;
68
+
69
+ constructor(options: IncidentStoreOptions) {
70
+ this.dir = options.dir;
71
+ this.maxScanDays = Math.min(options.maxScanDays ?? 7, 31);
72
+ this.defaultLimit = options.defaultLimit ?? 50;
73
+ this.maxLimit = options.maxLimit ?? 200;
74
+ }
75
+
76
+ /**
77
+ * Persist the incidents of one batch.
78
+ *
79
+ * The write is best effort: a failing store must never lose the batch
80
+ * itself. The returned number is the number of incidents that were
81
+ * written.
82
+ */
83
+ append(incidents: LogIncident[]): number {
84
+ if (!Array.isArray(incidents) || incidents.length === 0) return 0;
85
+ const lines = incidents
86
+ .filter((incident) => incident && incident.fingerprint)
87
+ .map((incident) => JSON.stringify({ ...incident, schemaVersion: INCIDENT_SCHEMA_VERSION }));
88
+ if (lines.length === 0) return 0;
89
+
90
+ const day = toIsoDay(new Date());
91
+ try {
92
+ const dir = join(this.dir, safeSegment(incidents[0].tenantId));
93
+ mkdirSync(dir, { recursive: true });
94
+ appendFileSync(join(dir, `incidents-${day}.ndjson`), `${lines.join("\n")}\n`, {
95
+ mode: 0o600,
96
+ });
97
+ return lines.length;
98
+ } catch {
99
+ return 0;
100
+ }
101
+ }
102
+
103
+ /**
104
+ * Query the incidents of one tenant.
105
+ *
106
+ * The incidents of the scanned files are merged by fingerprint, so a
107
+ * failure that was seen in many batches is one incident with a summed
108
+ * count, not many incidents.
109
+ */
110
+ query(params: IncidentQueryParams): IncidentQueryResult {
111
+ const limit = Math.min(params.limit ?? this.defaultLimit, this.maxLimit);
112
+ const dir = join(this.dir, safeSegment(params.tenantId));
113
+ const merged = new Map<string, LogIncident>();
114
+ let scannedFiles = 0;
115
+ let truncated = false;
116
+
117
+ for (const day of this.dayRange(params.since)) {
118
+ const path = join(dir, `incidents-${day}.ndjson`);
119
+ if (!existsSync(path)) continue;
120
+ scannedFiles++;
121
+ let content: string;
122
+ try {
123
+ content = readFileSync(path, "utf8");
124
+ } catch {
125
+ continue;
126
+ }
127
+ for (const line of content.split("\n")) {
128
+ if (!line.trim()) continue;
129
+ let incident: LogIncident;
130
+ try {
131
+ incident = JSON.parse(line) as LogIncident;
132
+ } catch {
133
+ continue;
134
+ }
135
+ if (!incident.fingerprint) continue;
136
+ if (!this.matches(incident, params)) continue;
137
+ const existing = merged.get(incident.fingerprint);
138
+ merged.set(
139
+ incident.fingerprint,
140
+ existing ? mergeIncident(existing, incident) : incident,
141
+ );
142
+ }
143
+ }
144
+
145
+ const incidents = [...merged.values()]
146
+ .sort((a, b) => {
147
+ if (a.severity !== b.severity) return a.severity === "error" ? -1 : 1;
148
+ return b.lastSeen.localeCompare(a.lastSeen);
149
+ })
150
+ .slice(0, limit);
151
+
152
+ return { incidents, truncated, scannedFiles };
153
+ }
154
+
155
+ /** The days a query may read, oldest first. */
156
+ private dayRange(since?: string): string[] {
157
+ const days: string[] = [];
158
+ const end = new Date();
159
+ const start = new Date(end.getTime() - (this.maxScanDays - 1) * 86_400_000);
160
+ if (since) {
161
+ const parsed = new Date(since);
162
+ if (!Number.isNaN(parsed.getTime()) && parsed > start) start.setTime(parsed.getTime());
163
+ }
164
+ for (let day = new Date(start); day <= end; day.setTime(day.getTime() + 86_400_000)) {
165
+ days.push(toIsoDay(day));
166
+ }
167
+ return days;
168
+ }
169
+
170
+ /** Does the incident match the filters of the query? */
171
+ private matches(incident: LogIncident, params: IncidentQueryParams): boolean {
172
+ if (incident.tenantId !== params.tenantId) return false;
173
+ if (params.severity && incident.severity !== params.severity) return false;
174
+ if (params.source && incident.source !== params.source) return false;
175
+ if (params.event && incident.event !== params.event) return false;
176
+ if (params.since && incident.lastSeen < params.since) return false;
177
+ if (params.until && incident.lastSeen >= params.until) return false;
178
+ return true;
179
+ }
180
+
181
+ /** The tenant directories of the store. Used by the maintenance tests. */
182
+ tenants(): string[] {
183
+ if (!existsSync(this.dir)) return [];
184
+ try {
185
+ return readdirSync(this.dir, { withFileTypes: true })
186
+ .filter((entry) => entry.isDirectory())
187
+ .map((entry) => entry.name);
188
+ } catch {
189
+ return [];
190
+ }
191
+ }
192
+ }
@@ -54,3 +54,24 @@ export type {
54
54
 
55
55
  export { createLogHttpHandler } from "./http.js";
56
56
  export type { LogHttpHandler, LogHttpOptions } from "./http.js";
57
+
58
+ export { IncidentStore } from "./incident-store.js";
59
+ export type {
60
+ IncidentQueryParams,
61
+ IncidentQueryResult,
62
+ IncidentStoreOptions,
63
+ } from "./incident-store.js";
64
+
65
+ export {
66
+ INCIDENT_COLLECTION_NAME,
67
+ IncidentQdrantWriter,
68
+ incidentPointId,
69
+ incidentVector,
70
+ tenantFilter,
71
+ toIncidentPayload,
72
+ } from "./incident-qdrant.js";
73
+ export type {
74
+ IncidentPayload,
75
+ IncidentPoint,
76
+ QdrantLike,
77
+ } from "./incident-qdrant.js";
@@ -11,6 +11,7 @@
11
11
  */
12
12
 
13
13
  import { validateBatch, type BatchValidationLimits } from "../ingest/schema.js";
14
+ import { extractIncidents, type LogIncident } from "../incidents/schema.js";
14
15
  import {
15
16
  LOG_READ_SCOPE,
16
17
  LOG_WRITE_SCOPE,
@@ -19,6 +20,8 @@ import {
19
20
  } from "./credentials.js";
20
21
  import { serverObjectKey } from "./keys.js";
21
22
  import type { LogIndexStore, LogQueryParams, LogQueryResult } from "./index-store.js";
23
+ import type { IncidentQueryParams, IncidentStore } from "./incident-store.js";
24
+ import type { IncidentQdrantWriter } from "./incident-qdrant.js";
22
25
  import type { LogOutbox, OutboxBatch } from "./outbox.js";
23
26
 
24
27
  export interface IngestSuccess {
@@ -52,20 +55,35 @@ export interface LogIngestServiceOptions {
52
55
  credentials: LogCredentialStore;
53
56
  outbox: LogOutbox;
54
57
  index: LogIndexStore;
58
+ /** Durable storage of the derived incidents. Optional. */
59
+ incidents?: IncidentStore;
60
+ /** Searchable view of the incidents. Optional. */
61
+ incidentIndex?: IncidentQdrantWriter;
55
62
  /** Validation limits for an inbound batch. */
56
63
  limits?: Partial<BatchValidationLimits>;
57
64
  }
58
65
 
66
+ export interface IncidentQuerySuccess {
67
+ incidents: LogIncident[];
68
+ truncated: boolean;
69
+ scannedFiles: number;
70
+ tenantId: string;
71
+ }
72
+
59
73
  export class LogIngestService {
60
74
  private readonly credentials: LogCredentialStore;
61
75
  private readonly outbox: LogOutbox;
62
76
  private readonly index: LogIndexStore;
77
+ private readonly incidents: IncidentStore | undefined;
78
+ private readonly incidentIndex: IncidentQdrantWriter | undefined;
63
79
  private readonly limits: Partial<BatchValidationLimits>;
64
80
 
65
81
  constructor(options: LogIngestServiceOptions) {
66
82
  this.credentials = options.credentials;
67
83
  this.outbox = options.outbox;
68
84
  this.index = options.index;
85
+ this.incidents = options.incidents;
86
+ this.incidentIndex = options.incidentIndex;
69
87
  this.limits = options.limits ?? {};
70
88
  }
71
89
 
@@ -136,6 +154,9 @@ export class LogIngestService {
136
154
  // The metadata index is best effort: a failing index never loses
137
155
  // the batch itself.
138
156
  this.index.append(batch, serverObjectKey(batch));
157
+ // The same holds for the derived incidents: they are a view of
158
+ // the batch, never a precondition for accepting it.
159
+ this.recordIncidents(batch);
139
160
  return {
140
161
  status: 202,
141
162
  body: {
@@ -193,4 +214,62 @@ export class LogIngestService {
193
214
  if (result.nextCursor) body.nextCursor = result.nextCursor;
194
215
  return { status: 200, body };
195
216
  }
217
+
218
+ /**
219
+ * Derive the incidents of a batch and store them.
220
+ *
221
+ * The tenant comes from the credential that was authenticated, never
222
+ * from the batch itself. A failing store or a failing Qdrant never
223
+ * affects the acceptance of the batch.
224
+ */
225
+ private recordIncidents(batch: OutboxBatch): void {
226
+ if (!this.incidents && !this.incidentIndex) return;
227
+ const derived = extractIncidents(batch.records, batch.tenantId, batch.installationId);
228
+ if (derived.length === 0) return;
229
+ if (this.incidents) this.incidents.append(derived);
230
+ if (this.incidentIndex) void this.incidentIndex.upsert(derived);
231
+ }
232
+
233
+ /**
234
+ * Query the incidents of the tenant of the caller.
235
+ *
236
+ * The `tenantId` of the request is ignored on purpose - only the
237
+ * credential decides whose incidents are visible.
238
+ */
239
+ queryIncidents(
240
+ params: Omit<IncidentQueryParams, "tenantId">,
241
+ bearerToken: string | undefined,
242
+ ): { status: number; body: IncidentQuerySuccess | IngestFailure } {
243
+ if (!this.credentials.configured) {
244
+ return {
245
+ status: 503,
246
+ body: { error: "log ingest is not configured", code: "ingest_unconfigured" },
247
+ };
248
+ }
249
+
250
+ const auth = this.credentials.authenticate(bearerToken);
251
+ if (!auth) {
252
+ return { status: 401, body: { error: "unauthorized", code: "unauthorized" } };
253
+ }
254
+ if (!auth.scopes.includes(LOG_READ_SCOPE)) {
255
+ return { status: 403, body: { error: "forbidden", code: "forbidden" } };
256
+ }
257
+ if (!this.incidents) {
258
+ return {
259
+ status: 503,
260
+ body: { error: "incident storage is not configured", code: "incidents_unconfigured" },
261
+ };
262
+ }
263
+
264
+ const result = this.incidents.query({ ...params, tenantId: auth.tenantId });
265
+ return {
266
+ status: 200,
267
+ body: {
268
+ incidents: result.incidents,
269
+ truncated: result.truncated,
270
+ scannedFiles: result.scannedFiles,
271
+ tenantId: auth.tenantId,
272
+ },
273
+ };
274
+ }
196
275
  }
@@ -2,9 +2,25 @@
2
2
  * The shipper owns the delivery decision.
3
3
  *
4
4
  * Producers call `log()`. The shipper redacts, samples, buffers, and then
5
- * delivers a batch through the configured transports in priority order:
5
+ * delivers a batch through the configured transports.
6
6
  *
7
- * R2 (durable archive) -> webhook (live) -> local spool (last resort)
7
+ * Two delivery modes exist:
8
+ *
9
+ * fallback (the default) - the transports form a chain. The first
10
+ * transport that accepts the batch wins and the later ones are not
11
+ * called:
12
+ *
13
+ * R2 (durable archive) -> webhook (live) -> local spool
14
+ *
15
+ * fanout (explicit opt-in) - the transports are independent. Every
16
+ * transport receives the batch, each one tracks its own success, and
17
+ * the batch is spooled only when EVERY transport failed:
18
+ *
19
+ * R2 (durable archive) + webhook (live) -> local spool
20
+ *
21
+ * Fallback is the default because it avoids duplicate records in the
22
+ * archive. Fanout is opt-in because it deliberately creates a second copy
23
+ * of every batch.
8
24
  *
9
25
  * If every transport fails the batch is spooled to disk and retried on the
10
26
  * next flush, so a temporary outage costs latency, not data.
@@ -31,6 +47,28 @@ import {
31
47
  type LogTransport,
32
48
  } from "./types.js";
33
49
 
50
+ /**
51
+ * How the batch is handed to the transports.
52
+ *
53
+ * - `fallback`: the first transport that accepts the batch wins.
54
+ * - `fanout`: every transport receives the batch independently.
55
+ */
56
+ export type DeliveryMode = "fallback" | "fanout";
57
+
58
+ /** The delivery state of one transport. */
59
+ export interface TransportStatus {
60
+ /** The name of the transport. */
61
+ name: string;
62
+ /** How many batches this transport accepted. */
63
+ delivered: number;
64
+ /** How many batches this transport rejected. */
65
+ failed: number;
66
+ /** The message of the last failure. */
67
+ lastError?: string;
68
+ /** ISO timestamp of the last successful delivery. */
69
+ lastSuccessAt?: string;
70
+ }
71
+
34
72
  export interface LogShipperOptions {
35
73
  /** Application name reported with every batch. */
36
74
  app?: string;
@@ -47,6 +85,12 @@ export interface LogShipperOptions {
47
85
  sessionId?: string;
48
86
  /** Transports in priority order. */
49
87
  transports?: LogTransport[];
88
+ /**
89
+ * How the transports are used. `fallback` (the default) lets the first
90
+ * transport that accepts the batch win; `fanout` delivers the batch to
91
+ * every transport independently.
92
+ */
93
+ delivery?: DeliveryMode;
50
94
  /** Local spool used when every transport fails. */
51
95
  spool?: LogSpool;
52
96
  /** Buffer bounds. */
@@ -86,6 +130,8 @@ export class LogShipper {
86
130
  private readonly hostLabel: string | undefined;
87
131
  private readonly sessionId: string | undefined;
88
132
  private readonly transports: LogTransport[];
133
+ private readonly delivery: DeliveryMode;
134
+ private readonly transportStatus = new Map<string, TransportStatus>();
89
135
  private readonly spool: LogSpool | undefined;
90
136
  private readonly buffer: LogBuffer;
91
137
  private readonly sampler: LogSampler;
@@ -112,6 +158,7 @@ export class LogShipper {
112
158
  this.hostLabel = options.hostLabel ?? hostname();
113
159
  this.sessionId = options.sessionId;
114
160
  this.transports = options.transports ?? [];
161
+ this.delivery = options.delivery ?? "fallback";
115
162
  this.spool = options.spool;
116
163
  this.buffer = new LogBuffer(options.buffer);
117
164
  this.sampler = new LogSampler(options.sampling);
@@ -221,6 +268,21 @@ export class LogShipper {
221
268
  };
222
269
  }
223
270
 
271
+ /**
272
+ * The delivery state of every transport.
273
+ *
274
+ * In fanout mode this is the only way to see that one transport is
275
+ * broken while the others still deliver.
276
+ */
277
+ getTransportStatus(): TransportStatus[] {
278
+ return [...this.transportStatus.values()].map((status) => ({ ...status }));
279
+ }
280
+
281
+ /** The delivery mode of the shipper. */
282
+ get deliveryMode(): DeliveryMode {
283
+ return this.delivery;
284
+ }
285
+
224
286
  private buildRecord(input: LogInput): LogRecord {
225
287
  const record: LogRecord = {
226
288
  ts: new Date(this.now()).toISOString(),
@@ -291,20 +353,73 @@ export class LogShipper {
291
353
  }
292
354
  }
293
355
 
294
- /** Try every transport in order. Returns true when one accepted the batch. */
356
+ /**
357
+ * Deliver the batch to the transports.
358
+ *
359
+ * In `fallback` mode the transports form a chain: the first one that
360
+ * accepts the batch wins and the later ones are not called.
361
+ *
362
+ * In `fanout` mode every transport receives the batch independently.
363
+ * Each transport tracks its own success, so a broken transport does not
364
+ * hide the success of the others. The batch is only lost when EVERY
365
+ * transport failed.
366
+ */
295
367
  private async deliver(batch: LogBatch): Promise<boolean> {
368
+ if (this.delivery === "fanout") return this.deliverToAll(batch);
296
369
  for (const transport of this.transports) {
297
370
  try {
298
371
  await transport.send(batch);
372
+ this.noteSuccess(transport.name);
299
373
  return true;
300
374
  } catch (error) {
301
- this.stats.errors[transport.name] =
302
- error instanceof Error ? error.message : String(error);
375
+ this.noteFailure(transport.name, error);
303
376
  }
304
377
  }
305
378
  return false;
306
379
  }
307
380
 
381
+ /** Deliver the batch to every transport. Returns true when one accepted it. */
382
+ private async deliverToAll(batch: LogBatch): Promise<boolean> {
383
+ let accepted = false;
384
+ for (const transport of this.transports) {
385
+ try {
386
+ await transport.send(batch);
387
+ this.noteSuccess(transport.name);
388
+ accepted = true;
389
+ } catch (error) {
390
+ this.noteFailure(transport.name, error);
391
+ }
392
+ }
393
+ return accepted;
394
+ }
395
+
396
+ /** Record a successful delivery. */
397
+ private noteSuccess(name: string): void {
398
+ const status = this.statusFor(name);
399
+ status.delivered++;
400
+ status.lastSuccessAt = new Date(this.now()).toISOString();
401
+ delete status.lastError;
402
+ }
403
+
404
+ /** Record a failed delivery. */
405
+ private noteFailure(name: string, error: unknown): void {
406
+ const message = error instanceof Error ? error.message : String(error);
407
+ this.stats.errors[name] = message;
408
+ const status = this.statusFor(name);
409
+ status.failed++;
410
+ status.lastError = message;
411
+ }
412
+
413
+ /** The delivery state of one transport. */
414
+ private statusFor(name: string): TransportStatus {
415
+ let status = this.transportStatus.get(name);
416
+ if (!status) {
417
+ status = { name, delivered: 0, failed: 0 };
418
+ this.transportStatus.set(name, status);
419
+ }
420
+ return status;
421
+ }
422
+
308
423
  /** Re-send spooled files. Stops at the first failure. */
309
424
  private async drainSpool(): Promise<void> {
310
425
  if (!this.spool) return;
@@ -49,6 +49,7 @@ export function initCentralLogging(
49
49
  appVersion: resolved.appVersion,
50
50
  installationId: resolved.installationId,
51
51
  transports: resolved.transports,
52
+ delivery: resolved.delivery,
52
53
  spool,
53
54
  buffer: resolved.buffer,
54
55
  sampling: resolved.sampling,