@nomosprotocol/sdk 2.3.0 → 2.3.2
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 +14 -3
- package/dist/index.cjs +161 -11
- package/dist/index.d.cts +96 -3
- package/dist/index.d.ts +96 -3
- package/dist/index.js +157 -11
- package/package.json +9 -2
package/README.md
CHANGED
|
@@ -161,6 +161,17 @@ const verdict = await nomos.can({
|
|
|
161
161
|
});
|
|
162
162
|
```
|
|
163
163
|
|
|
164
|
+
Name your agent so the transcript records who asked, and mark test traffic so it stays out of the authority's public history and counts:
|
|
165
|
+
|
|
166
|
+
```ts
|
|
167
|
+
const verdict = await nomos.can(
|
|
168
|
+
{ authority: "eu-ai-act", ai_categorises_biometric_data_for_sensitive_attributes: true },
|
|
169
|
+
{ caller: { agent_id: "acme-hiring-agent", purpose: process.env.CI ? "test" : "production" } },
|
|
170
|
+
);
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
The name is declared, not verified, and is shown as such. Don't know which authority applies? `GET /api/exchange/find?q=<what you're about to do>`, or the MCP tool `find_authority`.
|
|
174
|
+
|
|
164
175
|
If a paid authority has not been purchased, NOMOS throws `NomosPaymentRequiredError` with the price and purchase URL attached.
|
|
165
176
|
|
|
166
177
|
NOMOS never auto-charges on your behalf.
|
|
@@ -172,7 +183,7 @@ Use an authenticated client for artifacts belonging to your organization:
|
|
|
172
183
|
```ts
|
|
173
184
|
import { Nomos } from "@nomosprotocol/sdk";
|
|
174
185
|
|
|
175
|
-
const client = new Nomos("
|
|
186
|
+
const client = new Nomos("nmk_...");
|
|
176
187
|
|
|
177
188
|
const verdict = await client.can({
|
|
178
189
|
artifact_id: "loan_approval_v1",
|
|
@@ -263,7 +274,7 @@ itself needs.
|
|
|
263
274
|
|
|
264
275
|
A `.nomos` file is a sealed, machine-executable representation of institutional authority.
|
|
265
276
|
|
|
266
|
-
It can contain the rules, constraints, permissions, obligations, provenance, issuer information, version, and other
|
|
277
|
+
It can contain the rules, constraints, permissions, obligations, provenance, issuer information, version, and other authority metadata required to evaluate an action.
|
|
267
278
|
|
|
268
279
|
The artifact is cryptographically sealed.
|
|
269
280
|
|
|
@@ -470,7 +481,7 @@ The authenticated `Nomos` client exposes the broader platform:
|
|
|
470
481
|
```ts
|
|
471
482
|
import { Nomos } from "@nomosprotocol/sdk";
|
|
472
483
|
|
|
473
|
-
const client = new Nomos("
|
|
484
|
+
const client = new Nomos("nmk_...");
|
|
474
485
|
|
|
475
486
|
// Authorization
|
|
476
487
|
await client.can({
|
package/dist/index.cjs
CHANGED
|
@@ -41,12 +41,14 @@ __export(index_exports, {
|
|
|
41
41
|
WELL_KNOWN: () => WELL_KNOWN,
|
|
42
42
|
accept: () => accept,
|
|
43
43
|
act: () => act,
|
|
44
|
+
applyToolBindings: () => applyToolBindings,
|
|
44
45
|
approver: () => approver,
|
|
45
46
|
bindingDigest: () => bindingDigest,
|
|
46
47
|
buildAct: () => buildAct,
|
|
47
48
|
can: () => can,
|
|
48
49
|
certificateRegistry: () => certificateRegistry,
|
|
49
50
|
certify: () => certify,
|
|
51
|
+
describeSuggestion: () => describeSuggestion,
|
|
50
52
|
fetchDocument: () => fetchDocument,
|
|
51
53
|
generateSigner: () => generateSigner,
|
|
52
54
|
issuer: () => issuer,
|
|
@@ -57,6 +59,7 @@ __export(index_exports, {
|
|
|
57
59
|
memoryStore: () => memoryStore,
|
|
58
60
|
nomos: () => nomos,
|
|
59
61
|
originOf: () => originOf,
|
|
62
|
+
parseToolBindings: () => parseToolBindings,
|
|
60
63
|
passkeyApprover: () => passkeyApprover,
|
|
61
64
|
postgresPasskeyStore: () => postgresPasskeyStore,
|
|
62
65
|
postgresRegistryStore: () => postgresRegistryStore,
|
|
@@ -75,6 +78,7 @@ __export(index_exports, {
|
|
|
75
78
|
signRevocationList: () => signRevocationList,
|
|
76
79
|
signTestimony: () => signTestimony,
|
|
77
80
|
statusFor: () => statusFor,
|
|
81
|
+
suggestToolBindings: () => suggestToolBindings,
|
|
78
82
|
verifyAct: () => verifyAct,
|
|
79
83
|
verifyArtifact: () => verifyArtifact,
|
|
80
84
|
verifyChain: () => verifyChain,
|
|
@@ -187,7 +191,7 @@ function isRetryable(status) {
|
|
|
187
191
|
}
|
|
188
192
|
|
|
189
193
|
// src/http-client.ts
|
|
190
|
-
var SDK_VERSION = "
|
|
194
|
+
var SDK_VERSION = "2.3.2";
|
|
191
195
|
var HttpClient = class {
|
|
192
196
|
constructor(opts) {
|
|
193
197
|
this.opts = opts;
|
|
@@ -211,6 +215,7 @@ var HttpClient = class {
|
|
|
211
215
|
"User-Agent": `nomos-node/${SDK_VERSION}`,
|
|
212
216
|
"NOMOS-SDK-Version": SDK_VERSION
|
|
213
217
|
};
|
|
218
|
+
if (reqOpts?.headers) Object.assign(headers, reqOpts.headers);
|
|
214
219
|
if (reqOpts?.idempotencyKey) {
|
|
215
220
|
headers["Idempotency-Key"] = reqOpts.idempotencyKey;
|
|
216
221
|
}
|
|
@@ -719,6 +724,13 @@ function normalizeAuthorityQueryResult(data, authority) {
|
|
|
719
724
|
...data.revoked === true ? { revoked: true, revocation_reason: data.revocation_reason } : {}
|
|
720
725
|
};
|
|
721
726
|
}
|
|
727
|
+
function callerHeaders(c) {
|
|
728
|
+
const h = {};
|
|
729
|
+
if (c?.agent_id) h["X-Nomos-Agent"] = c.agent_id;
|
|
730
|
+
if (c?.acts_for) h["X-Nomos-Acts-For"] = c.acts_for;
|
|
731
|
+
if (c?.purpose) h["X-Nomos-Purpose"] = c.purpose;
|
|
732
|
+
return h;
|
|
733
|
+
}
|
|
722
734
|
async function canViaExchange(authority, facts, action, opts) {
|
|
723
735
|
const base = (opts?.baseUrl ?? DEFAULT_EXCHANGE_BASE).replace(/\/$/, "");
|
|
724
736
|
const url = `${base}/api/v1/can`;
|
|
@@ -726,7 +738,7 @@ async function canViaExchange(authority, facts, action, opts) {
|
|
|
726
738
|
try {
|
|
727
739
|
res = await fetch(url, {
|
|
728
740
|
method: "POST",
|
|
729
|
-
headers: { "Content-Type": "application/json" },
|
|
741
|
+
headers: { "Content-Type": "application/json", "User-Agent": `nomos-node/${SDK_VERSION}`, ...callerHeaders(opts?.caller) },
|
|
730
742
|
body: JSON.stringify({ artifact: authority, action, ...facts }),
|
|
731
743
|
signal: opts?.signal
|
|
732
744
|
});
|
|
@@ -739,8 +751,8 @@ async function canViaExchange(authority, facts, action, opts) {
|
|
|
739
751
|
if (!res.ok) mapHttpError(res.status, data, requestId);
|
|
740
752
|
return normalizeAuthorityQueryResult(data, authority);
|
|
741
753
|
}
|
|
742
|
-
async function canViaExchangeAuthenticated(http, authority, facts, action) {
|
|
743
|
-
const { data } = await http.post("/api/v1/can", { artifact: authority, action, ...facts });
|
|
754
|
+
async function canViaExchangeAuthenticated(http, authority, facts, action, caller) {
|
|
755
|
+
const { data } = await http.post("/api/v1/can", { artifact: authority, action, ...facts }, { headers: callerHeaders(caller) });
|
|
744
756
|
return normalizeAuthorityQueryResult(data, authority);
|
|
745
757
|
}
|
|
746
758
|
async function canViaArtifact(http, artifactId, facts, action) {
|
|
@@ -837,7 +849,6 @@ async function can(params, opts) {
|
|
|
837
849
|
return canViaExchange(params.authority, facts, action, opts);
|
|
838
850
|
}
|
|
839
851
|
async function canAuthenticated(http, params, opts) {
|
|
840
|
-
void opts;
|
|
841
852
|
const { facts, action } = splitFacts(params);
|
|
842
853
|
if (params.artifact !== void 0) {
|
|
843
854
|
if (!params.key_certs || !params.root_public_key_pem) {
|
|
@@ -846,13 +857,13 @@ async function canAuthenticated(http, params, opts) {
|
|
|
846
857
|
return canViaChain(params.artifact, params.key_certs, params.root_public_key_pem, facts, action, opts);
|
|
847
858
|
}
|
|
848
859
|
if (params.artifact_id) return canViaArtifact(http, params.artifact_id, facts, action);
|
|
849
|
-
if (params.authority) return canViaExchangeAuthenticated(http, params.authority, facts, action);
|
|
860
|
+
if (params.authority) return canViaExchangeAuthenticated(http, params.authority, facts, action, opts?.caller);
|
|
850
861
|
throw new Error("can(): `authority` (a public Exchange artifact), `artifact_id` (your own artifact), or `artifact` (chain-of-trust) is required.");
|
|
851
862
|
}
|
|
852
863
|
var nomos = { can };
|
|
853
864
|
|
|
854
865
|
// src/nomos.ts
|
|
855
|
-
var DEFAULT_BASE_URL = "https://
|
|
866
|
+
var DEFAULT_BASE_URL = "https://www.nomosprotocol.com";
|
|
856
867
|
var DEFAULT_MAX_RETRIES = 3;
|
|
857
868
|
var DEFAULT_TIMEOUT = 3e4;
|
|
858
869
|
var Nomos = class {
|
|
@@ -862,7 +873,7 @@ var Nomos = class {
|
|
|
862
873
|
constructor(apiKey, config = {}) {
|
|
863
874
|
if (!apiKey || typeof apiKey !== "string") {
|
|
864
875
|
throw new NomosAuthenticationError(
|
|
865
|
-
'A valid API key is required. Pass it as the first argument: new Nomos("
|
|
876
|
+
'A valid API key is required. Pass it as the first argument: new Nomos("nmk_...")'
|
|
866
877
|
);
|
|
867
878
|
}
|
|
868
879
|
this.mode = apiKey.startsWith("nms_test_") ? "test" : "live";
|
|
@@ -884,7 +895,7 @@ var Nomos = class {
|
|
|
884
895
|
* return shape either way, so calling code never needs to know which rail answered.
|
|
885
896
|
*
|
|
886
897
|
* @example
|
|
887
|
-
* const client = new Nomos('
|
|
898
|
+
* const client = new Nomos('nmk_...');
|
|
888
899
|
* const verdict = await client.can({ artifact_id: 'loan_approval_v1', credit_score: 720 });
|
|
889
900
|
*/
|
|
890
901
|
async can(params, opts) {
|
|
@@ -5047,9 +5058,14 @@ var TIE_ORDERS = {
|
|
|
5047
5058
|
function evaluate(artifact, facts) {
|
|
5048
5059
|
const logic = artifact.logic;
|
|
5049
5060
|
const res = logic.resolution ?? {};
|
|
5050
|
-
|
|
5051
|
-
if (!Array.isArray(decisions))
|
|
5061
|
+
if (!Array.isArray(logic.decisions))
|
|
5052
5062
|
throw new Error("logic.decisions missing");
|
|
5063
|
+
const declared = new Set(Object.keys(artifact.execution?.actions ?? {}));
|
|
5064
|
+
const isObligation = (d) => {
|
|
5065
|
+
const t = d?.then?.[0];
|
|
5066
|
+
return t?.type === "emit" || t?.type === "action" && declared.has(t?.action_name);
|
|
5067
|
+
};
|
|
5068
|
+
const decisions = logic.decisions.filter((d) => !isObligation(d));
|
|
5053
5069
|
const order = TIE_ORDERS[res.tie_breaker ?? "deny_wins"];
|
|
5054
5070
|
if (!order)
|
|
5055
5071
|
throw new Error("unknown tie_breaker");
|
|
@@ -5473,6 +5489,136 @@ async function verifyChainRemote(params, opts) {
|
|
|
5473
5489
|
throw new NomosAPIError(message, res.status, requestId);
|
|
5474
5490
|
}
|
|
5475
5491
|
|
|
5492
|
+
// src/bindings.ts
|
|
5493
|
+
var FORBIDDEN_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
5494
|
+
var hasOwn = (o, k) => Object.prototype.hasOwnProperty.call(o, k);
|
|
5495
|
+
var isScalar = (v) => typeof v === "string" || typeof v === "boolean" || typeof v === "number" && Number.isFinite(v);
|
|
5496
|
+
function parseToolBindings(raw) {
|
|
5497
|
+
const no = (why) => {
|
|
5498
|
+
throw new Error(why);
|
|
5499
|
+
};
|
|
5500
|
+
const obj = raw;
|
|
5501
|
+
if (!obj || typeof obj !== "object" || Array.isArray(obj)) no("it is not a JSON object");
|
|
5502
|
+
if (obj.version !== 1) no('"version" must be 1');
|
|
5503
|
+
if (typeof obj.artifact !== "string" || !obj.artifact) no('"artifact" must name the sealed policy');
|
|
5504
|
+
if (typeof obj.reviewed !== "boolean") no('"reviewed" must be true or false');
|
|
5505
|
+
if (!obj.tools || typeof obj.tools !== "object" || Array.isArray(obj.tools)) no('"tools" must be an object');
|
|
5506
|
+
for (const k of Object.keys(obj)) if (!["version", "artifact", "reviewed", "tools", "_review"].includes(k)) no(`unknown setting "${k}"`);
|
|
5507
|
+
const tools = {};
|
|
5508
|
+
for (const tool of Object.keys(obj.tools)) {
|
|
5509
|
+
if (FORBIDDEN_KEYS.has(tool)) no(`"${tool}" isn't a usable tool name`);
|
|
5510
|
+
const entry = obj.tools[tool];
|
|
5511
|
+
if (!entry || typeof entry !== "object" || Array.isArray(entry)) no(`tool "${tool}" must be an object with "facts"`);
|
|
5512
|
+
for (const k of Object.keys(entry)) if (!["facts", "_why"].includes(k)) no(`tool "${tool}": unknown setting "${k}"`);
|
|
5513
|
+
const facts = entry.facts;
|
|
5514
|
+
if (!facts || typeof facts !== "object" || Array.isArray(facts)) no(`tool "${tool}" needs "facts"`);
|
|
5515
|
+
tools[tool] = { facts: {} };
|
|
5516
|
+
for (const fact of Object.keys(facts)) {
|
|
5517
|
+
const where = `${tool}.${fact}`;
|
|
5518
|
+
if (fact === "tool") no(`${where}: "tool" is set by the guard to the tool's name`);
|
|
5519
|
+
if (FORBIDDEN_KEYS.has(fact)) no(`${where} isn't a usable fact name`);
|
|
5520
|
+
const b = facts[fact];
|
|
5521
|
+
if (!b || typeof b !== "object" || Array.isArray(b)) no(`${where} must be an object with "arg"`);
|
|
5522
|
+
for (const k of Object.keys(b)) if (!["arg", "scale", "map", "_why"].includes(k)) no(`${where}: "${k}" isn't allowed. A fact can only come from an argument of the call`);
|
|
5523
|
+
if (typeof b.arg !== "string" || !b.arg) no(`${where} needs "arg", the argument it comes from`);
|
|
5524
|
+
if (b.arg.split(".").some((s) => !s || FORBIDDEN_KEYS.has(s))) no(`${where}: "${b.arg}" isn't a usable argument path`);
|
|
5525
|
+
if (b.scale !== void 0 && b.map !== void 0) no(`${where}: use "scale" or "map", not both`);
|
|
5526
|
+
if (b.scale !== void 0 && (typeof b.scale !== "number" || !Number.isFinite(b.scale) || b.scale === 0)) no(`${where}: "scale" must be a non-zero number`);
|
|
5527
|
+
if (b.map !== void 0) {
|
|
5528
|
+
if (!b.map || typeof b.map !== "object" || Array.isArray(b.map)) no(`${where}: "map" must be an object`);
|
|
5529
|
+
for (const k of Object.keys(b.map)) if (FORBIDDEN_KEYS.has(k) || !isScalar(b.map[k])) no(`${where}: "map" can only hold plain values`);
|
|
5530
|
+
}
|
|
5531
|
+
tools[tool].facts[fact] = { arg: b.arg, ...b.scale !== void 0 ? { scale: b.scale } : {}, ...b.map !== void 0 ? { map: b.map } : {} };
|
|
5532
|
+
}
|
|
5533
|
+
}
|
|
5534
|
+
return { version: 1, artifact: obj.artifact, reviewed: obj.reviewed, tools };
|
|
5535
|
+
}
|
|
5536
|
+
function applyToolBindings(bindings, tool, args) {
|
|
5537
|
+
const inputs = { tool };
|
|
5538
|
+
const unresolved = [];
|
|
5539
|
+
const facts = hasOwn(bindings.tools, tool) ? bindings.tools[tool].facts : {};
|
|
5540
|
+
for (const [fact, b] of Object.entries(facts)) {
|
|
5541
|
+
let v = args;
|
|
5542
|
+
for (const seg of b.arg.split(".")) v = v && typeof v === "object" && !Array.isArray(v) && hasOwn(v, seg) ? v[seg] : void 0;
|
|
5543
|
+
if (v === void 0 || v === null) {
|
|
5544
|
+
unresolved.push({ fact, arg: b.arg, why: "missing" });
|
|
5545
|
+
continue;
|
|
5546
|
+
}
|
|
5547
|
+
if (b.scale !== void 0) {
|
|
5548
|
+
if (typeof v !== "number" || !Number.isFinite(v)) {
|
|
5549
|
+
unresolved.push({ fact, arg: b.arg, why: "not_a_number" });
|
|
5550
|
+
continue;
|
|
5551
|
+
}
|
|
5552
|
+
inputs[fact] = Number((v * b.scale).toFixed(9));
|
|
5553
|
+
continue;
|
|
5554
|
+
}
|
|
5555
|
+
if (!isScalar(v)) {
|
|
5556
|
+
unresolved.push({ fact, arg: b.arg, why: "not_a_value" });
|
|
5557
|
+
continue;
|
|
5558
|
+
}
|
|
5559
|
+
if (b.map) {
|
|
5560
|
+
if (!hasOwn(b.map, String(v))) {
|
|
5561
|
+
unresolved.push({ fact, arg: b.arg, why: "not_in_map" });
|
|
5562
|
+
continue;
|
|
5563
|
+
}
|
|
5564
|
+
inputs[fact] = b.map[String(v)];
|
|
5565
|
+
continue;
|
|
5566
|
+
}
|
|
5567
|
+
inputs[fact] = v;
|
|
5568
|
+
}
|
|
5569
|
+
return { inputs, unresolved };
|
|
5570
|
+
}
|
|
5571
|
+
var WEAK = /* @__PURE__ */ new Set(["is", "has", "the", "a", "an", "of", "to", "in", "id", "name", "type", "value", "status", "code", "data", "info", "flag", "number", "num", "total", "ai", "system"]);
|
|
5572
|
+
var UNITS = { cents: 0.01, pence: 0.01, fils: 0.01, usd: null, dollars: null, aed: null, eur: null };
|
|
5573
|
+
var words = (name) => name.replace(/([a-z0-9])([A-Z])/g, "$1 $2").split(/[^A-Za-z0-9]+/).map((w) => w.toLowerCase()).filter(Boolean);
|
|
5574
|
+
var flatProperties = (props, prefix = "") => Object.entries(props ?? {}).flatMap(([k, s]) => FORBIDDEN_KEYS.has(k) ? [] : s?.type === "object" && s.properties ? flatProperties(s.properties, `${prefix}${k}.`) : [{ path: `${prefix}${k}`, schema: s }]);
|
|
5575
|
+
function suggestToolBindings(artifact, tools, fields) {
|
|
5576
|
+
const bindings = { version: 1, artifact, reviewed: false, tools: {} };
|
|
5577
|
+
const proposals = [];
|
|
5578
|
+
const unbound = [];
|
|
5579
|
+
for (const tool of tools) {
|
|
5580
|
+
bindings.tools[tool.name] = { facts: {} };
|
|
5581
|
+
const args = flatProperties(tool.inputSchema?.properties);
|
|
5582
|
+
for (const field of fields) {
|
|
5583
|
+
if (field.name === "tool") continue;
|
|
5584
|
+
const want = words(field.name).filter((w) => !WEAK.has(w) && !(w in UNITS));
|
|
5585
|
+
const scored = args.map((a) => {
|
|
5586
|
+
const raw = words(a.path);
|
|
5587
|
+
const have = raw.filter((w) => !WEAK.has(w) && !(w in UNITS));
|
|
5588
|
+
const shared = want.filter((w) => have.includes(w));
|
|
5589
|
+
const unit = raw.find((w) => w in UNITS);
|
|
5590
|
+
const same = words(field.name).join("_") === raw.join("_");
|
|
5591
|
+
const sameCore = want.length > 0 && want.length === have.length && shared.length === want.length;
|
|
5592
|
+
return { a, shared, unit, same, sameCore, score: same ? 3 : sameCore ? 2 : shared.length ? shared.length / Math.max(want.length, have.length) : 0 };
|
|
5593
|
+
}).filter((s) => s.score > 0).sort((x, y) => y.score - x.score);
|
|
5594
|
+
if (!scored.length) {
|
|
5595
|
+
unbound.push({ tool: tool.name, fact: field.name, candidates: [] });
|
|
5596
|
+
continue;
|
|
5597
|
+
}
|
|
5598
|
+
const best = scored[0];
|
|
5599
|
+
if (scored[1] && scored[1].score === best.score) {
|
|
5600
|
+
unbound.push({ tool: tool.name, fact: field.name, candidates: scored.filter((s) => s.score === best.score).map((s) => s.a.path) });
|
|
5601
|
+
continue;
|
|
5602
|
+
}
|
|
5603
|
+
const scale = best.unit ? UNITS[best.unit] ?? void 0 : void 0;
|
|
5604
|
+
const why = best.same ? "the same name" : best.sameCore ? "the same words" : `shares "${best.shared.join(", ")}"`;
|
|
5605
|
+
proposals.push({ tool: tool.name, fact: field.name, arg: best.a.path, confidence: best.same || best.sameCore ? "exact" : "likely", why: scale ? `${why}; ${best.unit} scaled by ${scale}` : why, ...scale ? { scale } : {} });
|
|
5606
|
+
bindings.tools[tool.name].facts[field.name] = { arg: best.a.path, ...scale ? { scale } : {} };
|
|
5607
|
+
}
|
|
5608
|
+
}
|
|
5609
|
+
return { bindings, proposals, unbound };
|
|
5610
|
+
}
|
|
5611
|
+
function describeSuggestion(s) {
|
|
5612
|
+
const lines = [];
|
|
5613
|
+
for (const tool of Object.keys(s.bindings.tools)) {
|
|
5614
|
+
lines.push(`
|
|
5615
|
+
${tool}`);
|
|
5616
|
+
for (const p of s.proposals.filter((x) => x.tool === tool)) lines.push(` ${p.confidence === "exact" ? "matched " : "CHECK "} ${p.fact} <- ${p.arg}${p.scale ? ` x ${p.scale}` : ""} (${p.why})`);
|
|
5617
|
+
for (const u of s.unbound.filter((x) => x.tool === tool)) lines.push(` NO MATCH ${u.fact}${u.candidates.length ? ` (could be: ${u.candidates.join(", ")})` : ""}`);
|
|
5618
|
+
}
|
|
5619
|
+
return lines.join("\n");
|
|
5620
|
+
}
|
|
5621
|
+
|
|
5476
5622
|
// src/act/bytes.ts
|
|
5477
5623
|
var utf82 = (s) => new TextEncoder().encode(s);
|
|
5478
5624
|
var fromUtf82 = (b) => new TextDecoder().decode(b);
|
|
@@ -7034,12 +7180,14 @@ ${buttons}</body>`;
|
|
|
7034
7180
|
WELL_KNOWN,
|
|
7035
7181
|
accept,
|
|
7036
7182
|
act,
|
|
7183
|
+
applyToolBindings,
|
|
7037
7184
|
approver,
|
|
7038
7185
|
bindingDigest,
|
|
7039
7186
|
buildAct,
|
|
7040
7187
|
can,
|
|
7041
7188
|
certificateRegistry,
|
|
7042
7189
|
certify,
|
|
7190
|
+
describeSuggestion,
|
|
7043
7191
|
fetchDocument,
|
|
7044
7192
|
generateSigner,
|
|
7045
7193
|
issuer,
|
|
@@ -7050,6 +7198,7 @@ ${buttons}</body>`;
|
|
|
7050
7198
|
memoryStore,
|
|
7051
7199
|
nomos,
|
|
7052
7200
|
originOf,
|
|
7201
|
+
parseToolBindings,
|
|
7053
7202
|
passkeyApprover,
|
|
7054
7203
|
postgresPasskeyStore,
|
|
7055
7204
|
postgresRegistryStore,
|
|
@@ -7068,6 +7217,7 @@ ${buttons}</body>`;
|
|
|
7068
7217
|
signRevocationList,
|
|
7069
7218
|
signTestimony,
|
|
7070
7219
|
statusFor,
|
|
7220
|
+
suggestToolBindings,
|
|
7071
7221
|
verifyAct,
|
|
7072
7222
|
verifyArtifact,
|
|
7073
7223
|
verifyChain,
|
package/dist/index.d.cts
CHANGED
|
@@ -88,6 +88,17 @@ interface CanOptions {
|
|
|
88
88
|
baseUrl?: string;
|
|
89
89
|
/** AbortSignal to cancel the request. */
|
|
90
90
|
signal?: AbortSignal;
|
|
91
|
+
/** Who is asking, recorded on the transcript (sent as X-Nomos-Agent / -Acts-For / -Purpose).
|
|
92
|
+
* `purpose: 'test'` queries are answered and sealed but kept out of the authority's public
|
|
93
|
+
* history and counts — set it from tests and CI. Exchange authorities only. */
|
|
94
|
+
caller?: CanCaller;
|
|
95
|
+
}
|
|
96
|
+
interface CanCaller {
|
|
97
|
+
/** A stable name for your agent, e.g. "acme-credit-agent". */
|
|
98
|
+
agent_id?: string;
|
|
99
|
+
/** The organisation it acts for. Ignored when the request carries an API key (the key's account is used). */
|
|
100
|
+
acts_for?: string;
|
|
101
|
+
purpose?: 'production' | 'test';
|
|
91
102
|
}
|
|
92
103
|
interface CanResult {
|
|
93
104
|
/** True only for an AUTHORIZED verdict. DENIED and ESCALATED are both `false`. */
|
|
@@ -395,7 +406,7 @@ interface GenerateGovernanceResult {
|
|
|
395
406
|
download_url?: string;
|
|
396
407
|
}
|
|
397
408
|
interface NomosConfig {
|
|
398
|
-
/** Base URL override — defaults to https://
|
|
409
|
+
/** Base URL override — defaults to https://www.nomosprotocol.com */
|
|
399
410
|
baseUrl?: string;
|
|
400
411
|
/** Max retries on 429 / 5xx (default: 3) */
|
|
401
412
|
maxRetries?: number;
|
|
@@ -411,6 +422,8 @@ interface RequestOptions {
|
|
|
411
422
|
idempotencyKey?: string;
|
|
412
423
|
/** Per-request API key — useful for multi-tenant platforms */
|
|
413
424
|
apiKey?: string;
|
|
425
|
+
/** Extra request headers. */
|
|
426
|
+
headers?: Record<string, string>;
|
|
414
427
|
}
|
|
415
428
|
interface NomosRawResponse {
|
|
416
429
|
/** x-request-id header value — include in support tickets */
|
|
@@ -776,7 +789,7 @@ declare class Nomos {
|
|
|
776
789
|
* return shape either way, so calling code never needs to know which rail answered.
|
|
777
790
|
*
|
|
778
791
|
* @example
|
|
779
|
-
* const client = new Nomos('
|
|
792
|
+
* const client = new Nomos('nmk_...');
|
|
780
793
|
* const verdict = await client.can({ artifact_id: 'loan_approval_v1', credit_score: 720 });
|
|
781
794
|
*/
|
|
782
795
|
can(params: CanParams, opts?: CanOptions): Promise<CanResult>;
|
|
@@ -807,6 +820,86 @@ declare const nomos: {
|
|
|
807
820
|
*/
|
|
808
821
|
declare function verifyChain(params: VerifyChainParams, opts?: VerifyChainOptions): Promise<VerifyChainResult>;
|
|
809
822
|
|
|
823
|
+
/**
|
|
824
|
+
* Tool bindings: which of a tool's arguments is which fact a sealed policy reads. A policy reads
|
|
825
|
+
* `loan_amount`; a tool sends `amount_cents`. Without a binding the policy has nothing to decide on,
|
|
826
|
+
* and a fail-closed check holds every call.
|
|
827
|
+
*
|
|
828
|
+
* A binding decides what a policy sees, so it is built to be safe:
|
|
829
|
+
* - It is an explicit, reviewed file. Suggestions are proposals, marked unreviewed.
|
|
830
|
+
* - A fact only ever comes from an argument of the call. There are no constants, so nobody can
|
|
831
|
+
* hard-code a fact to quiet a policy.
|
|
832
|
+
* - With a binding, only bound facts reach the policy, so an agent can't state a fact the tool
|
|
833
|
+
* wouldn't act on by adding an argument of that name.
|
|
834
|
+
* - A missing argument or an unmapped value leaves the fact undecided. It is never guessed.
|
|
835
|
+
*
|
|
836
|
+
* Pure: no I/O, no model. Specified in NOMOS-SPEC-011 (Draft), nomos-spec/spec; see also
|
|
837
|
+
* docs/design-notes/tool-fact-binding.md.
|
|
838
|
+
*/
|
|
839
|
+
interface FactBinding {
|
|
840
|
+
/** The argument this fact comes from. Dots reach into objects: `customer.kyc`. */
|
|
841
|
+
arg: string;
|
|
842
|
+
/** Multiply a number: `amount_cents` into dollars is 0.01. */
|
|
843
|
+
scale?: number;
|
|
844
|
+
/** Translate a value: { "ok": "verified" }. A value not listed leaves the fact undecided. */
|
|
845
|
+
map?: Record<string, string | number | boolean>;
|
|
846
|
+
}
|
|
847
|
+
interface ToolBindings {
|
|
848
|
+
version: 1;
|
|
849
|
+
/** The sealed policy these facts belong to. */
|
|
850
|
+
artifact: string;
|
|
851
|
+
/** False until a person has checked it. The guard won't enforce an unreviewed file. */
|
|
852
|
+
reviewed: boolean;
|
|
853
|
+
tools: Record<string, {
|
|
854
|
+
facts: Record<string, FactBinding>;
|
|
855
|
+
}>;
|
|
856
|
+
}
|
|
857
|
+
/** Reads a bindings file, refusing anything it doesn't fully understand. Throws with a plain reason. */
|
|
858
|
+
declare function parseToolBindings(raw: unknown): ToolBindings;
|
|
859
|
+
interface UnresolvedFact {
|
|
860
|
+
fact: string;
|
|
861
|
+
arg: string;
|
|
862
|
+
why: 'missing' | 'not_a_number' | 'not_a_value' | 'not_in_map';
|
|
863
|
+
}
|
|
864
|
+
/** The facts a policy gets for this call, and which it couldn't get. */
|
|
865
|
+
declare function applyToolBindings(bindings: ToolBindings, tool: string, args: Record<string, unknown>): {
|
|
866
|
+
inputs: Record<string, string | number | boolean>;
|
|
867
|
+
unresolved: UnresolvedFact[];
|
|
868
|
+
};
|
|
869
|
+
interface ToolDescription {
|
|
870
|
+
name: string;
|
|
871
|
+
inputSchema?: {
|
|
872
|
+
properties?: Record<string, any>;
|
|
873
|
+
} | null;
|
|
874
|
+
}
|
|
875
|
+
interface PolicyField {
|
|
876
|
+
name: string;
|
|
877
|
+
type?: string;
|
|
878
|
+
description?: string | null;
|
|
879
|
+
values?: string[];
|
|
880
|
+
}
|
|
881
|
+
interface BindingProposal {
|
|
882
|
+
tool: string;
|
|
883
|
+
fact: string;
|
|
884
|
+
arg: string;
|
|
885
|
+
confidence: 'exact' | 'likely';
|
|
886
|
+
why: string;
|
|
887
|
+
scale?: number;
|
|
888
|
+
}
|
|
889
|
+
interface BindingSuggestion {
|
|
890
|
+
bindings: ToolBindings;
|
|
891
|
+
proposals: BindingProposal[];
|
|
892
|
+
unbound: Array<{
|
|
893
|
+
tool: string;
|
|
894
|
+
fact: string;
|
|
895
|
+
candidates: string[];
|
|
896
|
+
}>;
|
|
897
|
+
}
|
|
898
|
+
/** Proposes bindings from names alone, for a person to check. Never guesses a value translation. */
|
|
899
|
+
declare function suggestToolBindings(artifact: string, tools: ToolDescription[], fields: PolicyField[]): BindingSuggestion;
|
|
900
|
+
/** A plain report of a suggestion, for the person who has to check it. */
|
|
901
|
+
declare function describeSuggestion(s: BindingSuggestion): string;
|
|
902
|
+
|
|
810
903
|
type SignatureSuite = 'Ed25519' | 'ES256';
|
|
811
904
|
interface Signer {
|
|
812
905
|
/** NOMOS-SPEC-001 §8.4 key id of the public key. */
|
|
@@ -1542,4 +1635,4 @@ declare function approver(o: ApproverOptions): {
|
|
|
1542
1635
|
pending: Map<string, Pending>;
|
|
1543
1636
|
};
|
|
1544
1637
|
|
|
1545
|
-
export { ACT_MEDIA_TYPE, type AcceptOptions, type AcceptStore, type AcceptTransaction, type AcceptedAuthority, type KeyCertificate as ActKeyCertificate, type ActOptions, type ActResult, type ActStatus, type Action, type Answer, type ApproverOptions, type Artifact, type ArtifactList, type ArtifactSchema, type ArtifactSchemaField, type AttestationInfo, type BuildActOptions, type CanOptions, type CanParams, type CanResult, type CanVerdict, type CertificateRegistry, type ChainVerdictDecision, type ConservedStateInfo, type ConservedStateReceipt, type Contradiction, type DetectContradictionsParams, type DetectContradictionsResult, type EnrolmentClaims, type GenerateGovernanceParams, type GenerateGovernanceResult, type IssueOptions, type IssuerDocument, type IssuerOptions, type KeyCertificate$1 as KeyCertificate, type ListArtifactsParams, MAX_PRESENTED, Nomos, NomosAPIError, NomosActError, NomosAuthenticationError, NomosAuthorizationError, type NomosConfig, NomosDiscoveryError, NomosError, type NomosErrorCode, NomosIssuerNotTrustedError, NomosNetworkError, NomosNotFoundError, NomosPaymentRequiredError, NomosRateLimitError, type NomosRawResponse, NomosValidationError, type NomosWebhookEvent, type NomosWebhookEventType, NomosWebhookSignatureError, type PasskeyApproverOptions, type PasskeyCredential, type PasskeyStore, type PendingApproval, type PgClient, type PgPool, type PostgresStoreOptions, type Receipt, RegistryError, type RegistryStore, type RelyingPartyDocument, type RequestOptions, type Reservation, type ReserveByActParams, type ReserveByQueryParams, type ReserveParams, type RevocationSourceOptions, RevocationUnavailable, type SignatureSuite, type Signer, type Verdict, type VerifyChainOptions, type VerifyChainParams, type VerifyChainResult, type VerifyDecisionParams, type VerifyDecisionResult, WELL_KNOWN, type WithLastResponse, type WitnessDocument, type WitnessOptions, accept, act, approver, buildAct, can, certificateRegistry, certify, fetchDocument, generateSigner, issuer, kidOf, localSigner, memoryPasskeyStore, memoryRegistryStore, memoryStore, nomos, originOf, passkeyApprover, postgresPasskeyStore, postgresRegistryStore, postgresStore, presentedCertificates, readAttestation, reliedKids, revocationListCertificates, revocationSource, seal, seededSigner, signConsent, signEnrolmentToken, signInForce, signRevocation, signRevocationList, signTestimony, statusFor, verifyChain, verifyEnrolmentToken, witness };
|
|
1638
|
+
export { ACT_MEDIA_TYPE, type AcceptOptions, type AcceptStore, type AcceptTransaction, type AcceptedAuthority, type KeyCertificate as ActKeyCertificate, type ActOptions, type ActResult, type ActStatus, type Action, type Answer, type ApproverOptions, type Artifact, type ArtifactList, type ArtifactSchema, type ArtifactSchemaField, type AttestationInfo, type BindingProposal, type BindingSuggestion, type BuildActOptions, type CanCaller, type CanOptions, type CanParams, type CanResult, type CanVerdict, type CertificateRegistry, type ChainVerdictDecision, type ConservedStateInfo, type ConservedStateReceipt, type Contradiction, type DetectContradictionsParams, type DetectContradictionsResult, type EnrolmentClaims, type FactBinding, type GenerateGovernanceParams, type GenerateGovernanceResult, type IssueOptions, type IssuerDocument, type IssuerOptions, type KeyCertificate$1 as KeyCertificate, type ListArtifactsParams, MAX_PRESENTED, Nomos, NomosAPIError, NomosActError, NomosAuthenticationError, NomosAuthorizationError, type NomosConfig, NomosDiscoveryError, NomosError, type NomosErrorCode, NomosIssuerNotTrustedError, NomosNetworkError, NomosNotFoundError, NomosPaymentRequiredError, NomosRateLimitError, type NomosRawResponse, NomosValidationError, type NomosWebhookEvent, type NomosWebhookEventType, NomosWebhookSignatureError, type PasskeyApproverOptions, type PasskeyCredential, type PasskeyStore, type PendingApproval, type PgClient, type PgPool, type PolicyField, type PostgresStoreOptions, type Receipt, RegistryError, type RegistryStore, type RelyingPartyDocument, type RequestOptions, type Reservation, type ReserveByActParams, type ReserveByQueryParams, type ReserveParams, type RevocationSourceOptions, RevocationUnavailable, type SignatureSuite, type Signer, type ToolBindings, type ToolDescription, type UnresolvedFact, type Verdict, type VerifyChainOptions, type VerifyChainParams, type VerifyChainResult, type VerifyDecisionParams, type VerifyDecisionResult, WELL_KNOWN, type WithLastResponse, type WitnessDocument, type WitnessOptions, accept, act, applyToolBindings, approver, buildAct, can, certificateRegistry, certify, describeSuggestion, fetchDocument, generateSigner, issuer, kidOf, localSigner, memoryPasskeyStore, memoryRegistryStore, memoryStore, nomos, originOf, parseToolBindings, passkeyApprover, postgresPasskeyStore, postgresRegistryStore, postgresStore, presentedCertificates, readAttestation, reliedKids, revocationListCertificates, revocationSource, seal, seededSigner, signConsent, signEnrolmentToken, signInForce, signRevocation, signRevocationList, signTestimony, statusFor, suggestToolBindings, verifyChain, verifyEnrolmentToken, witness };
|
package/dist/index.d.ts
CHANGED
|
@@ -88,6 +88,17 @@ interface CanOptions {
|
|
|
88
88
|
baseUrl?: string;
|
|
89
89
|
/** AbortSignal to cancel the request. */
|
|
90
90
|
signal?: AbortSignal;
|
|
91
|
+
/** Who is asking, recorded on the transcript (sent as X-Nomos-Agent / -Acts-For / -Purpose).
|
|
92
|
+
* `purpose: 'test'` queries are answered and sealed but kept out of the authority's public
|
|
93
|
+
* history and counts — set it from tests and CI. Exchange authorities only. */
|
|
94
|
+
caller?: CanCaller;
|
|
95
|
+
}
|
|
96
|
+
interface CanCaller {
|
|
97
|
+
/** A stable name for your agent, e.g. "acme-credit-agent". */
|
|
98
|
+
agent_id?: string;
|
|
99
|
+
/** The organisation it acts for. Ignored when the request carries an API key (the key's account is used). */
|
|
100
|
+
acts_for?: string;
|
|
101
|
+
purpose?: 'production' | 'test';
|
|
91
102
|
}
|
|
92
103
|
interface CanResult {
|
|
93
104
|
/** True only for an AUTHORIZED verdict. DENIED and ESCALATED are both `false`. */
|
|
@@ -395,7 +406,7 @@ interface GenerateGovernanceResult {
|
|
|
395
406
|
download_url?: string;
|
|
396
407
|
}
|
|
397
408
|
interface NomosConfig {
|
|
398
|
-
/** Base URL override — defaults to https://
|
|
409
|
+
/** Base URL override — defaults to https://www.nomosprotocol.com */
|
|
399
410
|
baseUrl?: string;
|
|
400
411
|
/** Max retries on 429 / 5xx (default: 3) */
|
|
401
412
|
maxRetries?: number;
|
|
@@ -411,6 +422,8 @@ interface RequestOptions {
|
|
|
411
422
|
idempotencyKey?: string;
|
|
412
423
|
/** Per-request API key — useful for multi-tenant platforms */
|
|
413
424
|
apiKey?: string;
|
|
425
|
+
/** Extra request headers. */
|
|
426
|
+
headers?: Record<string, string>;
|
|
414
427
|
}
|
|
415
428
|
interface NomosRawResponse {
|
|
416
429
|
/** x-request-id header value — include in support tickets */
|
|
@@ -776,7 +789,7 @@ declare class Nomos {
|
|
|
776
789
|
* return shape either way, so calling code never needs to know which rail answered.
|
|
777
790
|
*
|
|
778
791
|
* @example
|
|
779
|
-
* const client = new Nomos('
|
|
792
|
+
* const client = new Nomos('nmk_...');
|
|
780
793
|
* const verdict = await client.can({ artifact_id: 'loan_approval_v1', credit_score: 720 });
|
|
781
794
|
*/
|
|
782
795
|
can(params: CanParams, opts?: CanOptions): Promise<CanResult>;
|
|
@@ -807,6 +820,86 @@ declare const nomos: {
|
|
|
807
820
|
*/
|
|
808
821
|
declare function verifyChain(params: VerifyChainParams, opts?: VerifyChainOptions): Promise<VerifyChainResult>;
|
|
809
822
|
|
|
823
|
+
/**
|
|
824
|
+
* Tool bindings: which of a tool's arguments is which fact a sealed policy reads. A policy reads
|
|
825
|
+
* `loan_amount`; a tool sends `amount_cents`. Without a binding the policy has nothing to decide on,
|
|
826
|
+
* and a fail-closed check holds every call.
|
|
827
|
+
*
|
|
828
|
+
* A binding decides what a policy sees, so it is built to be safe:
|
|
829
|
+
* - It is an explicit, reviewed file. Suggestions are proposals, marked unreviewed.
|
|
830
|
+
* - A fact only ever comes from an argument of the call. There are no constants, so nobody can
|
|
831
|
+
* hard-code a fact to quiet a policy.
|
|
832
|
+
* - With a binding, only bound facts reach the policy, so an agent can't state a fact the tool
|
|
833
|
+
* wouldn't act on by adding an argument of that name.
|
|
834
|
+
* - A missing argument or an unmapped value leaves the fact undecided. It is never guessed.
|
|
835
|
+
*
|
|
836
|
+
* Pure: no I/O, no model. Specified in NOMOS-SPEC-011 (Draft), nomos-spec/spec; see also
|
|
837
|
+
* docs/design-notes/tool-fact-binding.md.
|
|
838
|
+
*/
|
|
839
|
+
interface FactBinding {
|
|
840
|
+
/** The argument this fact comes from. Dots reach into objects: `customer.kyc`. */
|
|
841
|
+
arg: string;
|
|
842
|
+
/** Multiply a number: `amount_cents` into dollars is 0.01. */
|
|
843
|
+
scale?: number;
|
|
844
|
+
/** Translate a value: { "ok": "verified" }. A value not listed leaves the fact undecided. */
|
|
845
|
+
map?: Record<string, string | number | boolean>;
|
|
846
|
+
}
|
|
847
|
+
interface ToolBindings {
|
|
848
|
+
version: 1;
|
|
849
|
+
/** The sealed policy these facts belong to. */
|
|
850
|
+
artifact: string;
|
|
851
|
+
/** False until a person has checked it. The guard won't enforce an unreviewed file. */
|
|
852
|
+
reviewed: boolean;
|
|
853
|
+
tools: Record<string, {
|
|
854
|
+
facts: Record<string, FactBinding>;
|
|
855
|
+
}>;
|
|
856
|
+
}
|
|
857
|
+
/** Reads a bindings file, refusing anything it doesn't fully understand. Throws with a plain reason. */
|
|
858
|
+
declare function parseToolBindings(raw: unknown): ToolBindings;
|
|
859
|
+
interface UnresolvedFact {
|
|
860
|
+
fact: string;
|
|
861
|
+
arg: string;
|
|
862
|
+
why: 'missing' | 'not_a_number' | 'not_a_value' | 'not_in_map';
|
|
863
|
+
}
|
|
864
|
+
/** The facts a policy gets for this call, and which it couldn't get. */
|
|
865
|
+
declare function applyToolBindings(bindings: ToolBindings, tool: string, args: Record<string, unknown>): {
|
|
866
|
+
inputs: Record<string, string | number | boolean>;
|
|
867
|
+
unresolved: UnresolvedFact[];
|
|
868
|
+
};
|
|
869
|
+
interface ToolDescription {
|
|
870
|
+
name: string;
|
|
871
|
+
inputSchema?: {
|
|
872
|
+
properties?: Record<string, any>;
|
|
873
|
+
} | null;
|
|
874
|
+
}
|
|
875
|
+
interface PolicyField {
|
|
876
|
+
name: string;
|
|
877
|
+
type?: string;
|
|
878
|
+
description?: string | null;
|
|
879
|
+
values?: string[];
|
|
880
|
+
}
|
|
881
|
+
interface BindingProposal {
|
|
882
|
+
tool: string;
|
|
883
|
+
fact: string;
|
|
884
|
+
arg: string;
|
|
885
|
+
confidence: 'exact' | 'likely';
|
|
886
|
+
why: string;
|
|
887
|
+
scale?: number;
|
|
888
|
+
}
|
|
889
|
+
interface BindingSuggestion {
|
|
890
|
+
bindings: ToolBindings;
|
|
891
|
+
proposals: BindingProposal[];
|
|
892
|
+
unbound: Array<{
|
|
893
|
+
tool: string;
|
|
894
|
+
fact: string;
|
|
895
|
+
candidates: string[];
|
|
896
|
+
}>;
|
|
897
|
+
}
|
|
898
|
+
/** Proposes bindings from names alone, for a person to check. Never guesses a value translation. */
|
|
899
|
+
declare function suggestToolBindings(artifact: string, tools: ToolDescription[], fields: PolicyField[]): BindingSuggestion;
|
|
900
|
+
/** A plain report of a suggestion, for the person who has to check it. */
|
|
901
|
+
declare function describeSuggestion(s: BindingSuggestion): string;
|
|
902
|
+
|
|
810
903
|
type SignatureSuite = 'Ed25519' | 'ES256';
|
|
811
904
|
interface Signer {
|
|
812
905
|
/** NOMOS-SPEC-001 §8.4 key id of the public key. */
|
|
@@ -1542,4 +1635,4 @@ declare function approver(o: ApproverOptions): {
|
|
|
1542
1635
|
pending: Map<string, Pending>;
|
|
1543
1636
|
};
|
|
1544
1637
|
|
|
1545
|
-
export { ACT_MEDIA_TYPE, type AcceptOptions, type AcceptStore, type AcceptTransaction, type AcceptedAuthority, type KeyCertificate as ActKeyCertificate, type ActOptions, type ActResult, type ActStatus, type Action, type Answer, type ApproverOptions, type Artifact, type ArtifactList, type ArtifactSchema, type ArtifactSchemaField, type AttestationInfo, type BuildActOptions, type CanOptions, type CanParams, type CanResult, type CanVerdict, type CertificateRegistry, type ChainVerdictDecision, type ConservedStateInfo, type ConservedStateReceipt, type Contradiction, type DetectContradictionsParams, type DetectContradictionsResult, type EnrolmentClaims, type GenerateGovernanceParams, type GenerateGovernanceResult, type IssueOptions, type IssuerDocument, type IssuerOptions, type KeyCertificate$1 as KeyCertificate, type ListArtifactsParams, MAX_PRESENTED, Nomos, NomosAPIError, NomosActError, NomosAuthenticationError, NomosAuthorizationError, type NomosConfig, NomosDiscoveryError, NomosError, type NomosErrorCode, NomosIssuerNotTrustedError, NomosNetworkError, NomosNotFoundError, NomosPaymentRequiredError, NomosRateLimitError, type NomosRawResponse, NomosValidationError, type NomosWebhookEvent, type NomosWebhookEventType, NomosWebhookSignatureError, type PasskeyApproverOptions, type PasskeyCredential, type PasskeyStore, type PendingApproval, type PgClient, type PgPool, type PostgresStoreOptions, type Receipt, RegistryError, type RegistryStore, type RelyingPartyDocument, type RequestOptions, type Reservation, type ReserveByActParams, type ReserveByQueryParams, type ReserveParams, type RevocationSourceOptions, RevocationUnavailable, type SignatureSuite, type Signer, type Verdict, type VerifyChainOptions, type VerifyChainParams, type VerifyChainResult, type VerifyDecisionParams, type VerifyDecisionResult, WELL_KNOWN, type WithLastResponse, type WitnessDocument, type WitnessOptions, accept, act, approver, buildAct, can, certificateRegistry, certify, fetchDocument, generateSigner, issuer, kidOf, localSigner, memoryPasskeyStore, memoryRegistryStore, memoryStore, nomos, originOf, passkeyApprover, postgresPasskeyStore, postgresRegistryStore, postgresStore, presentedCertificates, readAttestation, reliedKids, revocationListCertificates, revocationSource, seal, seededSigner, signConsent, signEnrolmentToken, signInForce, signRevocation, signRevocationList, signTestimony, statusFor, verifyChain, verifyEnrolmentToken, witness };
|
|
1638
|
+
export { ACT_MEDIA_TYPE, type AcceptOptions, type AcceptStore, type AcceptTransaction, type AcceptedAuthority, type KeyCertificate as ActKeyCertificate, type ActOptions, type ActResult, type ActStatus, type Action, type Answer, type ApproverOptions, type Artifact, type ArtifactList, type ArtifactSchema, type ArtifactSchemaField, type AttestationInfo, type BindingProposal, type BindingSuggestion, type BuildActOptions, type CanCaller, type CanOptions, type CanParams, type CanResult, type CanVerdict, type CertificateRegistry, type ChainVerdictDecision, type ConservedStateInfo, type ConservedStateReceipt, type Contradiction, type DetectContradictionsParams, type DetectContradictionsResult, type EnrolmentClaims, type FactBinding, type GenerateGovernanceParams, type GenerateGovernanceResult, type IssueOptions, type IssuerDocument, type IssuerOptions, type KeyCertificate$1 as KeyCertificate, type ListArtifactsParams, MAX_PRESENTED, Nomos, NomosAPIError, NomosActError, NomosAuthenticationError, NomosAuthorizationError, type NomosConfig, NomosDiscoveryError, NomosError, type NomosErrorCode, NomosIssuerNotTrustedError, NomosNetworkError, NomosNotFoundError, NomosPaymentRequiredError, NomosRateLimitError, type NomosRawResponse, NomosValidationError, type NomosWebhookEvent, type NomosWebhookEventType, NomosWebhookSignatureError, type PasskeyApproverOptions, type PasskeyCredential, type PasskeyStore, type PendingApproval, type PgClient, type PgPool, type PolicyField, type PostgresStoreOptions, type Receipt, RegistryError, type RegistryStore, type RelyingPartyDocument, type RequestOptions, type Reservation, type ReserveByActParams, type ReserveByQueryParams, type ReserveParams, type RevocationSourceOptions, RevocationUnavailable, type SignatureSuite, type Signer, type ToolBindings, type ToolDescription, type UnresolvedFact, type Verdict, type VerifyChainOptions, type VerifyChainParams, type VerifyChainResult, type VerifyDecisionParams, type VerifyDecisionResult, WELL_KNOWN, type WithLastResponse, type WitnessDocument, type WitnessOptions, accept, act, applyToolBindings, approver, buildAct, can, certificateRegistry, certify, describeSuggestion, fetchDocument, generateSigner, issuer, kidOf, localSigner, memoryPasskeyStore, memoryRegistryStore, memoryStore, nomos, originOf, parseToolBindings, passkeyApprover, postgresPasskeyStore, postgresRegistryStore, postgresStore, presentedCertificates, readAttestation, reliedKids, revocationListCertificates, revocationSource, seal, seededSigner, signConsent, signEnrolmentToken, signInForce, signRevocation, signRevocationList, signTestimony, statusFor, suggestToolBindings, verifyChain, verifyEnrolmentToken, witness };
|
package/dist/index.js
CHANGED
|
@@ -107,7 +107,7 @@ function isRetryable(status) {
|
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
// src/http-client.ts
|
|
110
|
-
var SDK_VERSION = "
|
|
110
|
+
var SDK_VERSION = "2.3.2";
|
|
111
111
|
var HttpClient = class {
|
|
112
112
|
constructor(opts) {
|
|
113
113
|
this.opts = opts;
|
|
@@ -131,6 +131,7 @@ var HttpClient = class {
|
|
|
131
131
|
"User-Agent": `nomos-node/${SDK_VERSION}`,
|
|
132
132
|
"NOMOS-SDK-Version": SDK_VERSION
|
|
133
133
|
};
|
|
134
|
+
if (reqOpts?.headers) Object.assign(headers, reqOpts.headers);
|
|
134
135
|
if (reqOpts?.idempotencyKey) {
|
|
135
136
|
headers["Idempotency-Key"] = reqOpts.idempotencyKey;
|
|
136
137
|
}
|
|
@@ -639,6 +640,13 @@ function normalizeAuthorityQueryResult(data, authority) {
|
|
|
639
640
|
...data.revoked === true ? { revoked: true, revocation_reason: data.revocation_reason } : {}
|
|
640
641
|
};
|
|
641
642
|
}
|
|
643
|
+
function callerHeaders(c) {
|
|
644
|
+
const h = {};
|
|
645
|
+
if (c?.agent_id) h["X-Nomos-Agent"] = c.agent_id;
|
|
646
|
+
if (c?.acts_for) h["X-Nomos-Acts-For"] = c.acts_for;
|
|
647
|
+
if (c?.purpose) h["X-Nomos-Purpose"] = c.purpose;
|
|
648
|
+
return h;
|
|
649
|
+
}
|
|
642
650
|
async function canViaExchange(authority, facts, action, opts) {
|
|
643
651
|
const base = (opts?.baseUrl ?? DEFAULT_EXCHANGE_BASE).replace(/\/$/, "");
|
|
644
652
|
const url = `${base}/api/v1/can`;
|
|
@@ -646,7 +654,7 @@ async function canViaExchange(authority, facts, action, opts) {
|
|
|
646
654
|
try {
|
|
647
655
|
res = await fetch(url, {
|
|
648
656
|
method: "POST",
|
|
649
|
-
headers: { "Content-Type": "application/json" },
|
|
657
|
+
headers: { "Content-Type": "application/json", "User-Agent": `nomos-node/${SDK_VERSION}`, ...callerHeaders(opts?.caller) },
|
|
650
658
|
body: JSON.stringify({ artifact: authority, action, ...facts }),
|
|
651
659
|
signal: opts?.signal
|
|
652
660
|
});
|
|
@@ -659,8 +667,8 @@ async function canViaExchange(authority, facts, action, opts) {
|
|
|
659
667
|
if (!res.ok) mapHttpError(res.status, data, requestId);
|
|
660
668
|
return normalizeAuthorityQueryResult(data, authority);
|
|
661
669
|
}
|
|
662
|
-
async function canViaExchangeAuthenticated(http, authority, facts, action) {
|
|
663
|
-
const { data } = await http.post("/api/v1/can", { artifact: authority, action, ...facts });
|
|
670
|
+
async function canViaExchangeAuthenticated(http, authority, facts, action, caller) {
|
|
671
|
+
const { data } = await http.post("/api/v1/can", { artifact: authority, action, ...facts }, { headers: callerHeaders(caller) });
|
|
664
672
|
return normalizeAuthorityQueryResult(data, authority);
|
|
665
673
|
}
|
|
666
674
|
async function canViaArtifact(http, artifactId, facts, action) {
|
|
@@ -757,7 +765,6 @@ async function can(params, opts) {
|
|
|
757
765
|
return canViaExchange(params.authority, facts, action, opts);
|
|
758
766
|
}
|
|
759
767
|
async function canAuthenticated(http, params, opts) {
|
|
760
|
-
void opts;
|
|
761
768
|
const { facts, action } = splitFacts(params);
|
|
762
769
|
if (params.artifact !== void 0) {
|
|
763
770
|
if (!params.key_certs || !params.root_public_key_pem) {
|
|
@@ -766,13 +773,13 @@ async function canAuthenticated(http, params, opts) {
|
|
|
766
773
|
return canViaChain(params.artifact, params.key_certs, params.root_public_key_pem, facts, action, opts);
|
|
767
774
|
}
|
|
768
775
|
if (params.artifact_id) return canViaArtifact(http, params.artifact_id, facts, action);
|
|
769
|
-
if (params.authority) return canViaExchangeAuthenticated(http, params.authority, facts, action);
|
|
776
|
+
if (params.authority) return canViaExchangeAuthenticated(http, params.authority, facts, action, opts?.caller);
|
|
770
777
|
throw new Error("can(): `authority` (a public Exchange artifact), `artifact_id` (your own artifact), or `artifact` (chain-of-trust) is required.");
|
|
771
778
|
}
|
|
772
779
|
var nomos = { can };
|
|
773
780
|
|
|
774
781
|
// src/nomos.ts
|
|
775
|
-
var DEFAULT_BASE_URL = "https://
|
|
782
|
+
var DEFAULT_BASE_URL = "https://www.nomosprotocol.com";
|
|
776
783
|
var DEFAULT_MAX_RETRIES = 3;
|
|
777
784
|
var DEFAULT_TIMEOUT = 3e4;
|
|
778
785
|
var Nomos = class {
|
|
@@ -782,7 +789,7 @@ var Nomos = class {
|
|
|
782
789
|
constructor(apiKey, config = {}) {
|
|
783
790
|
if (!apiKey || typeof apiKey !== "string") {
|
|
784
791
|
throw new NomosAuthenticationError(
|
|
785
|
-
'A valid API key is required. Pass it as the first argument: new Nomos("
|
|
792
|
+
'A valid API key is required. Pass it as the first argument: new Nomos("nmk_...")'
|
|
786
793
|
);
|
|
787
794
|
}
|
|
788
795
|
this.mode = apiKey.startsWith("nms_test_") ? "test" : "live";
|
|
@@ -804,7 +811,7 @@ var Nomos = class {
|
|
|
804
811
|
* return shape either way, so calling code never needs to know which rail answered.
|
|
805
812
|
*
|
|
806
813
|
* @example
|
|
807
|
-
* const client = new Nomos('
|
|
814
|
+
* const client = new Nomos('nmk_...');
|
|
808
815
|
* const verdict = await client.can({ artifact_id: 'loan_approval_v1', credit_score: 720 });
|
|
809
816
|
*/
|
|
810
817
|
async can(params, opts) {
|
|
@@ -4967,9 +4974,14 @@ var TIE_ORDERS = {
|
|
|
4967
4974
|
function evaluate(artifact, facts) {
|
|
4968
4975
|
const logic = artifact.logic;
|
|
4969
4976
|
const res = logic.resolution ?? {};
|
|
4970
|
-
|
|
4971
|
-
if (!Array.isArray(decisions))
|
|
4977
|
+
if (!Array.isArray(logic.decisions))
|
|
4972
4978
|
throw new Error("logic.decisions missing");
|
|
4979
|
+
const declared = new Set(Object.keys(artifact.execution?.actions ?? {}));
|
|
4980
|
+
const isObligation = (d) => {
|
|
4981
|
+
const t = d?.then?.[0];
|
|
4982
|
+
return t?.type === "emit" || t?.type === "action" && declared.has(t?.action_name);
|
|
4983
|
+
};
|
|
4984
|
+
const decisions = logic.decisions.filter((d) => !isObligation(d));
|
|
4973
4985
|
const order = TIE_ORDERS[res.tie_breaker ?? "deny_wins"];
|
|
4974
4986
|
if (!order)
|
|
4975
4987
|
throw new Error("unknown tie_breaker");
|
|
@@ -5393,6 +5405,136 @@ async function verifyChainRemote(params, opts) {
|
|
|
5393
5405
|
throw new NomosAPIError(message, res.status, requestId);
|
|
5394
5406
|
}
|
|
5395
5407
|
|
|
5408
|
+
// src/bindings.ts
|
|
5409
|
+
var FORBIDDEN_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
5410
|
+
var hasOwn = (o, k) => Object.prototype.hasOwnProperty.call(o, k);
|
|
5411
|
+
var isScalar = (v) => typeof v === "string" || typeof v === "boolean" || typeof v === "number" && Number.isFinite(v);
|
|
5412
|
+
function parseToolBindings(raw) {
|
|
5413
|
+
const no = (why) => {
|
|
5414
|
+
throw new Error(why);
|
|
5415
|
+
};
|
|
5416
|
+
const obj = raw;
|
|
5417
|
+
if (!obj || typeof obj !== "object" || Array.isArray(obj)) no("it is not a JSON object");
|
|
5418
|
+
if (obj.version !== 1) no('"version" must be 1');
|
|
5419
|
+
if (typeof obj.artifact !== "string" || !obj.artifact) no('"artifact" must name the sealed policy');
|
|
5420
|
+
if (typeof obj.reviewed !== "boolean") no('"reviewed" must be true or false');
|
|
5421
|
+
if (!obj.tools || typeof obj.tools !== "object" || Array.isArray(obj.tools)) no('"tools" must be an object');
|
|
5422
|
+
for (const k of Object.keys(obj)) if (!["version", "artifact", "reviewed", "tools", "_review"].includes(k)) no(`unknown setting "${k}"`);
|
|
5423
|
+
const tools = {};
|
|
5424
|
+
for (const tool of Object.keys(obj.tools)) {
|
|
5425
|
+
if (FORBIDDEN_KEYS.has(tool)) no(`"${tool}" isn't a usable tool name`);
|
|
5426
|
+
const entry = obj.tools[tool];
|
|
5427
|
+
if (!entry || typeof entry !== "object" || Array.isArray(entry)) no(`tool "${tool}" must be an object with "facts"`);
|
|
5428
|
+
for (const k of Object.keys(entry)) if (!["facts", "_why"].includes(k)) no(`tool "${tool}": unknown setting "${k}"`);
|
|
5429
|
+
const facts = entry.facts;
|
|
5430
|
+
if (!facts || typeof facts !== "object" || Array.isArray(facts)) no(`tool "${tool}" needs "facts"`);
|
|
5431
|
+
tools[tool] = { facts: {} };
|
|
5432
|
+
for (const fact of Object.keys(facts)) {
|
|
5433
|
+
const where = `${tool}.${fact}`;
|
|
5434
|
+
if (fact === "tool") no(`${where}: "tool" is set by the guard to the tool's name`);
|
|
5435
|
+
if (FORBIDDEN_KEYS.has(fact)) no(`${where} isn't a usable fact name`);
|
|
5436
|
+
const b = facts[fact];
|
|
5437
|
+
if (!b || typeof b !== "object" || Array.isArray(b)) no(`${where} must be an object with "arg"`);
|
|
5438
|
+
for (const k of Object.keys(b)) if (!["arg", "scale", "map", "_why"].includes(k)) no(`${where}: "${k}" isn't allowed. A fact can only come from an argument of the call`);
|
|
5439
|
+
if (typeof b.arg !== "string" || !b.arg) no(`${where} needs "arg", the argument it comes from`);
|
|
5440
|
+
if (b.arg.split(".").some((s) => !s || FORBIDDEN_KEYS.has(s))) no(`${where}: "${b.arg}" isn't a usable argument path`);
|
|
5441
|
+
if (b.scale !== void 0 && b.map !== void 0) no(`${where}: use "scale" or "map", not both`);
|
|
5442
|
+
if (b.scale !== void 0 && (typeof b.scale !== "number" || !Number.isFinite(b.scale) || b.scale === 0)) no(`${where}: "scale" must be a non-zero number`);
|
|
5443
|
+
if (b.map !== void 0) {
|
|
5444
|
+
if (!b.map || typeof b.map !== "object" || Array.isArray(b.map)) no(`${where}: "map" must be an object`);
|
|
5445
|
+
for (const k of Object.keys(b.map)) if (FORBIDDEN_KEYS.has(k) || !isScalar(b.map[k])) no(`${where}: "map" can only hold plain values`);
|
|
5446
|
+
}
|
|
5447
|
+
tools[tool].facts[fact] = { arg: b.arg, ...b.scale !== void 0 ? { scale: b.scale } : {}, ...b.map !== void 0 ? { map: b.map } : {} };
|
|
5448
|
+
}
|
|
5449
|
+
}
|
|
5450
|
+
return { version: 1, artifact: obj.artifact, reviewed: obj.reviewed, tools };
|
|
5451
|
+
}
|
|
5452
|
+
function applyToolBindings(bindings, tool, args) {
|
|
5453
|
+
const inputs = { tool };
|
|
5454
|
+
const unresolved = [];
|
|
5455
|
+
const facts = hasOwn(bindings.tools, tool) ? bindings.tools[tool].facts : {};
|
|
5456
|
+
for (const [fact, b] of Object.entries(facts)) {
|
|
5457
|
+
let v = args;
|
|
5458
|
+
for (const seg of b.arg.split(".")) v = v && typeof v === "object" && !Array.isArray(v) && hasOwn(v, seg) ? v[seg] : void 0;
|
|
5459
|
+
if (v === void 0 || v === null) {
|
|
5460
|
+
unresolved.push({ fact, arg: b.arg, why: "missing" });
|
|
5461
|
+
continue;
|
|
5462
|
+
}
|
|
5463
|
+
if (b.scale !== void 0) {
|
|
5464
|
+
if (typeof v !== "number" || !Number.isFinite(v)) {
|
|
5465
|
+
unresolved.push({ fact, arg: b.arg, why: "not_a_number" });
|
|
5466
|
+
continue;
|
|
5467
|
+
}
|
|
5468
|
+
inputs[fact] = Number((v * b.scale).toFixed(9));
|
|
5469
|
+
continue;
|
|
5470
|
+
}
|
|
5471
|
+
if (!isScalar(v)) {
|
|
5472
|
+
unresolved.push({ fact, arg: b.arg, why: "not_a_value" });
|
|
5473
|
+
continue;
|
|
5474
|
+
}
|
|
5475
|
+
if (b.map) {
|
|
5476
|
+
if (!hasOwn(b.map, String(v))) {
|
|
5477
|
+
unresolved.push({ fact, arg: b.arg, why: "not_in_map" });
|
|
5478
|
+
continue;
|
|
5479
|
+
}
|
|
5480
|
+
inputs[fact] = b.map[String(v)];
|
|
5481
|
+
continue;
|
|
5482
|
+
}
|
|
5483
|
+
inputs[fact] = v;
|
|
5484
|
+
}
|
|
5485
|
+
return { inputs, unresolved };
|
|
5486
|
+
}
|
|
5487
|
+
var WEAK = /* @__PURE__ */ new Set(["is", "has", "the", "a", "an", "of", "to", "in", "id", "name", "type", "value", "status", "code", "data", "info", "flag", "number", "num", "total", "ai", "system"]);
|
|
5488
|
+
var UNITS = { cents: 0.01, pence: 0.01, fils: 0.01, usd: null, dollars: null, aed: null, eur: null };
|
|
5489
|
+
var words = (name) => name.replace(/([a-z0-9])([A-Z])/g, "$1 $2").split(/[^A-Za-z0-9]+/).map((w) => w.toLowerCase()).filter(Boolean);
|
|
5490
|
+
var flatProperties = (props, prefix = "") => Object.entries(props ?? {}).flatMap(([k, s]) => FORBIDDEN_KEYS.has(k) ? [] : s?.type === "object" && s.properties ? flatProperties(s.properties, `${prefix}${k}.`) : [{ path: `${prefix}${k}`, schema: s }]);
|
|
5491
|
+
function suggestToolBindings(artifact, tools, fields) {
|
|
5492
|
+
const bindings = { version: 1, artifact, reviewed: false, tools: {} };
|
|
5493
|
+
const proposals = [];
|
|
5494
|
+
const unbound = [];
|
|
5495
|
+
for (const tool of tools) {
|
|
5496
|
+
bindings.tools[tool.name] = { facts: {} };
|
|
5497
|
+
const args = flatProperties(tool.inputSchema?.properties);
|
|
5498
|
+
for (const field of fields) {
|
|
5499
|
+
if (field.name === "tool") continue;
|
|
5500
|
+
const want = words(field.name).filter((w) => !WEAK.has(w) && !(w in UNITS));
|
|
5501
|
+
const scored = args.map((a) => {
|
|
5502
|
+
const raw = words(a.path);
|
|
5503
|
+
const have = raw.filter((w) => !WEAK.has(w) && !(w in UNITS));
|
|
5504
|
+
const shared = want.filter((w) => have.includes(w));
|
|
5505
|
+
const unit = raw.find((w) => w in UNITS);
|
|
5506
|
+
const same = words(field.name).join("_") === raw.join("_");
|
|
5507
|
+
const sameCore = want.length > 0 && want.length === have.length && shared.length === want.length;
|
|
5508
|
+
return { a, shared, unit, same, sameCore, score: same ? 3 : sameCore ? 2 : shared.length ? shared.length / Math.max(want.length, have.length) : 0 };
|
|
5509
|
+
}).filter((s) => s.score > 0).sort((x, y) => y.score - x.score);
|
|
5510
|
+
if (!scored.length) {
|
|
5511
|
+
unbound.push({ tool: tool.name, fact: field.name, candidates: [] });
|
|
5512
|
+
continue;
|
|
5513
|
+
}
|
|
5514
|
+
const best = scored[0];
|
|
5515
|
+
if (scored[1] && scored[1].score === best.score) {
|
|
5516
|
+
unbound.push({ tool: tool.name, fact: field.name, candidates: scored.filter((s) => s.score === best.score).map((s) => s.a.path) });
|
|
5517
|
+
continue;
|
|
5518
|
+
}
|
|
5519
|
+
const scale = best.unit ? UNITS[best.unit] ?? void 0 : void 0;
|
|
5520
|
+
const why = best.same ? "the same name" : best.sameCore ? "the same words" : `shares "${best.shared.join(", ")}"`;
|
|
5521
|
+
proposals.push({ tool: tool.name, fact: field.name, arg: best.a.path, confidence: best.same || best.sameCore ? "exact" : "likely", why: scale ? `${why}; ${best.unit} scaled by ${scale}` : why, ...scale ? { scale } : {} });
|
|
5522
|
+
bindings.tools[tool.name].facts[field.name] = { arg: best.a.path, ...scale ? { scale } : {} };
|
|
5523
|
+
}
|
|
5524
|
+
}
|
|
5525
|
+
return { bindings, proposals, unbound };
|
|
5526
|
+
}
|
|
5527
|
+
function describeSuggestion(s) {
|
|
5528
|
+
const lines = [];
|
|
5529
|
+
for (const tool of Object.keys(s.bindings.tools)) {
|
|
5530
|
+
lines.push(`
|
|
5531
|
+
${tool}`);
|
|
5532
|
+
for (const p of s.proposals.filter((x) => x.tool === tool)) lines.push(` ${p.confidence === "exact" ? "matched " : "CHECK "} ${p.fact} <- ${p.arg}${p.scale ? ` x ${p.scale}` : ""} (${p.why})`);
|
|
5533
|
+
for (const u of s.unbound.filter((x) => x.tool === tool)) lines.push(` NO MATCH ${u.fact}${u.candidates.length ? ` (could be: ${u.candidates.join(", ")})` : ""}`);
|
|
5534
|
+
}
|
|
5535
|
+
return lines.join("\n");
|
|
5536
|
+
}
|
|
5537
|
+
|
|
5396
5538
|
// src/act/bytes.ts
|
|
5397
5539
|
var utf82 = (s) => new TextEncoder().encode(s);
|
|
5398
5540
|
var fromUtf82 = (b) => new TextDecoder().decode(b);
|
|
@@ -6953,12 +7095,14 @@ export {
|
|
|
6953
7095
|
WELL_KNOWN,
|
|
6954
7096
|
accept,
|
|
6955
7097
|
act,
|
|
7098
|
+
applyToolBindings,
|
|
6956
7099
|
approver,
|
|
6957
7100
|
bindingDigest,
|
|
6958
7101
|
buildAct,
|
|
6959
7102
|
can,
|
|
6960
7103
|
certificateRegistry,
|
|
6961
7104
|
certify,
|
|
7105
|
+
describeSuggestion,
|
|
6962
7106
|
fetchDocument,
|
|
6963
7107
|
generateSigner,
|
|
6964
7108
|
issuer,
|
|
@@ -6969,6 +7113,7 @@ export {
|
|
|
6969
7113
|
memoryStore,
|
|
6970
7114
|
nomos,
|
|
6971
7115
|
originOf,
|
|
7116
|
+
parseToolBindings,
|
|
6972
7117
|
passkeyApprover,
|
|
6973
7118
|
postgresPasskeyStore,
|
|
6974
7119
|
postgresRegistryStore,
|
|
@@ -6987,6 +7132,7 @@ export {
|
|
|
6987
7132
|
signRevocationList,
|
|
6988
7133
|
signTestimony,
|
|
6989
7134
|
statusFor,
|
|
7135
|
+
suggestToolBindings,
|
|
6990
7136
|
verifyAct,
|
|
6991
7137
|
verifyArtifact,
|
|
6992
7138
|
verifyChain,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nomosprotocol/sdk",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.2",
|
|
4
4
|
"description": "NOMOS for TypeScript: accept() for the system that makes a change, act() for the agent that asks, the issuer, witness and approver roles, and the Exchange client. Verification is local (@nomosprotocol/verify).",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -64,6 +64,13 @@
|
|
|
64
64
|
],
|
|
65
65
|
"author": "NOMOS",
|
|
66
66
|
"license": "MIT",
|
|
67
|
+
"repository": {
|
|
68
|
+
"type": "git",
|
|
69
|
+
"url": "git+https://github.com/nomos-spec/spec.git"
|
|
70
|
+
},
|
|
71
|
+
"bugs": {
|
|
72
|
+
"url": "https://github.com/nomos-spec/spec/issues"
|
|
73
|
+
},
|
|
67
74
|
"engines": {
|
|
68
75
|
"node": ">=20"
|
|
69
76
|
},
|
|
@@ -74,6 +81,6 @@
|
|
|
74
81
|
"dependencies": {
|
|
75
82
|
"@noble/curves": "^2.4.0",
|
|
76
83
|
"@noble/hashes": "^2.4.0",
|
|
77
|
-
"@nomosprotocol/verify": "^1.
|
|
84
|
+
"@nomosprotocol/verify": "^1.3.0"
|
|
78
85
|
}
|
|
79
86
|
}
|