@reclaimprotocol/agent 0.1.1-dev.1 → 0.1.2

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 (232) hide show
  1. package/README.md +1 -1
  2. package/lib/cdp/capture-engine.d.ts +66 -0
  3. package/lib/cdp/capture-engine.js +153 -0
  4. package/lib/cdp/capture.d.ts +9 -20
  5. package/lib/cdp/capture.js +14 -138
  6. package/lib/cdp/index.d.ts +3 -0
  7. package/lib/cdp/index.js +6 -0
  8. package/lib/cdp/launcher.js +4 -3
  9. package/lib/config/store.d.ts +7 -6
  10. package/lib/config/store.js +2 -2
  11. package/lib/consts.d.ts +68 -0
  12. package/lib/consts.js +134 -0
  13. package/lib/index.d.ts +2 -2
  14. package/lib/index.js +1 -1
  15. package/lib/logger.js +2 -1
  16. package/lib/mcp/api/operations.gen.d.ts +100 -48
  17. package/lib/mcp/api/operations.gen.js +1129 -194
  18. package/lib/mcp/api/to-zod.d.ts +24 -0
  19. package/lib/mcp/api/to-zod.js +94 -0
  20. package/lib/mcp/api/tools.js +1 -1
  21. package/lib/mcp/credentials/authenticate.d.ts +3 -0
  22. package/lib/mcp/{tools/credentials → credentials}/authenticate.js +3 -3
  23. package/lib/mcp/credentials/build.d.ts +5 -0
  24. package/lib/mcp/credentials/build.js +18 -0
  25. package/lib/mcp/{tools/credentials → credentials}/cache.d.ts +9 -9
  26. package/lib/mcp/{tools/credentials → credentials}/cache.js +36 -19
  27. package/lib/mcp/credentials/import.d.ts +2 -0
  28. package/lib/mcp/{tools/credentials → credentials}/import.js +2 -2
  29. package/lib/mcp/credentials/issue.d.ts +2 -0
  30. package/lib/mcp/{tools/credentials → credentials}/issue.js +4 -4
  31. package/lib/mcp/credentials/keypair.d.ts +17 -0
  32. package/lib/mcp/credentials/keypair.js +48 -0
  33. package/lib/mcp/credentials/link.d.ts +3 -0
  34. package/lib/mcp/credentials/link.js +107 -0
  35. package/lib/mcp/{tools/credentials → credentials}/list-cached.d.ts +1 -1
  36. package/lib/mcp/{tools/credentials → credentials}/list-cached.js +5 -5
  37. package/lib/mcp/credentials/owner-key.d.ts +23 -0
  38. package/lib/mcp/credentials/owner-key.js +58 -0
  39. package/lib/mcp/credentials/paths.d.ts +12 -0
  40. package/lib/mcp/credentials/paths.js +35 -0
  41. package/lib/mcp/credentials/poll.d.ts +27 -0
  42. package/lib/mcp/credentials/poll.js +61 -0
  43. package/lib/mcp/{tools/credentials → credentials}/resolve-owner-key.d.ts +1 -1
  44. package/lib/mcp/{tools/credentials → credentials}/resolve-owner-key.js +2 -2
  45. package/lib/mcp/credentials/session-cache.d.ts +14 -0
  46. package/lib/mcp/credentials/session-cache.js +42 -0
  47. package/lib/mcp/{tools/credentials → credentials}/status.d.ts +1 -1
  48. package/lib/mcp/credentials/status.js +76 -0
  49. package/lib/mcp/instructions.d.ts +1 -0
  50. package/lib/mcp/instructions.js +11 -0
  51. package/lib/mcp/register.d.ts +38 -0
  52. package/lib/mcp/register.js +80 -0
  53. package/lib/mcp/server.d.ts +2 -8
  54. package/lib/mcp/server.js +3 -33
  55. package/lib/mcp/start.js +17 -11
  56. package/lib/mcp/tools/agent/build.d.ts +5 -9
  57. package/lib/mcp/tools/agent/build.js +7 -24
  58. package/lib/mcp/tools/agent/index.d.ts +2 -0
  59. package/lib/mcp/tools/agent/index.js +3 -0
  60. package/lib/mcp/tools/agent/proof.js +3 -7
  61. package/lib/mcp/tools/agent/propose.js +13 -2
  62. package/lib/mcp/tools/agent/publish.js +172 -75
  63. package/lib/mcp/tools/agent/replay.js +0 -5
  64. package/lib/mcp/tools/analyze.d.ts +3 -0
  65. package/lib/mcp/tools/analyze.js +26 -0
  66. package/lib/mcp/tools/attach.d.ts +11 -0
  67. package/lib/mcp/tools/attach.js +72 -0
  68. package/lib/mcp/tools/authenticate/authenticate.js +107 -0
  69. package/lib/mcp/tools/authenticate/build.d.ts +15 -0
  70. package/lib/mcp/tools/authenticate/build.js +28 -0
  71. package/lib/mcp/tools/authenticate/decrypt-key.d.ts +19 -0
  72. package/lib/mcp/tools/authenticate/decrypt-key.js +46 -0
  73. package/lib/mcp/tools/authenticate/eth-key.d.ts +31 -0
  74. package/lib/mcp/tools/authenticate/eth-key.js +116 -0
  75. package/lib/mcp/tools/authenticate/import.js +57 -0
  76. package/lib/mcp/tools/authenticate/index.d.ts +2 -0
  77. package/lib/mcp/tools/authenticate/index.js +4 -0
  78. package/lib/mcp/tools/authenticate/issue.js +42 -0
  79. package/lib/mcp/tools/authenticate/resolve-owner-key.d.ts +13 -0
  80. package/lib/mcp/tools/authenticate/resolve-owner-key.js +53 -0
  81. package/lib/mcp/tools/capture.d.ts +10 -0
  82. package/lib/mcp/tools/capture.js +142 -0
  83. package/lib/mcp/tools/eval.d.ts +5 -0
  84. package/lib/mcp/tools/eval.js +127 -0
  85. package/lib/mcp/tools/find.d.ts +3 -0
  86. package/lib/mcp/tools/find.js +60 -0
  87. package/lib/mcp/tools/index.d.ts +3 -0
  88. package/lib/mcp/tools/index.js +6 -0
  89. package/lib/mcp/tools/owner-key.d.ts +2 -0
  90. package/lib/mcp/tools/owner-key.js +63 -0
  91. package/lib/mcp/tools/proof.d.ts +3 -0
  92. package/lib/mcp/tools/proof.js +214 -0
  93. package/lib/mcp/tools/propose.d.ts +9 -0
  94. package/lib/mcp/tools/propose.js +75 -0
  95. package/lib/mcp/tools/publish.d.ts +3 -0
  96. package/lib/mcp/tools/publish.js +59 -0
  97. package/lib/mcp/tools/replay.d.ts +3 -0
  98. package/lib/mcp/tools/replay.js +46 -0
  99. package/lib/mcp/tools/session.d.ts +10 -0
  100. package/lib/mcp/tools/session.js +29 -0
  101. package/lib/mcp/tools/verification/build.d.ts +12 -0
  102. package/lib/mcp/tools/verification/build.js +14 -0
  103. package/lib/mcp/tools/verification/diagnose.d.ts +11 -0
  104. package/lib/mcp/tools/verification/diagnose.js +132 -0
  105. package/lib/mcp/tools/verification/index.d.ts +1 -0
  106. package/lib/mcp/tools/verification/index.js +2 -0
  107. package/lib/mcp/tools/verification/result.d.ts +11 -0
  108. package/lib/mcp/tools/verification/result.js +126 -0
  109. package/lib/mcp/verifications/build.d.ts +5 -0
  110. package/lib/mcp/verifications/build.js +14 -0
  111. package/lib/mcp/verifications/create.d.ts +3 -0
  112. package/lib/mcp/verifications/create.js +57 -0
  113. package/lib/mcp/verifications/find.d.ts +3 -0
  114. package/lib/mcp/verifications/find.js +37 -0
  115. package/lib/mcp/verifications/get.d.ts +3 -0
  116. package/lib/mcp/verifications/get.js +26 -0
  117. package/lib/mcp/verifications/update.d.ts +3 -0
  118. package/lib/mcp/verifications/update.js +78 -0
  119. package/lib/old/client.d.ts +3 -0
  120. package/lib/old/flag.d.ts +4 -1
  121. package/lib/old/flag.js +4 -3
  122. package/lib/old/identity.d.ts +0 -10
  123. package/lib/old/identity.js +8 -7
  124. package/lib/old/instructions.d.ts +0 -6
  125. package/lib/old/instructions.js +6 -24
  126. package/lib/old/login-cdp.d.ts +0 -3
  127. package/lib/old/login-cdp.js +2 -4
  128. package/lib/old/to-register.d.ts +3 -0
  129. package/lib/old/to-register.js +32 -7
  130. package/lib/old/tools/authenticate.js +2 -1
  131. package/lib/old/tools/publish.js +71 -10
  132. package/lib/paths.js +2 -2
  133. package/lib/proof/attestor.d.ts +33 -1
  134. package/lib/proof/attestor.js +67 -64
  135. package/lib/proof/index.d.ts +5 -0
  136. package/lib/proof/index.js +6 -0
  137. package/lib/proof/proof-core.d.ts +35 -0
  138. package/lib/proof/proof-core.js +84 -0
  139. package/lib/provider/index.d.ts +5 -0
  140. package/lib/provider/index.js +9 -0
  141. package/lib/provider/injection-doc.d.ts +1 -0
  142. package/lib/provider/injection-doc.js +17 -0
  143. package/lib/provider/match-redaction-warning.d.ts +25 -0
  144. package/lib/provider/match-redaction-warning.js +35 -0
  145. package/lib/provider/schema.d.ts +16 -0
  146. package/lib/provider/schema.js +11 -1
  147. package/lib/provider/to-version.d.ts +61 -12
  148. package/lib/provider/to-version.js +109 -24
  149. package/lib/provider/verification-checks.d.ts +12 -0
  150. package/lib/provider/verification-checks.js +30 -0
  151. package/lib/routes.gen.d.ts +271 -0
  152. package/lib/routes.gen.js +73 -0
  153. package/lib/types/openapi.gen.d.ts +3967 -0
  154. package/lib/types/openapi.gen.js +5 -0
  155. package/package.json +16 -7
  156. package/skill/SKILL.md +35 -14
  157. package/skill/builder-mode.md +13 -0
  158. package/skill/injection-api.md +42 -0
  159. package/skill/old-mode.md +15 -0
  160. package/src/cdp/capture-engine.ts +256 -0
  161. package/src/cdp/capture.ts +25 -185
  162. package/src/cdp/index.ts +6 -0
  163. package/src/cdp/launcher.ts +5 -4
  164. package/src/config/store.ts +7 -6
  165. package/src/consts.ts +164 -0
  166. package/src/index.ts +2 -4
  167. package/src/logger.ts +2 -1
  168. package/src/mcp/api/operations.gen.ts +1155 -194
  169. package/src/mcp/api/to-zod.ts +115 -0
  170. package/src/mcp/api/tools.ts +9 -3
  171. package/src/mcp/instructions.ts +15 -0
  172. package/src/mcp/server.ts +5 -50
  173. package/src/mcp/start.ts +27 -11
  174. package/src/mcp/tools/agent/build.ts +7 -27
  175. package/src/mcp/tools/agent/index.ts +4 -0
  176. package/src/mcp/tools/agent/proof.ts +3 -8
  177. package/src/mcp/tools/agent/propose.ts +13 -2
  178. package/src/mcp/tools/agent/publish.ts +218 -92
  179. package/src/mcp/tools/agent/replay.ts +0 -5
  180. package/src/mcp/tools/{credentials → authenticate}/authenticate.ts +9 -8
  181. package/src/mcp/tools/authenticate/build.ts +32 -0
  182. package/src/mcp/tools/authenticate/decrypt-key.ts +59 -0
  183. package/src/mcp/tools/authenticate/eth-key.ts +162 -0
  184. package/src/mcp/tools/authenticate/import.ts +73 -0
  185. package/src/mcp/tools/authenticate/index.ts +4 -0
  186. package/src/mcp/tools/authenticate/issue.ts +50 -0
  187. package/src/mcp/tools/authenticate/resolve-owner-key.ts +60 -0
  188. package/src/mcp/tools/index.ts +6 -0
  189. package/src/mcp/tools/verification/build.ts +16 -0
  190. package/src/mcp/tools/verification/index.ts +2 -0
  191. package/src/mcp/tools/verification/result.ts +154 -0
  192. package/src/old/client.ts +3 -0
  193. package/src/old/flag.ts +4 -3
  194. package/src/old/identity.ts +8 -7
  195. package/src/old/instructions.ts +10 -25
  196. package/src/old/login-cdp.ts +2 -5
  197. package/src/old/to-register.ts +58 -26
  198. package/src/old/tools/authenticate.ts +2 -1
  199. package/src/old/tools/publish.ts +92 -16
  200. package/src/paths.ts +2 -2
  201. package/src/proof/attestor.ts +114 -72
  202. package/src/proof/index.ts +21 -0
  203. package/src/proof/proof-core.ts +119 -0
  204. package/src/provider/index.ts +20 -0
  205. package/src/provider/injection-doc.ts +21 -0
  206. package/src/provider/match-redaction-warning.ts +53 -0
  207. package/src/provider/schema.ts +23 -0
  208. package/src/provider/to-version.ts +180 -33
  209. package/src/provider/verification-checks.ts +36 -0
  210. package/lib/mcp/tools/credentials/build.d.ts +0 -16
  211. package/lib/mcp/tools/credentials/build.js +0 -33
  212. package/lib/mcp/tools/credentials/status.js +0 -62
  213. package/src/mcp/tools/credentials/build.ts +0 -37
  214. package/src/mcp/tools/credentials/cache.ts +0 -161
  215. package/src/mcp/tools/credentials/env-file.ts +0 -101
  216. package/src/mcp/tools/credentials/import.ts +0 -72
  217. package/src/mcp/tools/credentials/issue.ts +0 -107
  218. package/src/mcp/tools/credentials/list-cached.ts +0 -66
  219. package/src/mcp/tools/credentials/register.ts +0 -49
  220. package/src/mcp/tools/credentials/resolve-owner-key.ts +0 -78
  221. package/src/mcp/tools/credentials/status.ts +0 -82
  222. package/src/types/openapi.ts +0 -7
  223. /package/lib/mcp/{tools/credentials → credentials}/env-file.d.ts +0 -0
  224. /package/lib/mcp/{tools/credentials → credentials}/env-file.js +0 -0
  225. /package/lib/mcp/{tools/credentials → credentials}/register.d.ts +0 -0
  226. /package/lib/mcp/{tools/credentials → credentials}/register.js +0 -0
  227. /package/lib/mcp/tools/{credentials → authenticate}/authenticate.d.ts +0 -0
  228. /package/lib/mcp/tools/{credentials → authenticate}/import.d.ts +0 -0
  229. /package/lib/mcp/tools/{credentials → authenticate}/issue.d.ts +0 -0
  230. /package/lib/mcp/tools/{credentials → authenticate}/session-cache.d.ts +0 -0
  231. /package/lib/mcp/tools/{credentials → authenticate}/session-cache.js +0 -0
  232. /package/src/mcp/tools/{credentials → authenticate}/session-cache.ts +0 -0
