@reclaimprotocol/agent 0.1.5 → 0.1.6

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 (117) hide show
  1. package/lib/authoring/backend.d.ts +0 -24
  2. package/lib/authoring/find.d.ts +3 -0
  3. package/lib/authoring/find.js +54 -0
  4. package/lib/authoring/index.d.ts +3 -3
  5. package/lib/authoring/index.js +4 -3
  6. package/lib/authoring/propose.d.ts +3 -0
  7. package/lib/authoring/propose.js +109 -0
  8. package/lib/authoring/replay.d.ts +10 -0
  9. package/lib/authoring/replay.js +34 -0
  10. package/lib/authoring/tools.d.ts +13 -6
  11. package/lib/authoring/tools.js +108 -293
  12. package/lib/authoring/util.d.ts +27 -0
  13. package/lib/authoring/util.js +21 -0
  14. package/lib/consts.d.ts +6 -1
  15. package/lib/consts.js +9 -2
  16. package/lib/mcp/server.d.ts +2 -41
  17. package/lib/mcp/server.js +6 -34
  18. package/lib/mcp/start.js +4 -2
  19. package/lib/mcp/tools/agent/analyze.js +3 -3
  20. package/lib/mcp/tools/agent/build.d.ts +4 -4
  21. package/lib/mcp/tools/agent/build.js +13 -15
  22. package/lib/mcp/tools/agent/capture.d.ts +13 -1
  23. package/lib/mcp/tools/agent/capture.js +18 -85
  24. package/lib/mcp/tools/agent/eval.d.ts +5 -2
  25. package/lib/mcp/tools/agent/eval.js +11 -121
  26. package/lib/mcp/tools/agent/find.d.ts +10 -3
  27. package/lib/mcp/tools/agent/find.js +25 -31
  28. package/lib/mcp/tools/agent/proof.d.ts +13 -3
  29. package/lib/mcp/tools/agent/proof.js +81 -132
  30. package/lib/mcp/tools/agent/propose.d.ts +10 -9
  31. package/lib/mcp/tools/agent/propose.js +87 -64
  32. package/lib/mcp/tools/agent/replay.d.ts +10 -3
  33. package/lib/mcp/tools/agent/replay.js +29 -36
  34. package/lib/mcp/tools/agent/session.d.ts +1 -3
  35. package/lib/mcp/tools/agent/session.js +5 -5
  36. package/lib/mcp/tools/agent/shared.d.ts +5 -3
  37. package/lib/mcp/tools/agent/shared.js +29 -19
  38. package/lib/old/client.d.ts +35 -0
  39. package/lib/old/client.js +18 -0
  40. package/lib/old/login-cdp.d.ts +24 -5
  41. package/lib/old/login-cdp.js +29 -15
  42. package/lib/old/sdk-client.d.ts +39 -0
  43. package/lib/old/sdk-client.js +85 -0
  44. package/lib/old/to-register.d.ts +69 -0
  45. package/lib/old/to-register.js +52 -2
  46. package/lib/old/tools/authenticate.js +3 -7
  47. package/lib/old/tools/build.d.ts +6 -1
  48. package/lib/old/tools/build.js +11 -1
  49. package/lib/old/tools/get-provider-info.d.ts +16 -0
  50. package/lib/old/tools/get-provider-info.js +73 -0
  51. package/lib/old/tools/get-version-config.d.ts +17 -0
  52. package/lib/old/tools/get-version-config.js +47 -0
  53. package/lib/old/tools/publish.js +189 -2
  54. package/lib/old/tools/update-provider-metadata.d.ts +16 -0
  55. package/lib/old/tools/update-provider-metadata.js +61 -0
  56. package/lib/proof/attestor.d.ts +6 -3
  57. package/lib/proof/attestor.js +10 -1
  58. package/lib/proof/debug-response-dump.d.ts +4 -0
  59. package/lib/proof/debug-response-dump.js +55 -0
  60. package/lib/proof/patch-domhandler.d.ts +1 -0
  61. package/lib/proof/patch-domhandler.js +59 -0
  62. package/lib/proof/zk-files.js +7 -6
  63. package/lib/provider/dom-xpath.d.ts +17 -0
  64. package/lib/provider/dom-xpath.js +187 -0
  65. package/lib/provider/draft.d.ts +30 -2
  66. package/lib/provider/draft.js +117 -28
  67. package/lib/provider/index.d.ts +4 -0
  68. package/lib/provider/index.js +7 -0
  69. package/lib/provider/injection-doc.js +6 -0
  70. package/lib/provider/matcher.d.ts +17 -20
  71. package/lib/provider/matcher.js +394 -280
  72. package/lib/provider/schema.d.ts +7 -5
  73. package/lib/tools/registry.d.ts +14 -0
  74. package/lib/tools/registry.js +32 -0
  75. package/package.json +9 -1
  76. package/skill/SKILL.builder.md +42 -23
  77. package/skill/SKILL.old.md +6 -2
  78. package/skill/builder-mode.md +1 -1
  79. package/skill/injection-api.md +117 -0
  80. package/src/authoring/backend.ts +98 -0
  81. package/src/authoring/index.ts +20 -0
  82. package/src/authoring/tools.ts +273 -0
  83. package/src/authoring/util.ts +42 -0
  84. package/src/consts.ts +15 -2
  85. package/src/mcp/server.ts +11 -78
  86. package/src/mcp/start.ts +4 -1
  87. package/src/mcp/tools/agent/analyze.ts +3 -3
  88. package/src/mcp/tools/agent/build.ts +13 -21
  89. package/src/mcp/tools/agent/capture.ts +31 -115
  90. package/src/mcp/tools/agent/eval.ts +19 -155
  91. package/src/mcp/tools/agent/find.ts +33 -36
  92. package/src/mcp/tools/agent/proof.ts +87 -160
  93. package/src/mcp/tools/agent/propose.ts +93 -85
  94. package/src/mcp/tools/agent/replay.ts +32 -42
  95. package/src/mcp/tools/agent/session.ts +4 -5
  96. package/src/mcp/tools/agent/shared.ts +152 -0
  97. package/src/old/client.ts +56 -0
  98. package/src/old/login-cdp.ts +29 -23
  99. package/src/old/sdk-client.ts +105 -0
  100. package/src/old/to-register.ts +98 -6
  101. package/src/old/tools/authenticate.ts +3 -11
  102. package/src/old/tools/build.ts +12 -0
  103. package/src/old/tools/get-provider-info.ts +91 -0
  104. package/src/old/tools/get-version-config.ts +56 -0
  105. package/src/old/tools/publish.ts +244 -1
  106. package/src/old/tools/update-provider-metadata.ts +72 -0
  107. package/src/proof/attestor.ts +16 -4
  108. package/src/proof/debug-response-dump.ts +70 -0
  109. package/src/proof/patch-domhandler.ts +68 -0
  110. package/src/proof/zk-files.ts +7 -6
  111. package/src/provider/dom-xpath.ts +225 -0
  112. package/src/provider/draft.ts +168 -35
  113. package/src/provider/index.ts +8 -0
  114. package/src/provider/injection-doc.ts +6 -0
  115. package/src/provider/matcher.ts +477 -357
  116. package/src/provider/schema.ts +7 -5
  117. package/src/tools/registry.ts +92 -0
