@llui/agent 0.0.32 → 0.0.35

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 (145) hide show
  1. package/README.md +82 -1
  2. package/dist/client/agentConfirm.d.ts +48 -18
  3. package/dist/client/agentConfirm.d.ts.map +1 -1
  4. package/dist/client/agentConfirm.js +28 -25
  5. package/dist/client/agentConfirm.js.map +1 -1
  6. package/dist/client/agentConnect.d.ts +95 -34
  7. package/dist/client/agentConnect.d.ts.map +1 -1
  8. package/dist/client/agentConnect.js +85 -47
  9. package/dist/client/agentConnect.js.map +1 -1
  10. package/dist/client/agentLog.d.ts +31 -14
  11. package/dist/client/agentLog.d.ts.map +1 -1
  12. package/dist/client/agentLog.js +39 -20
  13. package/dist/client/agentLog.js.map +1 -1
  14. package/dist/client/effect-handler.d.ts +23 -0
  15. package/dist/client/effect-handler.d.ts.map +1 -1
  16. package/dist/client/effect-handler.js +185 -126
  17. package/dist/client/effect-handler.js.map +1 -1
  18. package/dist/client/effects.d.ts +13 -2
  19. package/dist/client/effects.d.ts.map +1 -1
  20. package/dist/client/effects.js.map +1 -1
  21. package/dist/client/factory.d.ts +55 -3
  22. package/dist/client/factory.d.ts.map +1 -1
  23. package/dist/client/factory.js +30 -5
  24. package/dist/client/factory.js.map +1 -1
  25. package/dist/client/rpc/describe-visible-content.d.ts +18 -5
  26. package/dist/client/rpc/describe-visible-content.d.ts.map +1 -1
  27. package/dist/client/rpc/describe-visible-content.js +112 -7
  28. package/dist/client/rpc/describe-visible-content.js.map +1 -1
  29. package/dist/client/rpc/list-actions.d.ts +52 -2
  30. package/dist/client/rpc/list-actions.d.ts.map +1 -1
  31. package/dist/client/rpc/list-actions.js +187 -5
  32. package/dist/client/rpc/list-actions.js.map +1 -1
  33. package/dist/client/rpc/query-state.d.ts +32 -0
  34. package/dist/client/rpc/query-state.d.ts.map +1 -0
  35. package/dist/client/rpc/query-state.js +82 -0
  36. package/dist/client/rpc/query-state.js.map +1 -0
  37. package/dist/client/rpc/send-message.d.ts +2 -0
  38. package/dist/client/rpc/send-message.d.ts.map +1 -1
  39. package/dist/client/rpc/send-message.js +119 -9
  40. package/dist/client/rpc/send-message.js.map +1 -1
  41. package/dist/client/rpc/would-dispatch.d.ts +66 -0
  42. package/dist/client/rpc/would-dispatch.d.ts.map +1 -0
  43. package/dist/client/rpc/would-dispatch.js +21 -0
  44. package/dist/client/rpc/would-dispatch.js.map +1 -0
  45. package/dist/client/ws-client.d.ts +3 -1
  46. package/dist/client/ws-client.d.ts.map +1 -1
  47. package/dist/client/ws-client.js +29 -0
  48. package/dist/client/ws-client.js.map +1 -1
  49. package/dist/codecs.d.ts +107 -0
  50. package/dist/codecs.d.ts.map +1 -0
  51. package/dist/codecs.js +166 -0
  52. package/dist/codecs.js.map +1 -0
  53. package/dist/protocol.d.ts +172 -12
  54. package/dist/protocol.d.ts.map +1 -1
  55. package/dist/protocol.js +7 -1
  56. package/dist/protocol.js.map +1 -1
  57. package/dist/server/cloudflare/durable-object.d.ts +11 -4
  58. package/dist/server/cloudflare/durable-object.d.ts.map +1 -1
  59. package/dist/server/cloudflare/durable-object.js.map +1 -1
  60. package/dist/server/cloudflare/index.d.ts +8 -4
  61. package/dist/server/cloudflare/index.d.ts.map +1 -1
  62. package/dist/server/cloudflare/index.js +8 -4
  63. package/dist/server/cloudflare/index.js.map +1 -1
  64. package/dist/server/cloudflare/worker.d.ts +10 -2
  65. package/dist/server/cloudflare/worker.d.ts.map +1 -1
  66. package/dist/server/cloudflare/worker.js +13 -6
  67. package/dist/server/cloudflare/worker.js.map +1 -1
  68. package/dist/server/core-entry.d.ts +2 -2
  69. package/dist/server/core-entry.d.ts.map +1 -1
  70. package/dist/server/core-entry.js +1 -1
  71. package/dist/server/core-entry.js.map +1 -1
  72. package/dist/server/core.d.ts +1 -3
  73. package/dist/server/core.d.ts.map +1 -1
  74. package/dist/server/core.js +13 -12
  75. package/dist/server/core.js.map +1 -1
  76. package/dist/server/factory.d.ts +1 -1
  77. package/dist/server/factory.d.ts.map +1 -1
  78. package/dist/server/factory.js +1 -2
  79. package/dist/server/factory.js.map +1 -1
  80. package/dist/server/http/mint.d.ts +6 -1
  81. package/dist/server/http/mint.d.ts.map +1 -1
  82. package/dist/server/http/mint.js +14 -6
  83. package/dist/server/http/mint.js.map +1 -1
  84. package/dist/server/http/resume.d.ts +3 -1
  85. package/dist/server/http/resume.d.ts.map +1 -1
  86. package/dist/server/http/resume.js +9 -7
  87. package/dist/server/http/resume.js.map +1 -1
  88. package/dist/server/index.d.ts +2 -2
  89. package/dist/server/index.d.ts.map +1 -1
  90. package/dist/server/index.js +1 -1
  91. package/dist/server/index.js.map +1 -1
  92. package/dist/server/lap/confirm-result.d.ts +0 -1
  93. package/dist/server/lap/confirm-result.d.ts.map +1 -1
  94. package/dist/server/lap/confirm-result.js +1 -1
  95. package/dist/server/lap/confirm-result.js.map +1 -1
  96. package/dist/server/lap/describe.d.ts +13 -2
  97. package/dist/server/lap/describe.d.ts.map +1 -1
  98. package/dist/server/lap/describe.js +23 -6
  99. package/dist/server/lap/describe.js.map +1 -1
  100. package/dist/server/lap/forward.d.ts +13 -1
  101. package/dist/server/lap/forward.d.ts.map +1 -1
  102. package/dist/server/lap/forward.js +75 -1
  103. package/dist/server/lap/forward.js.map +1 -1
  104. package/dist/server/lap/message.d.ts +0 -1
  105. package/dist/server/lap/message.d.ts.map +1 -1
  106. package/dist/server/lap/message.js +1 -1
  107. package/dist/server/lap/message.js.map +1 -1
  108. package/dist/server/lap/observe.d.ts +0 -1
  109. package/dist/server/lap/observe.d.ts.map +1 -1
  110. package/dist/server/lap/observe.js +1 -1
  111. package/dist/server/lap/observe.js.map +1 -1
  112. package/dist/server/lap/router.d.ts.map +1 -1
  113. package/dist/server/lap/router.js +7 -1
  114. package/dist/server/lap/router.js.map +1 -1
  115. package/dist/server/lap/wait.d.ts +0 -1
  116. package/dist/server/lap/wait.d.ts.map +1 -1
  117. package/dist/server/lap/wait.js +1 -1
  118. package/dist/server/lap/wait.js.map +1 -1
  119. package/dist/server/options.d.ts +7 -5
  120. package/dist/server/options.d.ts.map +1 -1
  121. package/dist/server/options.js.map +1 -1
  122. package/dist/server/token-store.d.ts +22 -0
  123. package/dist/server/token-store.d.ts.map +1 -1
  124. package/dist/server/token-store.js +24 -0
  125. package/dist/server/token-store.js.map +1 -1
  126. package/dist/server/token.d.ts +32 -17
  127. package/dist/server/token.d.ts.map +1 -1
  128. package/dist/server/token.js +40 -103
  129. package/dist/server/token.js.map +1 -1
  130. package/dist/server/web/upgrade.d.ts +1 -1
  131. package/dist/server/web/upgrade.js +1 -1
  132. package/dist/server/web/upgrade.js.map +1 -1
  133. package/dist/server/ws/pairing-registry.d.ts +22 -6
  134. package/dist/server/ws/pairing-registry.d.ts.map +1 -1
  135. package/dist/server/ws/pairing-registry.js +49 -0
  136. package/dist/server/ws/pairing-registry.js.map +1 -1
  137. package/dist/server/ws/upgrade.d.ts +0 -1
  138. package/dist/server/ws/upgrade.d.ts.map +1 -1
  139. package/dist/server/ws/upgrade.js +12 -4
  140. package/dist/server/ws/upgrade.js.map +1 -1
  141. package/dist/state-diff.d.ts +52 -0
  142. package/dist/state-diff.d.ts.map +1 -0
  143. package/dist/state-diff.js +119 -0
  144. package/dist/state-diff.js.map +1 -0
  145. package/package.json +7 -3
@@ -6,11 +6,51 @@ export type LapError = {
6
6
  retryAfterMs?: number;
7
7
  };
8
8
  };
9
+ /**
10
+ * Who can dispatch a Msg variant.
11
+ *
12
+ * - `'shared'` (default) — both UI bindings and the agent can dispatch.
13
+ * - `'human-only'` — UI-only. Agent calls to `/message` for these variants
14
+ * are rejected with `LapMessageRejectReason: 'human-only'`. Use for
15
+ * internal UI events (focus/blur, scroll, hover) the LLM has no business
16
+ * triggering.
17
+ * - `'agent-only'` — no UI binding exists. Reserved for LLM-driven flows
18
+ * like batch operations or "explain this state" introspection variants.
19
+ * Lint warns if a view references one via `send({ type: 'X' })`.
20
+ *
21
+ * JSDoc sugar: `@humanOnly` → `'human-only'`, `@agentOnly` → `'agent-only'`.
22
+ * Absence of either tag → `'shared'`. The two tags are mutually exclusive
23
+ * (enforced by `llui/agent-exclusive-annotations` ESLint rule).
24
+ */
25
+ export type DispatchMode = 'shared' | 'human-only' | 'agent-only';
9
26
  export type MessageAnnotations = {
10
27
  intent: string | null;
11
28
  alwaysAffordable: boolean;
12
29
  requiresConfirm: boolean;
13
- humanOnly: boolean;
30
+ dispatchMode: DispatchMode;
31
+ /**
32
+ * Concrete copy-paste example dispatches authored as `@example`
33
+ * JSDoc tags. Multiple tags on one variant become multiple
34
+ * entries (mix typical / edge cases without nesting strings).
35
+ */
36
+ examples: string[];
37
+ /**
38
+ * Non-blocking caution authored as `@warning`. Distinct from
39
+ * `requiresConfirm` (runtime user gate); this informs the LLM at
40
+ * affordance time so it can decide whether the dispatch's
41
+ * downstream is acceptable.
42
+ */
43
+ warning: string | null;
44
+ /**
45
+ * Effect kinds this variant emits when dispatched, declared via
46
+ * `@emits("kind1", "kind2")`. Lets the agent reason about side
47
+ * effects (cloud writes, analytics, persistent state changes)
48
+ * before dispatching, and chunk multi-step flows accordingly
49
+ * ("don't dispatch X 100 times — each one fires cloud/save").
50
+ * Empty when the variant doesn't emit effects or the author hasn't
51
+ * annotated it yet.
52
+ */
53
+ emits: string[];
14
54
  };