@@ -1,213 +1,53 @@
1
+ /**
2
+ * Local-CDP transport for the capture engine. Binds the page-level `Network.*`
3
+ * events directly and fetches bodies via the page's `getResponseBody`. All the
4
+ * request/response bookkeeping lives in `capture-engine.ts`, shared with the
5
+ * app's remote-Popcorn transport.
6
+ */
1
7
  import type CDP from 'chrome-remote-interface'
2
- import type { Protocol } from 'devtools-protocol'
3
- import { randomUUID } from 'node:crypto'
4
- import { extractGraphqlOp } from '../provider/graphql.ts'
5
- import type { CapturedRequest } from '../provider/schema.ts'
6
- import { BodyStore } from './eviction.ts'
8
+ import {
9
+ type CaptureSession,
10
+ createCaptureEngine,
11
+ type StartCaptureOptions,
12
+ } from './capture-engine.ts'
7
13
 
8
- /** Drop HTTP/2 pseudo-headers (`:authority`, `:method`, `:path`, `:scheme`,
9
- * `:status`) from a CDP header map. Chrome emits them on HTTP/2 requests,
10
- * but they're a transport-layer abstraction with no place in our domain:
11
- * the URL already carries authority/path/scheme, the request object carries
12
- * method, and Node's `fetch` (undici) throws on any header starting with
13
- * `:`. Stripping at capture time keeps every downstream consumer
14
- * (`get_request`, draft, replay, proof) clean by construction. */
15
- export function stripPseudoHeaders(
16
- headers: Protocol.Network.Headers,
17
- ): Record<string, string> {
18
- const out: Record<string, string> = {}
19
- for(const [k, v] of Object.entries(headers)) {
20
- if(!k.startsWith(':')) {
21
- out[k] = v
22
- }
23
- }
24
-
25
- return out
26
- }
27
-
28
- export interface CaptureSession {
29
- captureId: string
30
- requests: Map<string, CapturedRequest>
31
- bodies: BodyStore
32
- stop: () => Promise<void>
33
- }
34
-
35
- interface InFlight {
36
- requestId: string
37
- method: string
38
- url: string
39
- requestHeaders: Record<string, string>
40
- requestBody?: string
41
- startedAt: number
42
- }
43
-
44
- export interface StartCaptureOptions {
45
- maxBodyBytes?: number
46
- }
14
+ export { stripPseudoHeaders } from './capture-engine.ts'
15
+ export type { CaptureSession, StartCaptureOptions } from './capture-engine.ts'
47
16
 
