@acquiredintelligence/attend 0.0.0-stage → 0.2.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 (254) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +174 -2
  3. package/dist/attend.d.ts +30 -0
  4. package/dist/attend.d.ts.map +1 -0
  5. package/dist/attend.js +464 -0
  6. package/dist/attend.js.map +1 -0
  7. package/dist/cli.d.ts +3 -0
  8. package/dist/cli.d.ts.map +1 -0
  9. package/dist/cli.js +4 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/core/ids.d.ts +12 -0
  12. package/dist/core/ids.d.ts.map +1 -0
  13. package/dist/core/ids.js +97 -0
  14. package/dist/core/ids.js.map +1 -0
  15. package/dist/core/reducer.d.ts +26 -0
  16. package/dist/core/reducer.d.ts.map +1 -0
  17. package/dist/core/reducer.js +437 -0
  18. package/dist/core/reducer.js.map +1 -0
  19. package/dist/core/seen.d.ts +22 -0
  20. package/dist/core/seen.d.ts.map +1 -0
  21. package/dist/core/seen.js +61 -0
  22. package/dist/core/seen.js.map +1 -0
  23. package/dist/core/state.d.ts +12 -0
  24. package/dist/core/state.d.ts.map +1 -0
  25. package/dist/core/state.js +90 -0
  26. package/dist/core/state.js.map +1 -0
  27. package/dist/core/step.d.ts +14 -0
  28. package/dist/core/step.d.ts.map +1 -0
  29. package/dist/core/step.js +17 -0
  30. package/dist/core/step.js.map +1 -0
  31. package/dist/core/threshold.d.ts +40 -0
  32. package/dist/core/threshold.d.ts.map +1 -0
  33. package/dist/core/threshold.js +72 -0
  34. package/dist/core/threshold.js.map +1 -0
  35. package/dist/core/types.d.ts +704 -0
  36. package/dist/core/types.d.ts.map +1 -0
  37. package/dist/core/types.js +24 -0
  38. package/dist/core/types.js.map +1 -0
  39. package/dist/core/window.d.ts +38 -0
  40. package/dist/core/window.d.ts.map +1 -0
  41. package/dist/core/window.js +322 -0
  42. package/dist/core/window.js.map +1 -0
  43. package/dist/decisions.d.ts +53 -0
  44. package/dist/decisions.d.ts.map +1 -0
  45. package/dist/decisions.js +115 -0
  46. package/dist/decisions.js.map +1 -0
  47. package/dist/errors.d.ts +36 -0
  48. package/dist/errors.d.ts.map +1 -0
  49. package/dist/errors.js +53 -0
  50. package/dist/errors.js.map +1 -0
  51. package/dist/index.d.ts +10 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +4 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/internal/adapter.d.ts +21 -0
  56. package/dist/internal/adapter.d.ts.map +1 -0
  57. package/dist/internal/adapter.js +62 -0
  58. package/dist/internal/adapter.js.map +1 -0
  59. package/dist/internal/assert.d.ts +5 -0
  60. package/dist/internal/assert.d.ts.map +1 -0
  61. package/dist/internal/assert.js +14 -0
  62. package/dist/internal/assert.js.map +1 -0
  63. package/dist/internal/clock.d.ts +8 -0
  64. package/dist/internal/clock.d.ts.map +1 -0
  65. package/dist/internal/clock.js +38 -0
  66. package/dist/internal/clock.js.map +1 -0
  67. package/dist/internal/http.d.ts +42 -0
  68. package/dist/internal/http.d.ts.map +1 -0
  69. package/dist/internal/http.js +122 -0
  70. package/dist/internal/http.js.map +1 -0
  71. package/dist/internal/images.d.ts +18 -0
  72. package/dist/internal/images.d.ts.map +1 -0
  73. package/dist/internal/images.js +75 -0
  74. package/dist/internal/images.js.map +1 -0
  75. package/dist/internal/json.d.ts +3 -0
  76. package/dist/internal/json.d.ts.map +1 -0
  77. package/dist/internal/json.js +5 -0
  78. package/dist/internal/json.js.map +1 -0
  79. package/dist/internal/prompt.d.ts +31 -0
  80. package/dist/internal/prompt.d.ts.map +1 -0
  81. package/dist/internal/prompt.js +149 -0
  82. package/dist/internal/prompt.js.map +1 -0
  83. package/dist/internal/shared.d.ts +12 -0
  84. package/dist/internal/shared.d.ts.map +1 -0
  85. package/dist/internal/shared.js +138 -0
  86. package/dist/internal/shared.js.map +1 -0
  87. package/dist/jev.d.ts +74 -0
  88. package/dist/jev.d.ts.map +1 -0
  89. package/dist/jev.js +156 -0
  90. package/dist/jev.js.map +1 -0
  91. package/dist/llm.d.ts +164 -0
  92. package/dist/llm.d.ts.map +1 -0
  93. package/dist/llm.js +79 -0
  94. package/dist/llm.js.map +1 -0
  95. package/dist/mcp.d.ts +130 -0
  96. package/dist/mcp.d.ts.map +1 -0
  97. package/dist/mcp.js +550 -0
  98. package/dist/mcp.js.map +1 -0
  99. package/dist/memory.d.ts +10 -0
  100. package/dist/memory.d.ts.map +1 -0
  101. package/dist/memory.js +50 -0
  102. package/dist/memory.js.map +1 -0
  103. package/dist/postgres.d.ts +25 -0
  104. package/dist/postgres.d.ts.map +1 -0
  105. package/dist/postgres.js +56 -0
  106. package/dist/postgres.js.map +1 -0
  107. package/dist/redis.d.ts +20 -0
  108. package/dist/redis.d.ts.map +1 -0
  109. package/dist/redis.js +83 -0
  110. package/dist/redis.js.map +1 -0
  111. package/dist/server/compat.d.ts +13 -0
  112. package/dist/server/compat.d.ts.map +1 -0
  113. package/dist/server/compat.js +5 -0
  114. package/dist/server/compat.js.map +1 -0
  115. package/dist/server/cursor.d.ts +15 -0
  116. package/dist/server/cursor.d.ts.map +1 -0
  117. package/dist/server/cursor.js +50 -0
  118. package/dist/server/cursor.js.map +1 -0
  119. package/dist/server/events.d.ts +42 -0
  120. package/dist/server/events.d.ts.map +1 -0
  121. package/dist/server/events.js +189 -0
  122. package/dist/server/events.js.map +1 -0
  123. package/dist/server/fanout.d.ts +28 -0
  124. package/dist/server/fanout.d.ts.map +1 -0
  125. package/dist/server/fanout.js +184 -0
  126. package/dist/server/fanout.js.map +1 -0
  127. package/dist/server/guard.d.ts +19 -0
  128. package/dist/server/guard.d.ts.map +1 -0
  129. package/dist/server/guard.js +27 -0
  130. package/dist/server/guard.js.map +1 -0
  131. package/dist/server/http.d.ts +4 -0
  132. package/dist/server/http.d.ts.map +1 -0
  133. package/dist/server/http.js +323 -0
  134. package/dist/server/http.js.map +1 -0
  135. package/dist/server/ingest.d.ts +4 -0
  136. package/dist/server/ingest.d.ts.map +1 -0
  137. package/dist/server/ingest.js +400 -0
  138. package/dist/server/ingest.js.map +1 -0
  139. package/dist/server/install.d.ts +5 -0
  140. package/dist/server/install.d.ts.map +1 -0
  141. package/dist/server/install.js +91 -0
  142. package/dist/server/install.js.map +1 -0
  143. package/dist/server/poll.d.ts +4 -0
  144. package/dist/server/poll.d.ts.map +1 -0
  145. package/dist/server/poll.js +45 -0
  146. package/dist/server/poll.js.map +1 -0
  147. package/dist/server/serve.d.ts +19 -0
  148. package/dist/server/serve.d.ts.map +1 -0
  149. package/dist/server/serve.js +238 -0
  150. package/dist/server/serve.js.map +1 -0
  151. package/dist/server/sessions.d.ts +14 -0
  152. package/dist/server/sessions.d.ts.map +1 -0
  153. package/dist/server/sessions.js +54 -0
  154. package/dist/server/sessions.js.map +1 -0
  155. package/dist/server/stream.d.ts +11 -0
  156. package/dist/server/stream.d.ts.map +1 -0
  157. package/dist/server/stream.js +216 -0
  158. package/dist/server/stream.js.map +1 -0
  159. package/dist/server/tools.d.ts +22 -0
  160. package/dist/server/tools.d.ts.map +1 -0
  161. package/dist/server/tools.js +55 -0
  162. package/dist/server/tools.js.map +1 -0
  163. package/dist/server/types.d.ts +351 -0
  164. package/dist/server/types.d.ts.map +1 -0
  165. package/dist/server/types.js +5 -0
  166. package/dist/server/types.js.map +1 -0
  167. package/dist/server.d.ts +11 -0
  168. package/dist/server.d.ts.map +1 -0
  169. package/dist/server.js +10 -0
  170. package/dist/server.js.map +1 -0
  171. package/dist/shell/budget.d.ts +4 -0
  172. package/dist/shell/budget.d.ts.map +1 -0
  173. package/dist/shell/budget.js +5 -0
  174. package/dist/shell/budget.js.map +1 -0
  175. package/dist/shell/copy.d.ts +20 -0
  176. package/dist/shell/copy.d.ts.map +1 -0
  177. package/dist/shell/copy.js +73 -0
  178. package/dist/shell/copy.js.map +1 -0
  179. package/dist/shell/decisions.d.ts +6 -0
  180. package/dist/shell/decisions.d.ts.map +1 -0
  181. package/dist/shell/decisions.js +42 -0
  182. package/dist/shell/decisions.js.map +1 -0
  183. package/dist/shell/read.d.ts +7 -0
  184. package/dist/shell/read.d.ts.map +1 -0
  185. package/dist/shell/read.js +21 -0
  186. package/dist/shell/read.js.map +1 -0
  187. package/dist/shell/scheduler.d.ts +4 -0
  188. package/dist/shell/scheduler.d.ts.map +1 -0
  189. package/dist/shell/scheduler.js +90 -0
  190. package/dist/shell/scheduler.js.map +1 -0
  191. package/dist/shell/scope.d.ts +27 -0
  192. package/dist/shell/scope.d.ts.map +1 -0
  193. package/dist/shell/scope.js +343 -0
  194. package/dist/shell/scope.js.map +1 -0
  195. package/dist/shell/types.d.ts +168 -0
  196. package/dist/shell/types.d.ts.map +1 -0
  197. package/dist/shell/types.js +2 -0
  198. package/dist/shell/types.js.map +1 -0
  199. package/dist/sqlite.d.ts +14 -0
  200. package/dist/sqlite.d.ts.map +1 -0
  201. package/dist/sqlite.js +39 -0
  202. package/dist/sqlite.js.map +1 -0
  203. package/dist/step.d.ts +18 -0
  204. package/dist/step.d.ts.map +1 -0
  205. package/dist/step.js +14 -0
  206. package/dist/step.js.map +1 -0
  207. package/dist/store/memory.d.ts +12 -0
  208. package/dist/store/memory.d.ts.map +1 -0
  209. package/dist/store/memory.js +264 -0
  210. package/dist/store/memory.js.map +1 -0
  211. package/dist/store/postgres.d.ts +24 -0
  212. package/dist/store/postgres.d.ts.map +1 -0
  213. package/dist/store/postgres.js +364 -0
  214. package/dist/store/postgres.js.map +1 -0
  215. package/dist/store/redis.d.ts +12 -0
  216. package/dist/store/redis.d.ts.map +1 -0
  217. package/dist/store/redis.js +540 -0
  218. package/dist/store/redis.js.map +1 -0
  219. package/dist/store/sqlite-worker.d.ts +91 -0
  220. package/dist/store/sqlite-worker.d.ts.map +1 -0
  221. package/dist/store/sqlite-worker.js +322 -0
  222. package/dist/store/sqlite-worker.js.map +1 -0
  223. package/dist/store/sqlite.d.ts +34 -0
  224. package/dist/store/sqlite.d.ts.map +1 -0
  225. package/dist/store/sqlite.js +238 -0
  226. package/dist/store/sqlite.js.map +1 -0
  227. package/dist/store/types.d.ts +137 -0
  228. package/dist/store/types.d.ts.map +1 -0
  229. package/dist/store/types.js +2 -0
  230. package/dist/store/types.js.map +1 -0
  231. package/dist/testing/conformance.d.ts +13 -0
  232. package/dist/testing/conformance.d.ts.map +1 -0
  233. package/dist/testing/conformance.js +542 -0
  234. package/dist/testing/conformance.js.map +1 -0
  235. package/dist/testing/wire.d.ts +16 -0
  236. package/dist/testing/wire.d.ts.map +1 -0
  237. package/dist/testing/wire.js +304 -0
  238. package/dist/testing/wire.js.map +1 -0
  239. package/dist/testing.d.ts +113 -0
  240. package/dist/testing.d.ts.map +1 -0
  241. package/dist/testing.js +655 -0
  242. package/dist/testing.js.map +1 -0
  243. package/dist/types.d.ts +5 -0
  244. package/dist/types.d.ts.map +1 -0
  245. package/dist/types.js +5 -0
  246. package/dist/types.js.map +1 -0
  247. package/package.json +130 -4
  248. package/skills/attend/SKILL.md +231 -0
  249. package/skills/attend/references/judges.md +283 -0
  250. package/skills/attend/references/kinds.md +62 -0
  251. package/skills/attend/references/mcp.md +132 -0
  252. package/skills/attend/references/sinks.md +73 -0
  253. package/skills/attend/references/stores.md +90 -0
  254. package/skills/attend/references/testing.md +120 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Zettel Labs, Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,175 @@
