stitchkit 0.118.1 → 0.120.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 (180) hide show
  1. package/CHANGELOG.md +92 -0
  2. package/README.md +10 -7
  3. package/dist/browser/http.d.ts.map +1 -1
  4. package/dist/contract/client-types.d.ts +6 -3
  5. package/dist/contract/client-types.d.ts.map +1 -1
  6. package/dist/contract/define-validation.d.ts.map +1 -1
  7. package/dist/contract/define.d.ts +18 -12
  8. package/dist/contract/define.d.ts.map +1 -1
  9. package/dist/contract/endpoint-capabilities.d.ts +28 -0
  10. package/dist/contract/endpoint-capabilities.d.ts.map +1 -0
  11. package/dist/contract/factory.d.ts +49 -19
  12. package/dist/contract/factory.d.ts.map +1 -1
  13. package/dist/contract/tool-view.d.ts +1 -1
  14. package/dist/contract/tool-view.d.ts.map +1 -1
  15. package/dist/contract/transports.d.ts +5 -0
  16. package/dist/contract/transports.d.ts.map +1 -0
  17. package/dist/entrypoints/agent-runtime/coding-tools.js +9 -8
  18. package/dist/entrypoints/agent-runtime/harness.js +9 -8
  19. package/dist/entrypoints/agent-runtime/realtime.js +3 -3
  20. package/dist/entrypoints/agent-runtime/sandbox.js +10 -9
  21. package/dist/entrypoints/agent-runtime/sqlite/bun.js +12 -11
  22. package/dist/entrypoints/agent-runtime/sqlite/node.js +12 -11
  23. package/dist/entrypoints/agent-runtime/testing.js +12 -11
  24. package/dist/entrypoints/agent-runtime.js +22 -19
  25. package/dist/entrypoints/application/diagnostic-journal.js +3 -3
  26. package/dist/entrypoints/application/directory-inbox.js +4 -4
  27. package/dist/entrypoints/application/opentelemetry.js +1 -1
  28. package/dist/entrypoints/application.js +10 -10
  29. package/dist/entrypoints/cli/publish.js +4 -4
  30. package/dist/entrypoints/cli.js +13 -12
  31. package/dist/entrypoints/contract.d.ts +1 -1
  32. package/dist/entrypoints/contract.d.ts.map +1 -1
  33. package/dist/entrypoints/contract.js +6 -4
  34. package/dist/entrypoints/files.js +3 -3
  35. package/dist/entrypoints/geo/contract.d.ts +7 -0
  36. package/dist/entrypoints/geo/contract.d.ts.map +1 -0
  37. package/dist/entrypoints/geo/contract.js +6 -0
  38. package/dist/entrypoints/geo.js +60 -23
  39. package/dist/entrypoints/http.js +3 -3
  40. package/dist/entrypoints/index.js +9 -7
  41. package/dist/entrypoints/live.js +1 -1
  42. package/dist/entrypoints/node.js +7 -6
  43. package/dist/entrypoints/primitives.js +1 -1
  44. package/dist/entrypoints/process/owner-loss.js +1 -1
  45. package/dist/entrypoints/process.js +3 -3
  46. package/dist/entrypoints/react.js +1 -1
  47. package/dist/entrypoints/remote.js +4 -3
  48. package/dist/entrypoints/server.js +16 -15
  49. package/dist/entrypoints/telegram/screens.js +5 -5
  50. package/dist/entrypoints/telegram.js +7 -7
  51. package/dist/entrypoints/testing.js +7 -6
  52. package/dist/entrypoints/tools/agent.d.ts +9 -0
  53. package/dist/entrypoints/tools/agent.d.ts.map +1 -0
  54. package/dist/entrypoints/tools/agent.js +16 -0
  55. package/dist/entrypoints/tools/connections.js +7 -6
  56. package/dist/entrypoints/tools/contract.js +1 -1
  57. package/dist/entrypoints/tools/invoker.js +5 -4
  58. package/dist/entrypoints/tools/mcp.js +110 -9
  59. package/dist/entrypoints/tools/toolkit.d.ts +9 -0
  60. package/dist/entrypoints/tools/toolkit.d.ts.map +1 -0
  61. package/dist/entrypoints/tools/toolkit.js +40 -0
  62. package/dist/entrypoints/tools.d.ts +0 -10
  63. package/dist/entrypoints/tools.d.ts.map +1 -1
  64. package/dist/entrypoints/tools.js +38 -80
  65. package/dist/entrypoints/tracking/contract.js +5 -3
  66. package/dist/entrypoints/tracking/performance.js +3 -3
  67. package/dist/entrypoints/tracking.d.ts +1 -1
  68. package/dist/entrypoints/tracking.d.ts.map +1 -1
  69. package/dist/entrypoints/tracking.js +63 -83
  70. package/dist/entrypoints/xlsx.js +1 -1
  71. package/dist/geo/index.d.ts +2 -1
  72. package/dist/geo/index.d.ts.map +1 -1
  73. package/dist/geo/record.d.ts +8 -0
  74. package/dist/geo/record.d.ts.map +1 -0
  75. package/dist/geo/resolver.d.ts +1 -3
  76. package/dist/geo/resolver.d.ts.map +1 -1
  77. package/dist/geo/schema.d.ts +44 -0
  78. package/dist/geo/schema.d.ts.map +1 -0
  79. package/dist/geo/types.d.ts +2 -13
  80. package/dist/geo/types.d.ts.map +1 -1
  81. package/dist/{index-n5sv4z0w.js → index-0qyrcjfs.js} +16 -18
  82. package/dist/index-1psbyyhj.js +21 -0
  83. package/dist/{index-tsngj2b5.js → index-2fc1k9k2.js} +206 -206
  84. package/dist/index-3prvb42w.js +30 -0
  85. package/dist/{index-073nw9qr.js → index-3yb5kft5.js} +524 -522
  86. package/dist/{index-d9hq291n.js → index-4jpykzvw.js} +70 -81
  87. package/dist/index-568w258r.js +76 -0
  88. package/dist/index-69t14s4a.js +39 -0
  89. package/dist/{index-dky0dcmf.js → index-72r9k0av.js} +6 -2
  90. package/dist/{index-6p3frkv5.js → index-7zwtbak8.js} +9 -50
  91. package/dist/{index-90p34rts.js → index-8ryydawp.js} +7 -5
  92. package/dist/{index-vv1sch8a.js → index-8vzh5wpv.js} +13 -8
  93. package/dist/{index-75ns2ybj.js → index-8xyf8h2k.js} +1 -1
  94. package/dist/{index-xx1j310k.js → index-8yxgcyt6.js} +171 -169
  95. package/dist/{index-p6apg0jg.js → index-9frf01t9.js} +16 -9
  96. package/dist/{index-q0th8q0z.js → index-9mjrnqxs.js} +1 -3
  97. package/dist/{index-6f49krb5.js → index-aa50qwv4.js} +1 -1
  98. package/dist/{index-ega3yz4c.js → index-aqwg2dm5.js} +1 -1
  99. package/dist/{index-p0rf7sq9.js → index-bgcwxhxh.js} +225 -223
  100. package/dist/index-bph35vpy.js +77 -0
  101. package/dist/{index-tdpmfks8.js → index-bz479f0x.js} +1 -1
  102. package/dist/index-d3xdyjt6.js +38 -0
  103. package/dist/{index-q968hy6y.js → index-e452syyh.js} +1 -1
  104. package/dist/{index-86nbfysb.js → index-ff39f9dr.js} +3 -3
  105. package/dist/index-h1j71dr1.js +48 -0
  106. package/dist/{index-mgb7r8b8.js → index-jswst0h3.js} +1 -1
  107. package/dist/{index-095ya5hm.js → index-knmnj11j.js} +22 -191
  108. package/dist/{index-vwhrnp67.js → index-kz9734jc.js} +3 -3
  109. package/dist/{index-txg1npmg.js → index-mtwh9hyp.js} +1 -1
  110. package/dist/{index-dr3t5n1v.js → index-nn9qvkww.js} +46 -46
  111. package/dist/{index-ghtpfz4z.js → index-nyyam9ce.js} +2 -2
  112. package/dist/{index-qezhmp51.js → index-nz06qw5a.js} +3 -1
  113. package/dist/{index-1bx1xv1k.js → index-pfvde2fz.js} +5 -2
  114. package/dist/{index-w7jq3fz9.js → index-pq2m7t46.js} +1142 -1212
  115. package/dist/{index-yk4g8805.js → index-pq7rkwkk.js} +1 -30
  116. package/dist/{index-s80awwsw.js → index-qch1vcaa.js} +3 -1
  117. package/dist/{index-hdjmdwsj.js → index-qctbzmg9.js} +521 -511
  118. package/dist/{index-n8z3rvzw.js → index-qevqn3d3.js} +3 -5
  119. package/dist/{index-nqxrm176.js → index-r3db01kh.js} +1 -1
  120. package/dist/{index-v6vb5qx8.js → index-s3yxw6kt.js} +1 -1
  121. package/dist/{index-cqmqyjax.js → index-sa99p98w.js} +1 -1
  122. package/dist/index-sb9dr3tq.js +14 -0
  123. package/dist/{index-0gxvns6s.js → index-sba3e6m4.js} +1 -0
  124. package/dist/{index-f24bdt13.js → index-v1swr26p.js} +3 -1
  125. package/dist/{index-rhzkndr5.js → index-x4p3kw1p.js} +533 -530
  126. package/dist/{index-cycp3r3e.js → index-yb9n4pgj.js} +2 -2
  127. package/dist/{index-htxh46ej.js → index-ycqhyars.js} +2 -2
  128. package/dist/{index-9bwcthxw.js → index-yj6saztf.js} +31 -13
  129. package/dist/{index-f6m4c545.js → index-zrdcmg6j.js} +4 -6
  130. package/dist/{index-tvtacc9a.js → index-zyc64nbh.js} +1 -34
  131. package/dist/process/bun-child.d.ts +3 -2
  132. package/dist/process/bun-child.d.ts.map +1 -1
  133. package/dist/server/contract-method.d.ts.map +1 -1
  134. package/dist/tools/internal/surface-projector.d.ts.map +1 -1
  135. package/dist/tools/operations/async-operation-canonical-types.d.ts +1 -1
  136. package/dist/tracking/attribution.d.ts +21 -25
  137. package/dist/tracking/attribution.d.ts.map +1 -1
  138. package/dist/tracking/client-visit.d.ts +5 -7
  139. package/dist/tracking/client-visit.d.ts.map +1 -1
  140. package/dist/tracking/client.d.ts +2 -2
  141. package/dist/tracking/client.d.ts.map +1 -1
  142. package/dist/tracking/contract.d.ts +1 -1
  143. package/dist/tracking/host.d.ts +0 -1
  144. package/dist/tracking/host.d.ts.map +1 -1
  145. package/dist/tracking/privacy.d.ts +6 -0
  146. package/dist/tracking/privacy.d.ts.map +1 -1
  147. package/dist/tracking/schemas.d.ts +2 -2
  148. package/dist/tracking/schemas.d.ts.map +1 -1
  149. package/llms/agent-runtime-harness.txt +4 -3
  150. package/llms/agent-runtime-sandbox.txt +1 -1
  151. package/llms/agent-runtime.2.txt +3 -2
  152. package/llms/agent-runtime.3.txt +4 -46
  153. package/llms/agent-runtime.4.txt +113 -0
  154. package/llms/agent-runtime.txt +11 -13
  155. package/llms/cli.txt +1 -1
  156. package/llms/contract.txt +46 -24
  157. package/llms/geo-contract.txt +23 -0
  158. package/llms/geo.txt +40 -4
  159. package/llms/stitchkit.txt +16 -9
  160. package/llms/testing.txt +4 -6
  161. package/llms/tools-agent.txt +24 -0
  162. package/llms/tools-mcp.txt +71 -6
  163. package/llms/tools-toolkit.txt +23 -0
  164. package/llms/tools.2.txt +8 -5
  165. package/llms/tools.3.txt +9 -78
  166. package/llms/tools.txt +8 -8
  167. package/llms/tracking-contract.txt +1 -1
  168. package/llms/tracking.txt +27 -5
  169. package/llms/{upgrading-0.105.0-0.118.0.txt → upgrading-0.106.0-0.120.0.txt} +152 -410
  170. package/llms/upgrading-0.37.0-0.53.0.txt +969 -0
  171. package/llms/{upgrading-0.44.0-0.62.0.txt → upgrading-0.55.0-0.68.0.txt} +509 -528
  172. package/llms/{upgrading-0.63.0-0.83.0.txt → upgrading-0.69.0-0.95.0.txt} +506 -509
  173. package/llms/{upgrading-0.84.0-0.104.0.txt → upgrading-0.96.0-0.105.0.txt} +410 -506
  174. package/llms/upgrading.txt +5 -5
  175. package/llms-full.txt +475 -154
  176. package/llms.txt +17 -14
  177. package/package.json +32 -20
  178. package/llms/upgrading-0.37.0-0.44.0.txt +0 -444
  179. package/dist/{index-arjmb6de.js → index-1jwsfkfz.js} +0 -0
  180. package/dist/{index-qndsr7f0.js → index-5efrpfmj.js} +3 -3
