@reclaimprotocol/agent 0.1.36 → 0.1.38
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 +8 -8
- package/lib/authoring/backend.d.ts +12 -1
- package/lib/authoring/backend.js +3 -0
- package/lib/authoring/tools.js +33 -5
- package/lib/authoring/util.d.ts +43 -0
- package/lib/authoring/util.js +54 -0
- package/lib/cdp/chrome-for-testing.d.ts +14 -0
- package/lib/cdp/chrome-for-testing.js +43 -0
- package/lib/cdp/geo.d.ts +3 -0
- package/lib/cdp/geo.js +27 -15
- package/lib/cdp/launcher.d.ts +79 -1
- package/lib/cdp/launcher.js +244 -24
- package/lib/logger.js +3 -1
- package/lib/mcp/instructions.js +3 -3
- package/lib/mcp/start.js +17 -2
- package/lib/mcp/tools/agent/attach.d.ts +6 -0
- package/lib/mcp/tools/agent/attach.js +58 -118
- package/lib/mcp/tools/agent/build.js +8 -0
- package/lib/mcp/tools/agent/capture.js +33 -10
- package/lib/mcp/tools/agent/check-attestor.js +15 -7
- package/lib/mcp/tools/agent/draft-tools.d.ts +3 -0
- package/lib/mcp/tools/agent/draft-tools.js +170 -0
- package/lib/mcp/tools/agent/example-app.d.ts +2 -0
- package/lib/mcp/tools/agent/example-app.js +167 -0
- package/lib/mcp/tools/agent/pod-proof.js +5 -1
- package/lib/mcp/tools/agent/proof.d.ts +28 -0
- package/lib/mcp/tools/agent/proof.js +72 -0
- package/lib/mcp/tools/agent/shared.d.ts +8 -1
- package/lib/mcp/tools/agent/shared.js +98 -19
- package/lib/mcp/tools/agent/start-integration.d.ts +2 -1
- package/lib/mcp/tools/agent/start-integration.js +10 -6
- package/lib/mcp/tools/authenticate/authenticate.d.ts +48 -10
- package/lib/mcp/tools/authenticate/authenticate.js +212 -116
- package/lib/mcp/tools/authenticate/build.d.ts +2 -2
- package/lib/mcp/tools/authenticate/build.js +6 -3
- package/lib/mcp/tools/authenticate/builder-access.js +5 -2
- package/lib/mcp/tools/authenticate/eth-key.d.ts +13 -2
- package/lib/mcp/tools/authenticate/eth-key.js +29 -5
- package/lib/mcp/tools/authenticate/index.d.ts +1 -1
- package/lib/mcp/tools/authenticate/index.js +1 -1
- package/lib/mcp/tools/authenticate/issue-org-keypair.d.ts +10 -0
- package/lib/mcp/tools/authenticate/issue-org-keypair.js +82 -0
- package/lib/mcp/tools/authenticate/oauth-config.d.ts +31 -0
- package/lib/mcp/tools/authenticate/oauth-config.js +67 -0
- package/lib/mcp/tools/authenticate/resolve-owner-key.d.ts +4 -5
- package/lib/mcp/tools/authenticate/resolve-owner-key.js +40 -36
- package/lib/mcp/tools/authenticate/session-cache.d.ts +25 -1
- package/lib/mcp/tools/authenticate/session-cache.js +95 -4
- package/lib/mcp/tools/mode/mode.js +6 -6
- package/lib/old/login-cdp.js +2 -3
- package/lib/proof/attestor.js +2 -3
- package/lib/proof/check-attestor.d.ts +12 -2
- package/lib/proof/check-attestor.js +40 -10
- package/lib/proof/check-matchers.d.ts +36 -0
- package/lib/proof/check-matchers.js +161 -0
- package/lib/proof/zk-files.d.ts +50 -11
- package/lib/proof/zk-files.js +259 -63
- package/lib/provider/draft.d.ts +24 -1
- package/lib/provider/draft.js +135 -0
- package/lib/provider/matcher.js +171 -4
- package/package.json +6 -4
- package/skill/SKILL.builder.md +7 -2
- package/skill/SKILL.common.md +90 -70
- package/skill/SKILL.old.md +3 -3
- package/skill/builder-mode.md +35 -5
- package/skill/old-mode.md +18 -13
- package/skill/start-integration.md +50 -33
- package/skill/verification-client-integration.md +21 -6
- package/src/authoring/backend.ts +12 -1
- package/src/authoring/tools.ts +48 -7
- package/src/authoring/util.ts +64 -0
- package/src/cdp/chrome-for-testing.ts +66 -0
- package/src/cdp/geo.ts +36 -21
- package/src/cdp/launcher.ts +328 -24
- package/src/logger.ts +3 -1
- package/src/mcp/instructions.ts +3 -3
- package/src/mcp/start.ts +20 -1
- package/src/mcp/tools/agent/attach.ts +65 -128
- package/src/mcp/tools/agent/build.ts +9 -0
- package/src/mcp/tools/agent/capture.ts +54 -11
- package/src/mcp/tools/agent/check-attestor.ts +15 -7
- package/src/mcp/tools/agent/draft-tools.ts +234 -0
- package/src/mcp/tools/agent/example-app.ts +227 -0
- package/src/mcp/tools/agent/pod-proof.ts +5 -1
- package/src/mcp/tools/agent/proof.ts +110 -1
- package/src/mcp/tools/agent/shared.ts +130 -19
- package/src/mcp/tools/agent/start-integration.ts +10 -6
- package/src/mcp/tools/authenticate/authenticate.ts +276 -131
- package/src/mcp/tools/authenticate/build.ts +6 -3
- package/src/mcp/tools/authenticate/builder-access.ts +5 -2
- package/src/mcp/tools/authenticate/eth-key.ts +41 -7
- package/src/mcp/tools/authenticate/index.ts +1 -1
- package/src/mcp/tools/authenticate/issue-org-keypair.ts +106 -0
- package/src/mcp/tools/authenticate/oauth-config.ts +85 -0
- package/src/mcp/tools/authenticate/resolve-owner-key.ts +42 -39
- package/src/mcp/tools/authenticate/session-cache.ts +125 -5
- package/src/mcp/tools/mode/mode.ts +6 -6
- package/src/old/login-cdp.ts +2 -3
- package/src/proof/attestor.ts +2 -3
- package/src/proof/check-attestor.ts +55 -12
- package/src/proof/check-matchers.ts +227 -0
- package/src/proof/zk-files.ts +357 -65
- package/src/provider/draft.ts +215 -7
- package/src/provider/matcher.ts +237 -4
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { authoringTools, extendTool, } from "../../../authoring/index.js";
|
|
2
|
+
import { lookupIpCountry } from "../../../cdp/geo.js";
|
|
2
3
|
import { runAttestorProof } from "../../../proof/attestor.js";
|
|
3
4
|
import { checkAttestor } from "../../../proof/check-attestor.js";
|
|
4
5
|
import { replayProviderInPage } from "../../../proof/page-replay.js";
|
|
6
|
+
import { DYNAMIC_GEO, normalizeGeoLocation, } from "../../../provider/schema.js";
|
|
7
|
+
import { GENERATED_KEY_NOTE, resolveOrCreateEthKey, } from "../authenticate/eth-key.js";
|
|
5
8
|
import { diagnoseNetworkFailure, shapeRichProofResult } from "./proof.js";
|
|
6
9
|
/**
|
|
7
10
|
* OPRF mode this LOCAL (non-TEE) attestor can actually run. Recipes carry
|
|
@@ -30,10 +33,31 @@ function withLocalOprfMode(provider) {
|
|
|
30
33
|
}),
|
|
31
34
|
};
|
|
32
35
|
}
|
|
36
|
+
/** Templates a verification client replaces with the end user's country. */
|
|
37
|
+
const DYNAMIC_GEO_TEMPLATES = new Set([DYNAMIC_GEO, '{{DYNAMIC_GEO_SECRET}}']);
|
|
38
|
+
/**
|
|
39
|
+
* Where a local proof's request goes out from, resolved the way a
|
|
40
|
+
* verification client does it: the `geoLocation` argument, else the draft's
|
|
41
|
+
* fixed country, else (unset or `{{DYNAMIC_GEO}}`) the developer's own IP
|
|
42
|
+
* country, which is what `{{DYNAMIC_GEO}}` becomes when they verify.
|
|
43
|
+
*/
|
|
44
|
+
async function resolveProofEgress(provider, argument, lookupCountry) {
|
|
45
|
+
if (argument) {
|
|
46
|
+
return { geoLocation: argument.toUpperCase(), source: 'argument' };
|
|
47
|
+
}
|
|
48
|
+
const fixed = normalizeGeoLocation(provider.geoLocation);
|
|
49
|
+
if (fixed && !DYNAMIC_GEO_TEMPLATES.has(fixed)) {
|
|
50
|
+
return { geoLocation: fixed, source: 'draft' };
|
|
51
|
+
}
|
|
52
|
+
const country = await lookupCountry();
|
|
53
|
+
return country
|
|
54
|
+
? { geoLocation: country, source: 'developer-ip' }
|
|
55
|
+
: { source: 'none' };
|
|
56
|
+
}
|
|
33
57
|
/** The local backend for one capture: drive its tab over CDP, read its
|
|
34
58
|
* captured requests, prove via the in-process attestor, replay by re-fetching
|
|
35
59
|
* FROM INSIDE the tab (real cookies/session — see proof/page-replay.ts). */
|
|
36
|
-
function localBackend(entry, kept, check) {
|
|
60
|
+
function localBackend(entry, kept, check, runProof, lookupCountry) {
|
|
37
61
|
const { tabClient, session, drafts } = entry;
|
|
38
62
|
const sendCdp = (method, params) => {
|
|
39
63
|
return tabClient.send(method, params ?? {});
|
|
@@ -63,6 +87,15 @@ function localBackend(entry, kept, check) {
|
|
|
63
87
|
// Replayed FROM INSIDE the attached tab (real cookies/session), not
|
|
64
88
|
// a detached Node fetch — see proof/page-replay.ts.
|
|
65
89
|
const result = await replayProviderInPage({ sendCdp }, draft.provider, draft.secrets, opts);
|
|
90
|
+
// Remember the authenticated replay so a failed proof can tell "the
|
|
91
|
+
// site blocks non-browser clients" from a broken recipe.
|
|
92
|
+
if (!opts?.withoutSecrets) {
|
|
93
|
+
draft.lastReplay = {
|
|
94
|
+
status: result.status,
|
|
95
|
+
ok: result.status >= 200 && result.status < 300
|
|
96
|
+
&& result.matchesOriginal,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
66
99
|
return {
|
|
67
100
|
status: result.status,
|
|
68
101
|
matchesOriginal: result.matchesOriginal,
|
|
@@ -71,19 +104,47 @@ function localBackend(entry, kept, check) {
|
|
|
71
104
|
};
|
|
72
105
|
},
|
|
73
106
|
prove: async (draft, opts) => {
|
|
74
|
-
//
|
|
75
|
-
//
|
|
76
|
-
const
|
|
77
|
-
|
|
107
|
+
// No ownerAddress: resolve the configured key, or create a local test
|
|
108
|
+
// key, so a proof never stops to ask the developer for one.
|
|
109
|
+
const ownerKey = opts?.ownerAddress
|
|
110
|
+
? undefined
|
|
111
|
+
: resolveOrCreateEthKey();
|
|
112
|
+
const ownerAddress = opts?.ownerAddress ?? ownerKey?.address;
|
|
113
|
+
const egress = await resolveProofEgress(draft.provider, opts?.geoLocation, lookupCountry);
|
|
114
|
+
// Prove with the locally-runnable OPRF mode and the resolved egress;
|
|
115
|
+
// the draft (→ published recipe) keeps oprf-mpc and its template.
|
|
116
|
+
const { geoLocation: _template, ...provider } = withLocalOprfMode(draft.provider);
|
|
117
|
+
void _template;
|
|
118
|
+
const result = await runProof({
|
|
119
|
+
...provider,
|
|
120
|
+
...(egress.geoLocation ? { geoLocation: egress.geoLocation } : {}),
|
|
121
|
+
}, draft.secrets, {
|
|
122
|
+
...(ownerAddress ? { ownerAddress } : {}),
|
|
78
123
|
...(opts?.attestorUrl ? { attestorUrl: opts.attestorUrl } : {}),
|
|
79
124
|
});
|
|
80
125
|
const shaped = shapeRichProofResult(result, {
|
|
81
126
|
provider: draft.provider,
|
|
82
127
|
hasSecrets: Object.keys(draft.secrets).length > 0,
|
|
83
128
|
...(opts?.attestorUrl ? { attestorUrl: opts.attestorUrl } : {}),
|
|
129
|
+
...(draft.lastReplay ? { lastReplay: draft.lastReplay } : {}),
|
|
130
|
+
egress,
|
|
84
131
|
});
|
|
85
132
|
const diagnosis = await diagnoseNetworkFailure(result, check, opts?.attestorUrl);
|
|
86
|
-
return
|
|
133
|
+
return {
|
|
134
|
+
...shaped,
|
|
135
|
+
egress,
|
|
136
|
+
...(diagnosis ? { diagnosis } : {}),
|
|
137
|
+
...(ownerKey?.source === 'generated'
|
|
138
|
+
? {
|
|
139
|
+
ownerKey: {
|
|
140
|
+
address: ownerKey.address,
|
|
141
|
+
source: ownerKey.source,
|
|
142
|
+
path: ownerKey.path,
|
|
143
|
+
note: GENERATED_KEY_NOTE,
|
|
144
|
+
},
|
|
145
|
+
}
|
|
146
|
+
: {}),
|
|
147
|
+
};
|
|
87
148
|
},
|
|
88
149
|
};
|
|
89
150
|
}
|
|
@@ -93,42 +154,60 @@ function localBackend(entry, kept, check) {
|
|
|
93
154
|
const RUN_PROOF_EXTRAS = {
|
|
94
155
|
description: 'Proves the drafted recipe with a full zkTLS proof through the attestor '
|
|
95
156
|
+ 'SDK. Call it after `replay_request` looks right; attestor calls are '
|
|
96
|
-
+ 'expensive.
|
|
97
|
-
+ '
|
|
157
|
+
+ 'expensive. It signs with the configured proof-owner key and creates '
|
|
158
|
+
+ 'a local test key in the project `.env` when none exists; then the '
|
|
159
|
+
+ 'result has `ownerKey` with a `note`: tell the developer once, after '
|
|
160
|
+
+ 'the fact. Do not ask for a key first. Writes the full claim to '
|
|
98
161
|
+ '`~/.reclaim/claims/<timestamp>.json`. Returns `identifier`, '
|
|
99
162
|
+ '`extractedParameters`, `claimPath`, and a readable `claim` (request '
|
|
100
163
|
+ 'removed, byte arrays as base64). Set `RECLAIM_AGENT_TRACE=1` to also '
|
|
101
164
|
+ 'get `runLogPath`, a diagnostic dump with the attestor log stream. '
|
|
102
165
|
+ 'Set `attestorUrl` only if the developer supplied one; never invent '
|
|
103
|
-
+ 'backup URLs. If `errorKind` is `missing-owner-key`, the
|
|
104
|
-
+ 'no known private key:
|
|
105
|
-
+ '
|
|
166
|
+
+ 'backup URLs. If `errorKind` is `missing-owner-key`, the '
|
|
167
|
+
+ '`ownerAddress` you passed has no known private key: retry without '
|
|
168
|
+
+ '`ownerAddress`. Unlike `replay_request`, which re-sends from '
|
|
106
169
|
+ 'inside the attached browser tab, the attestor calls the target from '
|
|
107
170
|
+ 'its own network and IP. A request that replayed can still fail here '
|
|
108
171
|
+ 'for geo- or IP-bound content, such as country-locked pages or '
|
|
109
172
|
+ 'IP-allowlisted APIs. That is a property of the site, not a draft '
|
|
110
|
-
+ 'bug.
|
|
173
|
+
+ 'bug. The request goes out from `egress.geoLocation` in the result: '
|
|
174
|
+
+ 'the `geoLocation` argument, else the draft\'s fixed country, else '
|
|
175
|
+
+ 'your own IP country. After a network-like failure ("connection closed", '
|
|
111
176
|
+ '`ERROR_NETWORK_ERROR`, timeout), the result includes `diagnosis` '
|
|
112
177
|
+ 'with `attestor` (a `check_attestor` result), `likelyCause`, and '
|
|
113
|
-
+ '`next`. Follow `next`; do not retry the same proof.'
|
|
178
|
+
+ '`next`. Follow `next`; do not retry the same proof. When the '
|
|
179
|
+
+ 'attestor gets HTTP 403/406/429/503 or a challenge page, `diagnosis` '
|
|
180
|
+
+ 'has `kind: "blocked-non-browser-client"`: the site blocks '
|
|
181
|
+
+ 'non-browser clients or traffic from that country, and copying '
|
|
182
|
+
+ 'headers or cookies will not help. Follow its `next`. Run '
|
|
183
|
+
+ '`check_matchers` first to rule out the recipe offline.',
|
|
114
184
|
properties: {
|
|
115
185
|
ownerAddress: {
|
|
116
186
|
type: 'string',
|
|
117
187
|
pattern: '^0x[0-9a-fA-F]{40}$',
|
|
118
|
-
description: 'ETH address
|
|
119
|
-
+ '
|
|
120
|
-
+ 'locally (
|
|
188
|
+
description: 'Optional ETH address the resolved signing key must match. Omit '
|
|
189
|
+
+ 'it: run_proof resolves (or creates) the key itself. The '
|
|
190
|
+
+ 'private key is resolved locally (env / .env / key file), '
|
|
191
|
+
+ 'never passed here.',
|
|
121
192
|
},
|
|
122
193
|
attestorUrl: { type: 'string' },
|
|
194
|
+
geoLocation: {
|
|
195
|
+
type: 'string',
|
|
196
|
+
pattern: '^[A-Za-z]{2}$',
|
|
197
|
+
description: 'ISO country the attestor\'s request goes out from, for example '
|
|
198
|
+
+ '`US`. Omit it to use the draft\'s fixed country, or else your '
|
|
199
|
+
+ 'own IP country, as `{{DYNAMIC_GEO}}` resolves for you when you '
|
|
200
|
+
+ 'verify.',
|
|
201
|
+
},
|
|
123
202
|
},
|
|
124
|
-
required: [
|
|
203
|
+
required: [],
|
|
125
204
|
};
|
|
126
205
|
/** The shared authoring tools mapped to the MCP's shape: resolve each call's
|
|
127
206
|
* local backend from `args.captureId`, and widen the input schema — every tool
|
|
128
207
|
* takes `captureId`; `run_proof` also gets the credential-aware contract. The
|
|
129
208
|
* tools are authored plain in `../../../authoring`; this only wraps them with
|
|
130
209
|
* `extendTool` (handlers untouched — loose arg parse keeps `captureId`). */
|
|
131
|
-
export function sharedAuthoringTools(captures, check = checkAttestor) {
|
|
210
|
+
export function sharedAuthoringTools(captures, check = checkAttestor, runProof = runAttestorProof, lookupCountry = lookupIpCountry) {
|
|
132
211
|
const resolveBackend = (args) => {
|
|
133
212
|
const captureId = String(args.captureId);
|
|
134
213
|
const entry = captures.sessions.get(captureId);
|
|
@@ -136,7 +215,7 @@ export function sharedAuthoringTools(captures, check = checkAttestor) {
|
|
|
136
215
|
throw new Error(`no capture ${captureId} — call start_capture first `
|
|
137
216
|
+ '(it has been reset or never started).');
|
|
138
217
|
}
|
|
139
|
-
return localBackend(entry, captures, check);
|
|
218
|
+
return localBackend(entry, captures, check, runProof, lookupCountry);
|
|
140
219
|
};
|
|
141
220
|
return authoringTools(resolveBackend).map((tool) => {
|
|
142
221
|
if (tool.definition.name === 'run_proof') {
|
|
@@ -6,7 +6,8 @@ interface StartIntegrationArgs {
|
|
|
6
6
|
}
|
|
7
7
|
/**
|
|
8
8
|
* Returns the plan a coding agent follows to add Reclaim verification to the
|
|
9
|
-
* developer's app, from sign-in
|
|
9
|
+
* developer's app, from sign-in and a working proof to a tested Verify
|
|
10
|
+
* button. The plan lives in
|
|
10
11
|
* `skill/start-integration.md`; this tool fills in the inputs.
|
|
11
12
|
*/
|
|
12
13
|
export declare function startIntegrationTool(): RegisteredTool;
|
|
@@ -3,18 +3,22 @@ import { fileURLToPath } from 'node:url';
|
|
|
3
3
|
import { defineTool } from "../../server.js";
|
|
4
4
|
/**
|
|
5
5
|
* Returns the plan a coding agent follows to add Reclaim verification to the
|
|
6
|
-
* developer's app, from sign-in
|
|
6
|
+
* developer's app, from sign-in and a working proof to a tested Verify
|
|
7
|
+
* button. The plan lives in
|
|
7
8
|
* `skill/start-integration.md`; this tool fills in the inputs.
|
|
8
9
|
*/
|
|
9
10
|
export function startIntegrationTool() {
|
|
10
11
|
return defineTool({
|
|
11
12
|
name: 'start_integration',
|
|
12
13
|
description: 'Returns a step-by-step plan for adding Reclaim verification to the '
|
|
13
|
-
+ 'current codebase: sign in,
|
|
14
|
-
+ '
|
|
15
|
-
+ '
|
|
16
|
-
+ '
|
|
17
|
-
+ '
|
|
14
|
+
+ 'current codebase: sign in to Builder, attach the browser, capture, '
|
|
15
|
+
+ 'and prove the provider first, then set up the app (session route, '
|
|
16
|
+
+ 'callback, Verify button, local event proxy) after the proof or '
|
|
17
|
+
+ 'while waiting on the developer, bootstrapping from the '
|
|
18
|
+
+ 'builder-example repository when there is no app yet, then wire '
|
|
19
|
+
+ 'the provider and test. '
|
|
20
|
+
+ 'Call it first when a developer wants their users to prove '
|
|
21
|
+
+ 'something, and follow the plan to the end. Changes nothing itself.',
|
|
18
22
|
inputSchema: {
|
|
19
23
|
type: 'object',
|
|
20
24
|
required: ['goal'],
|
|
@@ -1,14 +1,52 @@
|
|
|
1
1
|
import type { ReclaimClient } from '@reclaimprotocol/client/api';
|
|
2
2
|
import { type RegisteredTool } from '../../server.ts';
|
|
3
|
-
|
|
3
|
+
type AuthToolName = 'reclaim_authenticate' | 'authenticate_builder';
|
|
4
|
+
/** Whether the browser launcher started, and why not when it didn't. */
|
|
5
|
+
export type BrowserLaunch = {
|
|
6
|
+
opened: boolean;
|
|
7
|
+
reason?: string;
|
|
8
|
+
};
|
|
9
|
+
export type PendingSignIn = {
|
|
10
|
+
status: 'PENDING';
|
|
11
|
+
signInUrl: string;
|
|
12
|
+
browserOpened: boolean;
|
|
13
|
+
reason?: string;
|
|
14
|
+
/** ISO timestamp when `signInUrl` stops working. */
|
|
15
|
+
expiresAt: string;
|
|
16
|
+
};
|
|
17
|
+
export type SignInOutcome = {
|
|
18
|
+
status: 'AUTHENTICATED';
|
|
19
|
+
expiresAt: string;
|
|
20
|
+
} | {
|
|
21
|
+
status: 'FAILED';
|
|
22
|
+
reason: string;
|
|
23
|
+
};
|
|
24
|
+
export declare function authenticateTool(client: ReclaimClient, name?: AuthToolName): RegisteredTool;
|
|
25
|
+
export declare function waitForSignInTool(client: ReclaimClient, authToolName?: AuthToolName): RegisteredTool;
|
|
4
26
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* browser
|
|
9
|
-
*
|
|
10
|
-
* validation (including a denied/failed login surfacing as
|
|
11
|
-
* `AuthorizationResponseError`) — this function only wires those calls
|
|
12
|
-
* together and owns the loopback server (no library spins that up for you).
|
|
27
|
+
* Start a sign-in and return its link without waiting for the developer. A
|
|
28
|
+
* sign-in already pending for `client` is returned as is rather than
|
|
29
|
+
* replaced. The flow finishes in the background: the loopback server keeps
|
|
30
|
+
* listening until the browser redirects back or the link expires, and on
|
|
31
|
+
* success caches the session and activates it on `client`.
|
|
13
32
|
*/
|
|
14
|
-
export declare function
|
|
33
|
+
export declare function startSignIn(client: ReclaimClient, openBrowserFn?: (url: string) => Promise<BrowserLaunch>): Promise<PendingSignIn>;
|
|
34
|
+
/**
|
|
35
|
+
* Wait up to `timeoutMs` for `client`'s sign-in to finish. Reports PENDING
|
|
36
|
+
* (with the link again) if it's still open when the wait runs out.
|
|
37
|
+
*/
|
|
38
|
+
export declare function waitForSignIn(client: ReclaimClient, timeoutMs: number): Promise<PendingSignIn | SignInOutcome | {
|
|
39
|
+
status: 'NOT_STARTED';
|
|
40
|
+
}>;
|
|
41
|
+
/**
|
|
42
|
+
* Try to open `url` in the system browser. Never writes to stdout (it carries
|
|
43
|
+
* MCP JSON-RPC); the URL goes to stderr for a developer watching the logs.
|
|
44
|
+
* On Linux without a display server it doesn't try. Otherwise a launcher
|
|
45
|
+
* that errors or exits non-zero within a short grace window counts as not
|
|
46
|
+
* opened.
|
|
47
|
+
*/
|
|
48
|
+
export declare function openBrowser(url: string, { env, platform }?: {
|
|
49
|
+
env?: NodeJS.ProcessEnv | undefined;
|
|
50
|
+
platform?: NodeJS.Platform | undefined;
|
|
51
|
+
}): Promise<BrowserLaunch>;
|
|
52
|
+
export {};
|