@reclaimprotocol/agent 0.1.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 (73) hide show
  1. package/lib/cdp/launcher.js +4 -3
  2. package/lib/consts.d.ts +68 -0
  3. package/lib/consts.js +134 -0
  4. package/lib/logger.js +2 -1
  5. package/lib/mcp/api/operations.gen.d.ts +3 -7
  6. package/lib/mcp/api/operations.gen.js +264 -199
  7. package/lib/mcp/server.d.ts +0 -6
  8. package/lib/mcp/server.js +0 -30
  9. package/lib/mcp/start.js +7 -7
  10. package/lib/mcp/tools/agent/build.d.ts +5 -9
  11. package/lib/mcp/tools/agent/build.js +5 -9
  12. package/lib/mcp/tools/agent/proof.js +2 -1
  13. package/lib/mcp/tools/agent/publish.js +166 -77
  14. package/lib/mcp/tools/authenticate/decrypt-key.d.ts +10 -23
  15. package/lib/mcp/tools/authenticate/decrypt-key.js +23 -26
  16. package/lib/mcp/tools/authenticate/eth-key.d.ts +0 -7
  17. package/lib/mcp/tools/authenticate/eth-key.js +5 -19
  18. package/lib/mcp/tools/authenticate/issue.js +1 -1
  19. package/lib/mcp/tools/verification/build.d.ts +1 -1
  20. package/lib/mcp/tools/verification/build.js +1 -1
  21. package/lib/mcp/tools/verification/result.d.ts +4 -5
  22. package/lib/mcp/tools/verification/result.js +17 -17
  23. package/lib/old/flag.d.ts +4 -1
  24. package/lib/old/flag.js +4 -3
  25. package/lib/old/identity.d.ts +0 -10
  26. package/lib/old/identity.js +8 -7
  27. package/lib/old/login-cdp.d.ts +0 -3
  28. package/lib/old/login-cdp.js +2 -4
  29. package/lib/old/to-register.js +6 -9
  30. package/lib/old/tools/authenticate.js +2 -1
  31. package/lib/old/tools/publish.js +58 -9
  32. package/lib/paths.js +2 -2
  33. package/lib/proof/attestor.js +2 -1
  34. package/lib/proof/proof-core.js +13 -2
  35. package/lib/provider/injection-doc.d.ts +1 -0
  36. package/lib/provider/injection-doc.js +17 -0
  37. package/lib/provider/match-redaction-warning.d.ts +25 -0
  38. package/lib/provider/match-redaction-warning.js +35 -0
  39. package/lib/provider/schema.d.ts +16 -0
  40. package/lib/provider/schema.js +11 -1
  41. package/lib/provider/to-version.d.ts +59 -7
  42. package/lib/provider/to-version.js +79 -28
  43. package/package.json +1 -1
  44. package/skill/builder-mode.md +6 -2
  45. package/skill/injection-api.md +42 -0
  46. package/skill/old-mode.md +2 -0
  47. package/src/cdp/launcher.ts +5 -4
  48. package/src/consts.ts +164 -0
  49. package/src/logger.ts +2 -1
  50. package/src/mcp/api/operations.gen.ts +262 -203
  51. package/src/mcp/server.ts +0 -46
  52. package/src/mcp/start.ts +13 -7
  53. package/src/mcp/tools/agent/build.ts +5 -9
  54. package/src/mcp/tools/agent/proof.ts +2 -1
  55. package/src/mcp/tools/agent/publish.ts +212 -94
  56. package/src/mcp/tools/authenticate/decrypt-key.ts +24 -29
  57. package/src/mcp/tools/authenticate/eth-key.ts +5 -25
  58. package/src/mcp/tools/authenticate/issue.ts +1 -1
  59. package/src/mcp/tools/verification/build.ts +1 -1
  60. package/src/mcp/tools/verification/result.ts +16 -17
  61. package/src/old/flag.ts +4 -3
  62. package/src/old/identity.ts +8 -7
  63. package/src/old/login-cdp.ts +2 -5
  64. package/src/old/to-register.ts +7 -10
  65. package/src/old/tools/authenticate.ts +2 -1
  66. package/src/old/tools/publish.ts +75 -15
  67. package/src/paths.ts +2 -2
  68. package/src/proof/attestor.ts +2 -1
  69. package/src/proof/proof-core.ts +13 -3
  70. package/src/provider/injection-doc.ts +21 -0
  71. package/src/provider/match-redaction-warning.ts +53 -0
  72. package/src/provider/schema.ts +23 -0
  73. package/src/provider/to-version.ts +137 -31
@@ -3,7 +3,51 @@ import type {
3
3
  CreateProviderVersionRequest,
4
4
  ProviderVersionRef,
5
5
  } from '@reclaimprotocol/client/openapi'
