@paybond/kit 0.9.4 → 0.9.5
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 +12 -6
- package/dist/init.js +58 -65
- package/dist/login.d.ts +1 -1
- package/dist/login.js +33 -14
- package/dist/mcp-server.js +35 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -28,17 +28,20 @@ Create a sandbox key for local development:
|
|
|
28
28
|
npx -p @paybond/kit paybond login
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
-
`paybond login` writes `PAYBOND_API_KEY` to `.env.local` with file mode `0600`, refuses to overwrite an existing key unless `--force` is passed
|
|
31
|
+
`paybond login` writes a sandbox `PAYBOND_API_KEY` to `.env.local` with file mode `0600`, adds the default `.env.local` target to `.gitignore` when needed, and refuses to overwrite an existing key unless `--force` is passed. Custom env-file paths inside a git repo must already be ignored. Live production keys are created by tenant admins in Console and stored in deployment secret managers.
|
|
32
32
|
|
|
33
33
|
## First guardrail scaffold
|
|
34
34
|
|
|
35
35
|
Use this first when you have a paid tool and want Paybond guardrails in the sandbox:
|
|
36
36
|
|
|
37
37
|
```bash
|
|
38
|
-
npx -p @paybond/kit paybond-init
|
|
38
|
+
npx -p @paybond/kit paybond-init \
|
|
39
|
+
--preset paid-tool-guard \
|
|
40
|
+
--framework provider-agnostic \
|
|
41
|
+
--out paybond-paid-tool-guard.ts
|
|
39
42
|
```
|
|
40
43
|
|
|
41
|
-
The generated
|
|
44
|
+
The generated integration opens Paybond from the environment, loads `.env.local` when `PAYBOND_API_KEY` is not already present, bootstraps a sandbox guardrail intent, wraps your paid-tool handler, and submits sandbox evidence. It does not generate a paid-tool implementation. Free Developer is sandbox-only; live settlement rails start on paid production plans.
|
|
42
45
|
|
|
43
46
|
## Tenant isolation
|
|
44
47
|
|
|
@@ -100,7 +103,7 @@ const guardedTool = guard.guardTool(
|
|
|
100
103
|
async (input) => bookHotel(input),
|
|
101
104
|
);
|
|
102
105
|
|
|
103
|
-
const result = await guardedTool({ hotelId: "
|
|
106
|
+
const result = await guardedTool({ hotelId: "hotel_123", maxPriceCents: 20_000 });
|
|
104
107
|
await paybond.guardrails.submitSandboxEvidence({
|
|
105
108
|
intentId: guardrail.intent_id,
|
|
106
109
|
payload: { result, sandbox: true },
|
|
@@ -112,7 +115,10 @@ The `paybond.harbor` and `paybond.guardrails` clients are created by `Paybond.op
|
|
|
112
115
|
Scaffold a guardrail integration:
|
|
113
116
|
|
|
114
117
|
```bash
|
|
115
|
-
npx -p @paybond/kit paybond-init
|
|
118
|
+
npx -p @paybond/kit paybond-init \
|
|
119
|
+
--preset paid-tool-guard \
|
|
120
|
+
--framework provider-agnostic \
|
|
121
|
+
--out paybond-paid-tool-guard.ts
|
|
116
122
|
```
|
|
117
123
|
|
|
118
124
|
## What the package includes
|
|
@@ -134,7 +140,7 @@ Gateway and trust helpers:
|
|
|
134
140
|
- Protocol-v2 helpers for mandate verification, replay-safe recognition proof verification, receipt reads, and A2A discovery
|
|
135
141
|
- `paybond login` for sandbox device approval and local `.env.local` API-key setup
|
|
136
142
|
- `paybond-mcp-server` for tenant-bound MCP tool exposure to any MCP-compatible host
|
|
137
|
-
- `paybond-init` for generating a Paybond guardrail integration
|
|
143
|
+
- `paybond-init` for generating a Paybond guardrail integration helper
|
|
138
144
|
|
|
139
145
|
Agent-facing surfaces are model-provider agnostic. Paybond verifies tool operations and tenant scope, not whether a tool call came from OpenAI, Anthropic, Gemini, a local model, or another runtime.
|
|
140
146
|
|
package/dist/init.js
CHANGED
|
@@ -26,15 +26,15 @@ const FRAMEWORK_NOTES = {
|
|
|
26
26
|
};
|
|
27
27
|
function usage() {
|
|
28
28
|
return [
|
|
29
|
-
"Usage: paybond-init [--preset paid-tool-guard] [--framework generic|provider-agnostic|openai|claude|anthropic|gemini|google-ai|vercel-ai|langgraph|mcp] [--out paybond-
|
|
29
|
+
"Usage: paybond-init [--preset paid-tool-guard] [--framework generic|provider-agnostic|openai|claude|anthropic|gemini|google-ai|vercel-ai|langgraph|mcp] [--out paybond-paid-tool-guard.ts] [--force]",
|
|
30
30
|
"",
|
|
31
|
-
"Scaffolds a production-shaped Paybond guardrail integration
|
|
31
|
+
"Scaffolds a production-shaped Paybond guardrail integration helper.",
|
|
32
32
|
].join("\n");
|
|
33
33
|
}
|
|
34
34
|
function parseArgs(argv) {
|
|
35
35
|
let preset = "paid-tool-guard";
|
|
36
36
|
let framework = "provider-agnostic";
|
|
37
|
-
let out = "paybond-
|
|
37
|
+
let out = "paybond-paid-tool-guard.ts";
|
|
38
38
|
let force = false;
|
|
39
39
|
for (let i = 0; i < argv.length; i += 1) {
|
|
40
40
|
const arg = argv[i];
|
|
@@ -85,7 +85,13 @@ function template(framework) {
|
|
|
85
85
|
type SandboxGuardrailEvidenceResult,
|
|
86
86
|
} from "@paybond/kit";
|
|
87
87
|
|
|
88
|
-
const
|
|
88
|
+
declare const process: {
|
|
89
|
+
env: Record<string, string | undefined>;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
// Production integration helpers only. Add your paid-tool handler in
|
|
93
|
+
// application code and pass it to wrapPaidTool(...).
|
|
94
|
+
const DEFAULT_OPERATION = "paid_tool.operation";
|
|
89
95
|
const DEFAULT_REQUESTED_SPEND_CENTS = 500;
|
|
90
96
|
|
|
91
97
|
export type PaidToolHandler<TInput, TResult> = (input: TInput) => TResult | Promise<TResult>;
|
|
@@ -107,22 +113,59 @@ export type SubmitSandboxEvidenceOptions = {
|
|
|
107
113
|
idempotencyKey?: string;
|
|
108
114
|
};
|
|
109
115
|
|
|
110
|
-
export type
|
|
111
|
-
|
|
112
|
-
|
|
116
|
+
export type OpenPaybondFromEnvOptions = {
|
|
117
|
+
/**
|
|
118
|
+
* Load PAYBOND_API_KEY from this local env file when the process environment
|
|
119
|
+
* does not already provide it. Pass false when your agent host injects secrets.
|
|
120
|
+
*/
|
|
121
|
+
envFile?: string | false;
|
|
113
122
|
};
|
|
114
123
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
124
|
+
function readEnvValue(body: string, key: string): string | undefined {
|
|
125
|
+
const pattern = new RegExp("^\\\\s*(?:export\\\\s+)?" + key + "\\\\s*=\\\\s*(.*)$", "m");
|
|
126
|
+
const match = body.match(pattern);
|
|
127
|
+
if (!match) return undefined;
|
|
128
|
+
let value = (match[1] ?? "").trim();
|
|
129
|
+
if (value.startsWith('"') && value.endsWith('"')) {
|
|
130
|
+
try {
|
|
131
|
+
value = JSON.parse(value);
|
|
132
|
+
} catch {
|
|
133
|
+
value = value.slice(1, -1);
|
|
134
|
+
}
|
|
135
|
+
} else if (value.startsWith("'") && value.endsWith("'")) {
|
|
136
|
+
value = value.slice(1, -1);
|
|
137
|
+
}
|
|
138
|
+
return value.trim() || undefined;
|
|
139
|
+
}
|
|
121
140
|
|
|
122
|
-
|
|
141
|
+
async function readTextFile(envFile: string): Promise<string | undefined> {
|
|
142
|
+
// @ts-ignore Node builtins are available in agent and CLI Node runtimes.
|
|
143
|
+
const fs: { readFile(path: string, encoding: "utf8"): Promise<string> } = await import("node:fs/promises");
|
|
144
|
+
try {
|
|
145
|
+
return await fs.readFile(envFile, "utf8");
|
|
146
|
+
} catch (err) {
|
|
147
|
+
if ((err as { code?: unknown })?.code === "ENOENT") return undefined;
|
|
148
|
+
throw err;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export async function loadPaybondEnvFile(envFile = ".env.local"): Promise<void> {
|
|
153
|
+
if (process.env.PAYBOND_API_KEY?.trim()) return;
|
|
154
|
+
const body = await readTextFile(envFile);
|
|
155
|
+
if (body === undefined) return;
|
|
156
|
+
const apiKey = readEnvValue(body, "PAYBOND_API_KEY");
|
|
157
|
+
if (apiKey) {
|
|
158
|
+
process.env.PAYBOND_API_KEY = apiKey;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export async function openPaybondFromEnv(options: OpenPaybondFromEnvOptions = {}): Promise<Paybond> {
|
|
163
|
+
if (options.envFile !== false) {
|
|
164
|
+
await loadPaybondEnvFile(options.envFile ?? ".env.local");
|
|
165
|
+
}
|
|
123
166
|
const apiKey = process.env.PAYBOND_API_KEY?.trim();
|
|
124
167
|
if (!apiKey) {
|
|
125
|
-
throw new Error("PAYBOND_API_KEY is required");
|
|
168
|
+
throw new Error("PAYBOND_API_KEY is required; run paybond login or configure your agent host to pass it");
|
|
126
169
|
}
|
|
127
170
|
|
|
128
171
|
return Paybond.open({
|
|
@@ -193,56 +236,6 @@ export async function submitSandboxEvidence(
|
|
|
193
236
|
idempotencyKey: options.idempotencyKey,
|
|
194
237
|
});
|
|
195
238
|
}
|
|
196
|
-
|
|
197
|
-
export async function replaceableSmokeTestPaidTool(
|
|
198
|
-
input: SmokePaidToolInput,
|
|
199
|
-
): Promise<SmokePaidToolResult> {
|
|
200
|
-
// Replace this sandbox smoke-test function with the real paid side-effecting tool.
|
|
201
|
-
return {
|
|
202
|
-
confirmationId: "sandbox-confirmation-" + input.itemId,
|
|
203
|
-
itemId: input.itemId,
|
|
204
|
-
chargedCents: Math.min(input.maxPriceCents, DEFAULT_REQUESTED_SPEND_CENTS),
|
|
205
|
-
sandbox: true,
|
|
206
|
-
};
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
export async function runSandboxSmokePath(): Promise<{
|
|
210
|
-
guardrail: SandboxGuardrailBootstrapResult;
|
|
211
|
-
toolResult: SmokePaidToolResult;
|
|
212
|
-
evidence: SandboxGuardrailEvidenceResult;
|
|
213
|
-
}> {
|
|
214
|
-
const paybond = await openPaybondFromEnv();
|
|
215
|
-
const guardrail = await bootstrapSandboxGuardrailIntent(paybond);
|
|
216
|
-
const guardedTool = wrapPaidTool(paybond, guardrail, replaceableSmokeTestPaidTool);
|
|
217
|
-
const toolResult = await guardedTool({
|
|
218
|
-
itemId: "replace-with-your-tool-input",
|
|
219
|
-
maxPriceCents: DEFAULT_REQUESTED_SPEND_CENTS,
|
|
220
|
-
});
|
|
221
|
-
const evidence = await submitSandboxEvidence(paybond, guardrail, {
|
|
222
|
-
confirmation_id: toolResult.confirmationId,
|
|
223
|
-
charged_cents: toolResult.chargedCents,
|
|
224
|
-
item_id: toolResult.itemId,
|
|
225
|
-
sandbox: toolResult.sandbox,
|
|
226
|
-
});
|
|
227
|
-
return { guardrail, toolResult, evidence };
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
async function main(): Promise<void> {
|
|
231
|
-
const result = await runSandboxSmokePath();
|
|
232
|
-
console.log(JSON.stringify(result, null, 2));
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
function normalizeFileURL(url: string): string {
|
|
236
|
-
return url.startsWith("file:///var/") ? url.replace("file:///var/", "file:///private/var/") : url;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
const invokedPath = process.argv[1] ? normalizeFileURL(new URL("file://" + process.argv[1]).href) : "";
|
|
240
|
-
if (invokedPath && normalizeFileURL(import.meta.url) === invokedPath) {
|
|
241
|
-
main().catch((err) => {
|
|
242
|
-
console.error(err instanceof Error ? err.message : String(err));
|
|
243
|
-
process.exitCode = 1;
|
|
244
|
-
});
|
|
245
|
-
}
|
|
246
239
|
`;
|
|
247
240
|
}
|
|
248
241
|
async function writeScaffold(out, body, force) {
|
package/dist/login.d.ts
CHANGED
package/dist/login.js
CHANGED
|
@@ -23,19 +23,22 @@ class OAuthPollError extends PaybondLoginError {
|
|
|
23
23
|
}
|
|
24
24
|
function usage() {
|
|
25
25
|
return [
|
|
26
|
-
"Usage: paybond login [--env sandbox
|
|
26
|
+
"Usage: paybond login [--env sandbox] [--env-file .env.local] [--gateway https://api.paybond.ai] [--no-open] [--force]",
|
|
27
27
|
"",
|
|
28
|
-
"Starts a device login and writes PAYBOND_API_KEY to
|
|
29
|
-
"
|
|
30
|
-
"
|
|
28
|
+
"Starts a device login and writes PAYBOND_API_KEY to a local env file.",
|
|
29
|
+
"The default .env.local target is added to .gitignore when needed.",
|
|
30
|
+
"Defaults to the sandbox environment. Production keys are created in Console and stored in secret managers.",
|
|
31
31
|
].join("\n");
|
|
32
32
|
}
|
|
33
33
|
function parseEnvironment(raw) {
|
|
34
34
|
const value = raw.trim().toLowerCase();
|
|
35
|
-
if (value === "sandbox"
|
|
35
|
+
if (value === "sandbox") {
|
|
36
36
|
return value;
|
|
37
37
|
}
|
|
38
|
-
|
|
38
|
+
if (value === "live") {
|
|
39
|
+
throw new PaybondLoginError("live device login is not supported; create production keys in Console and store them in a secret manager");
|
|
40
|
+
}
|
|
41
|
+
throw new PaybondLoginError("invalid --env (expected sandbox)");
|
|
39
42
|
}
|
|
40
43
|
export function parseArgs(argv) {
|
|
41
44
|
if (argv.length === 0) {
|
|
@@ -67,13 +70,12 @@ export function parseArgs(argv) {
|
|
|
67
70
|
continue;
|
|
68
71
|
}
|
|
69
72
|
if (arg === "--live") {
|
|
70
|
-
|
|
71
|
-
continue;
|
|
73
|
+
throw new PaybondLoginError("live device login is not supported; create production keys in Console and store them in a secret manager");
|
|
72
74
|
}
|
|
73
75
|
if (arg === "--env" || arg.startsWith("--env=")) {
|
|
74
76
|
const raw = arg === "--env" ? rest[++i] : arg.slice("--env=".length);
|
|
75
77
|
if (!raw || raw.startsWith("-")) {
|
|
76
|
-
throw new PaybondLoginError("invalid --env (expected sandbox
|
|
78
|
+
throw new PaybondLoginError("invalid --env (expected sandbox)");
|
|
77
79
|
}
|
|
78
80
|
environment = parseEnvironment(raw);
|
|
79
81
|
continue;
|
|
@@ -162,6 +164,9 @@ async function resolveEnvFile(envFile, cwd) {
|
|
|
162
164
|
return path.isAbsolute(envFile) ? path.resolve(envFile) : path.resolve(cwd, envFile);
|
|
163
165
|
}
|
|
164
166
|
export async function assertGitIgnored(envPath, cwd) {
|
|
167
|
+
await ensureGitIgnored(envPath, cwd, false);
|
|
168
|
+
}
|
|
169
|
+
async function ensureGitIgnored(envPath, cwd, autoAddDefaultEnvFile) {
|
|
165
170
|
const path = await pathModule();
|
|
166
171
|
const fs = await fsModule();
|
|
167
172
|
const rootResult = await spawnCommand("git", ["rev-parse", "--show-toplevel"], cwd);
|
|
@@ -180,6 +185,24 @@ export async function assertGitIgnored(envPath, cwd) {
|
|
|
180
185
|
return;
|
|
181
186
|
}
|
|
182
187
|
if (ignoreResult.code === 1) {
|
|
188
|
+
if (autoAddDefaultEnvFile && relativeTarget === DEFAULT_ENV_FILE) {
|
|
189
|
+
const gitignorePath = path.resolve(repoRoot, ".gitignore");
|
|
190
|
+
let existing = "";
|
|
191
|
+
try {
|
|
192
|
+
existing = await fs.readFile(gitignorePath, "utf8");
|
|
193
|
+
}
|
|
194
|
+
catch (err) {
|
|
195
|
+
if (!(err && typeof err === "object" && "code" in err && err.code === "ENOENT")) {
|
|
196
|
+
throw err;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
const suffix = existing.length > 0 && !existing.endsWith("\n") ? "\n" : "";
|
|
200
|
+
await fs.writeFile(gitignorePath, `${existing}${suffix}${DEFAULT_ENV_FILE}\n`, { encoding: "utf8", mode: 0o644 });
|
|
201
|
+
const recheck = await spawnCommand("git", ["-C", repoRoot, "check-ignore", "--quiet", "--", relativeTarget], cwd);
|
|
202
|
+
if (recheck.code === 0) {
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
183
206
|
throw new PaybondLoginError(`Refusing to write ${target} because it is not ignored by git. Add ${relativeTarget} to .gitignore or pass --env-file pointing outside the repo.`);
|
|
184
207
|
}
|
|
185
208
|
throw new PaybondLoginError(`Unable to verify git ignore status for ${target}: ${ignoreResult.stderr.trim() || "git check-ignore failed"}`);
|
|
@@ -376,14 +399,10 @@ export async function runLogin(options, deps = {}) {
|
|
|
376
399
|
const openBrowser = deps.openBrowser ?? defaultOpenBrowser;
|
|
377
400
|
const envPath = await resolveEnvFile(options.envFile, cwd);
|
|
378
401
|
await assertCanWriteEnvFile(envPath, options.force);
|
|
379
|
-
await
|
|
402
|
+
await ensureGitIgnored(envPath, cwd, options.envFile === DEFAULT_ENV_FILE);
|
|
380
403
|
const start = await startDeviceFlow(fetchFn, options.gateway, options.environment);
|
|
381
404
|
const verificationUrl = start.verification_uri_complete || start.verification_uri;
|
|
382
405
|
stdout.write(`Paybond ${options.environment} login\n`);
|
|
383
|
-
if (options.environment === "live") {
|
|
384
|
-
stdout.write(`WARNING: this mints a PRODUCTION operator API key with access to live tenant data and money movement.\n`);
|
|
385
|
-
stdout.write(`A tenant admin must approve it from an active live console session and confirm the live environment.\n`);
|
|
386
|
-
}
|
|
387
406
|
stdout.write(`Verification URL: ${verificationUrl}\n`);
|
|
388
407
|
stdout.write(`Code: ${start.user_code}\n`);
|
|
389
408
|
if (!options.noOpen) {
|
package/dist/mcp-server.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
// @ts-ignore Node builtins are available in the published CLI runtime.
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
2
4
|
import { GatewayAuthError, GatewayFraudClient, GatewaySignalClient, SignalHttpError, DEFAULT_PAYBOND_GATEWAY_BASE_URL, } from "./index.js";
|
|
3
5
|
const SERVER_NAME = "Paybond MCP";
|
|
4
6
|
const SERVER_VERSION = "0.6.0";
|
|
@@ -6,6 +8,35 @@ const MCP_PROTOCOL_VERSION = "2025-11-25";
|
|
|
6
8
|
const DEFAULT_PRINCIPAL_PATH = "/v1/auth/principal";
|
|
7
9
|
const DEFAULT_RECOGNITION_VERIFIER_ID = "paybond-gateway";
|
|
8
10
|
const agentRecognitionProofHeader = "x-paybond-agent-recognition-proof";
|
|
11
|
+
const DEFAULT_ENV_FILE = ".env.local";
|
|
12
|
+
function readEnvFileValue(envFile, key) {
|
|
13
|
+
let body;
|
|
14
|
+
try {
|
|
15
|
+
body = readFileSync(envFile, "utf8");
|
|
16
|
+
}
|
|
17
|
+
catch (err) {
|
|
18
|
+
if (err?.code === "ENOENT")
|
|
19
|
+
return undefined;
|
|
20
|
+
throw err;
|
|
21
|
+
}
|
|
22
|
+
const pattern = new RegExp("^\\s*(?:export\\s+)?" + key + "\\s*=\\s*(.*)$", "m");
|
|
23
|
+
const match = body.match(pattern);
|
|
24
|
+
if (!match)
|
|
25
|
+
return undefined;
|
|
26
|
+
let value = String(match[1] ?? "").trim();
|
|
27
|
+
if (value.startsWith('"') && value.endsWith('"')) {
|
|
28
|
+
try {
|
|
29
|
+
value = JSON.parse(value);
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
value = value.slice(1, -1);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
else if (value.startsWith("'") && value.endsWith("'")) {
|
|
36
|
+
value = value.slice(1, -1);
|
|
37
|
+
}
|
|
38
|
+
return value.trim() || undefined;
|
|
39
|
+
}
|
|
9
40
|
class GatewayHTTPError extends Error {
|
|
10
41
|
statusCode;
|
|
11
42
|
url;
|
|
@@ -845,12 +876,13 @@ export class PaybondMCPServer {
|
|
|
845
876
|
}
|
|
846
877
|
}
|
|
847
878
|
export function settingsFromEnv(env = process.env) {
|
|
848
|
-
const
|
|
879
|
+
const envFile = optionalEnv(env.PAYBOND_ENV_FILE) ?? DEFAULT_ENV_FILE;
|
|
880
|
+
const apiKey = String(env.PAYBOND_API_KEY ?? readEnvFileValue(envFile, "PAYBOND_API_KEY") ?? "").trim();
|
|
849
881
|
if (!apiKey) {
|
|
850
|
-
throw new Error("PAYBOND_API_KEY is required");
|
|
882
|
+
throw new Error("PAYBOND_API_KEY is required; run paybond login or configure your MCP host environment");
|
|
851
883
|
}
|
|
852
884
|
return {
|
|
853
|
-
gatewayBaseUrl: DEFAULT_PAYBOND_GATEWAY_BASE_URL,
|
|
885
|
+
gatewayBaseUrl: optionalEnv(env.PAYBOND_GATEWAY_BASE_URL) ?? DEFAULT_PAYBOND_GATEWAY_BASE_URL,
|
|
854
886
|
apiKey,
|
|
855
887
|
principalPath: optionalEnv(env.PAYBOND_PRINCIPAL_PATH) ?? DEFAULT_PRINCIPAL_PATH,
|
|
856
888
|
maxRetries: optionalEnv(env.PAYBOND_MCP_MAX_RETRIES)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@paybond/kit",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.5",
|
|
4
4
|
"description": "Paybond Kit for TypeScript: agent spend governance for paid tool calls with spend authorization, evidence receipts, refunds, disputes, hosted Gateway sessions, and settlement.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|