@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
- const next = await connect(mode, parsed, persisted, builderClient, dependencies);
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.21",
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.21",
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",
@@ -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
 
@@ -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. Obtain an `orgId` with `list_builder_organizations` in old-devtools mode or the generated `list_orgs` tool in Builder mode. If Builder answers 401, authenticate with `authenticate_builder` in old-devtools mode or the existing `authenticate` flow in Builder mode, then retry. 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.
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?.()