@@ -69,27 +69,3 @@ export interface AuthoringBackend {
69
69
  withoutSecrets?: boolean;
70
70
  }): Promise<unknown>;
71
71
  }
72
- /**
73
- * How a host (MCP / cloud) supplies its environment to the shared authoring
74
- * tools, which are authored once with the common `defineTool` primitive and
75
- * built per host by `buildAuthoringTools(host)`:
76
- * - `resolveBackend`: hand back the backend for one call. The MCP resolves it
77
- * from `args.captureId` (multi-session); the cloud returns its one run
78
- * backend.
79
- * - `sessionSchema`: input-schema props merged into EVERY tool (the MCP adds
80
- * `captureId`; the cloud adds nothing — the backend is implicit).
81
- * - `toolExtras`: per-tool schema/description additions (the MCP's rich,
82
- * credential-aware `run_proof` contract).
83
- */
84
- export interface AuthoringHost {
85
- resolveBackend(args: Record<string, unknown>): AuthoringBackend;
86
- sessionSchema?: {
87
- properties: Record<string, unknown>;
88
- required?: string[];
89
- };
90
- toolExtras?: Record<string, {
91
- description?: string;
92
- properties?: Record<string, unknown>;
93
- required?: string[];
94
- }>;
95
- }
@@ -0,0 +1,3 @@
1
+ import { type RegisteredTool } from '../tools/registry.ts';
2
+ import { type ResolveBackend } from './util.ts';
3
+ export declare function findTool(resolveBackend: ResolveBackend): RegisteredTool;
@@ -0,0 +1,54 @@
1
+ /**
2
+ * `find_requests_containing` — search captured responses for any encoding of a
3
+ * value and rank the requests that return it. Authored once as a plain
4
+ * {@link RegisteredTool}; the MCP and cloud loop each pass their own backend
5
+ * resolver (see tools.ts / mcp/tools/agent/shared.ts). Server-side: response
6
+ * bodies stay here, only metadata + a short snippet leave.
7
+ */
8
+ import { normalizeCandidates } from "../provider/normalize.js";
9
+ import { defineTool } from "../tools/registry.js";
10
+ import { objectSchema, publicRequest } from "./util.js";
11
+ export function findTool(resolveBackend) {
12
+ return defineTool({
13
+ name: 'find_requests_containing',
14
+ description: 'Search captured responses for any encoding of `value` (raw, '
15
+ + 'URL/JSON/HTML-escaped, …). Returns a ranked candidate list with '
16
+ + 'the matched variant, score, and a short snippet — used to locate '
17
+ + 'the request that returns a target. Server-side; bodies stay here.',
18
+ inputSchema: objectSchema({ value: { type: 'string' }, limit: { type: 'number' } }, ['value']),
19
+ }, async (args) => {
20
+ const backend = resolveBackend(args);
21
+ const variants = normalizeCandidates(String(args.value));
22
+ const ranked = [];
23
+ for (const r of backend.capture.requests.values()) {
24
+ if (!r.responseBody) {
25
+ continue;
26
+ }
27
+ let hit;
28
+ for (const v of variants) {
29
+ const idx = r.responseBody.indexOf(v);
30
+ if (idx >= 0) {
31
+ const start = Math.max(0, idx - 40);
32
+ const end = Math.min(r.responseBody.length, idx + v.length + 40);
33
+ hit = { snippet: r.responseBody.slice(start, end), variant: v };
34
+ break;
35
+ }
36
+ }
37
+ if (!hit) {
38
+ continue;
39
+ }
40
+ // Prefer JSON responses + smaller bodies (likely API endpoints).
41
+ const score = (r.contentType.includes('json') ? 10 : 0)
42
+ + Math.max(0, 5 - Math.log10(Math.max(r.size, 1)));
43
+ ranked.push({
44
+ ...publicRequest(r),
45
+ matchedVariant: hit.variant,
46
+ snippet: hit.snippet,
47
+ score,
48
+ });
49
+ }
50
+ ranked.sort((a, b) => b.score - a.score);
51
+ const limit = Number(args.limit) || 10;
52
+ return { candidates: ranked.slice(0, limit) };
53
+ });
54
+ }
@@ -1,4 +1,4 @@
1
- export type { AuthoringBackend, AuthoringHost, Draft, DraftStore, ProveOptions, SecretParams, } from './backend.ts';
1
+ export type { AuthoringBackend, Draft, DraftStore, ProveOptions, SecretParams, } from './backend.ts';
2
2
  export { makeDraftStore } from './backend.ts';
