@reclaimprotocol/agent 0.1.27 → 0.1.29

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 (92) hide show
  1. package/README.md +5 -5
  2. package/lib/authoring/tools.js +2 -1
  3. package/lib/consts.d.ts +1 -1
  4. package/lib/consts.js +1 -1
  5. package/lib/live/tunnel.d.ts +4 -0
  6. package/lib/live/tunnel.js +21 -12
  7. package/lib/mcp/api/operations.gen.d.ts +8 -8
  8. package/lib/mcp/api/operations.gen.js +339 -581
  9. package/lib/mcp/api/tools.d.ts +1 -1
  10. package/lib/mcp/instructions.js +7 -3
  11. package/lib/mcp/remap_errors.js +9 -5
  12. package/lib/mcp/start.js +1 -1
  13. package/lib/mcp/tools/agent/attach.d.ts +2 -2
  14. package/lib/mcp/tools/agent/attach.js +4 -0
  15. package/lib/mcp/tools/agent/build.d.ts +1 -1
  16. package/lib/mcp/tools/agent/live-view-url.d.ts +2 -0
  17. package/lib/mcp/tools/agent/live-view-url.js +11 -0
  18. package/lib/mcp/tools/agent/live-view.d.ts +4 -2
  19. package/lib/mcp/tools/agent/live-view.js +42 -39
  20. package/lib/mcp/tools/agent/propose.js +10 -4
  21. package/lib/mcp/tools/agent/publish.d.ts +1 -1
  22. package/lib/mcp/tools/agent/publish.js +49 -26
  23. package/lib/mcp/tools/agent/shared.js +0 -9
  24. package/lib/mcp/tools/authenticate/authenticate.d.ts +1 -1
  25. package/lib/mcp/tools/authenticate/build.d.ts +1 -1
  26. package/lib/mcp/tools/authenticate/builder-access.d.ts +1 -1
  27. package/lib/mcp/tools/verification/result.js +12 -13
  28. package/lib/old/login-cdp.d.ts +17 -6
  29. package/lib/old/login-cdp.js +28 -11
  30. package/lib/old/to-register.d.ts +6 -0
  31. package/lib/old/to-register.js +35 -5
  32. package/lib/old/tools/authenticate.d.ts +5 -4
  33. package/lib/old/tools/authenticate.js +9 -5
  34. package/lib/old/tools/publish.d.ts +2 -2
  35. package/lib/old/tools/publish.js +47 -21
  36. package/lib/proof/attestor-auth.d.ts +13 -0
  37. package/lib/proof/attestor-auth.js +16 -0
  38. package/lib/proof/attestor.d.ts +7 -4
  39. package/lib/proof/attestor.js +7 -4
  40. package/lib/proof/index.d.ts +1 -0
  41. package/lib/proof/index.js +1 -0
  42. package/lib/proof/pod-prover.d.ts +2 -0
  43. package/lib/proof/pod-prover.js +5 -5
  44. package/lib/provider/injection-doc.d.ts +2 -0
  45. package/lib/provider/injection-doc.js +7 -1
  46. package/lib/provider/post-publish-browser.d.ts +12 -0
  47. package/lib/provider/post-publish-browser.js +40 -0
  48. package/lib/provider/to-version.d.ts +19 -7
  49. package/lib/provider/to-version.js +67 -25
  50. package/lib/tools/registry.d.ts +1 -1
  51. package/lib/tools/registry.js +7 -4
  52. package/package.json +2 -2
  53. package/skill/SKILL.builder.md +118 -13
  54. package/skill/SKILL.common.md +30 -19
  55. package/skill/SKILL.old.md +22 -12
  56. package/skill/builder-mode.md +19 -9
  57. package/skill/community-contributions.md +108 -0
  58. package/skill/hash-validation.md +8 -5
  59. package/skill/interception.md +35 -22
  60. package/skill/old-mode.md +11 -5
  61. package/skill/user-script.md +41 -10
  62. package/src/authoring/tools.ts +2 -1
  63. package/src/consts.ts +1 -2
  64. package/src/live/tunnel.ts +28 -14
  65. package/src/mcp/api/operations.gen.ts +341 -585
  66. package/src/mcp/api/tools.ts +1 -1
  67. package/src/mcp/instructions.ts +7 -3
  68. package/src/mcp/remap_errors.ts +9 -7
  69. package/src/mcp/start.ts +1 -1
  70. package/src/mcp/tools/agent/attach.ts +6 -2
  71. package/src/mcp/tools/agent/build.ts +1 -1
  72. package/src/mcp/tools/agent/live-view-url.ts +13 -0
  73. package/src/mcp/tools/agent/live-view.ts +44 -39
  74. package/src/mcp/tools/agent/propose.ts +10 -4
  75. package/src/mcp/tools/agent/publish.ts +63 -28
  76. package/src/mcp/tools/agent/shared.ts +5 -0
  77. package/src/mcp/tools/authenticate/authenticate.ts +1 -1
  78. package/src/mcp/tools/authenticate/build.ts +1 -1
  79. package/src/mcp/tools/authenticate/builder-access.ts +1 -1
  80. package/src/mcp/tools/verification/result.ts +11 -13
  81. package/src/old/login-cdp.ts +38 -11
  82. package/src/old/to-register.ts +56 -7
  83. package/src/old/tools/authenticate.ts +9 -5
  84. package/src/old/tools/publish.ts +64 -22
  85. package/src/proof/attestor-auth.ts +33 -0
  86. package/src/proof/attestor.ts +14 -8
  87. package/src/proof/index.ts +4 -0
  88. package/src/proof/pod-prover.ts +7 -5
  89. package/src/provider/injection-doc.ts +9 -1
  90. package/src/provider/post-publish-browser.ts +56 -0
  91. package/src/provider/to-version.ts +104 -27
  92. package/src/tools/registry.ts +12 -9