48
17
  export async function startCapture(
49
18
  tab: CDP.Client,
50
19
  opts: StartCaptureOptions = {},
51
20
  ): Promise<CaptureSession> {
52
- const captureId = randomUUID()
53
- const requests = new Map<string, CapturedRequest>()
54
- const inFlight = new Map<string, InFlight>()
55
- const bodies = new BodyStore({
56
- maxBytes: opts.maxBodyBytes ?? 200 * 1024 * 1024,
21
+ const engine = createCaptureEngine({
22
+ ...(opts.maxBodyBytes !== undefined && { maxBodyBytes: opts.maxBodyBytes }),
23
+ fetchBody: (requestId) => tab.Network.getResponseBody({ requestId }),
57
24
  })
58
- // CDP doesn't guarantee `requestWillBeSent` arrives before
59
- // `requestWillBeSentExtraInfo` (same for the response pair). When extra
60
- // info lands first, buffer it here and drain on the matching primary
61
- // event. Without this, headers (Cookie, Authorization, …) get silently
62
- // dropped for any request whose events race in the unlucky order.
63
- const pendingRequestExtra = new Map<string, Record<string, string>>()
64
- const pendingResponseExtra = new Map<string, Record<string, string>>()
65
25
 
66
26
  const { Network } = tab
67
27
  await Network.enable()
68
28
 
69
- /** Merge extra headers from the ...ExtraInfo events into either the
70
- * in-flight entry or the finalized captured request, whichever has
71
- * arrived. If neither exists yet (extra-info-first race), buffer the
72
- * headers and drain on the matching primary event. */
73
- function mergeRequestHeaders(
74
- requestId: string,
75
- extra: Protocol.Network.Headers,
76
- ) {
77
- const clean = stripPseudoHeaders(extra)
78
- const f = inFlight.get(requestId)
79
- if(f) {
80
- f.requestHeaders = { ...f.requestHeaders, ...clean }
81
- return
82
- }
83
-
84
- const r = requests.get(requestId)
85
- if(r) {
86
- r.requestHeaders = { ...r.requestHeaders, ...clean }
87
- return
88
- }
89
-
90
- const buffered = pendingRequestExtra.get(requestId) ?? {}
91
- pendingRequestExtra.set(requestId, { ...buffered, ...clean })
92
- }
93
-
94
- function mergeResponseHeaders(
95
- requestId: string,
96
- extra: Protocol.Network.Headers,
97
- ) {
98
- const clean = stripPseudoHeaders(extra)
99
- const r = requests.get(requestId)
100
- if(r) {
101
- r.responseHeaders = { ...r.responseHeaders, ...clean }
102
- return
103
- }
104
-
105
- const buffered = pendingResponseExtra.get(requestId) ?? {}
106
- pendingResponseExtra.set(requestId, { ...buffered, ...clean })
107
- }
108
-
109
- Network.requestWillBeSent(({ requestId, request }) => {
110
- const f: InFlight = {
111
- requestId,
112
- method: request.method,
113
- url: request.url,
114
- requestHeaders: stripPseudoHeaders(request.headers),
115
- startedAt: Date.now(),
116
- }
117
- if(request.postData !== undefined) {
118
- f.requestBody = request.postData
119
- }
120
-
121
- // Drain any extra-info that arrived before us.
122
- const buffered = pendingRequestExtra.get(requestId)
123
- if(buffered) {
124
- f.requestHeaders = { ...f.requestHeaders, ...buffered }
125
- pendingRequestExtra.delete(requestId)
126
- }
127
-
128
- inFlight.set(requestId, f)
129
- })
130
-
29
+ Network.requestWillBeSent(engine.onRequestWillBeSent)
131
30
  // CDP intentionally omits `Cookie` (and other browser-injected headers)
132
31
  // from `requestWillBeSent.request.headers` for privacy. The real
133
32
  // outgoing headers — including Cookie — arrive on the matching
134
33
  // `requestWillBeSentExtraInfo` event.
135
34
  Network.requestWillBeSentExtraInfo(({ requestId, headers }) => {
136
- mergeRequestHeaders(requestId, headers)
35
+ engine.mergeRequestHeaders(requestId, headers)
137
36
  })
138
-
139
- Network.responseReceived(({ requestId, response }) => {
140
- const f = inFlight.get(requestId)
141
- if(!f) {
142
- return
143
- }
144
-
145
- const captured: CapturedRequest = {
146
- requestId,
147
- method: f.method,
148
- url: f.url,
149
- status: response.status,
150
- contentType: response.mimeType,
151
- size: response.encodedDataLength,
152
- requestHeaders: f.requestHeaders,
153
- responseHeaders: stripPseudoHeaders(response.headers),
154
- finishedAt: 0,
155
- }
156
-
157
- // Drain any response extra-info that arrived before us.
158
- const bufferedResp = pendingResponseExtra.get(requestId)
159
- if(bufferedResp) {
160
- captured.responseHeaders = {
161
- ...captured.responseHeaders,
162
- ...bufferedResp,
163
- }
164
- pendingResponseExtra.delete(requestId)
165
- }
166
-
167
- if(f.requestBody !== undefined) {
168
- captured.requestBody = f.requestBody
169
- }
170
-
171
- const op = extractGraphqlOp(f.requestBody)
172
- if(op !== undefined) {
173
- captured.graphqlOp = op
174
- }
175
-
176
- requests.set(requestId, captured)
177
- })
178
-
37
+ Network.responseReceived(engine.onResponseReceived)
179
38
  // Same privacy carve-out applies to `Set-Cookie` and other browser-
180
39
  // visible response headers; they arrive on responseReceivedExtraInfo.
181
40
  Network.responseReceivedExtraInfo(({ requestId, headers }) => {
182
- mergeResponseHeaders(requestId, headers)
41
+ engine.mergeResponseHeaders(requestId, headers)
183
42
  })
184
-
185
- Network.loadingFinished(async({ requestId }) => {
186
- const r = requests.get(requestId)
187
- if(!r) {
188
- return
189
- }
190
-
191
- try {
192
- const { body, base64Encoded } = await Network.getResponseBody({
193
- requestId,
194
- })
195
- const text = base64Encoded
196
- ? Buffer.from(body, 'base64').toString('utf8')
197
- : body
198
- bodies.set(requestId, text)
199
- r.responseBody = text
200
- r.finishedAt = Date.now()
201
- } catch{
202
- // Body might be unavailable for
203
- // some content-types (e.g. websocket). Skip.
204
- }
43
+ Network.loadingFinished(({ requestId }) => {
44
+ void engine.onLoadingFinished(requestId)
205
45
  })
206
46
 
207
47
  return {
208
- captureId,
209
- requests,
210
- bodies,
48
+ captureId: engine.captureId,
49
+ requests: engine.requests,
50
+ bodies: engine.bodies,
211
51
  stop: async() => {
212
52
  await Network.disable()
213
53
  },
@@ -0,0 +1,6 @@
1
+ // Capture pipeline shared with the app's remote-Popcorn transport:
2
+ // the transport-agnostic engine, the body store, and the local-CDP
3
+ // `startCapture`. Exposed as `@reclaimprotocol/agent/capture`.
4
+ export * from './capture-engine.ts'
5
+ export { startCapture } from './capture.ts'
6
+ export { BodyStore } from './eviction.ts'
@@ -2,6 +2,7 @@ import { type ChildProcess, spawn } from 'node:child_process'
2
2
  import { existsSync, mkdirSync } from 'node:fs'
3
3
  import { homedir, platform } from 'node:os'
4
4
  import { join } from 'node:path'
5
+ import { chromePath, localAppData } from '../consts.ts'
5
6
  import { reclaimHomeDirPath } from '../paths.ts'
6
7
 
7
8
  export interface LaunchOptions {
@@ -38,14 +39,14 @@ function browserCandidates(): string[] {
38
39
  '/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge',
39
40
  ]
40
41
  case 'win32': {
41
- const localAppData =
42
- process.env['LOCALAPPDATA'] ?? join(homedir(), 'AppData', 'Local')
42
+ const appData =
43
+ localAppData() ?? join(homedir(), 'AppData', 'Local')
43
44
  return [
44
45
  // System-wide Chrome
45
46
  'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe',
46
47
  'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe',
47
48
  // Per-user Chrome ("Install for me only")
48
- join(localAppData, 'Google', 'Chrome', 'Application', 'chrome.exe'),
49
+ join(appData, 'Google', 'Chrome', 'Application', 'chrome.exe'),
49
50
  // Edge — Chromium-based, preinstalled on Win 10/11
50
51
  'C:\\Program Files\\Microsoft\\Edge\\Application\\msedge.exe',
51
52
  'C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe',
@@ -87,7 +88,7 @@ export function findChromeBinary(): string {
87
88
  }
88
89
 
89
90
  export function launchChrome(opts: LaunchOptions): ChildProcess {
90
- const binary = process.env.RECLAIM_AGENT_CHROME_PATH ?? findChromeBinary()
91
+ const binary = chromePath() ?? findChromeBinary()
91
92
  if(!existsSync(opts.profileDir)) {
92
93
  mkdirSync(opts.profileDir, { recursive: true })
93
94
  }
@@ -6,8 +6,7 @@ import {
6
6
  writeFileSync,
7
7
  } from 'node:fs'
8
8
  import { dirname, join } from 'node:path'
9
- import type { CachedCredential } from '../mcp/tools/credentials/cache.ts'
10
- import type { CachedSession } from '../mcp/tools/credentials/session-cache.ts'
9
+ import type { CachedSession } from '../mcp/tools/authenticate/session-cache.ts'
11
10
  import type { OldIdentity } from '../old/client.ts'
12
11
  import { reclaimHomeDirPath } from '../paths.ts'
13
12
 
@@ -20,25 +19,27 @@ export interface ReclaimAgentConfig {
20
19
  * The single on-disk document at `~/.reclaim/config.json`. Each top-level
21
20
  * key is an independent section owned by a different subsystem:
22
21
  * - `browser_agent` — Chrome attach mode/port (the agent tools)
23
- * - `credentials` — cached app key-pairs (the credential tools)
24
22
  * - `session` — the auth bearer token (authenticate)
25
23
  * - `old_devtools` — externally-supplied identity for OLD-devtools mode
26
24
  * (USE_OLD_DEVTOOLS); independent of `session`'s
27
25
  * builder token. Deletable with the rest of `src/old/`.
28
26
  * Sections are persisted independently via `ConfigStore.write`, which
29
27
  * merges rather than replaces, so one subsystem never clobbers another's.
28
+ *
29
+ * NOTE: eth proof-owner keys are NOT cached here — they live as PEMs in the
30
+ * project (see authenticate/eth-key.ts). This config holds no private keys
31
+ * other than the (short-lived) session bearer token.
30
32
  */
31
33
  export interface ReclaimConfig {
32
34
  version: 1
33
35
  browser_agent?: ReclaimAgentConfig
34
- credentials?: CachedCredential[]
35
36
  session?: CachedSession
36
37
  old_devtools?: OldIdentity
37
38
  }
38
39
 
39
40
  /**
40
- * Read/write the unified Reclaim config document. The file holds secrets
41
- * (a bearer token and private keys), so it is always locked to `0600` and
41
+ * Read/write the unified Reclaim config document. The file holds the
42
+ * (short-lived) session bearer token, so it is always locked to `0600` and
42
43
  * its directory to `0700` — the `~/.ssh` posture. `read()` returns
43
44
  * `undefined` when the file is missing or unparseable; callers layer their
44
45
  * own validation (token expiry, credential shape) on top.
package/src/consts.ts ADDED
@@ -0,0 +1,164 @@
1
+ /**
2
+ * Centralized environment access for `@reclaimprotocol/agent`.
3
+ *
4
+ * This is the ONLY non-test source file under `src/` that reads
5
+ * `process.env`. Every other module imports a getter from here instead of
6
+ * touching `process.env` directly.
7
+ *
8
+ * Almost everything is exposed as a LAZY GETTER FUNCTION rather than an eager
9
+ * `const`, on purpose: several tests mutate env at runtime (mcp-credentials
10
+ * sets/deletes RECLAIM_PRIVATE_KEY / RECLAIM_PRIVATE_KEY_FILE / RECLAIM_HOME;
11
+ * old-devtools sets/deletes USE_OLD_DEVTOOLS), and most of these vars are read
12
+ * at call time anyway. An eager const captured at import time would freeze the
13
+ * value and break those tests. The one eager const that's safe is `LOG_LEVEL`,
14
+ * which is read once at logger construction.
15
+ *
16
+ * Each var's default/fallback literal is co-located with its getter.
17
+ */
18
+ import { DEFAULT_BASE_URL } from '@reclaimprotocol/client'
19
+ import { homedir } from 'node:os'
20
+ import { join } from 'node:path'
21
+ import { DEFAULT_OLD_API_URL } from './old/client.ts'
22
+
23
+ // ---------------------------------------------------------------------------
24
+ // Default / fallback literals (used only as env fallbacks).
25
+ // ---------------------------------------------------------------------------
26
+
27
+ /** Public attestor websocket URL — fallback for `RECLAIM_ATTESTOR_URL`. */
28
+ export const FALLBACK_ATTESTOR_URL = 'wss://attestor.reclaimprotocol.org:444/ws'
29
+
30
+ /** The devtools dashboard login page — fallback for `RECLAIM_OLD_LOGIN_URL`. */
31
+ export const DEFAULT_LOGIN_URL = 'https://dev.reclaimprotocol.org'
32
+
33
+ // Re-export the two non-env-fallback defaults so callers can keep importing
34
+ // their URL defaults from a single place if they wish.
35
+ export { DEFAULT_BASE_URL, DEFAULT_OLD_API_URL }
36
+
37
+ // ---------------------------------------------------------------------------
38
+ // Logging.
39
+ // ---------------------------------------------------------------------------
40
+
41
+ /** Pino log level. Read once at logger construction, so an eager const is
42
+ * safe (no test mutates LOG_LEVEL at runtime). */
43
+ export const LOG_LEVEL = process.env.LOG_LEVEL || 'info'
44
+
45
+ // ---------------------------------------------------------------------------
46
+ // Paths.
47
+ // ---------------------------------------------------------------------------
48
+
49
+ /** Reclaim cache directory (`~/.reclaim`). `RECLAIM_HOME` overrides it so
50
+ * tests can sandbox writes. */
51
+ export function reclaimHome(): string {
52
+ return process.env.RECLAIM_HOME || join(homedir(), '.reclaim')
53
+ }
54
+
55
+ // ---------------------------------------------------------------------------
56
+ // Mode flag.
57
+ // ---------------------------------------------------------------------------
58
+
59
+ /**
60
+ * `USE_OLD_DEVTOOLS` — single source of truth for which backend the MCP
61
+ * server targets. Defaults to OLD devtools while the builder backend is under
62
+ * development. Builder mode must be opted into EXPLICITLY with
63
+ * `USE_OLD_DEVTOOLS=false`; anything else keeps old mode on.
64
+ */
65
+ export function useOldDevtools(): boolean {
66
+ return (process.env.USE_OLD_DEVTOOLS ?? '').trim().toLowerCase() !== 'false'
67
+ }
68
+
69
+ // ---------------------------------------------------------------------------
70
+ // Chrome / CDP launcher.
71
+ // ---------------------------------------------------------------------------
72
+
73
+ /** `%LOCALAPPDATA%` on Windows, used to probe a per-user Chrome install. */
74
+ export function localAppData(): string | undefined {
75
+ return process.env['LOCALAPPDATA']
76
+ }
77
+
78
+ /** Explicit Chrome/Edge/Chromium binary path override. */
79
+ export function chromePath(): string | undefined {
80
+ return process.env.RECLAIM_AGENT_CHROME_PATH
81
+ }
82
+
83
+ // ---------------------------------------------------------------------------
84
+ // MCP server / API clients.
85
+ // ---------------------------------------------------------------------------
86
+
87
+ /** Agent tools (Chrome CDP capture, synthesis, proof) are disabled in hosted
88
+ * deployments by setting `RECLAIM_AGENT_DISABLED=1`. Shared by mcp/start and
89
+ * the old-mode authenticate tool. */
90
+ export function agentDisabled(): boolean {
91
+ return process.env.RECLAIM_AGENT_DISABLED === '1'
92
+ }
93
+
94
+ /** Old-devtools backend base URL. */
95
+ export function oldApiUrl(): string {
96
+ return process.env.RECLAIM_OLD_API_URL || DEFAULT_OLD_API_URL
97
+ }
98
+
99
+ /** Builder backend base URL. Shared by mcp/start and the verification tool. */
100
+ export function apiUrl(): string {
101
+ return process.env.RECLAIM_API_URL || DEFAULT_BASE_URL
102
+ }
103
+
104
+ /** Explicit builder API token (overrides the cached session token). */
105
+ export function apiToken(): string | undefined {
106
+ return process.env.RECLAIM_API_TOKEN
107
+ }
108
+
109
+ // ---------------------------------------------------------------------------
110
+ // Proof tracing.
111
+ // ---------------------------------------------------------------------------
112
+
113
+ /** Diagnostic trace capture (`RECLAIM_AGENT_TRACE=1`). Shared by the attestor
114
+ * logger capture and the proof-run dump. */
115
+ export function agentTraceEnabled(): boolean {
116
+ return process.env['RECLAIM_AGENT_TRACE'] === '1'
117
+ }
118
+
119
+ /** Attestor websocket URL override (`RECLAIM_ATTESTOR_URL`). */
120
+ export function attestorUrlOverride(): string | undefined {
121
+ return process.env['RECLAIM_ATTESTOR_URL']
122
+ }
123
+
124
+ // ---------------------------------------------------------------------------
125
+ // Eth proof-owner key resolution.
126
+ // ---------------------------------------------------------------------------
127
+
128
+ /** Raw 0x-hex Ethereum private key (`RECLAIM_PRIVATE_KEY`). */
129
+ export function privateKey(): string | undefined {
130
+ return process.env.RECLAIM_PRIVATE_KEY
131
+ }
132
+
133
+ /** Path to a raw-hex key file (`RECLAIM_PRIVATE_KEY_FILE`). */
134
+ export function privateKeyFile(): string | undefined {
135
+ return process.env.RECLAIM_PRIVATE_KEY_FILE
136
+ }
137
+
138
+ // ---------------------------------------------------------------------------
139
+ // Verification reads.
140
+ // ---------------------------------------------------------------------------
141
+
142
+ /** Per-org bearer secret (`rorg_…`) used to authenticate verification reads. */
143
+ export function orgSecret(): string | undefined {
144
+ return process.env.RECLAIM_ORG_SECRET
145
+ }
146
+
147
+ // ---------------------------------------------------------------------------
148
+ // Old-devtools identity / login.
149
+ // ---------------------------------------------------------------------------
150
+
151
+ /** Dashboard Firebase bearer token for the old backend. */
152
+ export function oldApiToken(): string | undefined {
153
+ return process.env.RECLAIM_OLD_API_TOKEN
154
+ }
155
+
156
+ /** An `eth:<addr>` (or bare `0x…`) uid for the old backend. */
157
+ export function oldEthUid(): string | undefined {
158
+ return process.env.RECLAIM_OLD_ETH_UID
159
+ }
160
+
161
+ /** Override for the old-devtools dashboard login URL. */
162
+ export function oldLoginUrl(): string | undefined {
163
+ return process.env.RECLAIM_OLD_LOGIN_URL
164
+ }
package/src/index.ts CHANGED
@@ -6,7 +6,5 @@
6
6
  export * from '@reclaimprotocol/client'
7
7
 
8
8
  // Agent — Chrome CDP capture, provider synthesis, replay, proof.
9
- export {
10
- buildAgentTools,
11
- } from './mcp/tools/agent/build.ts'
12
- export type { AgentState } from './mcp/tools/agent/build.ts'
9
+ export { buildAgentTools } from './mcp/tools/agent/index.ts'
10
+ export type { AgentState } from './mcp/tools/agent/index.ts'
package/src/logger.ts CHANGED
@@ -1,8 +1,9 @@
1
1
  import pino, { stdTimeFunctions } from 'pino'
2
+ import { LOG_LEVEL } from './consts.ts'
2
3
 
3
4
  export const LOGGER = pino({
4
5
  name: '@reclaimprotocol/agent',
5
6
  timestamp: stdTimeFunctions.isoTime,
6
7
  base: { hostname: undefined, pid: undefined },
7
8
  })
8
- LOGGER.level = process.env.LOG_LEVEL || 'info'
9
+ LOGGER.level = LOG_LEVEL