6
- import type { ReclaimProvider } from './schema.ts'
6
+ import type {
7
+ HttpMethod,
8
+ ReclaimProvider,
9
+ ResponseMatch,
10
+ ResponseRedaction,
11
+ } from './schema.ts'
12
+ import { DYNAMIC_GEO, normalizeGeoLocation } from './schema.ts'
13
+
14
+ /** One entry of the version's `requests[]` (a `RequestSelection`), derived
15
+ * from the openapi type so it can't drift from what the server accepts. */
16
+ type RequestSelection = CreateProviderVersionRequest['requests'][number]
17
+
18
+ /** The subset of a draft a request selection is built from — the only fields
19
+ * `providerToRequestSelection` reads. A full `ReclaimProvider` satisfies it,
20
+ * as does a lighter injected-request draft (no `name`/`paramValues`). */
21
+ export interface DraftRequest {
22
+ url: string
23
+ method: HttpMethod
24
+ body?: string
25
+ writeRedactionMode?: ReclaimProvider['writeRedactionMode']
26
+ additionalClientOptions?: ReclaimProvider['additionalClientOptions']
27
+ responseMatches?: ResponseMatch[]
28
+ responseRedactions?: ResponseRedaction[]
29
+ }
30
+
31
+ /** A request the page's injection script is allowed to fire, plus the
32
+ * pagination/optionality flags of `RequestSelectionTemplate`. Reuses the
33
+ * shared `DraftRequest` shape — no provider `name`/`paramValues` required. */
34
+ export interface AllowedJsRequest extends DraftRequest {
35
+ /** Allow the template to match many requests (e.g. pagination). Default
36
+ * true. */
37
+ multiple?: boolean
38
+ /** Fail validation if no request matches this template. Default true. */
39
+ required?: boolean
40
+ }
41
+
42
+ /** Optional extras for a create-version body beyond the request list. */
43
+ export interface CreateVersionOptions {
44
+ notes?: string
45
+ version?: ProviderVersionRef
46
+ /** JS injected before every page load (`webSettings.jsUserScripts`). */
47
+ jsUserScripts?: string
48
+ /** Requests the injection script may fire, as `RequestSelectionTemplate`s. */
49
+ allowedJsRequests?: AllowedJsRequest[]
50
+ }
7
51
 
8
52
  /**
9
53
  * Translate a drafted ReclaimProvider into the body for
@@ -24,15 +68,29 @@ const CONTEXT_PARAM_RE = /\{\{context\.([A-Za-z_][A-Za-z0-9_]*)\}\}/g
24
68
 
25
69
  /**
26
70
  * Derive the version's `requiredContext` JSON Schema from the
27
- * `{{context.<name>}}` placeholders in the provider's url/body — mechanical,
28
- * so a published recipe can never reference a context value the Builder
29
- * doesn't require. Returns undefined when the recipe has none (the field is
30
- * optional). Authors can refine types/descriptions in the version editor.
71
+ * `{{context.<name>}}` placeholders across EVERY request's url/body (plus any
72
+ * injected requests and the injection script) — mechanical, so a published
73
+ * recipe can never reference a context value the Builder doesn't require.
74
+ * Returns undefined when nothing references context (the field is optional).
75
+ * Authors can refine types/descriptions in the version editor.
31
76
  */