@@ -1,8 +1,10 @@
1
- import type { ReclaimClient } from '@reclaimprotocol/client'
1
+ import { badRequest, conflict } from '@hapi/boom'
2
+ import type { ReclaimClient } from '@reclaimprotocol/client/api'
2
3
  import type {
3
4
  CreateProviderVersionRequest,
4
5
  ProviderVersionRef,
5
6
  } from '@reclaimprotocol/client/openapi'
7
+ import assert from 'node:assert'
6
8
  import type {
7
9
  DraftResponseMatch,
8
10
  HttpMethod,
@@ -65,6 +67,9 @@ export interface AllowedJsRequest extends DraftRequest {
65
67
  export interface CreateVersionOptions {
66
68
  notes?: string
67
69
  version?: ProviderVersionRef
70
+ /** Complete context schema for this new immutable version. When omitted,
71
+ * it is derived from `{{context.<name>}}` placeholders. */
72
+ requiredContext?: CreateProviderVersionRequest['requiredContext']
68
73
  /** JS injected before every page load (`webSettings.jsUserScripts`). */
69
74
  jsUserScripts?: string
70
75
  /** Requests the injection script may fire, as `RequestSelectionTemplate`s. */
@@ -107,7 +112,8 @@ const CONTEXT_PARAM_RE = /\{\{context\.([A-Za-z_][A-Za-z0-9_]*)\}\}/g
107
112
  * injected requests and the injection script) — mechanical, so a published
108
113
  * recipe can never reference a context value the Builder doesn't require.
109
114
  * Returns undefined when nothing references context (the field is optional).
110
- * Authors can refine types/descriptions in the version editor.
115
+ * Authors can pass a complete schema when creating the new version to refine
116
+ * types or descriptions. Never edit a version in place after creation.
111
117
  *
112
118
  * A SECRET-named context param (see `classifyParamName`) is NOT rejected here
113
119
  * even when it's templated into the URL/geoLocation — write-redaction can
@@ -211,12 +217,13 @@ export function providerToCreateVersionRequest(
211
217
  opts: CreateVersionOptions = {},
212
218
  ): CreateProviderVersionRequest {
213
219
  const {
214
- notes, version, jsUserScripts, allowedJsRequests, interceptorOptions,
220
+ notes, version, requiredContext: requestedContext, jsUserScripts,
221
+ allowedJsRequests, interceptorOptions,
215
222
  } = opts
216
- const requiredContext = deriveRequiredContext(providers, {
217
- allowedJsRequests,
218
- jsUserScripts,
219
- })
223
+ const requiredContext = requestedContext ?? deriveRequiredContext(
224
+ providers,
225
+ { allowedJsRequests, jsUserScripts },
226
+ )
220
227
 
221
228
  // Each injected request carries its template flags (default true/true per
222
229
  // RequestSelectionTemplate) on top of the shared request shape.
@@ -282,36 +289,106 @@ export function providerToCreateVersionRequest(
282
289
  }
283
290
 
284
291
  /**
285
- * Fetch the current versions for a provider and return the next version above
286
- * the highest existing one (bumping the patch number), or 1.0.0 when the
287
- * provider has no versions yet. A failed lookup propagates — silently
288
- * resetting to 1.0.0 would re-publish a v3 provider as v1.0.0.
292
+ * Fetch every current version and resolve a strictly newer immutable version.
293
+ * The default bump is patch. Callers can request major/minor/patch or provide
294
+ * an exact version; an exact version must be higher than every existing one.
295
+ * A failed lookup propagates — silently resetting to 1.0.0 could collide with
296
+ * an existing version.
289
297
  */
290
298
  export async function nextVersion(
291
299
  client: ReclaimClient,
292
300
  providerId: string,
301
+ bump: VersionBump = 'patch',
293
302
  ): Promise<ProviderVersionRef> {
294
- const list = (await client.call('ListProviderVersions', {
295
- params: { providerId },
296
- query: {},
297
- })) as { items?: Array<{ version: ProviderVersionRef }> }
303
+ return bumpVersion(await listVersions(client, providerId), bump)
304
+ }
305
+
306
+ export type VersionBump = 'major' | 'minor' | 'patch'
298
307
 
299
- if(!list.items?.length) {
308
+ /** Resolve either an explicit version or a requested semantic bump. */
309
+ export async function resolveNewVersion(
310
+ client: ReclaimClient,
311
+ providerId: string,
312
+ input: { version?: ProviderVersionRef, bump?: VersionBump } = {},
313
+ ): Promise<ProviderVersionRef> {
314
+ assert(
315
+ !(input.version && input.bump),
316
+ badRequest('Pass either `version` or `bump`, not both.'),
317
+ )
318
+ const versions = await listVersions(client, providerId)
319
+ if(!input.version) {
320
+ return bumpVersion(versions, input.bump ?? 'patch')
321
+ }
322
+
323
+ const highest = highestVersion(versions)
324
+ assert(
325
+ !highest || compareVersions(input.version, highest) > 0,
326
+ conflict(
327
+ `Version ${formatVersion(input.version)} must be higher than the ` +
328
+ `current highest version ${highest ? formatVersion(highest) : 'none'}.`,
329
+ ),
330
+ )
331
+ return input.version
332
+ }
333
+
334
+ export function bumpVersion(
335
+ versions: ProviderVersionRef[],
336
+ bump: VersionBump = 'patch',
337
+ ): ProviderVersionRef {
338
+ const highest = highestVersion(versions)
339
+ if(!highest) {
300
340
  return { major: 1, minor: 0, patch: 0 }
301
341
  }
302
342
 
303
- // Find the highest version and bump its patch
304
- let hi = list.items[0].version
305
- for(const item of list.items) {
306
- const v = item.version
307
- if(
308
- v.major > hi.major ||
309
- (v.major === hi.major && v.minor > hi.minor) ||
310
- (v.major === hi.major && v.minor === hi.minor && v.patch > hi.patch)
311
- ) {
312
- hi = v
343
+ switch (bump) {
344
+ case 'major':
345
+ return { major: highest.major + 1, minor: 0, patch: 0 }
346
+ case 'minor':
347
+ return { major: highest.major, minor: highest.minor + 1, patch: 0 }
348
+ case 'patch':
349
+ return {
350
+ major: highest.major,
351
+ minor: highest.minor,
352
+ patch: highest.patch + 1,
353
+ }
354
+ }
355
+ }
356
+
357
+ async function listVersions(
358
+ client: ReclaimClient,
359
+ providerId: string,
360
+ ): Promise<ProviderVersionRef[]> {
361
+ const versions: ProviderVersionRef[] = []
362
+ let cursor: string | undefined
363
+ do {
364
+ const { data } = await client.call('ListProviderVersions', {
365
+ params: { providerId },
366
+ query: { cursor },
367
+ })
368
+ versions.push(...data.items.map((item) => item.version))
369
+ cursor = data.nextPageCursor
370
+ } while(cursor)
371
+
372
+ return versions
373
+ }
374
+
375
+ function highestVersion(
376
+ versions: ProviderVersionRef[],
377
+ ): ProviderVersionRef | undefined {
378
+ let highest: ProviderVersionRef | undefined
379
+ for(const version of versions) {
380
+ if(!highest || compareVersions(version, highest) > 0) {
381
+ highest = version
313
382
  }
314
383
  }
315
384
 
316
- return { major: hi.major, minor: hi.minor, patch: hi.patch + 1 }
385
+ return highest
386
+ }
387
+
388
+ function compareVersions(a: ProviderVersionRef, b: ProviderVersionRef) {
389
+ return a.major - b.major || a.minor - b.minor || a.patch - b.patch
390
+ }
391
+
392
+ function formatVersion(version: ProviderVersionRef) {
393
+ return `${version.major}.${version.minor}.${version.patch}`
317
394
  }
@@ -11,8 +11,8 @@
11
11
  * glue (`registerToolList` onto an `McpServer`) stays in `mcp/server.ts`, which
12
12
  * re-exports this primitive for the MCP-side tool files.
13
13
  */
14
- import { type Boom, isBoom } from '@hapi/boom'
15
- import type { ProblemDetails } from '@reclaimprotocol/client'
14
+ import { isBoom } from '@hapi/boom'
15
+ import { isProblemDetails, isProblemError } from '@reclaimprotocol/client/api'
16
16
  import type { JSONSchema } from 'zod/v4/core'
17
17
  import { toZod } from '../mcp/api/to-zod.ts'
18
18
 
@@ -59,8 +59,13 @@ export function defineTool<TArgs>(
59
59
  * else falls back to the plain message.
60
60
  */
61
61
  export function errorAsToolText(err: unknown): string {
62
+ if(isProblemError(err)) {
63
+ const detail = err.data.detail
64
+ return detail ? `${err.message}: ${detail}` : err.message
65
+ }
66
+
62
67
  if(isBoom(err) && err.output?.statusCode) {
63
- const detail = (err as Boom<ProblemDetails>).data?.detail
68
+ const detail = isProblemDetails(err.data) ? err.data.detail : undefined
64
69
  return detail ? `${err.message}: ${detail}` : err.message
65
70
  }
66
71
 
@@ -80,7 +85,7 @@ export function extendTool(
80
85
  tool: RegisteredTool,
81
86
  extra: {
82
87
  description?: string
83
- properties?: Record<string, unknown>
88
+ properties?: JSONSchema.ObjectSchema['properties']
84
89
  required?: string[]
85
90
  },
86
91
  ): RegisteredTool {
@@ -89,17 +94,15 @@ export function extendTool(
89
94
  ...(base.inputSchema.required ?? []),
90
95
  ...(extra.required ?? []),
91
96
  ]
92
- // The merged `properties` spread carries the base's untyped property values,
93
- // which don't structurally match ObjectSchema's strict per-property schema
94
- // type — assert the merged shape.
95
- const inputSchema = {
97
+ // Keep the merged schema checked against Zod's JSON Schema representation.
98
+ const inputSchema: JSONSchema.ObjectSchema = {
96
99
  ...base.inputSchema,
97
100
  properties: {
98
101
  ...base.inputSchema.properties,
99
102
  ...extra.properties,
100
103
  },
101
104
  ...(required.length ? { required } : {}),
102
- } as unknown as JSONSchema.ObjectSchema
105
+ }
103
106
  return {
104
107
  definition: {
105
108
  name: base.name,