@reclaimprotocol/agent 0.1.21 → 0.1.22
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.
|
@@ -18,6 +18,11 @@ export function attachTool(state, builderClient, name = 'attach_browser', before
|
|
|
18
18
|
+ 'port), builder (quota-accounted Popcorn browser with a '
|
|
19
19
|
+ 'shareable live view), or custom (caller-supplied CDP '
|
|
20
20
|
+ 'websocket). '
|
|
21
|
+
+ 'For builder mode, orgId may be omitted: it auto-resolves to '
|
|
22
|
+
+ 'the account\'s only organization, or — if there is more '
|
|
23
|
+
+ 'than one — returns needsChoice with the full list so the '
|
|
24
|
+
+ 'caller can ask the developer which to use and re-call with '
|
|
25
|
+
+ 'that orgId. '
|
|
21
26
|
+ 'Builder and custom CDP credentials are held in memory and never '
|
|
22
27
|
+ 'returned.',
|
|
23
28
|
inputSchema: {
|
|
@@ -52,7 +57,30 @@ export function attachTool(state, builderClient, name = 'attach_browser', before
|
|
|
52
57
|
configPath: defaultConfigPath(),
|
|
53
58
|
};
|
|
54
59
|
}
|
|
55
|
-
|
|
60
|
+
let orgId = parsed.orgId;
|
|
61
|
+
if (mode === 'builder' && !orgId) {
|
|
62
|
+
assert(builderClient, badRequest('Builder browser service is unavailable'));
|
|
63
|
+
const { data } = await builderClient.call('ListOrgs', { query: {} });
|
|
64
|
+
const orgs = data.items ?? [];
|
|
65
|
+
assert(orgs.length, badRequest('No organizations available for this account — create one '
|
|
66
|
+
+ 'first, or authenticate as a user who belongs to one.'));
|
|
67
|
+
if (orgs.length > 1) {
|
|
68
|
+
return {
|
|
69
|
+
needsChoice: true,
|
|
70
|
+
message: 'This account belongs to more than one organization. Ask '
|
|
71
|
+
+ 'the developer which one to use, then re-call '
|
|
72
|
+
+ 'attach_browser with mode "builder" and that orgId.',
|
|
73
|
+
organizations: orgs.map((o) => ({
|
|
74
|
+
id: o.id,
|
|
75
|
+
name: o.name,
|
|
76
|
+
kind: o.kind,
|
|
77
|
+
status: o.status,
|
|
78
|
+
})),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
orgId = orgs[0].id;
|
|
82
|
+
}
|
|
83
|
+
const next = await connect(mode, { ...parsed, orgId }, persisted, builderClient, dependencies);
|
|
56
84
|
try {
|
|
57
85
|
await beforeReplace?.();
|
|
58
86
|
await disposeAttached(state);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reclaimprotocol/agent",
|
|
3
3
|
"title": "Reclaim Agent",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.22",
|
|
5
5
|
"description": "Reclaim Protocol's tools for agents — Reclaim Protocol lets your app verify **data points** about its users — a follower count, an account balance, an order history. This package gives your AI coding agent the tools to **find, build, test and fix the _data verification providers_** (the recipes that verify a data point) by inspecting and replaying captured requests, checking sessions, evaluate proofs, publishing updates, and much more.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./lib/index.js",
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
84
84
|
"@noble/hashes": "^2.2.0",
|
|
85
85
|
"@reclaimprotocol/attestor-core": "^5.0.8",
|
|
86
|
-
"@reclaimprotocol/client": "0.1.
|
|
86
|
+
"@reclaimprotocol/client": "0.1.22",
|
|
87
87
|
"@reclaimprotocol/tls": "^0.1.3",
|
|
88
88
|
"chrome-remote-interface": "^0.33.0",
|
|
89
89
|
"domhandler": "^6.0.0",
|
package/skill/SKILL.builder.md
CHANGED
|
@@ -173,7 +173,9 @@ The value of any parameter marked secret is not included in the final proof, omi
|
|
|
173
173
|
|
|
174
174
|
When done, tell the developer the version is live (PRIVATE) or submitted for review (PUBLIC), and that they can integrate using the `providerId`.
|
|
175
175
|
|
|
176
|
-
- **If a browser is still attached**, `create_provider_version_from_capture`'s response carries a `_notes` reminder about it. Surface that to the dev and ask whether they want to keep the session open for further edits — only call `dispose_browser` once they confirm they're done. Never close it unprompted; a `builder`-mode session is quota-accounted, but the dev may still be mid-workflow.
|
|
176
|
+
- **If a browser is still attached**, `create_provider_version_from_capture`'s response carries a `_notes` reminder about it. Surface that to the dev and ask whether they want to keep the session open for further edits — only call `dispose_browser` once they confirm they're done. Never close it unprompted; a `builder`-mode session is quota-accounted, but the dev may still be mid-workflow. Closing remote browsers
|
|
177
|
+
soon is also important to avoid wasting resources. So as best
|
|
178
|
+
practise, close remote browser session when not needed anymore.
|
|
177
179
|
|
|
178
180
|
<!-- common: concerns-section -->
|
|
179
181
|
|
package/skill/SKILL.common.md
CHANGED
|
@@ -17,7 +17,7 @@ You drive the browser through the capture → draft → replay → prove loop us
|
|
|
17
17
|
1. **Attach.** Call `attach_browser`. If it returns `needsChoice: true`, ask the dev which browser source they want:
|
|
18
18
|
- `dedicated` — agent auto-launches Chrome with a dedicated profile under `~/.reclaim/chrome-profile`. Easiest local path; works out of the box.
|
|
19
19
|
- `attach` — connect to a Chrome the dev is already running. **Important Chrome 136+ gotcha:** the dev's Chrome must be launched with BOTH `--remote-debugging-port=9222` AND `--user-data-dir=<some-non-default-path>`. Since Chrome 136 (May 2025), the debug-port flag is silently ignored when the default user profile is in use. If `attach` fails, tell them this verbatim and offer to switch to `dedicated`.
|
|
20
|
-
- `builder` — allocate a quota-accounted remote Popcorn browser.
|
|
20
|
+
- `builder` — allocate a quota-accounted remote Popcorn browser. If Builder answers 401, authenticate with `authenticate_builder` in old-devtools mode or the existing `authenticate` flow in Builder mode, then retry. You can omit `orgId` and call `attach_browser` directly: it auto-resolves to the account's only organization, or — if the account belongs to more than one — comes back with `needsChoice: true` and an `organizations` list; **ask the dev which one to use** (don't guess or default to the first) and re-call `attach_browser` with that `orgId`. (`list_builder_organizations` in old-devtools mode / `list_orgs` in Builder mode still work directly if you want the list up front instead.) Return the FULL `liveViewUrl` to the dev verbatim — on its own line, never abbreviated, elided, or wrapped in prose that truncates it — so it stays one clean, copy-pasteable string; they'll share it with the volunteer operating the browser. This works in both publishing modes and consumes one VERIFICATION-pool use under the chosen organization's normal plan restrictions.
|
|
21
21
|
- `custom` — connect to a `ws://` or `wss://` CDP URL supplied by the dev. The URL is a credential: never repeat it, log it, or persist it. An optional `liveViewUrl` may be returned — if so, share it FULL and verbatim, same as `builder` above.
|
|
22
22
|
|
|
23
23
|
Re-call with the chosen `mode` and its required fields.
|
|
@@ -70,6 +70,11 @@ export function attachTool(
|
|
|
70
70
|
+ 'port), builder (quota-accounted Popcorn browser with a '
|
|
71
71
|
+ 'shareable live view), or custom (caller-supplied CDP '
|
|
72
72
|
+ 'websocket). '
|
|
73
|
+
+ 'For builder mode, orgId may be omitted: it auto-resolves to '
|
|
74
|
+
+ 'the account\'s only organization, or — if there is more '
|
|
75
|
+
+ 'than one — returns needsChoice with the full list so the '
|
|
76
|
+
+ 'caller can ask the developer which to use and re-call with '
|
|
77
|
+
+ 'that orgId. '
|
|
73
78
|
+ 'Builder and custom CDP credentials are held in memory and never '
|
|
74
79
|
+ 'returned.',
|
|
75
80
|
inputSchema: {
|
|
@@ -107,8 +112,42 @@ export function attachTool(
|
|
|
107
112
|
}
|
|
108
113
|
}
|
|
109
114
|
|
|
115
|
+
let orgId = parsed.orgId
|
|
116
|
+
if(mode === 'builder' && !orgId) {
|
|
117
|
+
assert(
|
|
118
|
+
builderClient,
|
|
119
|
+
badRequest('Builder browser service is unavailable'),
|
|
120
|
+
)
|
|
121
|
+
const { data } = await builderClient.call('ListOrgs', { query: {} })
|
|
122
|
+
const orgs = data.items ?? []
|
|
123
|
+
assert(
|
|
124
|
+
orgs.length,
|
|
125
|
+
badRequest(
|
|
126
|
+
'No organizations available for this account — create one '
|
|
127
|
+
+ 'first, or authenticate as a user who belongs to one.',
|
|
128
|
+
),
|
|
129
|
+
)
|
|
130
|
+
if(orgs.length > 1) {
|
|
131
|
+
return {
|
|
132
|
+
needsChoice: true,
|
|
133
|
+
message:
|
|
134
|
+
'This account belongs to more than one organization. Ask '
|
|
135
|
+
+ 'the developer which one to use, then re-call '
|
|
136
|
+
+ 'attach_browser with mode "builder" and that orgId.',
|
|
137
|
+
organizations: orgs.map((o) => ({
|
|
138
|
+
id: o.id,
|
|
139
|
+
name: o.name,
|
|
140
|
+
kind: o.kind,
|
|
141
|
+
status: o.status,
|
|
142
|
+
})),
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
orgId = orgs[0].id
|
|
147
|
+
}
|
|
148
|
+
|
|
110
149
|
const next = await connect(
|
|
111
|
-
mode, parsed, persisted, builderClient, dependencies,
|
|
150
|
+
mode, { ...parsed, orgId }, persisted, builderClient, dependencies,
|
|
112
151
|
)
|
|
113
152
|
try {
|
|
114
153
|
await beforeReplace?.()
|