15
55
  export type MessageSchemaEntry = {
16
56
  payloadSchema: object;
@@ -38,11 +78,59 @@ export type LapStateResponse = {
38
78
  export type LapActionsResponse = {
39
79
  actions: Array<{
40
80
  variant: string;
41
- intent: string;
81
+ /**
82
+ * Human-readable phrase from `@intent("…")`, or `null` when the
83
+ * variant has no `@intent` annotation. Callers that surface
84
+ * affordances to an LLM should treat `null` as "this action is
85
+ * undocumented" — neither synthesise a label from the variant name
86
+ * nor invent one. Pre-`@intent` variants would previously surface
87
+ * as `intent: "<variant>"` here, which made unannotated actions
88
+ * indistinguishable from properly-labelled ones; emitting `null`
89
+ * keeps the gap visible.
90
+ */
91
+ intent: string | null;
42
92
  requiresConfirm: boolean;
43
- source: 'binding' | 'always-affordable';
93
+ /**
94
+ * `'shared'` — both UI and agent can dispatch. `'agent-only'` — no UI
95
+ * binding exists; the agent is the sole dispatcher. `'human-only'`
96
+ * variants never appear here (filtered before serialization).
97
+ */
98
+ dispatchMode: 'shared' | 'agent-only';
99
+ /**
100
+ * Where this affordance came from:
101
+ * - `'binding'` — a tagged event handler is currently
102
+ * mounted in the rendered DOM.
103
+ * - `'always-affordable'` — the app's `agentAffordances(state)`
104
+ * hook listed it as available right now.
105
+ * - `'schema'` — neither of the above; the variant
106
+ * is in the Msg union and annotated `@agentOnly`. The
107
+ * `payloadHint` carries a synthesized example from the
108
+ * compiler-derived field types — copy-paste-ready for
109
+ * `send_message`. Bulk-edit operations land here.
110
+ */
111
+ source: 'binding' | 'always-affordable' | 'schema';
44
112
  selectorHint: string | null;
45
113
  payloadHint: object | null;
114
+ /** Cautionary text from `@warning` JSDoc, or null. */
115
+ warning: string | null;
116
+ /** Concrete examples from `@example` JSDoc, in source order. */
117
+ examples: string[];
118
+ /**
119
+ * Effect kinds this variant emits, from `@emits("k1", "k2")`.
120
+ * Empty when not annotated.
121
+ */
122
+ emits: string[];
123
+ /**
124
+ * Per-field guidance lifted from `@should("…")` JSDoc on payload
125
+ * fields. Path is dot/bracket notation rooted at the payload (e.g.
126
+ * `"cells[].meta"`). Surfaces hints that would otherwise be buried
127
+ * inside the schema tree, so callers can read them alongside
128
+ * `examples` without diving into `description.messages.variants`.
129
+ */
130
+ fieldHints: Array<{
131
+ path: string;
132
+ hint: string;
133
+ }>;
46
134
  }>;
47
135
  };
48
136
  export type LapMessageRequest = {
@@ -77,8 +165,22 @@ export type LapMessageRequest = {
77
165
  * the user's confirm/reject. Default 5_000ms.
78
166
  */
79
167
  timeoutMs?: number;
168
+ /**
169
+ * Include the full post-drain `stateAfter` snapshot in the response.
170
+ * Default `false` — the response carries `stateDiff` only and the
171
+ * caller applies it to the prior snapshot (from connect/observe). For
172
+ * apps with non-trivial state, the diff is orders of magnitude
173
+ * smaller than the full state, and resending the snapshot on every
174
+ * dispatch wastes bandwidth and (for LLM callers) context budget.
175
+ *
176
+ * Set `true` when the caller doesn't track state incrementally and
177
+ * wants the snapshot back. The legacy `confirmed` and `wait` paths
178
+ * always carry `stateAfter` because their flow is asynchronous and
179
+ * a diff would be ambiguous.
180
+ */
181
+ includeState?: boolean;
80
182
  };
81
- export type LapMessageRejectReason = 'humanOnly' | 'user-cancelled' | 'timeout' | 'invalid' | 'schema-error' | 'revoked' | 'paused';
183
+ export type LapMessageRejectReason = 'human-only' | 'user-cancelled' | 'timeout' | 'invalid' | 'schema-error' | 'revoked' | 'paused';
82
184
  /**
83
185
  * Drain metadata attached to `dispatched` / `confirmed` responses.
84
186
  * `effectsObserved` counts update-cycle commits (not individual effects) —
@@ -99,7 +201,22 @@ export type LapDrainMeta = {
99
201
  };
100
202
  export type LapMessageResponse = {
101
203
  status: 'dispatched';
102
- stateAfter: unknown;
204
+ /**
205
+ * Full post-drain state snapshot. Present only when the caller
206
+ * passed `includeState: true` in the request — by default,
207
+ * `stateDiff` is the only state-shaped field on the response
208
+ * because callers can apply the diff to the prior snapshot from
209
+ * `connect` / `observe`. See `LapMessageRequest.includeState`.
210
+ */
211
+ stateAfter?: unknown;
212
+ /**
213
+ * Structural diff from pre-dispatch state to post-drain state,
214
+ * in JSON-Patch shape (RFC 6902 subset: `add`, `remove`,
215
+ * `replace`). Empty when the dispatch produced no observable
216
+ * state change. The default state surface for callers — apply
217
+ * incrementally to the snapshot from `connect`/`observe`.
218
+ */
219
+ stateDiff: import('./state-diff.js').StateDiff;
103
220
  actions: LapActionsResponse['actions'];
104
221
  drain: LapDrainMeta;
105
222
  } | {
@@ -188,11 +305,34 @@ export type OutlineNode = {
188
305
  };
189
306
  export type LapDescribeVisibleResponse = {
190
307
  outline: OutlineNode[];
308
+ /**
309
+ * Where the outline came from:
310
+ * - `'data-agent'`: the app has `data-agent`-tagged zones and the
311
+ * walker scoped the outline to them. The author chose what to
312
+ * surface; trust the result.
313
+ * - `'fallback'`: no `data-agent` tags exist; the walker fell back
314
+ * to a depth- and count-limited semantic walk of the entire
315
+ * root element. Useful for first-pass dogfood targets that
316
+ * haven't tagged their views.
317
+ * - `'truncated'`: same as `'fallback'` but the cap (200 nodes)
318
+ * was hit before the walk finished. The visible content beyond
319
+ * that point is not represented; reach for `query_dom` or state
320
+ * reads if you need more.
321
+ */
322
+ source: 'data-agent' | 'fallback' | 'truncated';
191
323
  };
192
324
  export type AgentDocs = {
193
325
  purpose: string;
194
326
  overview?: string;
195
327
  cautions?: string[];
328
+ /**
329
+ * Free-form idiomatic-usage examples authored by the app: typical
330
+ * sequences of dispatches the LLM should know about, like "to
331
+ * delete a saved matrix: dispatch Confirm/Ask first, then on
332
+ * approve dispatch Cloud/Delete." Each entry is one example;
333
+ * order is up to the author.
334
+ */
335
+ examples?: string[];
196
336
  };
197
337
  export type AgentContext = {
198
338
  summary: string;
@@ -261,6 +401,15 @@ export type LogEntry = {
261
401
  variant?: string;
262
402
  intent?: string;
263
403
  detail?: string;
404
+ /**
405
+ * Structural diff from pre-dispatch state to post-drain state, in
406
+ * JSON-Patch shape. Populated only for `kind: 'dispatched'` entries
407
+ * — read entries (get_state / list_actions / observe / …) don't
408
+ * mutate state, and an empty diff would just be noise. Lets the
409
+ * agent reconstruct what each past action did without re-fetching
410
+ * state snapshots.
411
+ */
412
+ stateDiff?: import('./state-diff.js').StateDiff;
264
413
  };
265
414
  export type HelloFrame = {
266
415
  t: 'hello';
@@ -316,18 +465,29 @@ declare const TokenBrand: unique symbol;
316
465
  export type AgentToken = string & {
317
466
  readonly [TokenBrand]: 'AgentToken';
318
467
  };
319
- export type TokenPayload = {
320
- tid: string;
321
- iat: number;
322
- exp: number;
323
- scope: 'agent';
324
- };
325
468
  export type TokenStatus = 'awaiting-ws' | 'awaiting-claude' | 'active' | 'pending-resume' | 'revoked';
326
469
  export type TokenRecord = {
327
470
  tid: string;
471
+ /**
472
+ * SHA-256 hex of the bearer token. The plaintext token is never
473
+ * stored — incoming requests hash their `Authorization: Bearer …`
474
+ * value and look up by this field. Hash-only storage keeps a leaked
475
+ * store from being a live-token leak. Mirrors the standard session-
476
+ * cookie / API-key pattern.
477
+ */
478
+ tokenHash: string;
328
479
  uid: string | null;
329
480
  status: TokenStatus;
330
481
  createdAt: number;
482
+ /**
483
+ * Hard-expiry in milliseconds since epoch. The mint endpoint sets
484
+ * this to `now + hardExpiryMs`; the verify path rejects requests
485
+ * presenting tokens whose record has `expiresAt <= now`. Pre-0.0.35
486
+ * the equivalent value lived inside the JWT payload as `exp` (in
487
+ * seconds); the new opaque-token flow keeps it server-side so the
488
+ * record is the single source of truth.
489
+ */
490
+ expiresAt: number;
331
491
  lastSeenAt: number;
332
492
  pendingResumeUntil: number | null;
333
493
  origin: string;
@@ -378,5 +538,5 @@ export type AuditEntry = {
378
538
  event: AuditEvent;
379
539
  detail: object;
380
540
  };
381
- export {};
541
+ export { WIRE_TAG, WIRE_VALUE, CodecRegistry, isoDateCodec, epochMillisCodec, makeDefaultCodecs, encodeForWire, decodeFromWire, type AgentCodec, } from './codecs.js';
382
542
  //# sourceMappingURL=protocol.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"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"}
package/dist/protocol.js CHANGED
@@ -2,5 +2,11 @@
2
2
  // JSON over HTTPS between the llui-agent bridge (MCP side) and the
3
3
  // @llui/agent server library mounted in the developer's backend.
4
4
  // See docs/superpowers/specs/2026-04-19-llui-agent-design.md §7.
5
- export {};
5
+ // ── Codec exports ─────────────────────────────────────────────────
6
+ //
7
+ // Re-exported here so consumers can `import { ..., type AgentCodec }
8
+ // from '@llui/agent/protocol'`. The implementation lives in
9
+ // `./codecs.ts` to keep the protocol type surface together but the
10
+ // runtime registry/walkers separate.
11
+ export { WIRE_TAG, WIRE_VALUE, CodecRegistry, isoDateCodec, epochMillisCodec, makeDefaultCodecs, encodeForWire, decodeFromWire, } from './codecs.js';
6
12
  //# sourceMappingURL=protocol.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,mEAAmE;AACnE,iEAAiE;AACjE,iEAAiE","sourcesContent":["// ── LAP — LLui Agent Protocol ────────────────────────────────────\n// JSON over HTTPS between the llui-agent bridge (MCP side) and the\n// @llui/agent server library mounted in the developer's backend.\n// See docs/superpowers/specs/2026-04-19-llui-agent-design.md §7.\n\nexport type LapErrorCode =\n | 'auth-failed'\n | 'revoked'\n | 'paused'\n | 'rate-limited'\n | 'invalid'\n | 'schema-error'\n | 'timeout'\n | 'internal'\n\nexport type LapError = {\n error: {\n code: LapErrorCode\n detail?: string\n retryAfterMs?: number\n }\n}\n\nexport type MessageAnnotations = {\n intent: string | null\n alwaysAffordable: boolean\n requiresConfirm: boolean\n humanOnly: boolean\n}\n\nexport type MessageSchemaEntry = {\n payloadSchema: object\n annotations: MessageAnnotations\n}\n\nexport type LapDescribeResponse = {\n name: string\n version: string\n stateSchema: object\n messages: Record<string, MessageSchemaEntry>\n docs: AgentDocs | null\n conventions: {\n dispatchModel: 'TEA'\n confirmationModel: 'runtime-mediated'\n readSurfaces: readonly (\n | 'state'\n | 'query_dom'\n | 'describe_visible_content'\n | 'describe_context'\n )[]\n }\n schemaHash: string\n}\n\nexport type LapStateRequest = { path?: string }\nexport type LapStateResponse = { state: unknown }\n\nexport type LapActionsResponse = {\n actions: Array<{\n variant: string\n intent: string\n requiresConfirm: boolean\n source: 'binding' | 'always-affordable'\n selectorHint: string | null\n payloadHint: object | null\n }>\n}\n\nexport type LapMessageRequest = {\n msg: { type: string; [k: string]: unknown }\n reason?: string\n /**\n * Backpressure contract for how long `/message` waits before returning:\n * - `drained` (default): dispatch, then loop until the message queue is\n * idle for `drainQuietMs` ms or the 5s hard cap trips. Captures any\n * effect round-trips (http/delay/debounce) that feed back as messages.\n * - `idle`: dispatch + flush + one microtask yield. Captures the\n * synchronous update cycle but not async effects.\n * - `none`: dispatch and return without flushing. For high-throughput\n * fire-and-forget dispatch.\n */\n waitFor?: 'drained' | 'idle' | 'none'\n /**\n * Quiescence window when `waitFor === 'drained'`. Drain completes when\n * no new update cycle fires for this many ms. Default 100ms — long\n * enough for a localhost HTTP round-trip, short enough to be\n * imperceptible. Ignored for `idle` / `none`.\n */\n drainQuietMs?: number\n /**\n * Hard cap on total wait time. When `waitFor === 'drained'`, this is\n * the upper bound on how long the drain loop can run; if reached, the\n * response carries `drain.timedOut: true` with partial results. For\n * `pending-confirmation` messages, this is how long to wait for\n * the user's confirm/reject. Default 5_000ms.\n */\n timeoutMs?: number\n}\n\nexport type LapMessageRejectReason =\n | 'humanOnly'\n | 'user-cancelled'\n | 'timeout'\n | 'invalid'\n | 'schema-error'\n | 'revoked'\n | 'paused'\n\n/**\n * Drain metadata attached to `dispatched` / `confirmed` responses.\n * `effectsObserved` counts update-cycle commits (not individual effects) —\n * it's a proxy for \"how much activity happened during the drain window.\"\n * `errors` surfaces sync throws from `onEffect` and unhandled rejections\n * from effect handlers that fired during the drain window, so the LLM\n * can see when an HTTP handler crashed silently.\n */\nexport type LapDrainMeta = {\n effectsObserved: number\n durationMs: number\n timedOut: boolean\n errors: Array<{ kind: 'error' | 'unhandledrejection'; message: string; stack?: string }>\n}\n\nexport type LapMessageResponse =\n | {\n status: 'dispatched'\n stateAfter: unknown\n actions: LapActionsResponse['actions']\n drain: LapDrainMeta\n }\n | { status: 'pending-confirmation'; confirmId: string }\n | {\n /**\n * The user approved a `pending-confirmation` message. `stateAfter`\n * is the state snapshot captured when the approve was resolved;\n * effects produced by the approved dispatch may still be in\n * flight. The LLM should follow up with an `observe` call to\n * pick up a drained view and fresh actions — by design the\n * confirm path doesn't carry drain semantics because approval\n * can arrive arbitrarily later than the original request.\n */\n status: 'confirmed'\n stateAfter: unknown\n }\n | { status: 'rejected'; reason: LapMessageRejectReason; detail?: string }\n\nexport type LapConfirmResultRequest = { confirmId: string; timeoutMs?: number }\nexport type LapConfirmResultResponse =\n | { status: 'confirmed'; stateAfter: unknown }\n | { status: 'rejected'; reason: 'user-cancelled' | 'timeout' }\n | { status: 'still-pending' }\n\nexport type LapWaitRequest = { path?: string; timeoutMs?: number }\nexport type LapWaitResponse =\n | { status: 'changed'; stateAfter: unknown }\n | { status: 'timeout'; stateAfter: unknown }\n\nexport type LapQueryDomRequest = { name: string; multiple?: boolean }\nexport type LapQueryDomResponse = {\n elements: Array<{ text: string; attrs: Record<string, string>; path: number[] }>\n}\n\nexport type OutlineNode =\n | { kind: 'heading'; level: number; text: string }\n | { kind: 'text'; text: string }\n | { kind: 'list'; items: OutlineNode[] }\n | { kind: 'item'; text: string; children?: OutlineNode[] }\n | { kind: 'button'; text: string; disabled: boolean; actionVariant: string | null }\n | { kind: 'input'; label: string | null; value: string | null; type: string }\n | { kind: 'link'; text: string; href: string }\n\nexport type LapDescribeVisibleResponse = { outline: OutlineNode[] }\n\n// ── App + context documentation ──────────────────────────────────\n// Static app-level docs (authored once on the component record) and\n// dynamic per-state context docs (pure function of state, served by\n// `/lap/v1/context`). See spec §5.4.\n\nexport type AgentDocs = {\n purpose: string\n overview?: string\n cautions?: string[]\n}\n\nexport type AgentContext = {\n summary: string\n hints?: string[]\n cautions?: string[]\n}\n\nexport type LapContextResponse = { context: AgentContext }\n\n// ── Unified observe ──────────────────────────────────────────────\n// Single-call bootstrap. Replaces the get_state + list_actions +\n// describe_app trio for the common \"what can I see, what can I do\"\n// question. Returns the dynamic state + actions slice alongside the\n// static description (name/version/messages/docs) and any\n// state-derived context so one round-trip gives the LLM everything it\n// needs to decide its next action.\n\nexport type LapObserveResponse = {\n state: unknown\n actions: LapActionsResponse['actions']\n description: LapDescribeResponse\n context: AgentContext | null\n}\n\n// LAP endpoint catalog — a compile-time map binding each path to its\n// request/response shape. Useful for the bridge's dispatcher and for\n// typed test helpers.\nexport type LapEndpointMap = {\n '/lap/v1/describe': { req: null; res: LapDescribeResponse }\n '/lap/v1/state': { req: LapStateRequest; res: LapStateResponse }\n '/lap/v1/actions': { req: null; res: LapActionsResponse }\n '/lap/v1/message': { req: LapMessageRequest; res: LapMessageResponse }\n '/lap/v1/confirm-result': { req: LapConfirmResultRequest; res: LapConfirmResultResponse }\n '/lap/v1/wait': { req: LapWaitRequest; res: LapWaitResponse }\n '/lap/v1/query-dom': { req: LapQueryDomRequest; res: LapQueryDomResponse }\n '/lap/v1/describe-visible': { req: null; res: LapDescribeVisibleResponse }\n '/lap/v1/context': { req: null; res: LapContextResponse }\n '/lap/v1/observe': { req: null; res: LapObserveResponse }\n}\n\nexport type LapPath = keyof LapEndpointMap\nexport type LapRequest<P extends LapPath> = LapEndpointMap[P]['req']\nexport type LapResponse<P extends LapPath> = LapEndpointMap[P]['res']\n\n// ── Relay WS frames ──────────────────────────────────────────────\n// Bidirectional framing between the LLui runtime in the browser and\n// the @llui/agent server over /agent/ws. See spec §10.5.\n\nexport type LogKind =\n | 'proposed'\n | 'dispatched'\n | 'confirmed'\n | 'rejected'\n | 'blocked'\n | 'read'\n | 'error'\n\nexport type LogEntry = {\n id: string\n at: number\n kind: LogKind\n variant?: string\n intent?: string\n detail?: string\n}\n\nexport type HelloFrame = {\n t: 'hello'\n appName: string\n appVersion: string\n msgSchema: Record<string, MessageSchemaEntry>\n stateSchema: object\n affordancesSample: object[]\n docs: AgentDocs | null\n schemaHash: string\n}\n\nexport type RpcReplyFrame = { t: 'rpc-reply'; id: string; result: unknown }\nexport type RpcErrorFrame = { t: 'rpc-error'; id: string; code: string; detail?: string }\nexport type ConfirmResolvedFrame = {\n t: 'confirm-resolved'\n confirmId: string\n outcome: 'confirmed' | 'user-cancelled'\n stateAfter?: unknown\n}\nexport type StateUpdateFrame = { t: 'state-update'; path: string; stateAfter: unknown }\nexport type LogAppendFrame = { t: 'log-append'; entry: LogEntry }\n\nexport type ClientFrame =\n | HelloFrame\n | RpcReplyFrame\n | RpcErrorFrame\n | ConfirmResolvedFrame\n | StateUpdateFrame\n | LogAppendFrame\n\nexport type RpcFrame = { t: 'rpc'; id: string; tool: string; args: unknown }\nexport type RevokedFrame = { t: 'revoked' }\nexport type ActiveFrame = { t: 'active' }\n\nexport type ServerFrame = RpcFrame | RevokedFrame | ActiveFrame\n\n// ── Tokens + pairing ─────────────────────────────────────────────\n\ndeclare const TokenBrand: unique symbol\nexport type AgentToken = string & { readonly [TokenBrand]: 'AgentToken' }\n\nexport type TokenPayload = {\n tid: string\n iat: number\n exp: number\n scope: 'agent'\n}\n\nexport type TokenStatus =\n | 'awaiting-ws'\n | 'awaiting-claude'\n | 'active'\n | 'pending-resume'\n | 'revoked'\n\nexport type TokenRecord = {\n tid: string\n uid: string | null\n status: TokenStatus\n createdAt: number\n lastSeenAt: number\n pendingResumeUntil: number | null\n origin: string\n label: string | null\n}\n\nexport type AgentSession = {\n tid: string\n label: string\n status: 'active' | 'pending-resume' | 'revoked'\n createdAt: number\n lastSeenAt: number\n}\n\n// HTTP envelopes for the mint/resume/revoke/sessions endpoints (non-LAP).\n\nexport type MintRequest = Record<string, never>\nexport type MintResponse = {\n token: AgentToken\n tid: string\n wsUrl: string\n lapUrl: string\n expiresAt: number\n}\n\nexport type ResumeListRequest = { tids: string[] }\nexport type ResumeListResponse = { sessions: AgentSession[] }\n\nexport type ResumeClaimRequest = { tid: string }\nexport type ResumeClaimResponse = { token: AgentToken; wsUrl: string }\n\nexport type RevokeRequest = { tid: string }\nexport type RevokeResponse = { status: 'revoked' }\n\nexport type SessionsResponse = { sessions: AgentSession[] }\n\n// ── Audit ────────────────────────────────────────────────────────\n\nexport type AuditEvent =\n | 'mint'\n | 'claim'\n | 'resume'\n | 'revoke'\n | 'lap-call'\n | 'msg-dispatched'\n | 'msg-blocked'\n | 'confirm-proposed'\n | 'confirm-approved'\n | 'confirm-rejected'\n | 'rate-limited'\n | 'auth-failed'\n\nexport type AuditEntry = {\n at: number\n tid: string | null\n uid: string | null\n event: AuditEvent\n detail: object\n}\n"]}
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,mEAAmE;AACnE,iEAAiE;AACjE,iEAAiE;AA6gBjE,qEAAqE;AACrE,EAAE;AACF,qEAAqE;AACrE,4DAA4D;AAC5D,mEAAmE;AACnE,qCAAqC;AAErC,OAAO,EACL,QAAQ,EACR,UAAU,EACV,aAAa,EACb,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EACb,cAAc,GAEf,MAAM,aAAa,CAAA","sourcesContent":["// ── LAP — LLui Agent Protocol ────────────────────────────────────\n// JSON over HTTPS between the llui-agent bridge (MCP side) and the\n// @llui/agent server library mounted in the developer's backend.\n// See docs/superpowers/specs/2026-04-19-llui-agent-design.md §7.\n\nexport type LapErrorCode =\n | 'auth-failed'\n | 'revoked'\n | 'paused'\n | 'rate-limited'\n | 'invalid'\n | 'schema-error'\n | 'timeout'\n | 'internal'\n\nexport type LapError = {\n error: {\n code: LapErrorCode\n detail?: string\n retryAfterMs?: number\n }\n}\n\n/**\n * Who can dispatch a Msg variant.\n *\n * - `'shared'` (default) — both UI bindings and the agent can dispatch.\n * - `'human-only'` — UI-only. Agent calls to `/message` for these variants\n * are rejected with `LapMessageRejectReason: 'human-only'`. Use for\n * internal UI events (focus/blur, scroll, hover) the LLM has no business\n * triggering.\n * - `'agent-only'` — no UI binding exists. Reserved for LLM-driven flows\n * like batch operations or \"explain this state\" introspection variants.\n * Lint warns if a view references one via `send({ type: 'X' })`.\n *\n * JSDoc sugar: `@humanOnly` → `'human-only'`, `@agentOnly` → `'agent-only'`.\n * Absence of either tag → `'shared'`. The two tags are mutually exclusive\n * (enforced by `llui/agent-exclusive-annotations` ESLint rule).\n */\nexport type DispatchMode = 'shared' | 'human-only' | 'agent-only'\n\nexport type MessageAnnotations = {\n intent: string | null\n alwaysAffordable: boolean\n requiresConfirm: boolean\n dispatchMode: DispatchMode\n /**\n * Concrete copy-paste example dispatches authored as `@example`\n * JSDoc tags. Multiple tags on one variant become multiple\n * entries (mix typical / edge cases without nesting strings).\n */\n examples: string[]\n /**\n * Non-blocking caution authored as `@warning`. Distinct from\n * `requiresConfirm` (runtime user gate); this informs the LLM at\n * affordance time so it can decide whether the dispatch's\n * downstream is acceptable.\n */\n warning: string | null\n /**\n * Effect kinds this variant emits when dispatched, declared via\n * `@emits(\"kind1\", \"kind2\")`. Lets the agent reason about side\n * effects (cloud writes, analytics, persistent state changes)\n * before dispatching, and chunk multi-step flows accordingly\n * (\"don't dispatch X 100 times — each one fires cloud/save\").\n * Empty when the variant doesn't emit effects or the author hasn't\n * annotated it yet.\n */\n emits: string[]\n}\n\nexport type MessageSchemaEntry = {\n payloadSchema: object\n annotations: MessageAnnotations\n}\n\nexport type LapDescribeResponse = {\n name: string\n version: string\n stateSchema: object\n messages: Record<string, MessageSchemaEntry>\n docs: AgentDocs | null\n conventions: {\n dispatchModel: 'TEA'\n confirmationModel: 'runtime-mediated'\n readSurfaces: readonly (\n | 'state'\n | 'query_dom'\n | 'describe_visible_content'\n | 'describe_context'\n )[]\n }\n schemaHash: string\n}\n\nexport type LapStateRequest = { path?: string }\nexport type LapStateResponse = { state: unknown }\n\nexport type LapActionsResponse = {\n actions: Array<{\n variant: string\n /**\n * Human-readable phrase from `@intent(\"…\")`, or `null` when the\n * variant has no `@intent` annotation. Callers that surface\n * affordances to an LLM should treat `null` as \"this action is\n * undocumented\" — neither synthesise a label from the variant name\n * nor invent one. Pre-`@intent` variants would previously surface\n * as `intent: \"<variant>\"` here, which made unannotated actions\n * indistinguishable from properly-labelled ones; emitting `null`\n * keeps the gap visible.\n */\n intent: string | null\n requiresConfirm: boolean\n /**\n * `'shared'` — both UI and agent can dispatch. `'agent-only'` — no UI\n * binding exists; the agent is the sole dispatcher. `'human-only'`\n * variants never appear here (filtered before serialization).\n */\n dispatchMode: 'shared' | 'agent-only'\n /**\n * Where this affordance came from:\n * - `'binding'` — a tagged event handler is currently\n * mounted in the rendered DOM.\n * - `'always-affordable'` — the app's `agentAffordances(state)`\n * hook listed it as available right now.\n * - `'schema'` — neither of the above; the variant\n * is in the Msg union and annotated `@agentOnly`. The\n * `payloadHint` carries a synthesized example from the\n * compiler-derived field types — copy-paste-ready for\n * `send_message`. Bulk-edit operations land here.\n */\n source: 'binding' | 'always-affordable' | 'schema'\n selectorHint: string | null\n payloadHint: object | null\n /** Cautionary text from `@warning` JSDoc, or null. */\n warning: string | null\n /** Concrete examples from `@example` JSDoc, in source order. */\n examples: string[]\n /**\n * Effect kinds this variant emits, from `@emits(\"k1\", \"k2\")`.\n * Empty when not annotated.\n */\n emits: string[]\n /**\n * Per-field guidance lifted from `@should(\"…\")` JSDoc on payload\n * fields. Path is dot/bracket notation rooted at the payload (e.g.\n * `\"cells[].meta\"`). Surfaces hints that would otherwise be buried\n * inside the schema tree, so callers can read them alongside\n * `examples` without diving into `description.messages.variants`.\n */\n fieldHints: Array<{ path: string; hint: string }>\n }>\n}\n\nexport type LapMessageRequest = {\n msg: { type: string; [k: string]: unknown }\n reason?: string\n /**\n * Backpressure contract for how long `/message` waits before returning:\n * - `drained` (default): dispatch, then loop until the message queue is\n * idle for `drainQuietMs` ms or the 5s hard cap trips. Captures any\n * effect round-trips (http/delay/debounce) that feed back as messages.\n * - `idle`: dispatch + flush + one microtask yield. Captures the\n * synchronous update cycle but not async effects.\n * - `none`: dispatch and return without flushing. For high-throughput\n * fire-and-forget dispatch.\n */\n waitFor?: 'drained' | 'idle' | 'none'\n /**\n * Quiescence window when `waitFor === 'drained'`. Drain completes when\n * no new update cycle fires for this many ms. Default 100ms — long\n * enough for a localhost HTTP round-trip, short enough to be\n * imperceptible. Ignored for `idle` / `none`.\n */\n drainQuietMs?: number\n /**\n * Hard cap on total wait time. When `waitFor === 'drained'`, this is\n * the upper bound on how long the drain loop can run; if reached, the\n * response carries `drain.timedOut: true` with partial results. For\n * `pending-confirmation` messages, this is how long to wait for\n * the user's confirm/reject. Default 5_000ms.\n */\n timeoutMs?: number\n /**\n * Include the full post-drain `stateAfter` snapshot in the response.\n * Default `false` — the response carries `stateDiff` only and the\n * caller applies it to the prior snapshot (from connect/observe). For\n * apps with non-trivial state, the diff is orders of magnitude\n * smaller than the full state, and resending the snapshot on every\n * dispatch wastes bandwidth and (for LLM callers) context budget.\n *\n * Set `true` when the caller doesn't track state incrementally and\n * wants the snapshot back. The legacy `confirmed` and `wait` paths\n * always carry `stateAfter` because their flow is asynchronous and\n * a diff would be ambiguous.\n */\n includeState?: boolean\n}\n\nexport type LapMessageRejectReason =\n | 'human-only'\n | 'user-cancelled'\n | 'timeout'\n | 'invalid'\n | 'schema-error'\n | 'revoked'\n | 'paused'\n\n/**\n * Drain metadata attached to `dispatched` / `confirmed` responses.\n * `effectsObserved` counts update-cycle commits (not individual effects) —\n * it's a proxy for \"how much activity happened during the drain window.\"\n * `errors` surfaces sync throws from `onEffect` and unhandled rejections\n * from effect handlers that fired during the drain window, so the LLM\n * can see when an HTTP handler crashed silently.\n */\nexport type LapDrainMeta = {\n effectsObserved: number\n durationMs: number\n timedOut: boolean\n errors: Array<{ kind: 'error' | 'unhandledrejection'; message: string; stack?: string }>\n}\n\nexport type LapMessageResponse =\n | {\n status: 'dispatched'\n /**\n * Full post-drain state snapshot. Present only when the caller\n * passed `includeState: true` in the request — by default,\n * `stateDiff` is the only state-shaped field on the response\n * because callers can apply the diff to the prior snapshot from\n * `connect` / `observe`. See `LapMessageRequest.includeState`.\n */\n stateAfter?: unknown\n /**\n * Structural diff from pre-dispatch state to post-drain state,\n * in JSON-Patch shape (RFC 6902 subset: `add`, `remove`,\n * `replace`). Empty when the dispatch produced no observable\n * state change. The default state surface for callers — apply\n * incrementally to the snapshot from `connect`/`observe`.\n */\n stateDiff: import('./state-diff.js').StateDiff\n actions: LapActionsResponse['actions']\n drain: LapDrainMeta\n }\n | { status: 'pending-confirmation'; confirmId: string }\n | {\n /**\n * The user approved a `pending-confirmation` message. `stateAfter`\n * is the state snapshot captured when the approve was resolved;\n * effects produced by the approved dispatch may still be in\n * flight. The LLM should follow up with an `observe` call to\n * pick up a drained view and fresh actions — by design the\n * confirm path doesn't carry drain semantics because approval\n * can arrive arbitrarily later than the original request.\n */\n status: 'confirmed'\n stateAfter: unknown\n }\n | { status: 'rejected'; reason: LapMessageRejectReason; detail?: string }\n\nexport type LapConfirmResultRequest = { confirmId: string; timeoutMs?: number }\nexport type LapConfirmResultResponse =\n | { status: 'confirmed'; stateAfter: unknown }\n | { status: 'rejected'; reason: 'user-cancelled' | 'timeout' }\n | { status: 'still-pending' }\n\nexport type LapWaitRequest = { path?: string; timeoutMs?: number }\nexport type LapWaitResponse =\n | { status: 'changed'; stateAfter: unknown }\n | { status: 'timeout'; stateAfter: unknown }\n\nexport type LapQueryDomRequest = { name: string; multiple?: boolean }\nexport type LapQueryDomResponse = {\n elements: Array<{ text: string; attrs: Record<string, string>; path: number[] }>\n}\n\nexport type OutlineNode =\n | { kind: 'heading'; level: number; text: string }\n | { kind: 'text'; text: string }\n | { kind: 'list'; items: OutlineNode[] }\n | { kind: 'item'; text: string; children?: OutlineNode[] }\n | { kind: 'button'; text: string; disabled: boolean; actionVariant: string | null }\n | { kind: 'input'; label: string | null; value: string | null; type: string }\n | { kind: 'link'; text: string; href: string }\n\nexport type LapDescribeVisibleResponse = {\n outline: OutlineNode[]\n /**\n * Where the outline came from:\n * - `'data-agent'`: the app has `data-agent`-tagged zones and the\n * walker scoped the outline to them. The author chose what to\n * surface; trust the result.\n * - `'fallback'`: no `data-agent` tags exist; the walker fell back\n * to a depth- and count-limited semantic walk of the entire\n * root element. Useful for first-pass dogfood targets that\n * haven't tagged their views.\n * - `'truncated'`: same as `'fallback'` but the cap (200 nodes)\n * was hit before the walk finished. The visible content beyond\n * that point is not represented; reach for `query_dom` or state\n * reads if you need more.\n */\n source: 'data-agent' | 'fallback' | 'truncated'\n}\n\n// ── App + context documentation ──────────────────────────────────\n// Static app-level docs (authored once on the component record) and\n// dynamic per-state context docs (pure function of state, served by\n// `/lap/v1/context`). See spec §5.4.\n\nexport type AgentDocs = {\n purpose: string\n overview?: string\n cautions?: string[]\n /**\n * Free-form idiomatic-usage examples authored by the app: typical\n * sequences of dispatches the LLM should know about, like \"to\n * delete a saved matrix: dispatch Confirm/Ask first, then on\n * approve dispatch Cloud/Delete.\" Each entry is one example;\n * order is up to the author.\n */\n examples?: string[]\n}\n\nexport type AgentContext = {\n summary: string\n hints?: string[]\n cautions?: string[]\n}\n\nexport type LapContextResponse = { context: AgentContext }\n\n// ── Unified observe ──────────────────────────────────────────────\n// Single-call bootstrap. Replaces the get_state + list_actions +\n// describe_app trio for the common \"what can I see, what can I do\"\n// question. Returns the dynamic state + actions slice alongside the\n// static description (name/version/messages/docs) and any\n// state-derived context so one round-trip gives the LLM everything it\n// needs to decide its next action.\n\nexport type LapObserveResponse = {\n state: unknown\n actions: LapActionsResponse['actions']\n description: LapDescribeResponse\n context: AgentContext | null\n}\n\n// LAP endpoint catalog — a compile-time map binding each path to its\n// request/response shape. Useful for the bridge's dispatcher and for\n// typed test helpers.\nexport type LapEndpointMap = {\n '/lap/v1/describe': { req: null; res: LapDescribeResponse }\n '/lap/v1/state': { req: LapStateRequest; res: LapStateResponse }\n '/lap/v1/actions': { req: null; res: LapActionsResponse }\n '/lap/v1/message': { req: LapMessageRequest; res: LapMessageResponse }\n '/lap/v1/confirm-result': { req: LapConfirmResultRequest; res: LapConfirmResultResponse }\n '/lap/v1/wait': { req: LapWaitRequest; res: LapWaitResponse }\n '/lap/v1/query-dom': { req: LapQueryDomRequest; res: LapQueryDomResponse }\n '/lap/v1/describe-visible': { req: null; res: LapDescribeVisibleResponse }\n '/lap/v1/context': { req: null; res: LapContextResponse }\n '/lap/v1/observe': { req: null; res: LapObserveResponse }\n}\n\nexport type LapPath = keyof LapEndpointMap\nexport type LapRequest<P extends LapPath> = LapEndpointMap[P]['req']\nexport type LapResponse<P extends LapPath> = LapEndpointMap[P]['res']\n\n// ── Relay WS frames ──────────────────────────────────────────────\n// Bidirectional framing between the LLui runtime in the browser and\n// the @llui/agent server over /agent/ws. See spec §10.5.\n\nexport type LogKind =\n | 'proposed'\n | 'dispatched'\n | 'confirmed'\n | 'rejected'\n | 'blocked'\n | 'read'\n | 'error'\n\nexport type LogEntry = {\n id: string\n at: number\n kind: LogKind\n variant?: string\n intent?: string\n detail?: string\n /**\n * Structural diff from pre-dispatch state to post-drain state, in\n * JSON-Patch shape. Populated only for `kind: 'dispatched'` entries\n * — read entries (get_state / list_actions / observe / …) don't\n * mutate state, and an empty diff would just be noise. Lets the\n * agent reconstruct what each past action did without re-fetching\n * state snapshots.\n */\n stateDiff?: import('./state-diff.js').StateDiff\n}\n\nexport type HelloFrame = {\n t: 'hello'\n appName: string\n appVersion: string\n msgSchema: Record<string, MessageSchemaEntry>\n stateSchema: object\n affordancesSample: object[]\n docs: AgentDocs | null\n schemaHash: string\n}\n\nexport type RpcReplyFrame = { t: 'rpc-reply'; id: string; result: unknown }\nexport type RpcErrorFrame = { t: 'rpc-error'; id: string; code: string; detail?: string }\nexport type ConfirmResolvedFrame = {\n t: 'confirm-resolved'\n confirmId: string\n outcome: 'confirmed' | 'user-cancelled'\n stateAfter?: unknown\n}\nexport type StateUpdateFrame = { t: 'state-update'; path: string; stateAfter: unknown }\nexport type LogAppendFrame = { t: 'log-append'; entry: LogEntry }\n\nexport type ClientFrame =\n | HelloFrame\n | RpcReplyFrame\n | RpcErrorFrame\n | ConfirmResolvedFrame\n | StateUpdateFrame\n | LogAppendFrame\n\nexport type RpcFrame = { t: 'rpc'; id: string; tool: string; args: unknown }\nexport type RevokedFrame = { t: 'revoked' }\nexport type ActiveFrame = { t: 'active' }\n\nexport type ServerFrame = RpcFrame | RevokedFrame | ActiveFrame\n\n// ── Tokens + pairing ─────────────────────────────────────────────\n\ndeclare const TokenBrand: unique symbol\nexport type AgentToken = string & { readonly [TokenBrand]: 'AgentToken' }\n\nexport type TokenStatus =\n | 'awaiting-ws'\n | 'awaiting-claude'\n | 'active'\n | 'pending-resume'\n | 'revoked'\n\nexport type TokenRecord = {\n tid: string\n /**\n * SHA-256 hex of the bearer token. The plaintext token is never\n * stored — incoming requests hash their `Authorization: Bearer …`\n * value and look up by this field. Hash-only storage keeps a leaked\n * store from being a live-token leak. Mirrors the standard session-\n * cookie / API-key pattern.\n */\n tokenHash: string\n uid: string | null\n status: TokenStatus\n createdAt: number\n /**\n * Hard-expiry in milliseconds since epoch. The mint endpoint sets\n * this to `now + hardExpiryMs`; the verify path rejects requests\n * presenting tokens whose record has `expiresAt <= now`. Pre-0.0.35\n * the equivalent value lived inside the JWT payload as `exp` (in\n * seconds); the new opaque-token flow keeps it server-side so the\n * record is the single source of truth.\n */\n expiresAt: number\n lastSeenAt: number\n pendingResumeUntil: number | null\n origin: string\n label: string | null\n}\n\nexport type AgentSession = {\n tid: string\n label: string\n status: 'active' | 'pending-resume' | 'revoked'\n createdAt: number\n lastSeenAt: number\n}\n\n// HTTP envelopes for the mint/resume/revoke/sessions endpoints (non-LAP).\n\nexport type MintRequest = Record<string, never>\nexport type MintResponse = {\n token: AgentToken\n tid: string\n wsUrl: string\n lapUrl: string\n expiresAt: number\n}\n\nexport type ResumeListRequest = { tids: string[] }\nexport type ResumeListResponse = { sessions: AgentSession[] }\n\nexport type ResumeClaimRequest = { tid: string }\nexport type ResumeClaimResponse = { token: AgentToken; wsUrl: string }\n\nexport type RevokeRequest = { tid: string }\nexport type RevokeResponse = { status: 'revoked' }\n\nexport type SessionsResponse = { sessions: AgentSession[] }\n\n// ── Audit ────────────────────────────────────────────────────────\n\nexport type AuditEvent =\n | 'mint'\n | 'claim'\n | 'resume'\n | 'revoke'\n | 'lap-call'\n | 'msg-dispatched'\n | 'msg-blocked'\n | 'confirm-proposed'\n | 'confirm-approved'\n | 'confirm-rejected'\n | 'rate-limited'\n | 'auth-failed'\n\nexport type AuditEntry = {\n at: number\n tid: string | null\n uid: string | null\n event: AuditEvent\n detail: object\n}\n\n// ── Codec exports ─────────────────────────────────────────────────\n//\n// Re-exported here so consumers can `import { ..., type AgentCodec }\n// from '@llui/agent/protocol'`. The implementation lives in\n// `./codecs.ts` to keep the protocol type surface together but the\n// runtime registry/walkers separate.\n\nexport {\n WIRE_TAG,\n WIRE_VALUE,\n CodecRegistry,\n isoDateCodec,\n epochMillisCodec,\n makeDefaultCodecs,\n encodeForWire,\n decodeFromWire,\n type AgentCodec,\n} from './codecs.js'\n"]}
@@ -20,9 +20,8 @@
20
20
  * export class AgentDO {
21
21
  * private agent: AgentPairingDurableObject
22
22
  * constructor(_state: DurableObjectState, env: Env) {
23
- * this.agent = new AgentPairingDurableObject({
24
- * signingKey: env.AGENT_SIGNING_KEY,
25
- * })
23
+ * // Tokens are opaque (see token.ts) no signing key needed.
24
+ * this.agent = new AgentPairingDurableObject({})
26
25
  * }
27
26
  * fetch(req: Request): Promise<Response> {
28
27
  * return this.agent.fetch(req)
@@ -31,7 +30,15 @@
31
30
  *
32
31
  * export default {
33
32
  * async fetch(req: Request, env: Env): Promise<Response> {
34
- * return routeToAgentDO(req, env.AGENT_DO, env.AGENT_SIGNING_KEY)
33
+ * // routeToAgentDO now takes a `resolveTid` callback — typically
34
+ * // a fetch to the root DO's token-resolution endpoint, or a
35
+ * // const stub when you don't shard by tid.
36
+ * return routeToAgentDO(req, env.AGENT_DO, async (token) => {
37
+ * const stub = env.AGENT_DO.get(env.AGENT_DO.idFromName('__root'))
38
+ * const r = await stub.fetch(`http://internal/__resolve?token=${encodeURIComponent(token)}`)
39
+ * const body = (await r.json()) as { tid: string | null }
40
+ * return body.tid
41
+ * })
35
42
  * },
36
43
  * }
37
44
  * ```
@@ -1 +1 @@
1
- {"version":3,"file":"durable-object.d.ts","sourceRoot":"","sources":["../../../src/server/cloudflare/durable-object.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAI9D,MAAM,MAAM,oBAAoB,GAAG,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAA;AAEhE;;;;;;;;;GASG;AACH,qBAAa,yBAAyB;IACpC,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAA;gBAEnB,IAAI,EAAE,oBAAoB;IAIhC,KAAK,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC;CAgB7C"}
1
+ {"version":3,"file":"durable-object.d.ts","sourceRoot":"","sources":["../../../src/server/cloudflare/durable-object.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAI9D,MAAM,MAAM,oBAAoB,GAAG,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAA;AAEhE;;;;;;;;;GASG;AACH,qBAAa,yBAAyB;IACpC,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAA;gBAEnB,IAAI,EAAE,oBAAoB;IAIhC,KAAK,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC;CAgB7C"}
@@ -1 +1 @@
1
- {"version":3,"file":"durable-object.js","sourceRoot":"","sources":["../../../src/server/cloudflare/durable-object.ts"],"names":[],"mappings":"AAyCA,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAChD,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAA;AAI3D;;;;;;;;;GASG;AACH,MAAM,OAAO,yBAAyB;IAC3B,KAAK,CAAiB;IAE/B,YAAY,IAA0B;QACpC,IAAI,CAAC,KAAK,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAA;IACxC,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,GAAY;QACtB,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QAE5B,gEAAgE;QAChE,gEAAgE;QAChE,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QAC3C,IAAI,MAAM;YAAE,OAAO,MAAM,CAAA;QAEzB,iEAAiE;QACjE,sBAAsB;QACtB,IAAI,GAAG,CAAC,QAAQ,KAAK,WAAW,EAAE,CAAC;YACjC,OAAO,uBAAuB,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAA;QACjD,CAAC;QAED,OAAO,IAAI,QAAQ,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;IACnD,CAAC;CACF","sourcesContent":["/**\n * Durable Object helper for hosting the agent pairing + LAP surface\n * on Cloudflare Workers. One DO instance owns one `tid` — its\n * in-memory `PairingRegistry` survives across Worker isolate\n * invocations because the DO IS persistent.\n *\n * This file exports a class designed to be composed into a real\n * Durable Object in the user's Worker project. We intentionally\n * don't subclass `DurableObject` from `@cloudflare/workers-types` —\n * that dependency belongs to the user's project, not ours. Users\n * wrap an instance of `AgentPairingDurableObject` in their own DO\n * class and forward `fetch` to it.\n *\n * Usage in a Worker project:\n *\n * ```ts\n * // worker.ts\n * import { AgentPairingDurableObject } from '@llui/agent/server/cloudflare'\n *\n * export class AgentDO {\n * private agent: AgentPairingDurableObject\n * constructor(_state: DurableObjectState, env: Env) {\n * this.agent = new AgentPairingDurableObject({\n * signingKey: env.AGENT_SIGNING_KEY,\n * })\n * }\n * fetch(req: Request): Promise<Response> {\n * return this.agent.fetch(req)\n * }\n * }\n *\n * export default {\n * async fetch(req: Request, env: Env): Promise<Response> {\n * return routeToAgentDO(req, env.AGENT_DO, env.AGENT_SIGNING_KEY)\n * },\n * }\n * ```\n *\n * See `./worker.ts` for `routeToAgentDO` and the full wiring.\n */\nimport type { CoreOptions, AgentCoreHandle } from '../core.js'\nimport { createLluiAgentCore } from '../core.js'\nimport { handleCloudflareUpgrade } from '../web/upgrade.js'\n\nexport type DurableObjectOptions = Omit<CoreOptions, 'registry'>\n\n/**\n * Agent server instance scoped to a single Durable Object. All\n * pairing state lives in the DO's in-process memory — which is safe\n * here because the DO is a persistent addressable entity, not a\n * one-shot Worker isolate.\n *\n * Users instantiate one of these inside their DO class's constructor\n * and delegate `fetch` to `agent.fetch(req)`. LAP HTTP routes and\n * WebSocket upgrades both flow through this single entry.\n */\nexport class AgentPairingDurableObject {\n readonly agent: AgentCoreHandle\n\n constructor(opts: DurableObjectOptions) {\n this.agent = createLluiAgentCore(opts)\n }\n\n async fetch(req: Request): Promise<Response> {\n const url = new URL(req.url)\n\n // LAP routes (/agent/lap/v1/*, /agent/*). `router` returns null\n // for non-matching paths so we can fall through to the upgrade.\n const lapRes = await this.agent.router(req)\n if (lapRes) return lapRes\n\n // WebSocket upgrade — uses `WebSocketPair`, which only exists in\n // Cloudflare Workers.\n if (url.pathname === '/agent/ws') {\n return handleCloudflareUpgrade(req, this.agent)\n }\n\n return new Response('Not Found', { status: 404 })\n }\n}\n"]}
1
+ {"version":3,"file":"durable-object.js","sourceRoot":"","sources":["../../../src/server/cloudflare/durable-object.ts"],"names":[],"mappings":"AAgDA,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAChD,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAA;AAI3D;;;;;;;;;GASG;AACH,MAAM,OAAO,yBAAyB;IAC3B,KAAK,CAAiB;IAE/B,YAAY,IAA0B;QACpC,IAAI,CAAC,KAAK,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAA;IACxC,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,GAAY;QACtB,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QAE5B,gEAAgE;QAChE,gEAAgE;QAChE,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QAC3C,IAAI,MAAM;YAAE,OAAO,MAAM,CAAA;QAEzB,iEAAiE;QACjE,sBAAsB;QACtB,IAAI,GAAG,CAAC,QAAQ,KAAK,WAAW,EAAE,CAAC;YACjC,OAAO,uBAAuB,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAA;QACjD,CAAC;QAED,OAAO,IAAI,QAAQ,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;IACnD,CAAC;CACF","sourcesContent":["/**\n * Durable Object helper for hosting the agent pairing + LAP surface\n * on Cloudflare Workers. One DO instance owns one `tid` — its\n * in-memory `PairingRegistry` survives across Worker isolate\n * invocations because the DO IS persistent.\n *\n * This file exports a class designed to be composed into a real\n * Durable Object in the user's Worker project. We intentionally\n * don't subclass `DurableObject` from `@cloudflare/workers-types` —\n * that dependency belongs to the user's project, not ours. Users\n * wrap an instance of `AgentPairingDurableObject` in their own DO\n * class and forward `fetch` to it.\n *\n * Usage in a Worker project:\n *\n * ```ts\n * // worker.ts\n * import { AgentPairingDurableObject } from '@llui/agent/server/cloudflare'\n *\n * export class AgentDO {\n * private agent: AgentPairingDurableObject\n * constructor(_state: DurableObjectState, env: Env) {\n * // Tokens are opaque (see token.ts) — no signing key needed.\n * this.agent = new AgentPairingDurableObject({})\n * }\n * fetch(req: Request): Promise<Response> {\n * return this.agent.fetch(req)\n * }\n * }\n *\n * export default {\n * async fetch(req: Request, env: Env): Promise<Response> {\n * // routeToAgentDO now takes a `resolveTid` callback — typically\n * // a fetch to the root DO's token-resolution endpoint, or a\n * // const stub when you don't shard by tid.\n * return routeToAgentDO(req, env.AGENT_DO, async (token) => {\n * const stub = env.AGENT_DO.get(env.AGENT_DO.idFromName('__root'))\n * const r = await stub.fetch(`http://internal/__resolve?token=${encodeURIComponent(token)}`)\n * const body = (await r.json()) as { tid: string | null }\n * return body.tid\n * })\n * },\n * }\n * ```\n *\n * See `./worker.ts` for `routeToAgentDO` and the full wiring.\n */\nimport type { CoreOptions, AgentCoreHandle } from '../core.js'\nimport { createLluiAgentCore } from '../core.js'\nimport { handleCloudflareUpgrade } from '../web/upgrade.js'\n\nexport type DurableObjectOptions = Omit<CoreOptions, 'registry'>\n\n/**\n * Agent server instance scoped to a single Durable Object. All\n * pairing state lives in the DO's in-process memory — which is safe\n * here because the DO is a persistent addressable entity, not a\n * one-shot Worker isolate.\n *\n * Users instantiate one of these inside their DO class's constructor\n * and delegate `fetch` to `agent.fetch(req)`. LAP HTTP routes and\n * WebSocket upgrades both flow through this single entry.\n */\nexport class AgentPairingDurableObject {\n readonly agent: AgentCoreHandle\n\n constructor(opts: DurableObjectOptions) {\n this.agent = createLluiAgentCore(opts)\n }\n\n async fetch(req: Request): Promise<Response> {\n const url = new URL(req.url)\n\n // LAP routes (/agent/lap/v1/*, /agent/*). `router` returns null\n // for non-matching paths so we can fall through to the upgrade.\n const lapRes = await this.agent.router(req)\n if (lapRes) return lapRes\n\n // WebSocket upgrade — uses `WebSocketPair`, which only exists in\n // Cloudflare Workers.\n if (url.pathname === '/agent/ws') {\n return handleCloudflareUpgrade(req, this.agent)\n }\n\n return new Response('Not Found', { status: 404 })\n }\n}\n"]}
@@ -16,9 +16,8 @@
16
16
  * export class AgentDO {
17
17
  * private agent: AgentPairingDurableObject
18
18
  * constructor(_state: DurableObjectState, env: Env) {
19
- * this.agent = new AgentPairingDurableObject({
20
- * signingKey: env.AGENT_SIGNING_KEY,
21
- * })
19
+ * // Tokens are opaque (see token.ts) no signing key needed.
20
+ * this.agent = new AgentPairingDurableObject({})
22
21
  * }
23
22
  * fetch(req: Request) {
24
23
  * return this.agent.fetch(req)
@@ -27,7 +26,12 @@
27
26
  *
28
27
  * export default {
29
28
  * async fetch(req: Request, env: Env) {
30
- * return routeToAgentDO(req, env.AGENT_DO, env.AGENT_SIGNING_KEY)
29
+ * return routeToAgentDO(req, env.AGENT_DO, async (token) => {
30
+ * const stub = env.AGENT_DO.get(env.AGENT_DO.idFromName('__root'))
31
+ * const r = await stub.fetch(`http://internal/__resolve?token=${encodeURIComponent(token)}`)
32
+ * const body = (await r.json()) as { tid: string | null }
33
+ * return body.tid
34
+ * })
31
35
  * },
32
36
  * }
33
37
  * ```
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/cloudflare/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,OAAO,EAAE,yBAAyB,EAAE,KAAK,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAC1F,OAAO,EACL,cAAc,EACd,KAAK,6BAA6B,EAClC,KAAK,sBAAsB,EAC3B,KAAK,wBAAwB,GAC9B,MAAM,aAAa,CAAA;AACpB,OAAO,EACL,6BAA6B,EAC7B,uBAAuB,EACvB,YAAY,GACb,MAAM,iBAAiB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/cloudflare/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,OAAO,EAAE,yBAAyB,EAAE,KAAK,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAC1F,OAAO,EACL,cAAc,EACd,KAAK,6BAA6B,EAClC,KAAK,sBAAsB,EAC3B,KAAK,wBAAwB,GAC9B,MAAM,aAAa,CAAA;AACpB,OAAO,EACL,6BAA6B,EAC7B,uBAAuB,EACvB,YAAY,GACb,MAAM,iBAAiB,CAAA"}
@@ -16,9 +16,8 @@
16
16
  * export class AgentDO {
17
17
  * private agent: AgentPairingDurableObject
18
18
  * constructor(_state: DurableObjectState, env: Env) {
19
- * this.agent = new AgentPairingDurableObject({
20
- * signingKey: env.AGENT_SIGNING_KEY,
21
- * })
19
+ * // Tokens are opaque (see token.ts) no signing key needed.
20
+ * this.agent = new AgentPairingDurableObject({})
22
21
  * }
23
22
  * fetch(req: Request) {
24
23
  * return this.agent.fetch(req)
@@ -27,7 +26,12 @@
27
26
  *
28
27
  * export default {
29
28
  * async fetch(req: Request, env: Env) {
30
- * return routeToAgentDO(req, env.AGENT_DO, env.AGENT_SIGNING_KEY)
29
+ * return routeToAgentDO(req, env.AGENT_DO, async (token) => {
30
+ * const stub = env.AGENT_DO.get(env.AGENT_DO.idFromName('__root'))
31
+ * const r = await stub.fetch(`http://internal/__resolve?token=${encodeURIComponent(token)}`)
32
+ * const body = (await r.json()) as { tid: string | null }
33
+ * return body.tid
34
+ * })
31
35
  * },
32
36
  * }
33
37
  * ```
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/server/cloudflare/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,OAAO,EAAE,yBAAyB,EAA6B,MAAM,qBAAqB,CAAA;AAC1F,OAAO,EACL,cAAc,GAIf,MAAM,aAAa,CAAA;AACpB,OAAO,EACL,6BAA6B,EAC7B,uBAAuB,EACvB,YAAY,GACb,MAAM,iBAAiB,CAAA","sourcesContent":["/**\n * Cloudflare Workers + Durable Object adapter. Use this sub-path\n * from a Cloudflare Workers project where the agent pairing state\n * lives inside a Durable Object.\n *\n * See the full deployment recipe at\n * https://llui.dev/api/agent#cloudflare-deployment — the short\n * version:\n *\n * ```ts\n * import {\n * AgentPairingDurableObject,\n * routeToAgentDO,\n * } from '@llui/agent/server/cloudflare'\n *\n * export class AgentDO {\n * private agent: AgentPairingDurableObject\n * constructor(_state: DurableObjectState, env: Env) {\n * this.agent = new AgentPairingDurableObject({\n * signingKey: env.AGENT_SIGNING_KEY,\n * })\n * }\n * fetch(req: Request) {\n * return this.agent.fetch(req)\n * }\n * }\n *\n * export default {\n * async fetch(req: Request, env: Env) {\n * return routeToAgentDO(req, env.AGENT_DO, env.AGENT_SIGNING_KEY)\n * },\n * }\n * ```\n *\n * `wrangler.toml`:\n * ```toml\n * [[durable_objects.bindings]]\n * name = \"AGENT_DO\"\n * class_name = \"AgentDO\"\n *\n * [[migrations]]\n * tag = \"v1\"\n * new_classes = [\"AgentDO\"]\n * ```\n */\nexport { AgentPairingDurableObject, type DurableObjectOptions } from './durable-object.js'\nexport {\n routeToAgentDO,\n type MinimalDurableObjectNamespace,\n type MinimalDurableObjectId,\n type MinimalDurableObjectStub,\n} from './worker.js'\nexport {\n createWHATWGPairingConnection,\n handleCloudflareUpgrade,\n extractToken,\n} from '../web/index.js'\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/server/cloudflare/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,OAAO,EAAE,yBAAyB,EAA6B,MAAM,qBAAqB,CAAA;AAC1F,OAAO,EACL,cAAc,GAIf,MAAM,aAAa,CAAA;AACpB,OAAO,EACL,6BAA6B,EAC7B,uBAAuB,EACvB,YAAY,GACb,MAAM,iBAAiB,CAAA","sourcesContent":["/**\n * Cloudflare Workers + Durable Object adapter. Use this sub-path\n * from a Cloudflare Workers project where the agent pairing state\n * lives inside a Durable Object.\n *\n * See the full deployment recipe at\n * https://llui.dev/api/agent#cloudflare-deployment — the short\n * version:\n *\n * ```ts\n * import {\n * AgentPairingDurableObject,\n * routeToAgentDO,\n * } from '@llui/agent/server/cloudflare'\n *\n * export class AgentDO {\n * private agent: AgentPairingDurableObject\n * constructor(_state: DurableObjectState, env: Env) {\n * // Tokens are opaque (see token.ts) — no signing key needed.\n * this.agent = new AgentPairingDurableObject({})\n * }\n * fetch(req: Request) {\n * return this.agent.fetch(req)\n * }\n * }\n *\n * export default {\n * async fetch(req: Request, env: Env) {\n * return routeToAgentDO(req, env.AGENT_DO, async (token) => {\n * const stub = env.AGENT_DO.get(env.AGENT_DO.idFromName('__root'))\n * const r = await stub.fetch(`http://internal/__resolve?token=${encodeURIComponent(token)}`)\n * const body = (await r.json()) as { tid: string | null }\n * return body.tid\n * })\n * },\n * }\n * ```\n *\n * `wrangler.toml`:\n * ```toml\n * [[durable_objects.bindings]]\n * name = \"AGENT_DO\"\n * class_name = \"AgentDO\"\n *\n * [[migrations]]\n * tag = \"v1\"\n * new_classes = [\"AgentDO\"]\n * ```\n */\nexport { AgentPairingDurableObject, type DurableObjectOptions } from './durable-object.js'\nexport {\n routeToAgentDO,\n type MinimalDurableObjectNamespace,\n type MinimalDurableObjectId,\n type MinimalDurableObjectStub,\n} from './worker.js'\nexport {\n createWHATWGPairingConnection,\n handleCloudflareUpgrade,\n extractToken,\n} from '../web/index.js'\n"]}
@@ -32,9 +32,17 @@ export interface MinimalDurableObjectStub {
32
32
  *
33
33
  * This is the recommended entry for Cloudflare Workers deployments;
34
34
  * users who need custom routing can write their own and call the
35
- * underlying primitives (`verifyToken`, `namespace.get`, etc).
35
+ * underlying primitives directly.
36
+ *
37
+ * As of 0.0.35 the token format is opaque (random, not signed), so we
38
+ * can't recover `tid` from the token alone. The caller passes a
39
+ * `resolveTid` callback — typically `(token) => stub.fetch(...)` to
40
+ * the root DO's token-resolution endpoint — that turns a bearer into
41
+ * its tid via the shared token store. Callers that don't shard by
42
+ * tid can pass `() => Promise.resolve(rootName)` to route everything
43
+ * through the root DO.
36
44
  */
37
- export declare function routeToAgentDO(req: Request, namespace: MinimalDurableObjectNamespace, signingKey: string | Uint8Array, opts?: {
45
+ export declare function routeToAgentDO(req: Request, namespace: MinimalDurableObjectNamespace, resolveTid: (token: string) => Promise<string | null>, opts?: {
38
46
  rootName?: string;
39
47
  }): Promise<Response>;
40
48
  //# sourceMappingURL=worker.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../../src/server/cloudflare/worker.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,WAAW,6BAA6B;IAC5C,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,sBAAsB,CAAA;IAChD,GAAG,CAAC,EAAE,EAAE,sBAAsB,GAAG,wBAAwB,CAAA;CAC1D;AACD,MAAM,WAAW,sBAAsB;IAErC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CACvB;AACD,MAAM,WAAW,wBAAwB;IACvC,KAAK,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;CACvC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,OAAO,EACZ,SAAS,EAAE,6BAA6B,EACxC,UAAU,EAAE,MAAM,GAAG,UAAU,EAC/B,IAAI,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GAC/B,OAAO,CAAC,QAAQ,CAAC,CA4BnB"}
1
+ {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../../src/server/cloudflare/worker.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,WAAW,6BAA6B;IAC5C,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,sBAAsB,CAAA;IAChD,GAAG,CAAC,EAAE,EAAE,sBAAsB,GAAG,wBAAwB,CAAA;CAC1D;AACD,MAAM,WAAW,sBAAsB;IAErC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CACvB;AACD,MAAM,WAAW,wBAAwB;IACvC,KAAK,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;CACvC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,OAAO,EACZ,SAAS,EAAE,6BAA6B,EACxC,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,EACrD,IAAI,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GAC/B,OAAO,CAAC,QAAQ,CAAC,CA4BnB"}
@@ -1,4 +1,3 @@
1
- import { verifyToken } from '../token.js';
2
1
  /**
3
2
  * Route an incoming Worker `fetch` request to the Durable Object
4
3
  * that owns its `tid`.
@@ -17,9 +16,17 @@ import { verifyToken } from '../token.js';
17
16
  *
18
17
  * This is the recommended entry for Cloudflare Workers deployments;
19
18
  * users who need custom routing can write their own and call the
20
- * underlying primitives (`verifyToken`, `namespace.get`, etc).
19
+ * underlying primitives directly.
20
+ *
21
+ * As of 0.0.35 the token format is opaque (random, not signed), so we
22
+ * can't recover `tid` from the token alone. The caller passes a
23
+ * `resolveTid` callback — typically `(token) => stub.fetch(...)` to
24
+ * the root DO's token-resolution endpoint — that turns a bearer into
25
+ * its tid via the shared token store. Callers that don't shard by
26
+ * tid can pass `() => Promise.resolve(rootName)` to route everything
27
+ * through the root DO.
21
28
  */
22
- export async function routeToAgentDO(req, namespace, signingKey, opts = {}) {
29
+ export async function routeToAgentDO(req, namespace, resolveTid, opts = {}) {
23
30
  const rootName = opts.rootName ?? '__root';
24
31
  const url = new URL(req.url);
25
32
  const path = url.pathname;
@@ -38,10 +45,10 @@ export async function routeToAgentDO(req, namespace, signingKey, opts = {}) {
38
45
  const token = extractTokenFromRequest(req);
39
46
  if (!token)
40
47
  return new Response('Unauthorized', { status: 401 });
41
- const verified = await verifyToken(token, signingKey);
42
- if (verified.kind !== 'ok')
48
+ const tid = await resolveTid(token);
49
+ if (!tid)
43
50
  return new Response('Unauthorized', { status: 401 });
44
- const stub = namespace.get(namespace.idFromName(verified.payload.tid));
51
+ const stub = namespace.get(namespace.idFromName(tid));
45
52
  return stub.fetch(req);
46
53
  }
47
54
  function extractTokenFromRequest(req) {
@@ -1 +1 @@
1
- {"version":3,"file":"worker.js","sourceRoot":"","sources":["../../../src/server/cloudflare/worker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAoBzC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,GAAY,EACZ,SAAwC,EACxC,UAA+B,EAC/B,OAA8B,EAAE;IAEhC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAA;IAC1C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAC5B,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAA;IAEzB,iEAAiE;IACjE,mEAAmE;IACnE,8CAA8C;IAC9C,IACE,IAAI,KAAK,aAAa;QACtB,IAAI,KAAK,eAAe;QACxB,IAAI,KAAK,oBAAoB;QAC7B,IAAI,KAAK,qBAAqB;QAC9B,IAAI,KAAK,iBAAiB,EAC1B,CAAC;QACD,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAA;QAC1D,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IACxB,CAAC;IAED,0DAA0D;IAC1D,MAAM,KAAK,GAAG,uBAAuB,CAAC,GAAG,CAAC,CAAA;IAC1C,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,QAAQ,CAAC,cAAc,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;IAEhE,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,KAAK,EAAE,UAAU,CAAC,CAAA;IACrD,IAAI,QAAQ,CAAC,IAAI,KAAK,IAAI;QAAE,OAAO,IAAI,QAAQ,CAAC,cAAc,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;IAEhF,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAA;IACtE,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;AACxB,CAAC;AAED,SAAS,uBAAuB,CAAC,GAAY;IAC3C,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAA;IAC7C,IAAI,IAAI,EAAE,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAA;IACpE,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAC5B,MAAM,CAAC,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;IACvC,OAAO,CAAC,CAAA;AACV,CAAC","sourcesContent":["import { verifyToken } from '../token.js'\n\n/**\n * Minimal DurableObjectNamespace surface we need — `idFromName` +\n * `get` returning a `Stub` with `fetch(req)`. Kept structural so we\n * don't depend on `@cloudflare/workers-types` (the user's project has\n * them; we shouldn't duplicate).\n */\nexport interface MinimalDurableObjectNamespace {\n idFromName(name: string): MinimalDurableObjectId\n get(id: MinimalDurableObjectId): MinimalDurableObjectStub\n}\nexport interface MinimalDurableObjectId {\n // Opaque, but DO ids are passed back into `namespace.get()`.\n readonly name?: string\n}\nexport interface MinimalDurableObjectStub {\n fetch(req: Request): Promise<Response>\n}\n\n/**\n * Route an incoming Worker `fetch` request to the Durable Object\n * that owns its `tid`.\n *\n * The token travels in three places depending on the route:\n * - LAP HTTP calls: `Authorization: Bearer <token>` header\n * - Mint / resume HTTP calls: no token (identity resolver runs\n * inside the DO via the LAP router; we route by origin or a\n * special `/agent/mint` path — see below)\n * - WebSocket upgrade: `?token=<token>` in the URL\n *\n * Requests that don't carry a tid (mint, resume-list, sessions) are\n * routed to a \"root\" DO named `__root`, which handles identity /\n * token store operations centrally. LAP and WS calls route to the\n * per-tid DO so the pairing state stays local.\n *\n * This is the recommended entry for Cloudflare Workers deployments;\n * users who need custom routing can write their own and call the\n * underlying primitives (`verifyToken`, `namespace.get`, etc).\n */\nexport async function routeToAgentDO(\n req: Request,\n namespace: MinimalDurableObjectNamespace,\n signingKey: string | Uint8Array,\n opts: { rootName?: string } = {},\n): Promise<Response> {\n const rootName = opts.rootName ?? '__root'\n const url = new URL(req.url)\n const path = url.pathname\n\n // Non-LAP / non-WS management endpoints (mint, resume, sessions,\n // revoke) — there's no per-tid routing; use the root DO which owns\n // the shared token store + identity resolver.\n if (\n path === '/agent/mint' ||\n path === '/agent/revoke' ||\n path === '/agent/resume/list' ||\n path === '/agent/resume/claim' ||\n path === '/agent/sessions'\n ) {\n const stub = namespace.get(namespace.idFromName(rootName))\n return stub.fetch(req)\n }\n\n // Token-bearing routes (LAP + WS upgrade) — route by tid.\n const token = extractTokenFromRequest(req)\n if (!token) return new Response('Unauthorized', { status: 401 })\n\n const verified = await verifyToken(token, signingKey)\n if (verified.kind !== 'ok') return new Response('Unauthorized', { status: 401 })\n\n const stub = namespace.get(namespace.idFromName(verified.payload.tid))\n return stub.fetch(req)\n}\n\nfunction extractTokenFromRequest(req: Request): string | null {\n const auth = req.headers.get('authorization')\n if (auth?.startsWith('Bearer ')) return auth.slice('Bearer '.length)\n const url = new URL(req.url)\n const q = url.searchParams.get('token')\n return q\n}\n"]}
1
+ {"version":3,"file":"worker.js","sourceRoot":"","sources":["../../../src/server/cloudflare/worker.ts"],"names":[],"mappings":"AAkBA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,GAAY,EACZ,SAAwC,EACxC,UAAqD,EACrD,OAA8B,EAAE;IAEhC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAA;IAC1C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAC5B,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAA;IAEzB,iEAAiE;IACjE,mEAAmE;IACnE,8CAA8C;IAC9C,IACE,IAAI,KAAK,aAAa;QACtB,IAAI,KAAK,eAAe;QACxB,IAAI,KAAK,oBAAoB;QAC7B,IAAI,KAAK,qBAAqB;QAC9B,IAAI,KAAK,iBAAiB,EAC1B,CAAC;QACD,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAA;QAC1D,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IACxB,CAAC;IAED,0DAA0D;IAC1D,MAAM,KAAK,GAAG,uBAAuB,CAAC,GAAG,CAAC,CAAA;IAC1C,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,QAAQ,CAAC,cAAc,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;IAEhE,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC,KAAK,CAAC,CAAA;IACnC,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,QAAQ,CAAC,cAAc,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;IAE9D,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAA;IACrD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;AACxB,CAAC;AAED,SAAS,uBAAuB,CAAC,GAAY;IAC3C,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAA;IAC7C,IAAI,IAAI,EAAE,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAA;IACpE,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAC5B,MAAM,CAAC,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;IACvC,OAAO,CAAC,CAAA;AACV,CAAC","sourcesContent":["/**\n * Minimal DurableObjectNamespace surface we need — `idFromName` +\n * `get` returning a `Stub` with `fetch(req)`. Kept structural so we\n * don't depend on `@cloudflare/workers-types` (the user's project has\n * them; we shouldn't duplicate).\n */\nexport interface MinimalDurableObjectNamespace {\n idFromName(name: string): MinimalDurableObjectId\n get(id: MinimalDurableObjectId): MinimalDurableObjectStub\n}\nexport interface MinimalDurableObjectId {\n // Opaque, but DO ids are passed back into `namespace.get()`.\n readonly name?: string\n}\nexport interface MinimalDurableObjectStub {\n fetch(req: Request): Promise<Response>\n}\n\n/**\n * Route an incoming Worker `fetch` request to the Durable Object\n * that owns its `tid`.\n *\n * The token travels in three places depending on the route:\n * - LAP HTTP calls: `Authorization: Bearer <token>` header\n * - Mint / resume HTTP calls: no token (identity resolver runs\n * inside the DO via the LAP router; we route by origin or a\n * special `/agent/mint` path — see below)\n * - WebSocket upgrade: `?token=<token>` in the URL\n *\n * Requests that don't carry a tid (mint, resume-list, sessions) are\n * routed to a \"root\" DO named `__root`, which handles identity /\n * token store operations centrally. LAP and WS calls route to the\n * per-tid DO so the pairing state stays local.\n *\n * This is the recommended entry for Cloudflare Workers deployments;\n * users who need custom routing can write their own and call the\n * underlying primitives directly.\n *\n * As of 0.0.35 the token format is opaque (random, not signed), so we\n * can't recover `tid` from the token alone. The caller passes a\n * `resolveTid` callback — typically `(token) => stub.fetch(...)` to\n * the root DO's token-resolution endpoint — that turns a bearer into\n * its tid via the shared token store. Callers that don't shard by\n * tid can pass `() => Promise.resolve(rootName)` to route everything\n * through the root DO.\n */\nexport async function routeToAgentDO(\n req: Request,\n namespace: MinimalDurableObjectNamespace,\n resolveTid: (token: string) => Promise<string | null>,\n opts: { rootName?: string } = {},\n): Promise<Response> {\n const rootName = opts.rootName ?? '__root'\n const url = new URL(req.url)\n const path = url.pathname\n\n // Non-LAP / non-WS management endpoints (mint, resume, sessions,\n // revoke) — there's no per-tid routing; use the root DO which owns\n // the shared token store + identity resolver.\n if (\n path === '/agent/mint' ||\n path === '/agent/revoke' ||\n path === '/agent/resume/list' ||\n path === '/agent/resume/claim' ||\n path === '/agent/sessions'\n ) {\n const stub = namespace.get(namespace.idFromName(rootName))\n return stub.fetch(req)\n }\n\n // Token-bearing routes (LAP + WS upgrade) — route by tid.\n const token = extractTokenFromRequest(req)\n if (!token) return new Response('Unauthorized', { status: 401 })\n\n const tid = await resolveTid(token)\n if (!tid) return new Response('Unauthorized', { status: 401 })\n\n const stub = namespace.get(namespace.idFromName(tid))\n return stub.fetch(req)\n}\n\nfunction extractTokenFromRequest(req: Request): string | null {\n const auth = req.headers.get('authorization')\n if (auth?.startsWith('Bearer ')) return auth.slice('Bearer '.length)\n const url = new URL(req.url)\n const q = url.searchParams.get('token')\n return q\n}\n"]}