@reclaimprotocol/agent 0.1.22 → 0.1.24
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 +55 -20
- package/lib/authoring/backend.d.ts +13 -10
- package/lib/authoring/tools.js +106 -9
- package/lib/cdp/browser-proxy.d.ts +78 -0
- package/lib/cdp/browser-proxy.js +186 -0
- package/lib/cdp/capture-engine.js +8 -7
- package/lib/cdp/client.d.ts +10 -0
- package/lib/cdp/geo.d.ts +10 -0
- package/lib/cdp/geo.js +36 -0
- package/lib/cdp/index.d.ts +1 -0
- package/lib/cdp/index.js +1 -0
- package/lib/live/cloudflared.d.ts +15 -0
- package/lib/live/cloudflared.js +268 -0
- package/lib/live/page.d.ts +20 -0
- package/lib/live/page.js +134 -0
- package/lib/live/tunnel.d.ts +23 -0
- package/lib/live/tunnel.js +120 -0
- package/lib/live/viewer.d.ts +28 -0
- package/lib/live/viewer.js +232 -0
- package/lib/mcp/api/operations.gen.js +34 -26
- package/lib/mcp/api/to-zod.d.ts +1 -1
- package/lib/mcp/api/to-zod.js +1 -1
- package/lib/mcp/api/tools.js +1 -1
- package/lib/mcp/instructions.d.ts +15 -2
- package/lib/mcp/instructions.js +101 -38
- package/lib/mcp/start.js +4 -3
- package/lib/mcp/tools/agent/analyze.js +5 -1
- package/lib/mcp/tools/agent/attach.d.ts +8 -1
- package/lib/mcp/tools/agent/attach.js +166 -22
- package/lib/mcp/tools/agent/build.d.ts +13 -8
- package/lib/mcp/tools/agent/build.js +22 -11
- package/lib/mcp/tools/agent/capture.js +5 -1
- package/lib/mcp/tools/agent/eval.js +3 -1
- package/lib/mcp/tools/agent/find.js +6 -5
- package/lib/mcp/tools/agent/how-it-works.d.ts +15 -7
- package/lib/mcp/tools/agent/how-it-works.js +57 -17
- package/lib/mcp/tools/agent/live-view.d.ts +21 -0
- package/lib/mcp/tools/agent/live-view.js +153 -0
- package/lib/mcp/tools/agent/pod-proof.d.ts +8 -0
- package/lib/mcp/tools/agent/pod-proof.js +64 -0
- package/lib/mcp/tools/agent/propose.js +29 -3
- package/lib/mcp/tools/agent/proxy.d.ts +3 -0
- package/lib/mcp/tools/agent/proxy.js +199 -0
- package/lib/mcp/tools/agent/publish.js +49 -77
- package/lib/mcp/tools/agent/session.d.ts +2 -1
- package/lib/mcp/tools/agent/session.js +26 -7
- package/lib/mcp/tools/agent/shared.js +17 -8
- package/lib/mcp/tools/authenticate/authenticate.d.ts +11 -0
- package/lib/mcp/tools/authenticate/authenticate.js +143 -121
- package/lib/mcp/tools/authenticate/builder-access.d.ts +8 -3
- package/lib/mcp/tools/authenticate/builder-access.js +8 -3
- package/lib/mcp/tools/mode/mode.d.ts +1 -1
- package/lib/mcp/tools/mode/mode.js +26 -7
- package/lib/old/client.d.ts +9 -0
- package/lib/old/client.js +19 -1
- package/lib/old/instructions.d.ts +9 -1
- package/lib/old/instructions.js +4 -6
- package/lib/old/login-cdp.d.ts +2 -2
- package/lib/old/login-cdp.js +46 -6
- package/lib/old/to-register.d.ts +20 -8
- package/lib/old/to-register.js +7 -1
- package/lib/old/tools/authenticate.js +9 -1
- package/lib/old/tools/get-provider-info.js +6 -5
- package/lib/old/tools/issue-app-credentials.js +3 -2
- package/lib/old/tools/me-providers.js +3 -1
- package/lib/old/tools/publish.d.ts +1 -1
- package/lib/old/tools/publish.js +132 -129
- package/lib/old/tools/update-provider-metadata.d.ts +1 -1
- package/lib/old/tools/update-provider-metadata.js +1 -1
- package/lib/old/tools/verify-sdk-setup.js +1 -1
- package/lib/proof/attestor.d.ts +3 -3
- package/lib/proof/debug-response-dump.js +4 -4
- package/lib/proof/index.d.ts +1 -0
- package/lib/proof/index.js +1 -0
- package/lib/proof/page-replay.d.ts +36 -0
- package/lib/proof/page-replay.js +76 -0
- package/lib/proof/pod-prover.d.ts +47 -0
- package/lib/proof/pod-prover.js +155 -0
- package/lib/proof/replay.d.ts +28 -0
- package/lib/proof/replay.js +39 -18
- package/lib/provider/dom-xpath.js +11 -9
- package/lib/provider/draft.d.ts +13 -8
- package/lib/provider/draft.js +47 -13
- package/lib/provider/injection-doc.d.ts +23 -1
- package/lib/provider/injection-doc.js +34 -21
- package/lib/provider/match-redaction-warning.d.ts +2 -2
- package/lib/provider/match-redaction-warning.js +3 -3
- package/lib/provider/matcher.js +122 -12
- package/lib/provider/secrets.d.ts +3 -3
- package/lib/provider/secrets.js +3 -3
- package/lib/provider/to-version.d.ts +12 -9
- package/lib/provider/to-version.js +16 -4
- package/lib/tools/registry.d.ts +5 -5
- package/lib/tools/registry.js +5 -5
- package/package.json +4 -3
- package/samples/demo-server/README.md +7 -6
- package/skill/SKILL.builder.md +356 -189
- package/skill/SKILL.common.md +314 -79
- package/skill/SKILL.old.md +340 -155
- package/skill/builder-mode.md +58 -17
- package/skill/hash-validation.md +170 -0
- package/skill/interception.md +235 -0
- package/skill/js-sdk-integration.md +13 -7
- package/skill/old-mode.md +53 -12
- package/skill/user-script.md +61 -0
- package/src/authoring/backend.ts +13 -10
- package/src/authoring/tools.ts +128 -9
- package/src/cdp/capture-engine.ts +8 -7
- package/src/cdp/client.ts +8 -0
- package/src/cdp/geo.ts +52 -0
- package/src/cdp/index.ts +1 -0
- package/src/consts.ts +1 -0
- package/src/live/cloudflared.ts +348 -0
- package/src/live/page.ts +145 -0
- package/src/live/tunnel.ts +157 -0
- package/src/live/viewer.ts +293 -0
- package/src/mcp/api/operations.gen.ts +34 -26
- package/src/mcp/api/to-zod.ts +1 -1
- package/src/mcp/api/tools.ts +1 -1
- package/src/mcp/instructions.ts +121 -48
- package/src/mcp/start.ts +4 -3
- package/src/mcp/tools/agent/analyze.ts +5 -1
- package/src/mcp/tools/agent/attach.ts +194 -22
- package/src/mcp/tools/agent/build.ts +26 -15
- package/src/mcp/tools/agent/capture.ts +5 -1
- package/src/mcp/tools/agent/eval.ts +4 -1
- package/src/mcp/tools/agent/find.ts +6 -5
- package/src/mcp/tools/agent/how-it-works.ts +62 -21
- package/src/mcp/tools/agent/live-view.ts +198 -0
- package/src/mcp/tools/agent/pod-proof.ts +90 -0
- package/src/mcp/tools/agent/propose.ts +31 -3
- package/src/mcp/tools/agent/publish.ts +54 -78
- package/src/mcp/tools/agent/session.ts +26 -5
- package/src/mcp/tools/agent/shared.ts +19 -8
- package/src/mcp/tools/authenticate/authenticate.ts +167 -165
- package/src/mcp/tools/authenticate/builder-access.ts +8 -3
- package/src/mcp/tools/mode/mode.ts +28 -7
- package/src/old/client.ts +30 -1
- package/src/old/instructions.ts +4 -10
- package/src/old/login-cdp.ts +50 -6
- package/src/old/to-register.ts +28 -8
- package/src/old/tools/authenticate.ts +9 -1
- package/src/old/tools/get-provider-info.ts +6 -5
- package/src/old/tools/issue-app-credentials.ts +3 -2
- package/src/old/tools/me-providers.ts +3 -1
- package/src/old/tools/publish.ts +140 -130
- package/src/old/tools/update-provider-metadata.ts +1 -1
- package/src/old/tools/verify-sdk-setup.ts +1 -1
- package/src/proof/attestor.ts +3 -3
- package/src/proof/debug-response-dump.ts +4 -4
- package/src/proof/index.ts +8 -0
- package/src/proof/page-replay.ts +131 -0
- package/src/proof/pod-prover.ts +231 -0
- package/src/proof/replay.ts +60 -19
- package/src/provider/dom-xpath.ts +11 -9
- package/src/provider/draft.ts +56 -13
- package/src/provider/injection-doc.ts +37 -24
- package/src/provider/match-redaction-warning.ts +3 -3
- package/src/provider/matcher.ts +151 -10
- package/src/provider/secrets.ts +3 -3
- package/src/provider/to-version.ts +30 -13
- package/src/tools/registry.ts +5 -5
- package/skill/injection-api.md +0 -335
package/src/old/client.ts
CHANGED
|
@@ -47,6 +47,15 @@ export interface RegisterProviderBody {
|
|
|
47
47
|
* controller's destructure + its `providerConfig` write, both of which
|
|
48
48
|
* include it alongside `pageTitle`/`userAgent`. */
|
|
49
49
|
stepsToFollow?: string
|
|
50
|
+
/** Interception mechanism (`NONE` = standard replay flow, the default;
|
|
51
|
+
* `HAWKEYE`/`MSWJS`/`XHOOK` = JS-context interception; `CDP` = browser-
|
|
52
|
+
* level). Column default is `HAWKEYE` when omitted entirely — unlike
|
|
53
|
+
* `stepsToFollow`, and so on. above, whether the register endpoint actually
|
|
54
|
+
* PERSISTS this field is UNVERIFIED (no source access to confirm); sent
|
|
55
|
+
* here on the chance it does, but the publish tool always follows up
|
|
56
|
+
* with a config (add-version) call regardless, which is confirmed to
|
|
57
|
+
* persist it. */
|
|
58
|
+
injectionType?: 'NONE' | 'MSWJS' | 'XHOOK' | 'CDP' | 'HAWKEYE'
|
|
50
59
|
}
|
|
51
60
|
|
|
52
61
|
export interface UpdateProviderConfigBody {
|
|
@@ -353,11 +362,31 @@ export class ReclaimOldClient {
|
|
|
353
362
|
}
|
|
354
363
|
|
|
355
364
|
#asBoom(res: Response, json: unknown): Boom {
|
|
356
|
-
const
|
|
365
|
+
const rawMessage =
|
|
357
366
|
(json && typeof json === 'object' &&
|
|
358
367
|
typeof (json as { message?: unknown }).message === 'string'
|
|
359
368
|
? (json as { message: string }).message
|
|
360
369
|
: undefined) || res.statusText || 'Old devtools request failed'
|
|
370
|
+
// An identity ALREADY SET (as opposed to `#requireIdentity`'s "never
|
|
371
|
+
// authenticated" case, which never reaches the backend) plus either a
|
|
372
|
+
// 401/403 OR a message that itself names token verification means the
|
|
373
|
+
// backend rejected a token we had — that is, it's stale/invalid, not merely
|
|
374
|
+
// absent. The message check matters because this backend does NOT
|
|
375
|
+
// reliably use 401/403 for it — confirmed live: an actually-expired
|
|
376
|
+
// Firebase token surfaced as "Error while verifying token" with a
|
|
377
|
+
// status this narrow check (401/403-only) missed entirely, silently
|
|
378
|
+
// skipping the enrichment. The backend's own message gives no hint of
|
|
379
|
+
// the fix, and nothing else distinguishes this from Builder auth, so
|
|
380
|
+
// append repo-side guidance rather than replacing the raw detail.
|
|
381
|
+
const staleAuth = !!this.#identity && (
|
|
382
|
+
res.status === 401 || res.status === 403 ||
|
|
383
|
+
/verify.{0,20}token|token.{0,20}verif/i.test(rawMessage)
|
|
384
|
+
)
|
|
385
|
+
const message = staleAuth
|
|
386
|
+
? `${rawMessage} — your old-devtools login looks stale or invalid `
|
|
387
|
+
+ '(this is separate from Builder auth). Re-run reclaim_authenticate '
|
|
388
|
+
+ 'to refresh it, then retry.'
|
|
389
|
+
: rawMessage
|
|
361
390
|
// Shape `data` like a ProblemDetails so remapErrorAsResponse can render
|
|
362
391
|
// `${message}: ${data.detail}` and expose the raw body as structured.
|
|
363
392
|
return new Boom(message, {
|
package/src/old/instructions.ts
CHANGED
|
@@ -2,14 +2,8 @@
|
|
|
2
2
|
* MCP server instructions shown to the LLM when running in OLD-devtools mode
|
|
3
3
|
* (`USE_OLD_DEVTOOLS` unset or not `false`). Describes the REDUCED tool
|
|
4
4
|
* surface — there are no org/credential-link/review flows and no generated
|
|
5
|
-
* API tools here.
|
|
6
|
-
* `
|
|
7
|
-
*
|
|
5
|
+
* API tools here. Both modes' instructions load together in
|
|
6
|
+
* `mcp/instructions` (alongside the topic-split authoring guide); re-exported
|
|
7
|
+
* here so old-mode callers keep importing from their own module.
|
|
8
8
|
*/
|
|
9
|
-
|
|
10
|
-
import { fileURLToPath } from 'node:url'
|
|
11
|
-
|
|
12
|
-
export const OLD_MODE_INSTRUCTIONS = readFileSync(
|
|
13
|
-
fileURLToPath(new URL('../../skill/old-mode.md', import.meta.url)),
|
|
14
|
-
'utf8',
|
|
15
|
-
).trim()
|
|
9
|
+
export { OLD_MODE_INSTRUCTIONS } from '../mcp/instructions.ts'
|
package/src/old/login-cdp.ts
CHANGED
|
@@ -97,8 +97,8 @@ export interface CdpLoginResult {
|
|
|
97
97
|
* finish signing in, read the resulting Firebase ID token from page storage,
|
|
98
98
|
* then clean up. If we had to launch a dedicated Chrome for this, we close the
|
|
99
99
|
* whole browser afterwards; if we attached to a Chrome that was already up
|
|
100
|
-
* (
|
|
101
|
-
* disrupt it.
|
|
100
|
+
* (for example, the capture flow's), we only close the tab we opened so we
|
|
101
|
+
* don't disrupt it.
|
|
102
102
|
*/
|
|
103
103
|
export async function captureFirebaseTokenViaCdp(opts: {
|
|
104
104
|
loginUrl?: string
|
|
@@ -107,7 +107,13 @@ export async function captureFirebaseTokenViaCdp(opts: {
|
|
|
107
107
|
}): Promise<CdpLoginResult> {
|
|
108
108
|
const loginUrl =
|
|
109
109
|
opts.loginUrl || oldLoginUrl() || DEFAULT_LOGIN_URL
|
|
110
|
-
|
|
110
|
+
// 6 minutes, not 3. On a FRESH Chrome profile the dashboard is a cold load
|
|
111
|
+
// of an ~8.6 MB uncompressed bundle before the login form is even
|
|
112
|
+
// interactive — tens of seconds on a slow link — and only then does the
|
|
113
|
+
// developer start typing credentials and a 2FA code. The old 3-minute
|
|
114
|
+
// budget was routinely spent before they could finish, and the retry that
|
|
115
|
+
// followed looked like a 6-minute hang with no output.
|
|
116
|
+
const timeoutMs = opts.timeoutMs ?? 360_000
|
|
111
117
|
const pollMs = opts.pollMs ?? 1000
|
|
112
118
|
|
|
113
119
|
const cfg = new ConfigStore().read()?.browser_agent
|
|
@@ -123,7 +129,7 @@ export async function captureFirebaseTokenViaCdp(opts: {
|
|
|
123
129
|
throw new Error(
|
|
124
130
|
`attach mode: nothing answering CDP on port ${port}. Launch Chrome ` +
|
|
125
131
|
`with --remote-debugging-port=${port} AND a non-default ` +
|
|
126
|
-
'--user-data-dir, or switch to dedicated mode (
|
|
132
|
+
'--user-data-dir, or switch to dedicated mode (attach_browser).',
|
|
127
133
|
)
|
|
128
134
|
}
|
|
129
135
|
|
|
@@ -139,6 +145,10 @@ export async function captureFirebaseTokenViaCdp(opts: {
|
|
|
139
145
|
try {
|
|
140
146
|
const session = await handles.attachToTab(targetId)
|
|
141
147
|
const deadline = Date.now() + timeoutMs
|
|
148
|
+
// Tracks how far the page got, so a timeout can say WHICH thing stalled:
|
|
149
|
+
// a bundle that never finished downloading is a different problem from a
|
|
150
|
+
// developer who walked away mid-sign-in.
|
|
151
|
+
let sawInteractivePage = false
|
|
142
152
|
while(Date.now() < deadline) {
|
|
143
153
|
const result = await session.send('Runtime.evaluate', {
|
|
144
154
|
expression: EXTRACT_TOKEN_JS,
|
|
@@ -150,12 +160,24 @@ export async function captureFirebaseTokenViaCdp(opts: {
|
|
|
150
160
|
return { token: value, closedBrowser: launchedByUs }
|
|
151
161
|
}
|
|
152
162
|
|
|
163
|
+
if(!sawInteractivePage) {
|
|
164
|
+
sawInteractivePage = await pageIsInteractive(session)
|
|
165
|
+
}
|
|
166
|
+
|
|
153
167
|
await new Promise((resolve) => setTimeout(resolve, pollMs))
|
|
154
168
|
}
|
|
155
169
|
|
|
170
|
+
const waited = Math.round(timeoutMs / 1000)
|
|
156
171
|
throw new Error(
|
|
157
|
-
|
|
158
|
-
|
|
172
|
+
`Timed out after ${waited}s waiting for login. `
|
|
173
|
+
+ (sawInteractivePage
|
|
174
|
+
? 'The page finished loading, so sign-in was never completed — '
|
|
175
|
+
+ 'ask the developer to finish signing in at the opened window, '
|
|
176
|
+
+ 'then re-run reclaim_authenticate.'
|
|
177
|
+
: 'The page never became interactive, so the dashboard was still '
|
|
178
|
+
+ 'loading the whole time. On a fresh Chrome profile its bundle '
|
|
179
|
+
+ 'is a large cold download. Retry (the profile is now warm), or '
|
|
180
|
+
+ 'pass a bigger timeoutMs.'),
|
|
159
181
|
)
|
|
160
182
|
} finally {
|
|
161
183
|
// Best-effort cleanup — never mask the real result/error.
|
|
@@ -173,6 +195,28 @@ export async function captureFirebaseTokenViaCdp(opts: {
|
|
|
173
195
|
}
|
|
174
196
|
}
|
|
175
197
|
|
|
198
|
+
/**
|
|
199
|
+
* Whether the login page has reached a usable state. `readyState` alone is not
|
|
200
|
+
* enough for a single-bundle SPA: the document is 'complete' while the app is
|
|
201
|
+
* still parsing, and nothing is clickable yet. Requiring a rendered root as
|
|
202
|
+
* well is what distinguishes "still loading" from "waiting for the human".
|
|
203
|
+
*/
|
|
204
|
+
async function pageIsInteractive(
|
|
205
|
+
session: { send: (m: string, p?: object) => Promise<unknown> },
|
|
206
|
+
): Promise<boolean> {
|
|
207
|
+
try {
|
|
208
|
+
const result = await session.send('Runtime.evaluate', {
|
|
209
|
+
expression:
|
|
210
|
+
'document.readyState === "complete" '
|
|
211
|
+
+ '&& !!document.body && document.body.innerText.trim().length > 0',
|
|
212
|
+
returnByValue: true,
|
|
213
|
+
})
|
|
214
|
+
return runtimeResultValue(result) === true
|
|
215
|
+
} catch{
|
|
216
|
+
return false
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
176
220
|
function runtimeResultValue(value: unknown): unknown {
|
|
177
221
|
if(typeof value !== 'object' || !value || !('result' in value)) {
|
|
178
222
|
return undefined
|
package/src/old/to-register.ts
CHANGED
|
@@ -39,7 +39,8 @@ export interface OldProviderOpts {
|
|
|
39
39
|
/** Page-injection script — the devtools name for the builder's
|
|
40
40
|
* `webSettings.jsUserScripts`. Top-level on register, nested under
|
|
41
41
|
* `providerConfig` on config (add-version). The backend rejects a few
|
|
42
|
-
* deprecated injection APIs (
|
|
42
|
+
* deprecated injection APIs (for example, `window.payloadData`) with a
|
|
43
|
+
* 400. */
|
|
43
44
|
customInjection?: string
|
|
44
45
|
/** Accepted at register too (unlike the four fields below, which the
|
|
45
46
|
* backend only accepts on config/add-version). */
|
|
@@ -61,13 +62,24 @@ export interface OldProviderOpts {
|
|
|
61
62
|
* field from the request body. Free-form JSON. */
|
|
62
63
|
extensionConfig?: unknown
|
|
63
64
|
/** Provider-level `disableRequestReplay` (HAWKEYE document replay skip).
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
* `
|
|
69
|
-
* .
|
|
65
|
+
* The publish tool always forces this `true` — there is no author-facing
|
|
66
|
+
* way to enable document replay. Config (add-version) ONLY: the register
|
|
67
|
+
* endpoint hardcodes it to false regardless of what's sent, so the
|
|
68
|
+
* publish tool always follows a register up with an add-version call to
|
|
69
|
+
* actually apply it (see `old/tools/publish.ts`). The builder backend's
|
|
70
|
+
* inverse-named equivalent, `webSettings.clientOptions.inapp
|
|
71
|
+
* .interceptorOptions.isDocumentRequestReplayEnabled`, is likewise always
|
|
72
|
+
* force-disabled by `providerToCreateVersionRequest`. */
|
|
70
73
|
disableRequestReplay?: boolean
|
|
74
|
+
/** Interception mechanism — `NONE` (the publish tool's default) for the
|
|
75
|
+
* standard capture→replay flow; `HAWKEYE`/`MSWJS`/`XHOOK`/`CDP` for a
|
|
76
|
+
* genuine live-interception provider. Old-devtools calls this
|
|
77
|
+
* `injectionType`; builder's equivalent is `webSettings.clientOptions
|
|
78
|
+
* .inapp.interceptorOptions.interceptorType` (no `NONE` value there —
|
|
79
|
+
* omitting the whole object is builder's no-interception signal
|
|
80
|
+
* instead). See `old/client.ts`'s `RegisterProviderBody.injectionType`
|
|
81
|
+
* doc for the register-persistence caveat. */
|
|
82
|
+
injectionType?: 'NONE' | 'MSWJS' | 'XHOOK' | 'CDP' | 'HAWKEYE'
|
|
71
83
|
}
|
|
72
84
|
|
|
73
85
|
interface OldResponseMatch {
|
|
@@ -269,6 +281,10 @@ export function providerToRegisterBody(
|
|
|
269
281
|
body.stepsToFollow = opts.stepsToFollow
|
|
270
282
|
}
|
|
271
283
|
|
|
284
|
+
if(opts.injectionType !== undefined) {
|
|
285
|
+
body.injectionType = opts.injectionType
|
|
286
|
+
}
|
|
287
|
+
|
|
272
288
|
return body
|
|
273
289
|
}
|
|
274
290
|
|
|
@@ -323,6 +339,10 @@ export function providerToConfigBody(
|
|
|
323
339
|
providerConfig.disableRequestReplay = opts.disableRequestReplay
|
|
324
340
|
}
|
|
325
341
|
|
|
342
|
+
if(opts.injectionType !== undefined) {
|
|
343
|
+
providerConfig.injectionType = opts.injectionType
|
|
344
|
+
}
|
|
345
|
+
|
|
326
346
|
return { providerConfig, version, versionInfo }
|
|
327
347
|
}
|
|
328
348
|
|
|
@@ -336,7 +356,7 @@ export interface SemverTriplet {
|
|
|
336
356
|
/**
|
|
337
357
|
* Pull `{major,minor,patch}` triplets out of a `/versions` response, tolerant
|
|
338
358
|
* of the exact envelope (array, `{ providerVersions: [...] }`, `{ items }`,
|
|
339
|
-
|
|
359
|
+
*, and so on). Each entry's `version` is the triplet.
|
|
340
360
|
*/
|
|
341
361
|
export function extractVersions(resp: unknown): SemverTriplet[] {
|
|
342
362
|
const list = pickArray(resp)
|
|
@@ -46,6 +46,11 @@ export function authenticateTool(client: ReclaimOldClient): RegisteredTool {
|
|
|
46
46
|
'and closes the tab. A previously stored identity that is still ' +
|
|
47
47
|
'valid is reused first (pass `useBrowser: true` to force a fresh ' +
|
|
48
48
|
'login). \n\n' +
|
|
49
|
+
'EXPECT THIS TO TAKE A WHILE ON A FIRST RUN: a fresh Chrome ' +
|
|
50
|
+
'profile downloads the dashboard cold, so tell the developer it is ' +
|
|
51
|
+
'loading and that the window is waiting for them — do not re-run ' +
|
|
52
|
+
'the tool while it is still waiting. It polls for up to 6 minutes ' +
|
|
53
|
+
'and reports whether the page ever became interactive.\n\n' +
|
|
49
54
|
'Manual overrides:\n' +
|
|
50
55
|
'- `token`: paste a Firebase ID token (skips the browser).\n' +
|
|
51
56
|
'- `ethAddress`: an `eth:0x…` / `0x…` uid for an already-provisioned ' +
|
|
@@ -73,7 +78,10 @@ export function authenticateTool(client: ReclaimOldClient): RegisteredTool {
|
|
|
73
78
|
timeoutMs: {
|
|
74
79
|
type: 'number',
|
|
75
80
|
description:
|
|
76
|
-
'How long to wait for sign-in, in ms (default
|
|
81
|
+
'How long to wait for sign-in, in ms (default 360000, i.e. 6 '
|
|
82
|
+
+ 'minutes). A fresh Chrome profile loads the dashboard cold, '
|
|
83
|
+
+ 'which can take tens of seconds before the form is usable — '
|
|
84
|
+
+ 'that time comes out of this budget.',
|
|
77
85
|
},
|
|
78
86
|
useBrowser: {
|
|
79
87
|
type: 'boolean',
|
|
@@ -3,8 +3,8 @@ import { defineTool, type RegisteredTool } from '../../mcp/server.ts'
|
|
|
3
3
|
import type { ReclaimSdkClient } from '../sdk-client.ts'
|
|
4
4
|
|
|
5
5
|
/** Best-effort call: resolve to the response, or to an error string instead
|
|
6
|
-
* of throwing — one endpoint 404ing (
|
|
7
|
-
* hide a result the other endpoint DID have. */
|
|
6
|
+
* of throwing — one endpoint 404ing (for example, a bad `versionNumber`)
|
|
7
|
+
* shouldn't hide a result the other endpoint DID have. */
|
|
8
8
|
async function attempt(
|
|
9
9
|
label: string,
|
|
10
10
|
call: () => Promise<unknown>,
|
|
@@ -51,8 +51,9 @@ export function getProviderInfoTool(client: ReclaimSdkClient): RegisteredTool {
|
|
|
51
51
|
'computed `isScriptRequestingClaim` flag). Read `provider` here ' +
|
|
52
52
|
'BEFORE create_provider_version_from_capture so you can pass the ' +
|
|
53
53
|
'whole existing config back — that tool always creates a new ' +
|
|
54
|
-
'version and carries nothing forward. One endpoint failing (
|
|
55
|
-
'an invalid `versionNumber`) is reported under `errors`
|
|
54
|
+
'version and carries nothing forward. One endpoint failing (for ' +
|
|
55
|
+
'example, an invalid `versionNumber`) is reported under `errors` ' +
|
|
56
|
+
'without ' +
|
|
56
57
|
'hiding a result the other endpoint did return.',
|
|
57
58
|
inputSchema: {
|
|
58
59
|
type: 'object',
|
|
@@ -64,7 +65,7 @@ export function getProviderInfoTool(client: ReclaimSdkClient): RegisteredTool {
|
|
|
64
65
|
versionNumber: {
|
|
65
66
|
type: 'string',
|
|
66
67
|
description:
|
|
67
|
-
'Specific version,
|
|
68
|
+
'Specific version, for example, "1.0.2". Omit for the ' +
|
|
68
69
|
"provider's current latest version.",
|
|
69
70
|
},
|
|
70
71
|
},
|
|
@@ -24,8 +24,9 @@ export function issueAppCredentialsTool(
|
|
|
24
24
|
'starts UNLINKED and sandboxed (100 sessions) — call ' +
|
|
25
25
|
'link_app_to_account to attach it to your dashboard account and ' +
|
|
26
26
|
'check_app_status to check its state. Store `appSecret` like a ' +
|
|
27
|
-
'password (
|
|
28
|
-
'is returned once and cannot be
|
|
27
|
+
'password (for example, in a gitignored .env as ' +
|
|
28
|
+
'RECLAIM_APP_SECRET) — it is returned once and cannot be ' +
|
|
29
|
+
'recovered from the server.',
|
|
29
30
|
inputSchema: { type: 'object', properties: {} },
|
|
30
31
|
},
|
|
31
32
|
async() => {
|
|
@@ -21,7 +21,9 @@ export function getMeProvidersTool(client: ReclaimOldClient): RegisteredTool {
|
|
|
21
21
|
'first). Returns provider metadata including each `providerId` — ' +
|
|
22
22
|
'pass one back to create_provider_version_from_capture to publish a ' +
|
|
23
23
|
'new version of that provider instead of creating a duplicate. ' +
|
|
24
|
-
'Requires reclaim_authenticate first
|
|
24
|
+
'Requires reclaim_authenticate (old-devtools login) first — this ' +
|
|
25
|
+
'is separate from authenticate_builder/Builder auth, which does ' +
|
|
26
|
+
'not authorize this call. Check status with get_devtools_mode.',
|
|
25
27
|
inputSchema: {
|
|
26
28
|
type: 'object',
|
|
27
29
|
properties: {
|