@@ -14,15 +14,80 @@ Also read:
14
14
 
15
15
  ## `stitchkit/tools/mcp`
16
16
 
17
- A server-only leaf over the same MCP owner as `stitchkit/tools`. Its runtime and strict
18
- NodeNext declarations require Zod and `@modelcontextprotocol/server`, with no AI SDK peer.
19
- HTTP/stdio factories, mounts, schema policy, catalog and resource helpers keep their canonical
20
- behavior and names. See [MCP guide](../guide/mcp-and-agents.md#mcp--createmcphandler).
17
+ Server-only, and the one place the MCP server is exported. Its runtime and strict NodeNext
18
+ declarations require Zod and the `@modelcontextprotocol/server` v2 peer, with no AI SDK peer;
19
+ MCP hosts and tests use the separate `@modelcontextprotocol/client` package.
20
+
21
+ Framework-owned MCP tools advertise the exact declared output schema and return
22
+ the validated value unchanged as `structuredContent`, including arrays, scalars
23
+ and `null`. Tools without an output contract advertise and return no structured
24
+ payload. See [MCP guide](../guide/mcp-and-agents.md#mcp--createmcphandler).
21
25
 
22
26
  | Export | Kind | Purpose |
23
27
  |--------|------|---------|
24
- | `createMcpHandler` / `createMcpHttpRoute` / `buildMcpServer` / `mountMcp` | function | the shared authenticated HTTP handler, raw-route adapter, SDK server and contract mount |
25
- | `createStdioMcpServer` / `bindStdioProcessSignals` | function | the shared stdio server and bounded process cleanup |
28
+ | `createMcpHandler` | function | a stateless dual-era Streamable-HTTP MCP handler — [guide](../guide/mcp-and-agents.md#mcp--createmcphandler) |
29
+ | `createMcpHttpRoute` | function | framework-owned `RawRoute` adapter for an MCP HTTP handler |
30
+ | `createStdioMcpServer` | function | a complete stdio MCP server — [guide](../guide/mcp-and-agents.md#mcp-over-stdio--createstdiomcpserver) |
31
+ | `bindStdioProcessSignals` | function | explicitly bind OS signals to one close-only stdio handle — [guide](../guide/testing-and-deployment.md#stdio-process-signals) |
32
+ | `buildMcpServer` | function | build an `McpServer` from contract/runtime surfaces; no-auth configs omit the second argument |
33
+ | `mountMcp` | function | add contract tools to an existing `McpServer` — [guide](../guide/mcp-and-agents.md#mountmcp) |
34
+ | `validateMcpSchemas` | function | object-shaped assertion over the exact advertised schema surface — compatibility, typed properties and portable formats ([guide](../guide/mcp-and-agents.md#mcp-schema-validation-profile)) |
35
+ | `McpHandlerConfig` | _type_ | server surface plus stateless HTTP transport config |
36
+ | `McpHttpConfig` | _type_ | HTTP auth, protected-resource, legacy-era and security options |
37
+ | `McpHttpHandler` | _type_ | framework-owned `{ fetch(request), close() }` lifecycle |
38
+ | `McpHttpSecurityConfig` | _type_ | Fetch-boundary Host and Origin allowlists |
39
+ | `McpLegacyPolicy` | _type_ | `'serve' \| 'reject'` protocol-era compatibility policy |
40
+ | `McpStdioHandle` | _type_ | closeable official stdio transport handle |
41
+ | `StdioMcpServerConfig` | _type_ | config for `createStdioMcpServer` |
42
+ | `StdioCloseTarget` | _type_ | minimal close-only target accepted by `bindStdioProcessSignals` |
43
+ | `StdioProcessSignalsOptions` | _type_ | signal source, close callbacks and phased error reporting |
44
+ | `StdioProcessSignalsBinding` | _type_ | close-only signal binding with observed `promise` and listener `close()` |
45
+ | `StdioProcessSignalsErrorPhase` | _type_ | `'prepare' \| 'close' \| 'complete'` reporting phase |
46
+ | `McpServerBuildConfig` | _type_ | shared config for `buildMcpServer` |
47
+ | `McpServerSharedConfig` | _type_ | transport-neutral options shared by direct and finite surface configs |
48
+ | `McpServer` | _type_ | official split-SDK server instance accepted by raw extension points |
49
+ | `DirectMcpSurfaceConfig` | _type_ | static or identity-dynamic `services` / `runtimeTools` source |
50
+ | `FiniteMcpSurfaceConfig` | _type_ | bounded `surfaces` registry plus typed selector |
51
+ | `McpSurfaceDefinition` | _type_ | one immutable `{ services, runtimeTools }` MCP surface |
52
+ | `McpSurfaceRegistry` | _type_ | finite keyed surface registry for eager preparation |
53
+ | `StdioAuthConfig` | _type_ | startup identity composed into `StdioMcpServerConfig` |
54
+ | `McpMountConfig` | _type_ | config for `mountMcp` |
55
+ | `McpSchemaValidationConfig` | _type_ | shared `{ policy, requireTypedProperties, allowUntyped, requirePortableFormats, allowFormats }` profile |
56
+ | `ValidateMcpSchemasConfig` | _type_ | standalone validation profile plus `services`, `extend`, flattening and logger |
57
+ | `IncompatibleSchemaPolicy` | _type_ | `'throw' \| 'skip' \| 'warn'` |
26
58
  | `RuntimeToolDefinitionWithOutput` / `RuntimeToolDefinitionWithoutOutput` | _type_ | the one neutral construction, shared with `stitchkit/cli` and `stitchkit/tools`; MCP-only presenters are its fourth type argument, `RuntimeMcpToolPresenters<z.output<typeof output>>` |
27
59
  | `RuntimeToolDefinition` | _type_ | heterogeneous registration; the canonical runner validates input/output before invocation |
28
60
  | `RuntimeMcpToolPresenters` / `RuntimeMcpPresentation` | _type_ | official SDK content without framework-owned `structuredContent` or `isError`; one presenter owner shared with the full SDK surface |
61
+
62
+ ### Catalog stamp
63
+
64
+ Every advertised tool and every tool result carries the fingerprint of the catalog it came
65
+ from, so a long-lived consumer can see that its own copy is stale **without making a
66
+ request for it**. `createMcpHandler` is stateless by construction and therefore has no
67
+ retained session to push `notifications/tools/list_changed` down; the stamp needs none.
68
+
69
+ Store the stamp beside the tools when you list them, compare it against the one on every
70
+ result, and re-list when they differ — including on a refusal, which is exactly when a
71
+ stale catalog is the likeliest explanation and the least visible one. The server side
72
+ needs no wiring: every mount stamps what it advertises.
73
+
74
+ | Export | Kind | Summary |
75
+ |--------|------|---------|
76
+ | `readMcpCatalogStamp` | function | read a peer's stamp out of `_meta`, or `null` when there is none |
77
+ | `mcpCatalogMeta` | function | the `_meta` fragment a stamped tool or result carries |
78
+ | `MCP_CATALOG_META_KEY` | const | the namespaced `_meta` key (`stitchkit/catalog`) |
79
+ | `McpCatalogStamp` | _type_ | `{ digest, tools }` — the catalog fingerprint and its tool count |
80
+
81
+ ### MCP Apps (widgets)
82
+
83
+ Interactive MCP resources — [ADR 0019](../decisions/0019-generic-native-tools.md).
84
+
85
+ | Export | Kind | Summary |
86
+ |--------|------|---------|
87
+ | `mountMcpResource` | function | mount an MCP Apps widget resource |
88
+ | `inlineMcpAppBundle` | function | inline a built widget bundle into a resource |
89
+ | `EXT_APPS_BUNDLE_PLACEHOLDER` | const | the placeholder token `inlineMcpAppBundle` replaces |
90
+ | `RESOURCE_MIME_TYPE` | const | the MCP Apps resource MIME type |
91
+ | `McpResourceDef` | _type_ | an MCP Apps resource definition |
92
+ | `McpAppResourceMeta` | _type_ | resource `_meta` for an MCP App |
93
+ | `McpAppCsp` | _type_ | the widget content-security policy |
@@ -0,0 +1,23 @@
1
+ # stitchkit/tools/toolkit — stitchkit docs slice
2
+
3
+ > Generated from the `docs/` tree by `bun run gen:llms`. The index of all slices is
4
+ > `llms.txt` in this package.
5
+
6
+ Contains: API reference: `stitchkit/tools/toolkit` (docs/api/reference.md)
7
+
8
+ Also read:
9
+ - see `llms/tools.txt` for the MCP & agents guide
10
+
11
+ ==============================================================================
12
+ # API reference: `stitchkit/tools/toolkit` (docs/api/reference.md)
13
+ ==============================================================================
14
+
15
+ ## `stitchkit/tools/toolkit`
16
+
17
+ Server-only. One context-typed tool set served over MCP and to an AI SDK agent, so it
18
+ needs both the `@modelcontextprotocol/server` and `ai` peers. → ADR 0284.
19
+
20
+ | Export | Kind | Summary |
21
+ |--------|------|---------|
22
+ | `createToolkit` | function | context-typed tool mounts — [guide](../guide/cli.md#typed-context) |
23
+ | `Toolkit` | _type_ | the context-pinned tool surface from `createToolkit` |
package/llms/tools.2.txt CHANGED
@@ -154,8 +154,8 @@ export const users = defineContract({ prefix: 'users' }, {
154
154
  reshapes values inside the full schema. With `output` alone it is a slice, and
155
155
  the full result must fit that schema — `withToolView` refuses the endpoint at
156
156
  compile time when it does not.
157
- - **Exposure.** A view needs a tool transport. With `createContractFactory({
158
- toolExposure: 'explicit' })` an endpoint without `expose` is HTTP-only, so an
157
+ - **Exposure.** A view needs a tool transport. With `createContractFactory<Scope>().configure({
158
+ toolExposure: { default: ['HTTP'] } })` an endpoint without `expose` is HTTP-only, so an
159
159
  endpoint with a view names its tool transports in `expose`.
160
160
  - **What it refuses.** `defineContract` rejects a view on an endpoint with no
161
161
  tool transport or no full `output`, on a raw, `rawBody`, multipart,
@@ -178,7 +178,7 @@ see [Agent application runtime](./agent-runtime.md).
178
178
  `generateText` / `streamText`:
179
179
 
180
180
  ```ts
181
- import { mountAgent } from 'stitchkit/tools'
181
+ import { mountAgent } from 'stitchkit/tools/agent'
182
182
  import { generateText } from 'ai'
183
183
 
184
184
  const tools = mountAgent(usersService, { context: { userId: 'agent-1' } })
@@ -262,7 +262,9 @@ result. Optional presentation callbacks map that result to MCP content and AI
262
262
  SDK model output without coupling the handler to either SDK:
263
263
 
264
264
  ```ts
265
- import { createMcpHandler, defineRuntimeTool, mountAgent } from 'stitchkit/tools'
265
+ import { defineRuntimeTool } from 'stitchkit/tools'
266
+ import { createMcpHandler } from 'stitchkit/tools/mcp'
267
+ import { mountAgent } from 'stitchkit/tools/agent'
266
268
  import { z } from 'zod'
267
269
 
268
270
  const renderPreview = defineRuntimeTool({
@@ -628,7 +630,8 @@ hooks. The built-in `mountViewFile`, `mountWait`, `mountDownload` and
628
630
  media helper fetches with SSRF and path-traversal defenses:
629
631
 
630
632
  ```ts
631
- import { createMcpHandler, mountViewFile } from 'stitchkit/tools'
633
+ import { mountViewFile } from 'stitchkit/tools'
634
+ import { createMcpHandler } from 'stitchkit/tools/mcp'
632
635
 
633
636
  const handleMcp = createMcpHandler({
634
637
  serverInfo: { name: 'my-app', version: '1.0.0' },
package/llms/tools.3.txt CHANGED
@@ -14,57 +14,25 @@ Parts of this slice:
14
14
 
15
15
  ## `stitchkit/tools`
16
16
 
17
- Server-only. Turns contracts into MCP and AI-agent tools. MCP server surfaces
18
- need the `@modelcontextprotocol/server` v2 peer; MCP hosts/tests use the separate
19
- `@modelcontextprotocol/client` package. Agent surfaces need the `ai` peer.
20
-
21
- Framework-owned MCP tools advertise the exact declared output schema and return
22
- the validated value unchanged as `structuredContent`, including arrays, scalars
23
- and `null`. Tools without an output contract advertise and return no structured
24
- payload.
17
+ Server-only, and imported without any optional peer: the transport-neutral tool layer —
18
+ the registry, tool names and manifest, runtime tools, native tools, the invoker, the OAuth
19
+ provider and the durability engine. An application that serves its operations over HTTP and
20
+ CLI lists its tool names here with neither MCP nor the AI SDK installed. The adapters that
21
+ need a peer have their own subpaths: [`stitchkit/tools/mcp`](#stitchkittoolsmcp) (the MCP
22
+ server SDK), [`stitchkit/tools/agent`](#stitchkittoolsagent) (the `ai` peer) and
23
+ [`stitchkit/tools/toolkit`](#stitchkittoolstoolkit) (both). → ADR 0284.
25
24
 
26
25
  | Export | Kind | Summary |
27
26
  |--------|------|---------|
28
- | `createMcpHandler` | function | a stateless dual-era Streamable-HTTP MCP handler — [guide](../guide/mcp-and-agents.md#mcp--createmcphandler) |
29
- | `createMcpHttpRoute` | function | framework-owned `RawRoute` adapter for an MCP HTTP handler |
30
- | `createStdioMcpServer` | function | a complete stdio MCP server — [guide](../guide/mcp-and-agents.md#mcp-over-stdio--createstdiomcpserver) |
31
- | `bindStdioProcessSignals` | function | explicitly bind OS signals to one close-only stdio handle — [guide](../guide/testing-and-deployment.md#stdio-process-signals) |
32
- | `buildMcpServer` | function | build an `McpServer` from contract/runtime surfaces; no-auth configs omit the second argument |
33
- | `mountMcp` | function | add contract tools to an existing `McpServer` — [guide](../guide/mcp-and-agents.md#mountmcp) |
34
- | `mountAgent` | function | a Vercel AI SDK `ToolSet` from a service; failed executions reject through the SDK tool-error channel with a safe typed envelope, while successful output is never classified by field name — [guide](../guide/mcp-and-agents.md#ai-agents--mountagent) |
35
27
  | `defineRuntimeTool` | function | define one validated pathless operation for explicit MCP, Agent and/or CLI surfaces — [guide](../guide/mcp-and-agents.md#pathless-runtime-tools-and-multimodal-results) |
36
28
  | `createRuntimeToolFactory` | function | bind shared identity and Zod-validated per-call context for runtime tools — [guide](../guide/mcp-and-agents.md#pathless-runtime-tools-and-multimodal-results) |
37
- | `createToolInvoker` | function | compile an exposure-aware in-process dispatcher over the canonical tool runner; use peer-free `stitchkit/tools/invoker`, or the full `stitchkit/tools` adapter barrel — [guide](../guide/mcp-and-agents.md#in-process-calls--createtoolinvoker) |
38
- | `createToolkit` | function | context-typed tool mounts — [guide](../guide/cli.md#typed-context) |
29
+ | `createToolInvoker` | function | compile an exposure-aware in-process dispatcher over the canonical tool runner; use `stitchkit/tools/invoker` or `stitchkit/tools`, both peer-free — [guide](../guide/mcp-and-agents.md#in-process-calls--createtoolinvoker) |
39
30
  | `mountViewFile` | function | a native multimodal "view file" MCP tool |
40
31
  | `resolveMedia` | function | resolve a media reference for a tool result |
41
- | `validateMcpSchemas` | function | object-shaped assertion over the exact advertised schema surface — compatibility, typed properties and portable formats ([guide](../guide/mcp-and-agents.md#mcp-schema-validation-profile)) |
42
32
  | `listToolNames` | function | every contract/runtime tool name with origin, identity and transports — for stable snapshots — [guide](../guide/mcp-and-agents.md#pinning-tool-names--listtoolnames) |
43
33
  | `listContractToolNames` | function | the same listing straight from contracts — no handlers or stub services needed |
44
34
  | `describeToolCatalog` | function | inspect the exact model-facing names, source identities, schema byte sizes and deferred state; an explicit total byte budget fails closed |
45
35
  | `ToolCatalogConfig` / `ToolCatalogEntry` | _type_ | catalog source, transport, optional explicit schema budget and one inspectable result row |
46
- | `McpHandlerConfig` | _type_ | server surface plus stateless HTTP transport config |
47
- | `McpHttpConfig` | _type_ | HTTP auth, protected-resource, legacy-era and security options |
48
- | `McpHttpHandler` | _type_ | framework-owned `{ fetch(request), close() }` lifecycle |
49
- | `McpHttpSecurityConfig` | _type_ | Fetch-boundary Host and Origin allowlists |
50
- | `McpLegacyPolicy` | _type_ | `'serve' \| 'reject'` protocol-era compatibility policy |
51
- | `McpStdioHandle` | _type_ | closeable official stdio transport handle |
52
- | `StdioMcpServerConfig` | _type_ | config for `createStdioMcpServer` |
53
- | `StdioCloseTarget` | _type_ | minimal close-only target accepted by `bindStdioProcessSignals` |
54
- | `StdioProcessSignalsOptions` | _type_ | signal source, close callbacks and phased error reporting |
55
- | `StdioProcessSignalsBinding` | _type_ | close-only signal binding with observed `promise` and listener `close()` |
56
- | `StdioProcessSignalsErrorPhase` | _type_ | `'prepare' \| 'close' \| 'complete'` reporting phase |
57
- | `McpServerBuildConfig` | _type_ | shared config for `buildMcpServer` |
58
- | `McpServerSharedConfig` | _type_ | transport-neutral options shared by direct and finite surface configs |
59
- | `McpServer` | _type_ | official split-SDK server instance accepted by raw extension points |
60
- | `DirectMcpSurfaceConfig` | _type_ | static or identity-dynamic `services` / `runtimeTools` source |
61
- | `FiniteMcpSurfaceConfig` | _type_ | bounded `surfaces` registry plus typed selector |
62
- | `McpSurfaceDefinition` | _type_ | one immutable `{ services, runtimeTools }` MCP surface |
63
- | `McpSurfaceRegistry` | _type_ | finite keyed surface registry for eager preparation |
64
- | `StdioAuthConfig` | _type_ | startup identity composed into `StdioMcpServerConfig` |
65
- | `McpMountConfig` | _type_ | config for `mountMcp` |
66
- | `McpSchemaValidationConfig` | _type_ | shared `{ policy, requireTypedProperties, allowUntyped, requirePortableFormats, allowFormats }` profile |
67
- | `ValidateMcpSchemasConfig` | _type_ | standalone validation profile plus `services`, `extend`, flattening and logger |
68
36
  | `RuntimeToolDefinition` | _type_ | heterogeneous registration of pathless operations in `runtimeTools: [...]`; an inline handler is contextually typed by the parsed object, a definition constructed with its own schema registers unchanged, and the runner validates input before the handler |
69
37
  | `RuntimeToolDefinitionBase` | _type_ | common name, identity, input, exposure and MCP metadata fields |
70
38
  | `RuntimeToolDefinitionWithOutput` | _type_ | the one neutral construction: identity, schemas and a handler typed from them; the fourth type argument names the adapter's `present` extension (`RuntimeToolPresenters<…>` here, `RuntimeMcpToolPresenters<…>` on `stitchkit/tools/mcp`, none by default) |
@@ -90,11 +58,8 @@ payload.
90
58
  | `CimdCacheEvent` | _type_ | observable CIMD cache hit, miss, revalidation and eviction event |
91
59
  | `createSecureClientMetadataFetcher` | function | production HTTPS, DNS/IP-pinned CIMD fetcher |
92
60
  | `RuntimeAgentModelOutput` | _type_ | AI SDK model-facing text/JSON/content output returned by `present.agent` |
93
- | `AgentMountConfig` | _type_ | config for `mountAgent` |
94
61
  | `AgentToolRegistry` / `AgentToolRegistryBuilder` / `AgentToolRegistryInput` | _type_ | the composed runtime surface and its builder: declared defaults, `replace`/`disable` by name, and the exact `{ tools, names }` a mount receives |
95
62
  | `defineToolRegistry` | function | compose runtime tools over one declared default set; an unknown `replace`/`disable` name is refused instead of silently leaving the default in place |
96
- | `AgentContext` | _type_ | the context merged into agent tool handlers |
97
- | `Toolkit` | _type_ | the context-pinned tool surface from `createToolkit` |
98
63
  | `ToolExtend` | _type_ | extra-args extension for `mountMcp` / `mountAgent` |
99
64
  | `ToolLifecycle` | _type_ | `beforeHandle` / `afterHandle` gate for tool calls — [guide](../guide/mcp-and-agents.md#guarding-tools--lifecycle) |
100
65
  | `ToolExecutionControlReason` | _type_ | internal managed-execution stop reason: stale run or requested interruption |
@@ -126,7 +91,6 @@ payload.
126
91
  | `NonPortableFormat` | _type_ | one `{ path, format }` portability finding |
127
92
  | `PORTABLE_JSON_SCHEMA_FORMATS` | constant | portable-format baseline used by MCP validation |
128
93
  | `ToolNameEntry` | _type_ | one `listToolNames` row — `{ kind, name, service, method, transports }` |
129
- | `IncompatibleSchemaPolicy` | _type_ | `'throw' \| 'skip' \| 'warn'` |
130
94
  | `McpMediaContent` | _type_ | a multimodal MCP content item |
131
95
 
132
96
  ### Native tools
@@ -163,7 +127,7 @@ runtime-tool runner, plus deliberate raw MCP adapters over the same mechanics.
163
127
  | `AsyncOperationOutputCapability` | _type_ | optional result/artifact schema plus handler |
164
128
  | `RuntimeAsyncOperationConfig` | _type_ | runtime-only descriptor configuration |
165
129
  | `RuntimeAsyncOperation` | _type_ | inferred generated definitions and schemas |
166
- | `AsyncOperationContractConfig` | _type_ | canonical contract config where start returns the operation id; optional `expose` names the transports per capability, because this contract is built inside the framework and never passes through a consumer's `toolExposure: 'explicit'` factory |
130
+ | `AsyncOperationContractConfig` | _type_ | canonical contract config where start returns the operation id; optional `expose` names the transports per capability, because this contract is built inside the framework and never passes through a consumer's configured factory |
167
131
  | `AsyncOperationContractWithStartOutputConfig` | _type_ | canonical contract config with an application start envelope and typed id extractor |
168
132
  | `DefinedAsyncOperationContract` | _type_ | generated contract, capability keys, schemas and parsed adapters |
169
133
  | `ContractAsyncOperationConfig` | _type_ | literal contract method binding and handlers |
@@ -230,39 +194,6 @@ mountAgent(services, { durability: (toolCallId) => myLedgerFor(toolCallId) });
230
194
  | `AgentToolError` | class | the model-safe envelope a failed agent tool throws |
231
195
  | `isAgentToolError` | function | brand check for it — a consumer running its own loop no longer parses the message |
232
196
 
233
- ### Catalog stamp
234
-
235
- Every advertised tool and every tool result carries the fingerprint of the catalog it came
236
- from, so a long-lived consumer can see that its own copy is stale **without making a
237
- request for it**. `createMcpHandler` is stateless by construction and therefore has no
238
- retained session to push `notifications/tools/list_changed` down; the stamp needs none.
239
-
240
- Store the stamp beside the tools when you list them, compare it against the one on every
241
- result, and re-list when they differ — including on a refusal, which is exactly when a
242
- stale catalog is the likeliest explanation and the least visible one. The server side
243
- needs no wiring: every mount stamps what it advertises.
244
-
245
- | Export | Kind | Summary |
246
- |--------|------|---------|
247
- | `readMcpCatalogStamp` | function | read a peer's stamp out of `_meta`, or `null` when there is none |
248
- | `mcpCatalogMeta` | function | the `_meta` fragment a stamped tool or result carries |
249
- | `MCP_CATALOG_META_KEY` | const | the namespaced `_meta` key (`stitchkit/catalog`) |
250
- | `McpCatalogStamp` | _type_ | `{ digest, tools }` — the catalog fingerprint and its tool count |
251
-
252
- ### MCP Apps (widgets)
253
-
254
- Interactive MCP resources — [ADR 0019](../decisions/0019-generic-native-tools.md).
255
-
256
- | Export | Kind | Summary |
257
- |--------|------|---------|
258
- | `mountMcpResource` | function | mount an MCP Apps widget resource |
259
- | `inlineMcpAppBundle` | function | inline a built widget bundle into a resource |
260
- | `EXT_APPS_BUNDLE_PLACEHOLDER` | const | the placeholder token `inlineMcpAppBundle` replaces |
261
- | `RESOURCE_MIME_TYPE` | const | the MCP Apps resource MIME type |
262
- | `McpResourceDef` | _type_ | an MCP Apps resource definition |
263
- | `McpAppResourceMeta` | _type_ | resource `_meta` for an MCP App |
264
- | `McpAppCsp` | _type_ | the widget content-security policy |
265
-
266
197
  ### Introspection & internals
267
198
 
268
199
  Advanced building blocks — the shared machinery the mounts are built on.
package/llms/tools.txt CHANGED
@@ -125,10 +125,10 @@ recursive calls without retaining request state. Every invocation gets a fresh
125
125
  tool-call context and runs the same extension resolution, input/output
126
126
  validation, lifecycle, hooks and output-strip reporter as mounted tools.
127
127
 
128
- The dedicated entrypoint needs only the normal `stitchkit`/`zod` install. Use
129
- the broader `stitchkit/tools` barrel when the same program also mounts MCP or AI
130
- adapters and has installed their optional peers. Both imports reach the same
131
- runner; this is dependency isolation, not a second execution implementation.
128
+ The dedicated entrypoint needs only the normal `stitchkit`/`zod` install, and so does
129
+ `stitchkit/tools`, which exports the same invoker beside the rest of the tool layer. Both
130
+ imports reach the same runner; this is dependency isolation, not a second execution
131
+ implementation.
132
132
 
133
133
  `invoke` returns the canonical discriminated `ToolResult`, not an AI SDK or MCP
134
134
  presentation envelope. `invokeOrThrow` returns validated data and throws the
@@ -150,9 +150,8 @@ get the view's defaults and projected answer, which is what `collectTools` and
150
150
  An MCP-only server imports `stitchkit/tools/mcp` and installs
151
151
  `stitchkit`, `zod` and `@modelcontextprotocol/server`. The leaf's runtime and strict
152
152
  NodeNext declarations require no `ai`. It exports the existing HTTP/stdio server,
153
- schema policy, catalog and resource helpers; their implementation and security are shared
154
- with the full `stitchkit/tools` barrel. Use that full barrel when the application also
155
- needs its AI SDK features.
153
+ schema policy, catalog and resource helpers, and it is the only entrypoint that does:
154
+ `stitchkit/tools` loads no optional peer. AI SDK tools come from `stitchkit/tools/agent`.
156
155
 
157
156
  `createMcpHandler` builds a complete stateless Streamable-HTTP MCP endpoint on
158
157
  the official TypeScript SDK v2 server package. It owns server creation,
@@ -876,7 +875,8 @@ stitchkit ships the OAuth **protocol mechanics**; the app supplies only
876
875
  **identity and storage**. Three pieces wire it together:
877
876
 
878
877
  ```ts
879
- import { createMcpHandler, createMcpHttpRoute, mountOAuthProvider, oauthProtectedResourceRoute } from 'stitchkit/tools'
878
+ import { mountOAuthProvider, oauthProtectedResourceRoute } from 'stitchkit/tools'
879
+ import { createMcpHandler, createMcpHttpRoute } from 'stitchkit/tools/mcp'
880
880
  import { createServer } from 'stitchkit/server'
881
881
 
882
882
  const resource = 'https://api.example.com/mcp'
@@ -22,7 +22,7 @@ browser code that only sends events does not import it. → ADR 0280
22
22
  | `createTrackingContract` / `TrackingContractConfig` / `TrackingContractEndpoints` | function / _type_ | `bootstrap` (`POST /visit`) and `track` (`POST /events`, `safelistedBody`) from the application's event types, scope and optional extras |
23
23
  | `createTrackingSchemas` / `TrackingSchemas` / `TrackingSchemasConfig` | function / _type_ | every schema of one surface — `event`, `request`, `response`, `disposition`, `entry`, `bootstrap` — from `eventTypes`, optional `eventExtras`, `buildIdPattern`, `maxEventsPerBatch` |
24
24
  | `TrackingEventEnvelope` / `TrackingEventShape` | _type_ | `eventId`, `visitId`, `browserStreamId`, `browserSequence`, `type`, `page`, `metadata`, `clientTimestamp` |
25
- | `TrackEventsRequest` / `TrackEventsResponse` / `TrackEventsResponseSchema` | _type_ / schema | a batch (`buildId`, `events`, `utm`) and its answer (`accepted`, `dispositions`) |
25
+ | `TrackEventsRequest` / `TrackEventsResponse` / `TrackEventsResponseSchema` | _type_ / schema | a batch (`buildId`, `events`; attribution travels with the visit bootstrap) and its answer (`accepted`, `dispositions`) |
26
26
  | `TrackingDisposition` / `TrackingDispositionSchema` / `TrackingDispositionStatus` / `TrackingDispositionStatusSchema` | _type_ / schema | `accepted` / `duplicate` / `identity-invalid` / `excluded-bot` — every one terminal |
27
27
  | `VisitEntryContext` / `VisitEntryContextShape` / `VisitBootstrapResponse` / `VisitBootstrapResponseSchema` | _type_ / schema | what a browser reports to open a visit (lineage, landing, referrer, UTM, display, screen, `buildId`, outbox health) and the lease it gets back |
28
28
  | `TrackingOutboxState` / `TrackingOutboxStateSchema` | _type_ / schema | `available` / `unavailable` |
package/llms/tracking.txt CHANGED
@@ -27,7 +27,7 @@ Both entrypoints are **evolving**.
27
27
  | the event envelope, the batch, the dispositions, the visit entry and lease schemas | the event **types**, their metadata, their labels |
28
28
  | the tab-shared outbox with reserved sequences and a short flush lease | which storage adapter (IndexedDB in a tab) |
29
29
  | the page-leave beacon that arrives, and its queued insurance copy | the session, the router, the React provider |
30
- | visible time, scroll milestones, `data-track` clicks, UTM first/current touch | the referrer → source map, the attribute names |
30
+ | visible time, scroll milestones, `data-track` clicks, raw first/current touch | channel classification, click-marker names, the attribute names |
31
31
  | `dispositionTrackingBatch`, `issueVisitLease`, `activeIntervalOf`, presence | the tables, the transaction, adoption, geo, reports |
32
32
 
33
33
  ## Contract
@@ -74,7 +74,7 @@ const client = createTrackingClient<BrowserEvents>({
74
74
  deliver: (batch) => api.tracking.track(batch), // or a socket first, HTTP as the fallback
75
75
  unloadUrl: urls.tracking.track(),
76
76
  outbox: createTrackingOutbox(indexedDbOutboxStorage('my-app-tracking')),
77
- referrerMap: [{ pattern: /t\.me|telegram\.org/, source: 'telegram', medium: 'social' }],
77
+ clickIdParams: ['gclid', 'gbraid', 'wbraid', 'msclkid', 'yclid', 'ttclid', 'fbclid'],
78
78
  isAction: isInteractionAction,
79
79
  onVisit: (visitId) => rum.setVisit(visitId),
80
80
  })
@@ -87,6 +87,28 @@ client.track('ITEM_VIEW', { itemId, itemTitle })
87
87
  client.track('SIGN_OUT')
88
88
  ```
89
89
 
90
+ Attribution carries observations, not a channel verdict. `utm` contains only the current URL's
91
+ `utm_*` parameters, retaining case and whitespace up to 200 characters per field; tags without
92
+ `utm_source` are valid. Parameter names are case-sensitive (`UTM_SOURCE` is not a tag), a repeated
93
+ tag keeps its first value, and a whitespace-only value is kept as the fact it is. `referrer` carries
94
+ the referring URL with credentials masked. Neither an external referrer nor a click marker creates
95
+ campaign tags. Classify the channel on your server.
96
+
97
+ Attribution belongs to the visit: the bootstrap entry carries it, and an event batch carries events
98
+ only. Join events to their visit on the server to attribute them.
99
+
100
+ `clickIdParams` is the application's ordered list of query-parameter names to recognise. There is no
101
+ built-in list: the first configured name with a nonempty value becomes `clickId` in the touch and
102
+ bootstrap entry. Only the name is retained, never the click ID's value: a referrer from your own site
103
+ repeats the landing query, so the value of every configured marker in a referrer is masked too. An empty
104
+ list collects none; names must contain 1–200 characters, and `createTrackingClient` refuses a list that
105
+ does not. Bootstrap collects these facts even if browser storage is unavailable.
106
+
107
+ `client.attribution()` returns `firstTouch` and `currentTouch`. The first is persisted for 90 days
108
+ by default; the current is this capture's raw context, so an untagged page does not inherit an earlier
109
+ campaign. The server owns any policy for retaining the last non-direct channel. Stored first-touch
110
+ records carry a format version; unversioned attribution is discarded because its tags may be inferred.
111
+
90
112
  Two knobs match the client to your schema: `batchSize` is the contract's
91
113
  `maxEventsPerBatch` (a larger batch is a `400` the outbox can never retire),
92
114
  and `decorate` adds your `eventExtras` — a locale, an area, or the identity a
@@ -323,7 +345,7 @@ shapes are `stitchkit/tracking/contract`, the server half is
323
345
  | Export | Kind | Summary |
324
346
  |--------|------|---------|
325
347
  | `createTrackingClient` | function | the client: visit lease and renewal, pending queue, synchronous identity from reserved sequences, outbox and flush lease, delivery, the string-body page-leave beacon plus a queued copy, visible time, scroll milestones, declarative clicks, heartbeats |
326
- | `TrackingClient` / `TrackingClientConfig` | _type_ | `track` / `onNavigate` / `start` / `visitId` / `browserStreamId` / `attribution`, and the host, `buildId`, `builtin` names, `bootstrap`, `deliver`, optional `decorate` (your `eventExtras` on every minted event), `unload` / `unloadUrl`, `outbox`, `onUnauthorized`, `onVisit`, `onFailure`, `isAction`, `referrerMap`, `clickAttributes`, `hrefPolicy` (`path-only` by default; `full` retains click query/fragment before `decorate`), `scrollMilestones`, `batchSize`, periods and limits |
348
+ | `TrackingClient` / `TrackingClientConfig` | _type_ | `track` / `onNavigate` / `start` / `visitId` / `browserStreamId` / `attribution`, and the host, `buildId`, `builtin` names, `bootstrap`, `deliver`, optional `decorate` (your `eventExtras` on every minted event), `unload` / `unloadUrl`, `outbox`, `onUnauthorized`, `onVisit`, `onFailure`, `isAction`, `clickIdParams` (ordered application-defined marker names; no values retained), `clickAttributes`, `hrefPolicy` (`path-only` by default; `full` retains click query/fragment before `decorate`), `scrollMilestones`, `batchSize`, periods and limits |
327
349
  | `TrackFn` / `EventsWithMetadata` / `EventsWithoutMetadata` | _type_ | `track(type)` / `track(type, metadata)` typed by the application's metadata map, and the two halves of that map |
328
350
  | `BuiltinTrackingEventTypes` / `CONVENTIONAL_TRACKING_EVENT_TYPES` | _type_ / const | the application's names for the events the client emits itself; the conventional `PAGE_VIEW` … `INTERACTION` set |
329
351
  | `browserTrackingHost` / `TrackingHost` / `TrackingPageContext` | function / _type_ | everything the client takes from a browser tab behind one interface — page context, visibility, scroll depth, events, intervals, clocks, storage — so a test or a non-tab host can supply its own |
@@ -336,8 +358,8 @@ shapes are `stitchkit/tracking/contract`, the server half is
336
358
  | `createVisibleTimeMeter` / `VisibleTimeMeter` / `VisibleInterval` / `VisibleHeartbeat` / `VisibleTimeMeterOptions` | function / _type_ | additive visible time — `checkpoint` / `cut` / `heartbeat`, each interval with its own id; a hidden heartbeat carries no interval |
337
359
  | `scrollDepthPercent` / `createScrollMilestones` / `ScrollMilestones` | function / _type_ | depth as a percentage of the scrollable range; milestones fired once each per page |
338
360
  | `createOncePerPage` / `OncePerPage` | function / _type_ | one fact per key per page within a window — the guard a twice-mounted component cannot keep itself |
339
- | `resolveAttribution` / `ResolveAttributionInput` / `ResolvedAttribution` / `AttributionStorage` / `ReferrerRule` | function / _type_ | first-touch once, current-touch on every new UTM; the referrer → source/medium map is the application's, there is no built-in list |
340
- | `parseUtmFromSearch` / `parseReferrer` | function | the two parsers `resolveAttribution` is built from |
361
+ | `resolveAttribution` / `ResolveAttributionInput` / `ResolvedAttribution` / `AttributionStorage` | function / _type_ | persisted first-touch with TTL, raw current-touch on each capture; actual UTM, referrer and optional `clickId` name from `clickIdParams`; `storage: null` collects without persistence; no channel inference |
362
+ | `parseUtmFromSearch` | function | reads only `utm_*`, preserving case and whitespace up to 200 characters per field; any tag is sufficient, no source required |
341
363
  | `redactTrackingText` / `redactTrackingValue` | functions | mask passwords, sign-in credentials and signed launch data in text or a value of any shape; the key stays, and navigation and campaign parameters are untouched |
342
364
  | `resolveTrackedClick` / `ResolveTrackedClickOptions` / `TrackedClick` / `TrackedClickAttributes` / `ClickTarget` | function / _type_ | `data-track` → click, `data-track-action` → interaction, a link to another origin → outbound; attribute names configurable; `hrefPolicy: 'full'` retains query/fragment (default `path-only` omits them), URL credentials excluded; `leavesPage` says which path to send on |
343
365