@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.
- package/README.md +1 -1
- package/lib/cdp/capture-engine.d.ts +66 -0
- package/lib/cdp/capture-engine.js +153 -0
- package/lib/cdp/capture.d.ts +9 -20
- package/lib/cdp/capture.js +14 -138
- package/lib/cdp/index.d.ts +3 -0
- package/lib/cdp/index.js +6 -0
- package/lib/cdp/launcher.js +4 -3
- package/lib/config/store.d.ts +7 -6
- package/lib/config/store.js +2 -2
- package/lib/consts.d.ts +68 -0
- package/lib/consts.js +134 -0
- package/lib/index.d.ts +2 -2
- package/lib/index.js +1 -1
- package/lib/logger.js +2 -1
- package/lib/mcp/api/operations.gen.d.ts +100 -48
- package/lib/mcp/api/operations.gen.js +1129 -194
- package/lib/mcp/api/to-zod.d.ts +24 -0
- package/lib/mcp/api/to-zod.js +94 -0
- package/lib/mcp/api/tools.js +1 -1
- package/lib/mcp/credentials/authenticate.d.ts +3 -0
- package/lib/mcp/{tools/credentials → credentials}/authenticate.js +3 -3
- package/lib/mcp/credentials/build.d.ts +5 -0
- package/lib/mcp/credentials/build.js +18 -0
- package/lib/mcp/{tools/credentials → credentials}/cache.d.ts +9 -9
- package/lib/mcp/{tools/credentials → credentials}/cache.js +36 -19
- package/lib/mcp/credentials/import.d.ts +2 -0
- package/lib/mcp/{tools/credentials → credentials}/import.js +2 -2
- package/lib/mcp/credentials/issue.d.ts +2 -0
- package/lib/mcp/{tools/credentials → credentials}/issue.js +4 -4
- package/lib/mcp/credentials/keypair.d.ts +17 -0
- package/lib/mcp/credentials/keypair.js +48 -0
- package/lib/mcp/credentials/link.d.ts +3 -0
- package/lib/mcp/credentials/link.js +107 -0
- package/lib/mcp/{tools/credentials → credentials}/list-cached.d.ts +1 -1
- package/lib/mcp/{tools/credentials → credentials}/list-cached.js +5 -5
- package/lib/mcp/credentials/owner-key.d.ts +23 -0
- package/lib/mcp/credentials/owner-key.js +58 -0
- package/lib/mcp/credentials/paths.d.ts +12 -0
- package/lib/mcp/credentials/paths.js +35 -0
- package/lib/mcp/credentials/poll.d.ts +27 -0
- package/lib/mcp/credentials/poll.js +61 -0
- package/lib/mcp/{tools/credentials → credentials}/resolve-owner-key.d.ts +1 -1
- package/lib/mcp/{tools/credentials → credentials}/resolve-owner-key.js +2 -2
- package/lib/mcp/credentials/session-cache.d.ts +14 -0
- package/lib/mcp/credentials/session-cache.js +42 -0
- package/lib/mcp/{tools/credentials → credentials}/status.d.ts +1 -1
- package/lib/mcp/credentials/status.js +76 -0
- package/lib/mcp/instructions.d.ts +1 -0
- package/lib/mcp/instructions.js +11 -0
- package/lib/mcp/register.d.ts +38 -0
- package/lib/mcp/register.js +80 -0
- package/lib/mcp/server.d.ts +2 -8
- package/lib/mcp/server.js +3 -33
- package/lib/mcp/start.js +17 -11
- package/lib/mcp/tools/agent/build.d.ts +5 -9
- package/lib/mcp/tools/agent/build.js +7 -24
- package/lib/mcp/tools/agent/index.d.ts +2 -0
- package/lib/mcp/tools/agent/index.js +3 -0
- package/lib/mcp/tools/agent/proof.js +3 -7
- package/lib/mcp/tools/agent/propose.js +13 -2
- package/lib/mcp/tools/agent/publish.js +172 -75
- package/lib/mcp/tools/agent/replay.js +0 -5
- package/lib/mcp/tools/analyze.d.ts +3 -0
- package/lib/mcp/tools/analyze.js +26 -0
- package/lib/mcp/tools/attach.d.ts +11 -0
- package/lib/mcp/tools/attach.js +72 -0
- package/lib/mcp/tools/authenticate/authenticate.js +107 -0
- package/lib/mcp/tools/authenticate/build.d.ts +15 -0
- package/lib/mcp/tools/authenticate/build.js +28 -0
- package/lib/mcp/tools/authenticate/decrypt-key.d.ts +19 -0
- package/lib/mcp/tools/authenticate/decrypt-key.js +46 -0
- package/lib/mcp/tools/authenticate/eth-key.d.ts +31 -0
- package/lib/mcp/tools/authenticate/eth-key.js +116 -0
- package/lib/mcp/tools/authenticate/import.js +57 -0
- package/lib/mcp/tools/authenticate/index.d.ts +2 -0
- package/lib/mcp/tools/authenticate/index.js +4 -0
- package/lib/mcp/tools/authenticate/issue.js +42 -0
- package/lib/mcp/tools/authenticate/resolve-owner-key.d.ts +13 -0
- package/lib/mcp/tools/authenticate/resolve-owner-key.js +53 -0
- package/lib/mcp/tools/capture.d.ts +10 -0
- package/lib/mcp/tools/capture.js +142 -0
- package/lib/mcp/tools/eval.d.ts +5 -0
- package/lib/mcp/tools/eval.js +127 -0
- package/lib/mcp/tools/find.d.ts +3 -0
- package/lib/mcp/tools/find.js +60 -0
- package/lib/mcp/tools/index.d.ts +3 -0
- package/lib/mcp/tools/index.js +6 -0
- package/lib/mcp/tools/owner-key.d.ts +2 -0
- package/lib/mcp/tools/owner-key.js +63 -0
- package/lib/mcp/tools/proof.d.ts +3 -0
- package/lib/mcp/tools/proof.js +214 -0
- package/lib/mcp/tools/propose.d.ts +9 -0
- package/lib/mcp/tools/propose.js +75 -0
- package/lib/mcp/tools/publish.d.ts +3 -0
- package/lib/mcp/tools/publish.js +59 -0
- package/lib/mcp/tools/replay.d.ts +3 -0
- package/lib/mcp/tools/replay.js +46 -0
- package/lib/mcp/tools/session.d.ts +10 -0
- package/lib/mcp/tools/session.js +29 -0
- package/lib/mcp/tools/verification/build.d.ts +12 -0
- package/lib/mcp/tools/verification/build.js +14 -0
- package/lib/mcp/tools/verification/diagnose.d.ts +11 -0
- package/lib/mcp/tools/verification/diagnose.js +132 -0
- package/lib/mcp/tools/verification/index.d.ts +1 -0
- package/lib/mcp/tools/verification/index.js +2 -0
- package/lib/mcp/tools/verification/result.d.ts +11 -0
- package/lib/mcp/tools/verification/result.js +126 -0
- package/lib/mcp/verifications/build.d.ts +5 -0
- package/lib/mcp/verifications/build.js +14 -0
- package/lib/mcp/verifications/create.d.ts +3 -0
- package/lib/mcp/verifications/create.js +57 -0
- package/lib/mcp/verifications/find.d.ts +3 -0
- package/lib/mcp/verifications/find.js +37 -0
- package/lib/mcp/verifications/get.d.ts +3 -0
- package/lib/mcp/verifications/get.js +26 -0
- package/lib/mcp/verifications/update.d.ts +3 -0
- package/lib/mcp/verifications/update.js +78 -0
- package/lib/old/client.d.ts +3 -0
- package/lib/old/flag.d.ts +4 -1
- package/lib/old/flag.js +4 -3
- package/lib/old/identity.d.ts +0 -10
- package/lib/old/identity.js +8 -7
- package/lib/old/instructions.d.ts +0 -6
- package/lib/old/instructions.js +6 -24
- package/lib/old/login-cdp.d.ts +0 -3
- package/lib/old/login-cdp.js +2 -4
- package/lib/old/to-register.d.ts +3 -0
- package/lib/old/to-register.js +32 -7
- package/lib/old/tools/authenticate.js +2 -1
- package/lib/old/tools/publish.js +71 -10
- package/lib/paths.js +2 -2
- package/lib/proof/attestor.d.ts +33 -1
- package/lib/proof/attestor.js +67 -64
- package/lib/proof/index.d.ts +5 -0
- package/lib/proof/index.js +6 -0
- package/lib/proof/proof-core.d.ts +35 -0
- package/lib/proof/proof-core.js +84 -0
- package/lib/provider/index.d.ts +5 -0
- package/lib/provider/index.js +9 -0
- package/lib/provider/injection-doc.d.ts +1 -0
- package/lib/provider/injection-doc.js +17 -0
- package/lib/provider/match-redaction-warning.d.ts +25 -0
- package/lib/provider/match-redaction-warning.js +35 -0
- package/lib/provider/schema.d.ts +16 -0
- package/lib/provider/schema.js +11 -1
- package/lib/provider/to-version.d.ts +61 -12
- package/lib/provider/to-version.js +109 -24
- package/lib/provider/verification-checks.d.ts +12 -0
- package/lib/provider/verification-checks.js +30 -0
- package/lib/routes.gen.d.ts +271 -0
- package/lib/routes.gen.js +73 -0
- package/lib/types/openapi.gen.d.ts +3967 -0
- package/lib/types/openapi.gen.js +5 -0
- package/package.json +16 -7
- package/skill/SKILL.md +35 -14
- package/skill/builder-mode.md +13 -0
- package/skill/injection-api.md +42 -0
- package/skill/old-mode.md +15 -0
- package/src/cdp/capture-engine.ts +256 -0
- package/src/cdp/capture.ts +25 -185
- package/src/cdp/index.ts +6 -0
- package/src/cdp/launcher.ts +5 -4
- package/src/config/store.ts +7 -6
- package/src/consts.ts +164 -0
- package/src/index.ts +2 -4
- package/src/logger.ts +2 -1
- package/src/mcp/api/operations.gen.ts +1155 -194
- package/src/mcp/api/to-zod.ts +115 -0
- package/src/mcp/api/tools.ts +9 -3
- package/src/mcp/instructions.ts +15 -0
- package/src/mcp/server.ts +5 -50
- package/src/mcp/start.ts +27 -11
- package/src/mcp/tools/agent/build.ts +7 -27
- package/src/mcp/tools/agent/index.ts +4 -0
- package/src/mcp/tools/agent/proof.ts +3 -8
- package/src/mcp/tools/agent/propose.ts +13 -2
- package/src/mcp/tools/agent/publish.ts +218 -92
- package/src/mcp/tools/agent/replay.ts +0 -5
- package/src/mcp/tools/{credentials → authenticate}/authenticate.ts +9 -8
- package/src/mcp/tools/authenticate/build.ts +32 -0
- package/src/mcp/tools/authenticate/decrypt-key.ts +59 -0
- package/src/mcp/tools/authenticate/eth-key.ts +162 -0
- package/src/mcp/tools/authenticate/import.ts +73 -0
- package/src/mcp/tools/authenticate/index.ts +4 -0
- package/src/mcp/tools/authenticate/issue.ts +50 -0
- package/src/mcp/tools/authenticate/resolve-owner-key.ts +60 -0
- package/src/mcp/tools/index.ts +6 -0
- package/src/mcp/tools/verification/build.ts +16 -0
- package/src/mcp/tools/verification/index.ts +2 -0
- package/src/mcp/tools/verification/result.ts +154 -0
- package/src/old/client.ts +3 -0
- package/src/old/flag.ts +4 -3
- package/src/old/identity.ts +8 -7
- package/src/old/instructions.ts +10 -25
- package/src/old/login-cdp.ts +2 -5
- package/src/old/to-register.ts +58 -26
- package/src/old/tools/authenticate.ts +2 -1
- package/src/old/tools/publish.ts +92 -16
- package/src/paths.ts +2 -2
- package/src/proof/attestor.ts +114 -72
- package/src/proof/index.ts +21 -0
- package/src/proof/proof-core.ts +119 -0
- package/src/provider/index.ts +20 -0
- package/src/provider/injection-doc.ts +21 -0
- package/src/provider/match-redaction-warning.ts +53 -0
- package/src/provider/schema.ts +23 -0
- package/src/provider/to-version.ts +180 -33
- package/src/provider/verification-checks.ts +36 -0
- package/lib/mcp/tools/credentials/build.d.ts +0 -16
- package/lib/mcp/tools/credentials/build.js +0 -33
- package/lib/mcp/tools/credentials/status.js +0 -62
- package/src/mcp/tools/credentials/build.ts +0 -37
- package/src/mcp/tools/credentials/cache.ts +0 -161
- package/src/mcp/tools/credentials/env-file.ts +0 -101
- package/src/mcp/tools/credentials/import.ts +0 -72
- package/src/mcp/tools/credentials/issue.ts +0 -107
- package/src/mcp/tools/credentials/list-cached.ts +0 -66
- package/src/mcp/tools/credentials/register.ts +0 -49
- package/src/mcp/tools/credentials/resolve-owner-key.ts +0 -78
- package/src/mcp/tools/credentials/status.ts +0 -82
- package/src/types/openapi.ts +0 -7
- /package/lib/mcp/{tools/credentials → credentials}/env-file.d.ts +0 -0
- /package/lib/mcp/{tools/credentials → credentials}/env-file.js +0 -0
- /package/lib/mcp/{tools/credentials → credentials}/register.d.ts +0 -0
- /package/lib/mcp/{tools/credentials → credentials}/register.js +0 -0
- /package/lib/mcp/tools/{credentials → authenticate}/authenticate.d.ts +0 -0
- /package/lib/mcp/tools/{credentials → authenticate}/import.d.ts +0 -0
- /package/lib/mcp/tools/{credentials → authenticate}/issue.d.ts +0 -0
- /package/lib/mcp/tools/{credentials → authenticate}/session-cache.d.ts +0 -0
- /package/lib/mcp/tools/{credentials → authenticate}/session-cache.js +0 -0
- /package/src/mcp/tools/{credentials → authenticate}/session-cache.ts +0 -0
package/src/cdp/capture.ts
CHANGED
|
@@ -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
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
8
|
+
import {
|
|
9
|
+
type CaptureSession,
|
|
10
|
+
createCaptureEngine,
|
|
11
|
+
type StartCaptureOptions,
|
|
12
|
+
} from './capture-engine.ts'
|
|
7
13
|
|
|
8
|
-
|
|
9
|
-
|
|
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
|
|
53
|
-
|
|
54
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
},
|
package/src/cdp/index.ts
ADDED
|
@@ -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'
|
package/src/cdp/launcher.ts
CHANGED
|
@@ -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
|
|
42
|
-
|
|
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(
|
|
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 =
|
|
91
|
+
const binary = chromePath() ?? findChromeBinary()
|
|
91
92
|
if(!existsSync(opts.profileDir)) {
|
|
92
93
|
mkdirSync(opts.profileDir, { recursive: true })
|
|
93
94
|
}
|
package/src/config/store.ts
CHANGED
|
@@ -6,8 +6,7 @@ import {
|
|
|
6
6
|
writeFileSync,
|
|
7
7
|
} from 'node:fs'
|
|
8
8
|
import { dirname, join } from 'node:path'
|
|
9
|
-
import type {
|
|
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
|
|
41
|
-
* (
|
|
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
|
-
|
|
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 =
|
|
9
|
+
LOGGER.level = LOG_LEVEL
|