3
- export { buildAuthoringTools } from './tools.ts';
4
- export { defineTool, type RegisteredTool, type ToolDefinition, } from '../tools/registry.ts';
3
+ export { authoringTools } from './tools.ts';
4
+ export { defineTool, extendTool, type RegisteredTool, type ToolDefinition, } from '../tools/registry.ts';
@@ -1,5 +1,6 @@
1
1
  export { makeDraftStore } from "./backend.js";
2
- export { buildAuthoringTools } from "./tools.js";
2
+ export { authoringTools } from "./tools.js";
3
3
  // The shared tool primitive — re-exported so consumers (the cloud loop) get the
4
- // RegisteredTool type/`defineTool` without importing the MCP subsystem.
5
- export { defineTool, } from "../tools/registry.js";
4
+ // RegisteredTool type/`defineTool`/`extendTool` without importing the MCP
5
+ // subsystem.
6
+ export { defineTool, extendTool, } from "../tools/registry.js";
@@ -0,0 +1,3 @@
1
+ import { type RegisteredTool } from '../tools/registry.ts';
2
+ import { type ResolveBackend } from './util.ts';
3
+ export declare function proposeTool(resolveBackend: ResolveBackend): RegisteredTool;
@@ -0,0 +1,109 @@
1
+ /**
2
+ * `propose_provider` — draft a provider (recipe + captured secrets) from ONE
3
+ * captured request, one match + redaction per target value. Authored once as a
4
+ * plain {@link RegisteredTool}; hosts pass their own backend resolver. The
5
+ * draft (recipe + real secret header values) is held server-side under an
6
+ * opaque `draftId`; the result carries only the secret-free provider.
7
+ */
8
+ import { draftProvider } from "../provider/draft.js";
9
+ import { OPRF_MAX_BYTES } from "../provider/matcher.js";
10
+ import { verificationWarnings } from "../provider/verification-checks.js";
11
+ import { defineTool } from "../tools/registry.js";
12
+ import { objectSchema } from "./util.js";
13
+ export function proposeTool(resolveBackend) {
14
+ return defineTool({
15
+ name: 'propose_provider',
16
+ description: 'Draft a provider from ONE captured request. Pass `targets` (an '
17
+ + 'array): one entry per value to extract, each with its `value` '
18
+ + '(verbatim) and a distinct `name` (its param). The provider gets '
19
+ + 'one match + redaction per target. Returns a draftId + recipe '
20
+ + '(never secrets). Prefer a SINGLE request holding ALL values. '
21
+ + 'Single-value shorthand: `target` + `name`. Per-target `hash` '
22
+ + 'OPRF-hashes that value.',
23
+ inputSchema: objectSchema({
24
+ requestId: { type: 'string' },
25
+ name: { type: 'string' },
26
+ targets: {
27
+ type: 'array',
28
+ items: {
29
+ type: 'object',
30
+ properties: {
31
+ value: { type: 'string' },
32
+ name: { type: 'string' },
33
+ hash: {
34
+ type: 'string',
35
+ enum: ['oprf-raw', 'oprf', 'oprf-mpc'],
36
+ },
37
+ },
38
+ required: ['value', 'name'],
39
+ },
40
+ },
41
+ target: { type: 'string' },
42
+ hash: { type: 'string', enum: ['oprf-raw', 'oprf', 'oprf-mpc'] },
43
+ }, ['requestId', 'name']),
44
+ }, async (args) => {
45
+ const backend = resolveBackend(args);
46
+ const requestId = String(args.requestId);
47
+ const providerName = String(args.name);
48
+ const defaultHash = args.hash;
49
+ // Explicit multi-value `targets`, else the single `target` shorthand.
50
+ const raw = Array.isArray(args.targets) ? args.targets : [];
51
+ const targets = raw.length
52
+ ? raw.map((t) => {
53
+ const o = t;
54
+ return {
55
+ value: String(o.value),
56
+ name: String(o.name),
57
+ ...(typeof o.hash === 'string'
58
+ ? { hash: o.hash }
59
+ : {}),
60
+ };
61
+ })
62
+ : typeof args.target === 'string'
63
+ ? [{
64
+ value: args.target,
65
+ name: providerName,
66
+ ...(defaultHash ? { hash: defaultHash } : {}),
67
+ }]
68
+ : [];
69
+ if (targets.length === 0) {
70
+ throw new Error('propose_provider needs a `target` value or a non-empty '
71
+ + '`targets` array');
72
+ }
73
+ for (const t of targets) {
74
+ if ((t.hash ?? defaultHash) !== undefined
75
+ && t.value.length > OPRF_MAX_BYTES) {
76
+ throw new Error(`OPRF caps hashed values at ${OPRF_MAX_BYTES} bytes; got `
77
+ + `${t.value.length}-byte "${t.value}". Use a tighter `
78
+ + 'target or drop `hash`.');
79
+ }
80
+ }
81
+ const captured = backend.capture.requests.get(requestId);
82
+ if (!captured) {
83
+ throw new Error(`no captured request ${requestId}`);
84
+ }
85
+ if (!captured.responseBody) {
86
+ throw new Error(`request body unavailable for ${requestId}`);
87
+ }
88
+ const { provider, secretRefs, extractions } = draftProvider(captured, targets, providerName, defaultHash);
89
+ // Materialize the real secret header values for later replay/prove;
90
+ // they stay in the server-side draft, never in this result.
91
+ const secrets = {};
92
+ for (const ref of secretRefs) {
93
+ const real = captured.requestHeaders[ref.name];
94
+ if (real !== undefined) {
95
+ secrets[ref.name] = real;
96
+ }
97
+ }
98
+ const draftId = backend.drafts.put({
99
+ provider, secretRefs, secrets, requestId, extractions,
100
+ });
101
+ const warnings = verificationWarnings(provider);
102
+ return {
103
+ draftId,
104
+ provider,
105
+ secretRefs,
106
+ ...(warnings.length ? { verificationWarnings: warnings } : {}),
107
+ };
108
+ });
109
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * `replay_request` — validate a drafted recipe before proving: confirm its
3
+ * selectors extract the target(s), and (with `withoutSecrets`) that the
4
+ * endpoint is auth-bound. Authored once as a plain {@link RegisteredTool}; the
5
+ * backend does the actual replay (MCP re-runs locally, cloud re-issues in the
6
+ * TEE pod).
7
+ */
8
+ import { type RegisteredTool } from '../tools/registry.ts';
9
+ import { type ResolveBackend } from './util.ts';
10
+ export declare function replayTool(resolveBackend: ResolveBackend): RegisteredTool;
@@ -0,0 +1,34 @@
1
+ /**
2
+ * `replay_request` — validate a drafted recipe before proving: confirm its
3
+ * selectors extract the target(s), and (with `withoutSecrets`) that the
4
+ * endpoint is auth-bound. Authored once as a plain {@link RegisteredTool}; the
5
+ * backend does the actual replay (MCP re-runs locally, cloud re-issues in the
6
+ * TEE pod).
7
+ */
8
+ import { defineTool } from "../tools/registry.js";
9
+ import { objectSchema } from "./util.js";
10
+ export function replayTool(resolveBackend) {
11
+ return defineTool({
12
+ name: 'replay_request',
13
+ description: 'Validate the drafted recipe before proving — confirm its selectors '
14
+ + 'extract the target value. Returns diagnostics; run before '
15
+ + 'proving. Set `withoutSecrets: true` for the AUTH-BOUND check: it '
16
+ + 're-issues the request with NO secrets/cookies (an anonymous '
17
+ + 'visitor). If the values still extract (valid:true), the endpoint '
18
+ + 'is PUBLIC and the proof would not bind to the user — reject it '
19
+ + 'and find an auth-bound request instead.',
20
+ inputSchema: objectSchema({
21
+ draftId: { type: 'string' },
22
+ withoutSecrets: { type: 'boolean' },
23
+ }, ['draftId']),
24
+ }, async (args) => {
25
+ const backend = resolveBackend(args);
26
+ const draft = backend.drafts.get(String(args.draftId));
27
+ if (!draft) {
28
+ throw new Error(`no draft ${String(args.draftId)}`);
29
+ }
30
+ return backend.replay(draft, {
31
+ withoutSecrets: Boolean(args.withoutSecrets),
32
+ });
33
+ });
34
+ }
@@ -1,9 +1,16 @@
1
1
  import { type RegisteredTool } from '../tools/registry.ts';
2
- import type { AuthoringHost } from './backend.ts';
2
+ import { type ResolveBackend } from './util.ts';
3
3
  /**
4
- * Build the authoring tools for a host as plain {@link RegisteredTool}s — the
5
- * same primitive the MCP-only tools use. Each handler resolves the backend via
6
- * `host.resolveBackend(args)`; the schema merges the host's `sessionSchema`
7
- * (e.g. `captureId`) and any per-tool `toolExtras`.
4
+ * The authoring tools — navigate/inspect authored inline here; find/propose/
5
+ * replay live in their own files ({@link findTool}/{@link proposeTool}/
6
+ * {@link replayTool}) and are composed in below. Each is a plain `defineTool`
7
+ * primitive, so there is one canonical `RegisteredTool` per tool and no
8
+ * parallel tool shape. Every handler resolves its session backend via
9
+ * `resolveBackend(args)`: the cloud passes `() => backend` (one backend per
10
+ * run); the MCP passes an `args.captureId`-keyed resolver. Hosts that need
11
+ * extra input schema (the MCP's `captureId` session handle + the
12
+ * credential-aware `run_proof` contract) MAP these tools through `extendTool`
13
+ * (see mcp/tools/agent/shared.ts) — the tools themselves stay plain, and args
14
+ * parse loosely so the extra fields still reach the resolver/handler.
8
15
  */
9
- export declare function buildAuthoringTools(host: AuthoringHost): RegisteredTool[];
16
+ export declare function authoringTools(resolveBackend: ResolveBackend): RegisteredTool[];