32
77
  export function deriveRequiredContext(
33
- provider: ReclaimProvider,
78
+ providers: ReclaimProvider[],
79
+ injection: {
80
+ allowedJsRequests?: AllowedJsRequest[]
81
+ jsUserScripts?: string
82
+ } = {},
34
83
  ): CreateProviderVersionRequest['requiredContext'] {
35
- const haystack = `${provider.url}\n${provider.body ?? ''}`
84
+ const parts: string[] = []
85
+ for(const p of [...providers, ...(injection.allowedJsRequests ?? [])]) {
86
+ parts.push(p.url, p.body ?? '')
87
+ }
88
+
89
+ if(injection.jsUserScripts) {
90
+ parts.push(injection.jsUserScripts)
91
+ }
92
+
93
+ const haystack = parts.join('\n')
36
94
  const names = new Set<string>()
37
95
  for(const m of haystack.matchAll(CONTEXT_PARAM_RE)) {
38
96
  names.add(m[1])
@@ -50,42 +108,90 @@ export function deriveRequiredContext(
50
108
  return { type: 'object', required: [...names], properties }
51
109
  }
52
110
 
111
+ /**
112
+ * Translate one drafted request into a `RequestSelection`. Shared by the
113
+ * top-level `requests` and by `allowedJsRequests`.
114
+ *
115
+ * `responseMatches`/`responseRedactions` are INDEPENDENT parallel arrays,
116
+ * isomorphic to the attestor's `ProviderParams<'http'>` (no nested fold).
117
+ * `responseRedactions` decide which portions of the response are revealed;
118
+ * `responseMatches` then run against the union of the revealed content. Neither
119
+ * depends on the other's length or order, so both pass through untouched.
120
+ * (The old-devtools translator has its own opt-in index-pairing concern; the
121
+ * builder deliberately does not.)
122
+ */
123
+ export function providerToRequestSelection(
124
+ provider: DraftRequest,
125
+ ): RequestSelection {
126
+ const responseMatches = (provider.responseMatches ?? []).map((match) => ({
127
+ type: match.type,
128
+ value: match.value,
129
+ isOptional: false,
130
+ }))
131
+ const responseRedactions = provider.responseRedactions ?? []
132
+
133
+ return {
134
+ url: provider.url,
135
+ method: provider.method,
136
+ credentials: 'include',
137
+ ...(provider.body ? { requestBodyTemplate: provider.body } : {}),
138
+ ...(provider.writeRedactionMode
139
+ ? { writeRedactionMode: provider.writeRedactionMode }
140
+ : {}),
141
+ ...(provider.additionalClientOptions
142
+ ? { additionalClientOptions: provider.additionalClientOptions }
143
+ : {}),
144
+ ...(responseMatches.length > 0 ? { responseMatches } : {}),
145
+ ...(responseRedactions.length > 0 ? { responseRedactions } : {}),
146
+ }
147
+ }
148
+
149
+ /** First provider that declares an explicit (non-default) egress wins; if none
150
+ * do, fall back to DYNAMIC_GEO (resolved to the verifying user's country). */
151
+ function pickGeoLocation(providers: ReclaimProvider[]): string {
152
+ for(const provider of providers) {
153
+ const geo = normalizeGeoLocation(provider.geoLocation)
154
+ if(geo) {
155
+ return geo
156
+ }
157
+ }
158
+
159
+ return DYNAMIC_GEO
160
+ }
161
+
53
162
  export function providerToCreateVersionRequest(
54
- provider: ReclaimProvider,
163
+ providers: ReclaimProvider[],
55
164
  initialUrl: string,
56
- notes?: string,
57
- version?: ProviderVersionRef,
165
+ opts: CreateVersionOptions = {},
58
166
  ): CreateProviderVersionRequest {
59
- const requiredContext = deriveRequiredContext(provider)
60
- // Inline responseRedactions into matches[*].extract (1-to-1 by index).
61
- const matches = (provider.responseMatches ?? []).map((match, i) => {
62
- const redaction = provider.responseRedactions?.[i]
63
- return {
64
- type: match.type,
65
- value: match.value,
66
- isOptional: false,
67
- ...(redaction ? { extract: redaction } : {}),
68
- }
167
+ const { notes, version, jsUserScripts, allowedJsRequests } = opts
168
+ const requiredContext = deriveRequiredContext(providers, {
169
+ allowedJsRequests,
170
+ jsUserScripts,
69
171
  })
70
172
 
173
+ // Each injected request carries its template flags (default true/true per
174
+ // RequestSelectionTemplate) on top of the shared request shape.
175
+ const allowedJs = (allowedJsRequests ?? []).map((req) => ({
176
+ ...providerToRequestSelection(req),
177
+ multiple: req.multiple ?? true,
178
+ required: req.required ?? true,
179
+ }))
180
+ const script = jsUserScripts?.trim()
181
+
71
182
  return {
72
183
  version: version ?? { major: 1, minor: 0, patch: 0 },
73
184
  initialUrl,
74
- requests: [
75
- {
76
- url: provider.url,
77
- method: provider.method,
78
- credentials: 'include',
79
- ...(provider.body ? { requestBodyTemplate: provider.body } : {}),
80
- ...(matches.length > 0 ? { matches } : {}),
81
- },
82
- ],
83
- allowedJsRequests: [],
185
+ // Every drafted provider becomes one request — the recipe runs them all.
186
+ requests: providers.map(providerToRequestSelection),
187
+ allowedJsRequests: allowedJs,
84
188
  // Mirror the builder openapi defaults explicitly — the server does not
85
189
  // apply schema defaults to request bodies.
86
190
  webSettings: {
87
- geoLocation: '{{DYNAMIC_GEO}}',
191
+ geoLocation: pickGeoLocation(providers),
88
192
  clientOptions: { portal: { useProxy: true } },
193
+ // Only set when non-empty; an empty string would store a no-op script.
194
+ ...(script ? { jsUserScripts: script } : {}),
89
195
  },
90
196
  // Derived from `{{context.<name>}}` placeholders only — a captured
91
197
  // provider's `paramValues` are extracted response parameters, not