1
- # Temporary Holding Version
1
+ <p align="center">
2
+ <img src="docs/assets/banner.jpg" alt="An abstract head drawn in green contour lines, eyes closed, with a comic-style hit mark at its top left where a stream of green dots converges" width="100%">
3
+ </p>
2
4
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
5
+ <h1 align="center">attend</h1>
6
+
7
+ <p align="center">Decide when an event should wake your agent.</p>
8
+
9
+ <p align="center">
10
+ <a href="https://www.npmjs.com/package/@acquiredintelligence/attend"><img alt="npm version" src="https://img.shields.io/npm/v/@acquiredintelligence/attend"></a>
11
+ <a href="https://github.com/acquiredintelligence/attend/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/acquiredintelligence/attend/actions/workflows/ci.yml/badge.svg"></a>
12
+ <a href="LICENSE"><img alt="MIT license" src="https://img.shields.io/npm/l/@acquiredintelligence/attend"></a>
13
+ <img alt="Node 22.13 or later" src="https://img.shields.io/node/v/@acquiredintelligence/attend">
14
+ </p>
15
+
16
+ <p align="center">
17
+ <a href="#see-it-decide">Demo</a> ·
18
+ <a href="docs/how-it-works.md">How it works</a> ·
19
+ <a href="#read-the-docs">Docs</a> ·
20
+ <a href="skills/attend/SKILL.md">Agent skill</a>
21
+ </p>
22
+
23
+ Picture an agent that watches your app. The app never stops talking: log lines, messages, clicks, alerts. Wake the agent on every event and it never finishes a thought. Put it behind a debounce and it sleeps through the one message that mattered.
24
+
25
+ attend holds each scope's events until they add up to something, asks a judge what the agent should do, and hands your app one decision. Your app keeps the final say in how that decision runs. In the sample below, a failed build waits, and the user's question wakes the agent with both.
26
+
27
+ ```ts
28
+ import { createAttend, defaultNotice } from '@acquiredintelligence/attend';
29
+
30
+ const attend = createAttend({
31
+ kind: { 'user.message': 'flush', 'build.failed': 'closing' },
32
+ judge: async ({ window }) => ({ route: window.reason === 'flush' ? 'interrupt' : 'note' }),
33
+ sink: (decision) => console.log(`[${decision.route}]\n${defaultNotice(decision)}`),
34
+ });
35
+
36
+ void attend.run();
37
+ await attend.push('session-1', { name: 'build.failed', text: 'Build 4521 failed: 1 test' });
38
+ await attend.push('session-1', { name: 'user.message', text: 'can you look?' });
39
+ ```
40
+
41
+ The build failure alone never wakes the agent. The user's message settles the window at once, and the agent hears both lines in one notice:
42
+
43
+ ```text
44
+ [interrupt]
45
+ Build 4521 failed: 1 test
46
+ can you look?
47
+ Attend to this now, even mid-task.
48
+ ```
49
+
50
+ ## Install
51
+
52
+ ```sh
53
+ npm install @acquiredintelligence/attend
54
+ ```
55
+
56
+ attend needs Node 22.13 or later and ships ESM only. The engine has no runtime dependencies. Before production, replace the function judge with [a real judge](docs/judges.md) and pass `store` [a database store](docs/storage.md); without one, state lives in memory.
57
+
58
+ ## See it decide
59
+
60
+ In a clone of this repo, `pnpm demo` streams a short CI story from a real MCP Events server into attend and prints what the agent hears. It needs no API key and no database. The source is [`examples/demo.ts`](examples/demo.ts).
61
+
62
+ ```text
63
+ attend demo: a CI server streams MCP Events, and attend decides what the agent hears.
64
+
65
+ 0.0s event ci.started {"run":4521,"branch":"main"}
66
+ 0.1s event ci.log {"line":"pnpm install"}
67
+ 0.2s event ci.log {"line":"pnpm test"}
68
+ 0.3s event ci.log {"line":"211 passed, 1 failed"}
69
+ 0.4s event ci.test_failed {"test":"checkout applies the coupon"}
70
+ 0.6s settle 5 events (closing)
71
+ 0.6s judge wait (hold the window and judge it again)
72
+ 1.0s event comment.created {"author":"sam","body":"can you look?"}
73
+ 1.0s settle 6 events (flush), merged with the held window
74
+ 1.0s judge interrupt
75
+ 1.0s deliver interrupt
76
+ ci.started {"run":4521,"branch":"main"}
77
+ ci.log {"line":"pnpm install"}
78
+ ci.log {"line":"pnpm test"}
79
+ ci.log {"line":"211 passed, 1 failed"}
80
+ ci.test_failed {"test":"checkout applies the coupon"}
81
+ comment.created {"author":"sam","body":"can you look?"}
82
+ Attend to this now, even mid-task.
83
+ 1.8s event deploy.finished {"env":"staging","sha":"9f3c2e1"}
84
+ 2.0s settle 1 event (closing)
85
+ 2.0s judge note
86
+ 2.0s deliver note
87
+ deploy.finished {"env":"staging","sha":"9f3c2e1"}
88
+ Background only. No reply is needed.
89
+
90
+ 7 events in, 2 deliveries out. Waking on every event would have run the agent 7 times.
91
+ ```
92
+
93
+ attend held the log lines until the failed test closed the window. The judge chose `wait`, so the user's comment joined the held window, and one interrupt carried all six events to the agent. The deploy arrived as a `note`.
94
+
95
+ ## What you get
96
+
97
+ - **6 routes.** The judge picks `interrupt`, `queue`, `note`, `ask`, `wait` or `skip`, and your app carries it out.
98
+ - **Windows that settle when an act ends.** A finished build or a message to the agent settles the window. A log line never wakes the agent on its own.
99
+ - **Your choice of judge.** TypeSafe's Jev, the OpenAI Decisions API, any model through `llmJudge`, or a plain function.
100
+ - **4 stores.** Memory, SQLite, Postgres and Redis, each crash-tested at every commit boundary in CI.
101
+ - **At-least-once delivery.** A decision keeps its id across retries, so your sink can drop repeats.
102
+ - **0 runtime dependencies** when embedded, or one command to serve decisions over MCP Events.
103
+
104
+ ## How it works
105
+
106
+ ```text
107
+ app events (the firehose)
108
+ | push() in-process, or NDJSON over HTTP to attend serve
109
+ v
110
+ +----------------------------------------------------------+
111
+ | attend |
112
+ | window one per scope; events pile up |
113
+ | settle the act in it is finished, or the window |
114
+ | is old, or full, or you flushed it |
115
+ | judge reads the settled window, picks a route: |
116
+ | interrupt | queue | note | ask | skip | wait |
117
+ | log every step and decision is persisted |
118
+ +----------------------------------------------------------+
119
+ | a handful of decisions
120
+ v
121
+ decisions out
122
+ |-- in-process: your sink's handler for the route
123
+ '-- attend serve: MCP Events poll, stream and tools, for any MCP client
124
+ v
125
+ your agent reacts (barge in, take it next turn, add context, offer the user a prompt);
126
+ your app decides how each route is carried out
127
+ ```
128
+
129
+ The judge picks the route, and your app carries it out. `interrupt` means the agent should hear this now, and your handler decides whether that cancels the turn, steers it or shows a banner. Raw events never leave attend. Only settled, judged decisions do. [How attend works](docs/how-it-works.md) walks through each step, and [the reference](docs/reference.md) lists every kind, route and default.
130
+
131
+ ## Run it in your process or beside it
132
+
133
+ | | Embedded | `attend serve` |
134
+ |---|---|---|
135
+ | What | `createAttend` in your process | The same engine as a process of its own: a sidecar next to your app |
136
+ | Events in | `attend.push(scope, events)` | `POST /v1/ingest` with NDJSON, from any language |
137
+ | Decisions out | Your `sink`, called in-process | MCP Events: `events/poll`, `events/stream`, and the `attend_wait` and `attend_window` tools |
138
+ | Use it for | **Real-time agents.** The default. Flush to delivery stays in-process, with no network hop. | Apps that are not TypeScript, several agents on one firehose, or a team that wants one shared attention service |
139
+
140
+ To run the sidecar, see [Run attend as a sidecar with attend serve](docs/serve.md).
141
+
142
+ ## Read the docs
143
+
144
+ | Page | Read it to |
145
+ |---|---|
146
+ | [How attend works](docs/how-it-works.md) | understand scopes, windows, settling and the decision log |
147
+ | [Reference](docs/reference.md) | look up kinds, routes, guarantees and defaults |
148
+ | [Choose a judge](docs/judges.md) | pick and configure Jev, the Decisions API, `llmJudge` or your own, and set the window budget and the act threshold |
149
+ | [Deliver decisions to your agent](docs/sinks.md) | write an idempotent sink and a dead-letter handler |
150
+ | [Choose a store](docs/storage.md) | run on memory, SQLite, Postgres or Redis, and share a store between processes |
151
+ | [Give a Mastra agent attention](docs/mastra.md) | wire attend in front of a Mastra agent with one sink |
152
+ | [Feed attend from an MCP Events server](docs/mcp-events.md) | subscribe a scope to an MCP Events stream with `mcpEventsSource` |
153
+ | [Run attend as a sidecar](docs/serve.md) | send events over HTTP and subscribe agents over MCP |
154
+ | [attend serve reference](docs/serve-reference.md) | look up every flag and the ingest wire format |
155
+ | [Test with a fake clock](docs/testing.md) | make settling deterministic in your tests |
156
+ | [Write a store adapter](docs/adapters.md) | implement `ScopeStore` and run the conformance and crash suites |
157
+
158
+ ## Let your coding agent wire it in
159
+
160
+ The repo ships an [Agent Skill](skills/attend/SKILL.md) that leads your coding agent through wiring attend into your app. It works out which events the app emits, which of them are signals, and which deserve which reaction. It tells you in a few lines what it will do, asks one batch of questions with a recommended default for each, and wires it in with one small module and a few call sites at your existing event chokepoints. To install it in Claude Code:
161
+
162
+ ```text
163
+ /plugin marketplace add acquiredintelligence/attend
164
+ /plugin install attend@attend
165
+ ```
166
+
167
+ For Codex or Cursor, copy `skills/attend` into your project's `.agents/skills/`. The npm package includes the skill at `node_modules/@acquiredintelligence/attend/skills/attend`. The third-party Vercel Labs CLI also installs it with `npx skills add acquiredintelligence/attend`. That CLI is not part of this project.
168
+
169
+ ## Status
170
+
171
+ attend is v0, and its API can change before 1.0. MCP Events is a working-group draft, so its wire shapes can change too. `@acquiredintelligence/attend/mcp` follows the current draft.
172
+
173
+ ## License
174
+
175
+ MIT. Built by the team behind [Zettel](https://zettel.study).
@@ -0,0 +1,30 @@
1
+ import type { Clock, Source, Decision, DeliveredRoute, EventLog, Sink } from './types.js';
2
+ import type { Attend, AttendConfig } from './shell/types.js';
3
+ /** Errors raised by intake and effect handlers. */
4
+ export { BackpressureError, ConflictError, OutboxFullError, PermanentError } from './errors.js';
5
+ /** Public configuration and runner contracts. */
6
+ export type { AdmissionOptions, Attend, AttendConfig, DeadLetterHandler, DecisionCursorPage, DecisionFilter, DecisionReadOptions, EventInput, JudgeContext, RunOptions } from './shell/types.js';
7
+ /** Creates a scope-owning shell over a log and snapshot store. */
8
+ export declare function createAttend(config: AttendConfig): Attend;
9
+ /** Internal snapshot kill switch for recovery and differential verification. */
10
+ export declare function createAttendInternal(config: AttendConfig, snapshot?: 'ratio' | 'always'): Attend;
11
+ /** One delivery handler per delivered route. */
12
+ export type RouteHandlers = {
13
+ [R in DeliveredRoute]: (decision: Decision & {
14
+ route: R;
15
+ }, signal: AbortSignal) => void | Promise<void>;
16
+ };
17
+ /** A sink with a required handler for each delivered route. */
18
+ export declare function routes(handlers: RouteHandlers): Sink;
19
+ /** The text an agent hears: the window's event lines oldest first, what was left out, and one line on the route. */
20
+ export declare function defaultNotice(decision: Decision, options?: {
21
+ maxLines?: number;
22
+ }): string;
23
+ /** A resumable source over an event log, with optional polling and blocking waits. */
24
+ export declare function logSource(log: EventLog, scope: string, options?: {
25
+ limit?: number;
26
+ blockMs?: number;
27
+ pollMs?: number;
28
+ clock?: Clock;
29
+ }): Source;
30
+ //# sourceMappingURL=attend.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attend.d.ts","sourceRoot":"","sources":["../src/attend.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAA2B,QAAQ,EAAE,cAAc,EAAgC,QAAQ,EAAwG,IAAI,EAAS,MAAM,YAAY,CAAC;AAC9P,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAc,MAAM,kBAAkB,CAAC;AAUzE,mDAAmD;AACnD,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAChG,iDAAiD;AACjD,YAAY,EAAE,gBAAgB,EAAE,MAAM,EAAE,YAAY,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,cAAc,EAAE,mBAAmB,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEjM,kEAAkE;AAClE,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAEzD;AAED,gFAAgF;AAChF,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,GAAE,OAAO,GAAG,QAAkB,GAAG,MAAM,CAgUzG;AA0BD,gDAAgD;AAChD,MAAM,MAAM,aAAa,GAAG;KACzB,CAAC,IAAI,cAAc,GAAG,CAAC,QAAQ,EAAE,QAAQ,GAAG;QAAE,KAAK,EAAE,CAAC,CAAA;KAAE,EAAE,MAAM,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;CACxG,CAAC;AAEF,+DAA+D;AAC/D,wBAAgB,MAAM,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI,CAiBpD;AASD,oHAAoH;AACpH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAWzF;AAED,sFAAsF;AACtF,wBAAgB,SAAS,CAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,GAAG,MAAM,CAsB9I"}