@decidio/sdk 0.1.8 → 0.1.10

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/dist/signing.js CHANGED
@@ -56,3 +56,59 @@ export function signBoundProof(privateKeyBase64, fields) {
56
56
  const signature = Buffer.from(edSign(null, Buffer.from(`${protectedHdr}.${payload}`, "utf8"), key)).toString("base64url");
57
57
  return { agentId: fields.agentId, did: fields.did, action: fields.action, amount: fields.amount, scope: fields.scope, workspaceId: fields.workspaceId, nonce, exp, proof: { protected: protectedHdr, signature } };
58
58
  }
59
+ export class DecidioUnsafeArgumentsError extends Error {
60
+ decisionId;
61
+ constructor(message, decisionId) {
62
+ super(message);
63
+ this.decisionId = decisionId;
64
+ this.name = "DecidioUnsafeArgumentsError";
65
+ }
66
+ }
67
+ export function assertJsonSafe(value, path = "args") {
68
+ const seen = new Set();
69
+ const walk = (v, p) => {
70
+ if (v === null || typeof v === "boolean" || typeof v === "string")
71
+ return;
72
+ if (typeof v === "number") {
73
+ if (!Number.isFinite(v))
74
+ throw new DecidioUnsafeArgumentsError(`[decidio] ${p} is ${String(v)} — a non-finite number does not survive JSON (it becomes null), so what a human approves would not be what executes. pass a finite number or a string.`);
75
+ return;
76
+ }
77
+ if (typeof v === "undefined")
78
+ throw new DecidioUnsafeArgumentsError(`[decidio] ${p} is undefined — JSON drops or nullifies it, so what a human approves would not be what executes. use null explicitly or omit the field.`);
79
+ if (typeof v === "bigint")
80
+ throw new DecidioUnsafeArgumentsError(`[decidio] ${p} is a BigInt — JSON cannot represent it. pass it as a string.`);
81
+ if (typeof v === "function" || typeof v === "symbol")
82
+ throw new DecidioUnsafeArgumentsError(`[decidio] ${p} is a ${typeof v} — it cannot be serialized for approval.`);
83
+ if (typeof v === "object") {
84
+ if (seen.has(v))
85
+ throw new DecidioUnsafeArgumentsError(`[decidio] ${p} is part of a circular structure — it cannot be serialized for approval.`);
86
+ seen.add(v);
87
+ if (Array.isArray(v)) {
88
+ v.forEach((x, i) => walk(x, `${p}[${i}]`));
89
+ seen.delete(v);
90
+ return;
91
+ }
92
+ const proto = Object.getPrototypeOf(v);
93
+ if (proto !== Object.prototype && proto !== null) {
94
+ const name = v?.constructor?.name ?? "a class instance";
95
+ throw new DecidioUnsafeArgumentsError(`[decidio] ${p} is ${name === "Object" ? "an exotic object" : `a ${name}`} — only plain JSON objects survive serialization with their meaning intact (a Map, for example, becomes {}); convert it to plain JSON first.`);
96
+ }
97
+ if (typeof v.toJSON === "function")
98
+ throw new DecidioUnsafeArgumentsError(`[decidio] ${p} defines toJSON() — its serialized form would differ from the value the signature covers. pass the plain serialized form instead.`);
99
+ for (const [k, x] of Object.entries(v))
100
+ walk(x, `${p}.${k}`);
101
+ seen.delete(v);
102
+ return;
103
+ }
104
+ throw new DecidioUnsafeArgumentsError(`[decidio] ${p} has unsupported type ${typeof v}.`);
105
+ };
106
+ walk(value, path);
107
+ }
108
+ export function assertSafeTransport(url, hasCredential) {
109
+ if (!hasCredential)
110
+ return;
111
+ if (/^http:\/\//i.test(url) && !/^http:\/\/(localhost|127\.0\.0\.1|\[::1\])([:/]|$)/i.test(url)) {
112
+ throw new Error(`[decidio] refusing to send credentials over plaintext http to ${url.replace(/^(https?:\/\/[^/]+).*$/i, "$1")} — use https, or localhost for local dev. Nothing was sent.`);
113
+ }
114
+ }
package/openapi.yaml CHANGED
@@ -5,7 +5,7 @@
5
5
  openapi: 3.1.0
6
6
  info:
7
7
  title: Decidio Agent Gate
8
- version: 0.1.8
8
+ version: 0.1.10
9
9
  description: >
10
10
  Authorize an AI-agent action (proceed | route | block), confirm the captured outcome, and
11
11
  receive the signed resume webhook when a routed action is decided. Every outcome seals a
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decidio/sdk",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "description": "One-line approval gate for AI-agent actions. Wrap a risky tool call with guard.protect(); Decidio's policy engine decides proceed | route | block, a human approves routed actions, and every outcome is sealed as a verifiable Authority Receipt.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -77,11 +77,11 @@
77
77
  },
78
78
  "scripts": {
79
79
  "typecheck": "tsc --noEmit",
80
- "build": "node -e \"fs.rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.build.json",
80
+ "build": "node -e \"fs.rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.build.json && tsc -p tsconfig.types.json",
81
81
  "prepublishOnly": "npm run typecheck && npm run build"
82
82
  },
83
83
  "dependencies": {
84
- "@decidio/verify": "0.1.7"
84
+ "@decidio/verify": "0.1.9"
85
85
  },
86
86
  "author": "OmniTwin Technologies Inc.",
87
87
  "bugs": {