@oracle-agent/oracle 0.35.21 → 0.35.22
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 +24 -1
- package/dist/agent-lifecycle.mjs +3 -0
- package/dist/assets/skills/oracle-desk-product/SKILL.md +1 -1
- package/dist/bin/desk-server.mjs +36 -36
- package/dist/bin/oracle-mev-arb-shadow.mjs +4 -4
- package/dist/bin/oracle-mev-shadow.mjs +6 -6
- package/dist/bin/oracle-route.mjs +11 -11
- package/dist/bin/oracle-scan.mjs +15 -15
- package/dist/bin/oracle.mjs +19 -10
- package/dist/cli/commands/chat.mjs +1 -1
- package/dist/cli/commands/context.mjs +16 -0
- package/dist/cli/commands/doctor.mjs +5 -5
- package/dist/cli/commands/eval.mjs +89 -89
- package/dist/cli/commands/lifecycle.mjs +17 -0
- package/dist/cli/commands/model.mjs +1 -1
- package/dist/cli/commands/quickstart.mjs +5 -5
- package/dist/cli/commands/sign.mjs +1 -1
- package/dist/cli/commands/signer.mjs +22 -22
- package/dist/cli/commands/snipe.mjs +4 -4
- package/dist/cli/commands/swap.mjs +4 -4
- package/dist/cli/commands/venues.mjs +2 -2
- package/dist/context-graph.mjs +3 -0
- package/dist/data/desk-data.mjs +34 -34
- package/dist/data/providers/lp-destination-discovery.mjs +6 -0
- package/dist/data/providers/lp-liquidity-ranker.mjs +1 -0
- package/dist/index.mjs +50 -48
- package/dist/local-signer/anvil-attestation-worker.mjs +1 -1
- package/dist/local-signer/runtime.mjs +1 -1
- package/dist/router/index.mjs +3 -3
- package/dist/router/prepare-bridge.mjs +2 -2
- package/dist/scanner/index.mjs +4 -4
- package/dist/tenant-rbac.mjs +1 -1
- package/dist/workflow-telemetry.mjs +1 -1
- package/package.json +5 -1
- package/public/eval-report.json +1 -1
- package/public/oracle-splash/brand/liquidlaunch.webp +0 -0
- package/public/oracle-splash/brand/markets.webp +0 -0
- package/public/oracle-splash/brand/motion.webp +0 -0
- package/public/oracle-splash/brand/nest.webp +0 -0
- package/public/oracle-splash/brand/outcome.webp +0 -0
- package/public/oracle-splash/brand/silhouette.webp +0 -0
- package/public/oracle-splash/brand/tradexyz.webp +0 -0
- package/public/oracle-splash/index.html +9 -9
- package/server.json +2 -2
package/dist/tenant-rbac.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createHash as M}from"node:crypto";var f=1,p=1,b=1,H="local-owner",W="local-owner",B=Object.freeze(["owner","operator","agent","viewer"]),K=Object.freeze(["tenant","config","policy","grant","workflow","trade","receipt","audit","telemetry"]),g=Object.freeze({read:"read",create:"create",update:"update",delete:"delete",manage:"manage",prepare:"prepare",cancel:"cancel",export:"export",approve:"approve"}),F=Object.freeze(["owner"]),s=Object.freeze({ALLOW_ROLE_PERMISSION:"allow.role_permission",DENY_MISSING_CONTEXT:"deny.missing_context",DENY_INVALID_CONTEXT:"deny.invalid_context",DENY_INVALID_REQUEST:"deny.invalid_request",DENY_UNKNOWN_RESOURCE:"deny.unknown_resource",DENY_UNKNOWN_ACTION:"deny.unknown_action",DENY_UNBOUND_OBJECT:"deny.unbound_object",DENY_TENANT_MISMATCH:"deny.tenant_mismatch",DENY_RESOURCE_MISMATCH:"deny.resource_mismatch",DENY_ROLE_PERMISSION:"deny.role_permission",DENY_POLICY_NOT_APPROVER:"deny.policy_not_approver"}),j=new Set(B),A=new Set(K),X=new Set(Object.values(g)),D=new Set(["user","service","local-owner"]),k=new Set(["verified-session","service-credential","desktop-session","owner-arm-token","local-owner"]),m=/^[A-Za-z0-9][A-Za-z0-9._:@-]{0,127}$/,x="tob1",V=new WeakSet,L=Object.freeze({owner:Object.freeze(["tenant:read","tenant:manage","config:read","config:manage","policy:read","policy:manage","grant:read","grant:create","grant:update","grant:delete","grant:manage","workflow:read","workflow:create","workflow:update","workflow:delete","workflow:cancel","workflow:approve","trade:read","trade:prepare","receipt:read","receipt:export","audit:read","audit:export","telemetry:read","telemetry:create","telemetry:export"]),operator:Object.freeze(["tenant:read","config:read","policy:read","grant:read","workflow:read","workflow:create","workflow:update","workflow:cancel","trade:read","trade:prepare","receipt:read","audit:read","telemetry:read","telemetry:create"]),agent:Object.freeze(["tenant:read","config:read","policy:read","grant:read","workflow:read","workflow:create","workflow:update","trade:read","trade:prepare","receipt:read","telemetry:create"]),viewer:Object.freeze(["tenant:read","config:read","grant:read","workflow:read","trade:read","receipt:read","audit:read","telemetry:read"])}),ee=Object.freeze(Object.fromEntries(Object.entries(L).map(([e,t])=>[e,Object.freeze([...t])]))),o=class extends Error{constructor(t,n="invalid-context"){super(t),this.name="TenantContextError",this.code=n}};function N(e){return!!e&&typeof e=="object"&&!Array.isArray(e)&&Object.getPrototypeOf(e)===Object.prototype}function E(e){if(e&&typeof e=="object"&&!Object.isFrozen(e)){Object.freeze(e);for(let t of Object.values(e))E(t)}return e}function I(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map(I).join(",")}]`:`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${I(e[t])}`).join(",")}}`}function S(e){return M("sha256").update(I(e)).digest("hex")}function R(e,t,n){if(!N(e))throw new o(`${n} must be a plain object`);let r=Object.keys(e).filter(a=>!t.has(a));if(r.length)throw new o(`${n} has unknown fields: ${r.sort().join(", ")}`)}function O(e,t){let n=String(e??"").trim();if(!m.test(n))throw new o(`${t} is invalid`);return n}function C(e,t="assignedRoles"){if(!Array.isArray(e)||e.length===0)throw new o(`${t} must contain at least one trusted role`,"missing-role-assignment");let n=[...new Set(e.map(a=>String(a??"").trim()))].sort(),r=n.filter(a=>!j.has(a));if(r.length)throw new o(`${t} contains unknown roles: ${r.join(", ")}`,"unknown-role");return n}function Y(e,t){return e.length===t.length&&e.every((n,r)=>n===t[r])}function J(e){if(!N(e)||e.schemaVersion!==f||!m.test(e.tenantId||"")||typeof e.localCompatibility!="boolean")return!1;let t=e.actor;if(!N(t)||t.schemaVersion!==p||!m.test(t.actorId||"")||!D.has(t.actorType)||!k.has(t.authSource)||!Array.isArray(t.roles)||t.roles.length===0)return!1;let n=[...new Set(t.roles)].sort();return n.every(r=>j.has(r))&&Y(n,t.roles)}function $(e,{assignedRoles:t,localCompatibility:n=!1}={}){if(R(e,new Set(["schemaVersion","tenantId","actor","localCompatibility"]),"tenant claims"),e.schemaVersion!=null&&e.schemaVersion!==f)throw new o("unsupported tenant context schema version","unsupported-version");let r=O(e.tenantId,"tenantId");if(R(e.actor,new Set(["schemaVersion","actorId","actorType","authSource","roles"]),"actor claims"),e.actor.schemaVersion!=null&&e.actor.schemaVersion!==p)throw new o("unsupported actor identity schema version","unsupported-version");let a=C(t);if(e.actor.roles!==void 0){let w;try{w=C(e.actor.roles,"claimed roles")}catch{throw new o("claimed roles do not match the trusted assignment","forged-role")}if(!Y(w,a))throw new o("claimed roles do not match the trusted assignment","forged-role")}if(e.localCompatibility!==void 0&&e.localCompatibility!==n)throw new o("local compatibility may only be set by the trusted boundary","forged-local-compatibility");let c=String(e.actor.actorType??"").trim(),d=String(e.actor.authSource??"").trim();if(!D.has(c))throw new o("actorType is invalid");if(!k.has(d))throw new o("authSource is invalid");let i=E({schemaVersion:f,tenantId:r,actor:{schemaVersion:p,actorId:O(e.actor.actorId,"actorId"),actorType:c,authSource:d,roles:a},localCompatibility:n===!0});return V.add(i),i}function Z(e,t){let n=O(e,"tenantId"),r=O(t,"workflowId");if(n.includes(":")||r.includes(":"))throw new o("stream key parts must not contain ':'","invalid-stream-key");return`${n}:${r}`}function te(e,t){return v(e),Z(e.tenantId,t)}function ne(e,{assignedRoles:t,localCompatibility:n=!1}={}){let r=e?.headers,a=typeof r?.get=="function"?d=>r.get(d):d=>r?.[d]??r?.[String(d).toLowerCase()];a?.("x-oracle-tenant-id"),a?.("x-oracle-tenant"),a?.("x-oracle-role"),a?.("x-oracle-roles");let c=e?.stamped??e?.claims??{};return $({schemaVersion:c.schemaVersion??f,tenantId:c.tenantId,actor:{schemaVersion:c.actor?.schemaVersion??p,actorId:c.actor?.actorId,actorType:c.actor?.actorType,authSource:c.actor?.authSource,roles:void 0},localCompatibility:void 0},{assignedRoles:t,localCompatibility:n})}function re({authSource:e="local-owner"}={}){if(!new Set(["local-owner","desktop-session","owner-arm-token"]).has(e))throw new o("local owner authSource is invalid");return $({schemaVersion:f,tenantId:H,actor:{schemaVersion:p,actorId:W,actorType:"local-owner",authSource:e}},{assignedRoles:["owner"],localCompatibility:!0})}function u(e){return V.has(e)&&J(e)}function v(e){if(!u(e))throw new o("a resolved tenant context is required","unresolved-context");return e}function h(e){return Buffer.from(e,"utf8").toString("base64url")}function _(e,t){if(!e||!/^[A-Za-z0-9_-]+$/.test(e))throw new o(`${t} binding is invalid`,"invalid-object-binding");let n=Buffer.from(e,"base64url").toString("utf8");if(!n||h(n)!==e)throw new o(`${t} binding is non-canonical`,"invalid-object-binding");return n}function z(e){let t=String(e??"").trim();if(!t||t.length>256||/[\u0000-\u001f\u007f]/.test(t))throw new o("objectId is invalid","invalid-object-id");return t}function oe(e,t,n){v(e);let r=String(t??"").trim();if(!A.has(r))throw new o("resource is unknown","unknown-resource");let a=z(n);return`${x}.${h(e.tenantId)}.${h(r)}.${h(a)}`}function G(e){let t=String(e??""),n=t.split(".");if(n.length!==4||n[0]!==x)throw new o("tenant-bound object id required","unbound-object");let r=_(n[1],"tenant"),a=_(n[2],"resource"),c=_(n[3],"object");if(!m.test(r)||!A.has(a))throw new o("tenant-bound object id is invalid","invalid-object-binding");return z(c),E({schemaVersion:1,tenantId:r,resource:a,objectId:c,boundId:t})}function P(e){if(typeof e!="string"||!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/.test(e))return null;let t=Date.parse(e);return Number.isFinite(t)&&new Date(t).toISOString()===e?e:null}function T(e){let t={...e,decisionId:S(e)};return E(t)}function Q({context:e,resource:t,action:n,objectId:r=null,decidedAt:a}={}){let c=P(a),d={schemaVersion:b,recordType:"tenant.access-decision",decidedAt:c,tenantId:u(e)?e.tenantId:null,actor:u(e)?{actorId:e.actor.actorId,actorType:e.actor.actorType,authSource:e.actor.authSource,roles:[...e.actor.roles]}:null,request:{resource:typeof t=="string"?t:null,action:typeof n=="string"?n:null,objectRefHash:r==null?null:S(String(r))}},i=l=>T({...d,allowed:!1,outcome:"deny",reason:l});if(e==null)return i(s.DENY_MISSING_CONTEXT);if(!u(e))return i(s.DENY_INVALID_CONTEXT);if(!c)return i(s.DENY_INVALID_REQUEST);if(!A.has(t))return i(s.DENY_UNKNOWN_RESOURCE);if(!X.has(n))return i(s.DENY_UNKNOWN_ACTION);if(r!=null){let l;try{l=G(r)}catch{return i(s.DENY_UNBOUND_OBJECT)}if(l.tenantId!==e.tenantId)return i(s.DENY_TENANT_MISMATCH);if(l.resource!==t)return i(s.DENY_RESOURCE_MISMATCH)}if(n===g.approve&&!e.actor.roles.some(U=>F.includes(U)))return i(s.DENY_ROLE_PERMISSION);let w=`${t}:${n}`,y=e.actor.roles.some(l=>L[l]?.includes(w));return T({...d,allowed:y,outcome:y?"allow":"deny",reason:y?s.ALLOW_ROLE_PERMISSION:s.DENY_ROLE_PERMISSION})}function ae(e={}){let t=P(e.decidedAt),n=e.context,r=e.resource??"workflow",a=e.objectId??null;return T({schemaVersion:b,recordType:"tenant.access-decision",decidedAt:t,tenantId:u(n)?n.tenantId:null,actor:u(n)?{actorId:n.actor.actorId,actorType:n.actor.actorType,authSource:n.actor.authSource,roles:[...n.actor.roles]}:null,request:{resource:typeof r=="string"?r:null,action:g.approve,objectRefHash:a==null?null:S(String(a))},allowed:!1,outcome:"deny",reason:s.DENY_POLICY_NOT_APPROVER})}function ce(e){let t=Q(e);if(!t.allowed){let n=new o(`tenant access denied: ${t.reason}`,"access-denied");throw n.decision=t,n}return t}function ie(e){if(!N(e)||e.schemaVersion!==b||e.recordType!=="tenant.access-decision"||!Object.isFrozen(e))return!1;let{decisionId:t,...n}=e;return typeof t=="string"&&t===S(n)&&typeof e.allowed=="boolean"&&["allow","deny"].includes(e.outcome)}export{p as ACTOR_IDENTITY_VERSION,W as LOCAL_OWNER_ACTOR_ID,H as LOCAL_OWNER_TENANT_ID,b as TENANT_ACCESS_DECISION_VERSION,g as TENANT_ACTIONS,F as TENANT_APPROVER_ROLES,f as TENANT_CONTEXT_VERSION,s as TENANT_DECISION_REASONS,K as TENANT_RESOURCES,B as TENANT_ROLES,ee as TENANT_ROLE_PERMISSIONS,o as TenantContextError,v as assertResolvedTenantContext,oe as bindTenantObjectId,Z as canonicalTenantStreamKey,re as createLocalOwnerTenantContext,ae as decidePolicyApproval,Q as decideTenantAccess,u as isResolvedTenantContext,ie as isTenantAuditDecision,G as parseTenantObjectId,ce as requireTenantAccess,ne as resolveDispatcherStampedTenantContext,$ as resolveTenantContext,te as tenantStreamKeyFromContext};
|
|
1
|
+
import{createHash as ee}from"node:crypto";var y=1,h=1,j=1,L="local-owner",Y="local-owner",te=Object.freeze(["owner","operator","agent","viewer"]),ne=Object.freeze(["tenant","config","policy","grant","workflow","trade","receipt","audit","telemetry","context","lifecycle"]),D=Object.freeze({read:"read",create:"create",update:"update",delete:"delete",manage:"manage",prepare:"prepare",cancel:"cancel",export:"export",approve:"approve"}),re=Object.freeze(["owner"]),l=Object.freeze({ALLOW_ROLE_PERMISSION:"allow.role_permission",DENY_MISSING_CONTEXT:"deny.missing_context",DENY_INVALID_CONTEXT:"deny.invalid_context",DENY_INVALID_REQUEST:"deny.invalid_request",DENY_UNKNOWN_RESOURCE:"deny.unknown_resource",DENY_UNKNOWN_ACTION:"deny.unknown_action",DENY_UNBOUND_OBJECT:"deny.unbound_object",DENY_TENANT_MISMATCH:"deny.tenant_mismatch",DENY_RESOURCE_MISMATCH:"deny.resource_mismatch",DENY_ROLE_PERMISSION:"deny.role_permission",DENY_POLICY_NOT_APPROVER:"deny.policy_not_approver"}),U=new Set(te),k=new Set(ne),oe=new Set(Object.values(D)),W=new Set(["user","service","local-owner"]),H=new Set(["verified-session","service-credential","desktop-session","owner-arm-token","local-owner"]),N=/^[A-Za-z0-9][A-Za-z0-9._:@-]{0,127}$/,B="tob1",K=new WeakSet,F=new WeakMap,X=Object.freeze({owner:Object.freeze(["tenant:read","tenant:manage","config:read","config:manage","policy:read","policy:manage","grant:read","grant:create","grant:update","grant:delete","grant:manage","workflow:read","workflow:create","workflow:update","workflow:delete","workflow:cancel","workflow:approve","trade:read","trade:prepare","receipt:read","receipt:export","audit:read","audit:export","telemetry:read","telemetry:create","telemetry:export","context:read","context:create","context:update","context:delete","context:manage","context:export","lifecycle:read","lifecycle:create","lifecycle:update","lifecycle:delete","lifecycle:manage","lifecycle:approve","lifecycle:export"]),operator:Object.freeze(["tenant:read","config:read","policy:read","grant:read","workflow:read","workflow:create","workflow:update","workflow:cancel","trade:read","trade:prepare","receipt:read","audit:read","telemetry:read","telemetry:create","context:read","context:create","context:update","context:delete","lifecycle:read","lifecycle:create","lifecycle:update","lifecycle:manage"]),agent:Object.freeze(["tenant:read","config:read","policy:read","grant:read","workflow:read","workflow:create","workflow:update","trade:read","trade:prepare","receipt:read","telemetry:create","context:read","context:create","context:update","lifecycle:read"]),viewer:Object.freeze(["tenant:read","config:read","grant:read","workflow:read","trade:read","receipt:read","audit:read","telemetry:read","context:read","lifecycle:read"])}),fe=Object.freeze(Object.fromEntries(Object.entries(X).map(([e,t])=>[e,Object.freeze([...t])]))),o=class extends Error{constructor(t,n="invalid-context"){super(t),this.name="TenantContextError",this.code=n}};function m(e){return!!e&&typeof e=="object"&&!Array.isArray(e)&&Object.getPrototypeOf(e)===Object.prototype}function _(e){if(e&&typeof e=="object"&&!Object.isFrozen(e)){Object.freeze(e);for(let t of Object.values(e))_(t)}return e}function R(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map(R).join(",")}]`:`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${R(e[t])}`).join(",")}}`}function g(e){return ee("sha256").update(R(e)).digest("hex")}function P(e,t,n){if(!m(e))throw new o(`${n} must be a plain object`);let r=Object.keys(e).filter(a=>!t.has(a));if(r.length)throw new o(`${n} has unknown fields: ${r.sort().join(", ")}`)}function E(e,t){let n=String(e??"").trim();if(!N.test(n))throw new o(`${t} is invalid`);return n}function M(e,t="assignedRoles"){if(!Array.isArray(e)||e.length===0)throw new o(`${t} must contain at least one trusted role`,"missing-role-assignment");let n=[...new Set(e.map(a=>String(a??"").trim()))].sort(),r=n.filter(a=>!U.has(a));if(r.length)throw new o(`${t} contains unknown roles: ${r.join(", ")}`,"unknown-role");return n}function q(e,t){return e.length===t.length&&e.every((n,r)=>n===t[r])}function ae(e){if(!m(e)||e.schemaVersion!==y||!N.test(e.tenantId||"")||typeof e.localCompatibility!="boolean")return!1;let t=e.actor;if(!m(t)||t.schemaVersion!==h||!N.test(t.actorId||"")||!W.has(t.actorType)||!H.has(t.authSource)||!Array.isArray(t.roles)||t.roles.length===0)return!1;let n=[...new Set(t.roles)].sort();return n.every(r=>U.has(r))&&q(n,t.roles)}function J(e,{assignedTenantId:t,assignedActorId:n,assignedActorType:r,assignedAuthSource:a,assignedRoles:s,assignedContextDomains:c=null,localCompatibility:i=!1}={}){let f=e;if(P(f,new Set(["schemaVersion","tenantId","actor","localCompatibility"]),"tenant claims"),f.schemaVersion!=null&&f.schemaVersion!==y)throw new o("unsupported tenant context schema version","unsupported-version");if(![t,n,r,a].every(d=>d!=null))throw new o("trusted tenant and actor identity assignments are required","missing-trusted-identity");let u=f.actor??{};if(P(u,new Set(["schemaVersion","actorId","actorType","authSource","roles"]),"actor claims"),u.schemaVersion!=null&&u.schemaVersion!==h)throw new o("unsupported actor identity schema version","unsupported-version");let v=E(t,"tenantId"),z=E(n,"actorId"),I=String(r).trim(),T=String(a).trim();if(!W.has(I))throw new o("actorType is invalid");if(!H.has(T))throw new o("authSource is invalid");let b=M(s);if(!Array.isArray(c)&&c!=null)throw new o("assignedContextDomains must be an array","invalid-domain-assignment");let $=c==null?b.includes("owner")?["*"]:[]:[...new Set(c.map(d=>String(d??"").trim()))].sort();if($.some(d=>d!=="*"&&!/^[a-z0-9][a-z0-9._-]{0,95}$/.test(d)))throw new o("assignedContextDomains contains an invalid domain","invalid-domain-assignment");if(u.roles!==void 0){let d;try{d=M(u.roles,"claimed roles")}catch{throw new o("claimed roles do not match the trusted assignment","forged-role")}if(!q(d,b))throw new o("claimed roles do not match the trusted assignment","forged-role")}if(f.localCompatibility!==void 0&&f.localCompatibility!==i)throw new o("local compatibility may only be set by the trusted boundary","forged-local-compatibility");if([[f.tenantId,v],[u.actorId,z],[u.actorType,I],[u.authSource,T]].some(([d,Q])=>d!==void 0&&String(d).trim()!==Q))throw new o("claimed identity does not match the trusted assignment","forged-identity");let A=_({schemaVersion:y,tenantId:v,actor:{schemaVersion:h,actorId:z,actorType:I,authSource:T,roles:b},localCompatibility:i===!0});return K.add(A),F.set(A,Object.freeze($)),A}function ie(e,t){V(e);let n=String(t??"").trim();if(!/^[a-z0-9][a-z0-9._-]{0,95}$/.test(n))return!1;let r=F.get(e)||[];return r.includes("*")||r.includes(n)}function pe(e,t){if(!ie(e,t))throw new o("context domain access denied","domain-access-denied");return t}function ce(e,t){let n=E(e,"tenantId"),r=E(t,"workflowId");if(n.includes(":")||r.includes(":"))throw new o("stream key parts must not contain ':'","invalid-stream-key");return`${n}:${r}`}function we(e,t){return V(e),ce(e.tenantId,t)}function me(e,{assignedRoles:t,assignedContextDomains:n=null,localCompatibility:r=!1}={}){let a=e?.headers,s=typeof a?.get=="function"?i=>a.get(i):i=>a?.[i]??a?.[String(i).toLowerCase()];s?.("x-oracle-tenant-id"),s?.("x-oracle-tenant"),s?.("x-oracle-role"),s?.("x-oracle-roles");let c=e?.stamped;if(!m(c)||!m(c.actor))throw new o("a trusted dispatcher identity stamp is required","missing-trusted-identity");return J({schemaVersion:c.schemaVersion??y,actor:{schemaVersion:c.actor.schemaVersion??h}},{assignedTenantId:c.tenantId,assignedActorId:c.actor.actorId,assignedActorType:c.actor.actorType,assignedAuthSource:c.actor.authSource,assignedRoles:t,assignedContextDomains:n,localCompatibility:r})}function ye({authSource:e="local-owner"}={}){if(!new Set(["local-owner","desktop-session","owner-arm-token"]).has(e))throw new o("local owner authSource is invalid");return J({schemaVersion:y,tenantId:L,actor:{schemaVersion:h,actorId:Y,actorType:"local-owner",authSource:e}},{assignedTenantId:L,assignedActorId:Y,assignedActorType:"local-owner",assignedAuthSource:e,assignedRoles:["owner"],localCompatibility:!0})}function w(e){return K.has(e)&&ae(e)}function V(e){if(!w(e))throw new o("a resolved tenant context is required","unresolved-context");return e}function S(e){return Buffer.from(e,"utf8").toString("base64url")}function x(e,t){if(!e||!/^[A-Za-z0-9_-]+$/.test(e))throw new o(`${t} binding is invalid`,"invalid-object-binding");let n=Buffer.from(e,"base64url").toString("utf8");if(!n||S(n)!==e)throw new o(`${t} binding is non-canonical`,"invalid-object-binding");return n}function Z(e){let t=String(e??"").trim();if(!t||t.length>256||/[\u0000-\u001f\u007f]/.test(t))throw new o("objectId is invalid","invalid-object-id");return t}function he(e,t,n){V(e);let r=String(t??"").trim();if(!k.has(r))throw new o("resource is unknown","unknown-resource");let a=Z(n);return`${B}.${S(e.tenantId)}.${S(r)}.${S(a)}`}function se(e){let t=String(e??""),n=t.split(".");if(n.length!==4||n[0]!==B)throw new o("tenant-bound object id required","unbound-object");let r=x(n[1],"tenant"),a=x(n[2],"resource"),s=x(n[3],"object");if(!N.test(r)||!k.has(a))throw new o("tenant-bound object id is invalid","invalid-object-binding");return Z(s),_({schemaVersion:1,tenantId:r,resource:a,objectId:s,boundId:t})}function G(e){if(typeof e!="string"||!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/.test(e))return null;let t=Date.parse(e);return Number.isFinite(t)&&new Date(t).toISOString()===e?e:null}function C(e){let t={...e,decisionId:g(e)};return _(t)}function de({context:e,resource:t,action:n,objectId:r=null,decidedAt:a}={}){let s=G(a),c={schemaVersion:j,recordType:"tenant.access-decision",decidedAt:s,tenantId:w(e)?e.tenantId:null,actor:w(e)?{actorId:e.actor.actorId,actorType:e.actor.actorType,authSource:e.actor.authSource,roles:[...e.actor.roles]}:null,request:{resource:typeof t=="string"?t:null,action:typeof n=="string"?n:null,objectRefHash:r==null?null:g(String(r))}},i=p=>C({...c,allowed:!1,outcome:"deny",reason:p});if(e==null)return i(l.DENY_MISSING_CONTEXT);if(!w(e))return i(l.DENY_INVALID_CONTEXT);if(!s)return i(l.DENY_INVALID_REQUEST);if(!k.has(t))return i(l.DENY_UNKNOWN_RESOURCE);if(!oe.has(n))return i(l.DENY_UNKNOWN_ACTION);if(r!=null){let p;try{p=se(r)}catch{return i(l.DENY_UNBOUND_OBJECT)}if(p.tenantId!==e.tenantId)return i(l.DENY_TENANT_MISMATCH);if(p.resource!==t)return i(l.DENY_RESOURCE_MISMATCH)}if(n===D.approve&&!e.actor.roles.some(u=>re.includes(u)))return i(l.DENY_ROLE_PERMISSION);let f=`${t}:${n}`,O=e.actor.roles.some(p=>X[p]?.includes(f));return C({...c,allowed:O,outcome:O?"allow":"deny",reason:O?l.ALLOW_ROLE_PERMISSION:l.DENY_ROLE_PERMISSION})}function Oe(e={}){let t=G(e.decidedAt),n=e.context,r=e.resource??"workflow",a=e.objectId??null;return C({schemaVersion:j,recordType:"tenant.access-decision",decidedAt:t,tenantId:w(n)?n.tenantId:null,actor:w(n)?{actorId:n.actor.actorId,actorType:n.actor.actorType,authSource:n.actor.authSource,roles:[...n.actor.roles]}:null,request:{resource:typeof r=="string"?r:null,action:D.approve,objectRefHash:a==null?null:g(String(a))},allowed:!1,outcome:"deny",reason:l.DENY_POLICY_NOT_APPROVER})}function Se(e){let t=de(e);if(!t.allowed){let n=new o(`tenant access denied: ${t.reason}`,"access-denied");throw n.decision=t,n}return t}function Ne(e){if(!m(e)||e.schemaVersion!==j||e.recordType!=="tenant.access-decision"||!Object.isFrozen(e))return!1;let{decisionId:t,...n}=e;return typeof t=="string"&&t===g(n)&&typeof e.allowed=="boolean"&&["allow","deny"].includes(e.outcome)}export{h as ACTOR_IDENTITY_VERSION,Y as LOCAL_OWNER_ACTOR_ID,L as LOCAL_OWNER_TENANT_ID,j as TENANT_ACCESS_DECISION_VERSION,D as TENANT_ACTIONS,re as TENANT_APPROVER_ROLES,y as TENANT_CONTEXT_VERSION,l as TENANT_DECISION_REASONS,ne as TENANT_RESOURCES,te as TENANT_ROLES,fe as TENANT_ROLE_PERMISSIONS,o as TenantContextError,V as assertResolvedTenantContext,he as bindTenantObjectId,ie as canAccessContextDomain,ce as canonicalTenantStreamKey,ye as createLocalOwnerTenantContext,Oe as decidePolicyApproval,de as decideTenantAccess,w as isResolvedTenantContext,Ne as isTenantAuditDecision,se as parseTenantObjectId,pe as requireContextDomainAccess,Se as requireTenantAccess,me as resolveDispatcherStampedTenantContext,J as resolveTenantContext,we as tenantStreamKeyFromContext};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createHash as ee,randomBytes as te}from"node:crypto";var X=Object.freeze(["owner","operator","agent","viewer"]),J=Object.freeze(["tenant","config","policy","grant","workflow","trade","receipt","audit","telemetry"]),G=Object.freeze({read:"read",create:"create",update:"update",delete:"delete",manage:"manage",prepare:"prepare",cancel:"cancel",export:"export",approve:"approve"}),Oe=Object.freeze(["owner"]),be=Object.freeze({ALLOW_ROLE_PERMISSION:"allow.role_permission",DENY_MISSING_CONTEXT:"deny.missing_context",DENY_INVALID_CONTEXT:"deny.invalid_context",DENY_INVALID_REQUEST:"deny.invalid_request",DENY_UNKNOWN_RESOURCE:"deny.unknown_resource",DENY_UNKNOWN_ACTION:"deny.unknown_action",DENY_UNBOUND_OBJECT:"deny.unbound_object",DENY_TENANT_MISMATCH:"deny.tenant_mismatch",DENY_RESOURCE_MISMATCH:"deny.resource_mismatch",DENY_ROLE_PERMISSION:"deny.role_permission",DENY_POLICY_NOT_APPROVER:"deny.policy_not_approver"}),Te=new Set(X),Ee=new Set(J),_e=new Set(Object.values(G));var q=/^[A-Za-z0-9][A-Za-z0-9._:@-]{0,127}$/;var Q=Object.freeze({owner:Object.freeze(["tenant:read","tenant:manage","config:read","config:manage","policy:read","policy:manage","grant:read","grant:create","grant:update","grant:delete","grant:manage","workflow:read","workflow:create","workflow:update","workflow:delete","workflow:cancel","workflow:approve","trade:read","trade:prepare","receipt:read","receipt:export","audit:read","audit:export","telemetry:read","telemetry:create","telemetry:export"]),operator:Object.freeze(["tenant:read","config:read","policy:read","grant:read","workflow:read","workflow:create","workflow:update","workflow:cancel","trade:read","trade:prepare","receipt:read","audit:read","telemetry:read","telemetry:create"]),agent:Object.freeze(["tenant:read","config:read","policy:read","grant:read","workflow:read","workflow:create","workflow:update","trade:read","trade:prepare","receipt:read","telemetry:create"]),viewer:Object.freeze(["tenant:read","config:read","grant:read","workflow:read","trade:read","receipt:read","audit:read","telemetry:read"])}),Ae=Object.freeze(Object.fromEntries(Object.entries(Q).map(([e,t])=>[e,Object.freeze([...t])]))),h=class extends Error{constructor(t,n="invalid-context"){super(t),this.name="TenantContextError",this.code=n}};function k(e,t){let n=String(e??"").trim();if(!q.test(n))throw new h(`${t} is invalid`);return n}function C(e,t){let n=k(e,"tenantId"),r=k(t,"workflowId");if(n.includes(":")||r.includes(":"))throw new h("stream key parts must not contain ':'","invalid-stream-key");return`${n}:${r}`}var L=1,$=1,ne=Object.freeze(["succeeded","denied","invalid","failed","cancelled","timed_out","unavailable","skipped"]),re=Object.freeze(["workflow","task","intent","plan","run","event","eval"]),S=Object.freeze(["taskId","intentId","planId","runId","eventId"]);function I(e,t){return C(e,t)}var p=Object.freeze({maxAttributes:24,maxKeyLength:48,maxStringLength:256,maxArrayLength:8}),D=new Set(ne),oe=new Set(re),ae=new Set(S),ie=/^[0-9a-f]{32}$/,j=/^[0-9a-f]{16}$/,se=/^[0-9a-f]{64}$/,v=new WeakSet,ce=/^[A-Za-z0-9][A-Za-z0-9._:/-]{0,95}$/,V=/^[A-Za-z0-9][A-Za-z0-9._:@/-]{0,127}$/,de=/^[A-Za-z][A-Za-z0-9_.-]*$/,le=Object.freeze(["authorization","bearer","cookie","credential","password","passphrase","secret","token","privatekey","privkey","seed","mnemonic","keystore","signature","prompt","systemmessage","usermessage","assistantmessage","rawtransaction","signedtransaction","serializedtransaction","transactionbytes","calldata","callbytes","inputdata"]),ue=/(?:^|\s)Bearer\s+\S+|-----BEGIN [A-Z ]*PRIVATE KEY-----|\bxprv[0-9A-Za-z]{20,}\b|\bsk-[A-Za-z0-9_-]{16,}\b|[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{6,}\.[A-Za-z0-9_-]{16,}/i,fe=/(?:0x)?[0-9a-fA-F]{66,}/,pe=/[A-Za-z0-9+/=_-]{96,}/,a=class extends Error{constructor(t,n="invalid-telemetry"){super(t),this.name="WorkflowTelemetryError",this.code=n}};function w(e){return!!e&&typeof e=="object"&&!Array.isArray(e)&&Object.getPrototypeOf(e)===Object.prototype}function u(e){if(e&&typeof e=="object"&&!Object.isFrozen(e)){Object.freeze(e);for(let t of Object.values(e))u(t)}return e}function E(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map(E).join(",")}]`:`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${E(e[t])}`).join(",")}}`}function K(e){return ee("sha256").update(E(e)).digest("hex")}function R(e,t,n){let r=n?n(e,t):te(e).toString("hex");return String(r??"").trim().toLowerCase()}function O(e={}){if(e==null)return{};if(!w(e))throw new a("correlation must be a plain object");let t=Object.keys(e).filter(r=>!ae.has(r));if(t.length)throw new a(`unknown correlation fields: ${t.sort().join(", ")}`);let n={};for(let r of S){if(e[r]==null)continue;let o=String(e[r]).trim();if(!V.test(o))throw new a(`${r} is invalid`);n[r]=o}return n}function f(e){if(!w(e)||e.schemaVersion!==L)throw new a("trace context version is invalid","invalid-trace");if(!ie.test(e.traceId||"")||!j.test(e.spanId||"")||/^0+$/.test(e.traceId)||/^0+$/.test(e.spanId))throw new a("trace or span id is invalid","invalid-trace");if(e.parentSpanId!==null&&!j.test(e.parentSpanId||""))throw new a("parent span id is invalid","invalid-trace");if(typeof e.sampled!="boolean")throw new a("sampled must be boolean","invalid-trace");return O(e.correlation),e}function _({traceId:e,spanId:t,parentSpanId:n=null,sampled:r=!1,correlation:o={}}={},{idFactory:s}={}){let i=e==null?R(16,"trace",s):String(e).trim().toLowerCase(),c=t==null?R(8,"span",s):String(t).trim().toLowerCase(),l=n==null?null:String(n).trim().toLowerCase(),d=u({schemaVersion:L,traceId:i,spanId:c,parentSpanId:l,sampled:r===!0,correlation:O(o)});return f(d)}var je=_;function Re(e,{spanId:t,correlation:n={}}={},{idFactory:r}={}){f(e);let o=O(n),s={...e.correlation};for(let[i,c]of Object.entries(o)){if(s[i]!=null&&s[i]!==c)throw new a(`correlation ${i} cannot change inside a trace`,"correlation-conflict");s[i]=c}return _({traceId:e.traceId,spanId:t,parentSpanId:e.spanId,sampled:e.sampled,correlation:s},{idFactory:r})}function we(e){return f(e),`00-${e.traceId}-${e.spanId}-${e.sampled?"01":"00"}`}function me(e,{correlation:t={}}={}){let n=/^00-([0-9a-f]{32})-([0-9a-f]{16})-(0[01])$/.exec(String(e??"").trim().toLowerCase());if(!n||/^0+$/.test(n[1])||/^0+$/.test(n[2]))throw new a("traceparent is invalid","invalid-traceparent");return _({traceId:n[1],spanId:n[2],sampled:n[3]==="01",correlation:t})}var Y=Object.freeze({taskId:"x-oracle-task-id",intentId:"x-oracle-intent-id",planId:"x-oracle-plan-id",runId:"x-oracle-run-id",eventId:"x-oracle-event-id"});function x(e,t){if(e?.get&&typeof e.get=="function")return e.get(t);if(!e||typeof e!="object")return null;let n=t.toLowerCase();for(let[r,o]of Object.entries(e))if(r.toLowerCase()===n)return o;return null}function xe(e,t={}){f(e);let n={};n.traceparent=we(e);for(let[r,o]of Object.entries(Y))e.correlation[r]!=null&&(n[o]=e.correlation[r]);return u(n)}function ze(e){let t={};for(let[n,r]of Object.entries(Y)){let o=x(e,r);o!=null&&String(o).trim()&&(t[n]=String(o).trim())}return me(x(e,"traceparent"),{correlation:t})}function z(e){let t=String(e).replace(/[^a-z0-9]/gi,"").toLowerCase();return le.some(n=>t.includes(n))}function ye(e){return ue.test(e)||fe.test(e)||pe.test(e)?{value:"[REDACTED]",redacted:!0,truncated:!1}:e.length>p.maxStringLength?{value:`${e.slice(0,p.maxStringLength-1)}\u2026`,redacted:!1,truncated:!0}:{value:e,redacted:!1,truncated:!1}}function P(e){if(typeof e=="string")return ye(e);if(typeof e=="boolean")return{value:e,redacted:!1,truncated:!1};if(typeof e=="number"&&Number.isFinite(e))return{value:e,redacted:!1,truncated:!1};if(Array.isArray(e)){let t=e.slice(0,p.maxArrayLength),n=[],r=!1,o=e.length>t.length;for(let s of t){if(!["string","boolean","number"].includes(typeof s))return null;let i=P(s);if(!i)return null;n.push(i.value),r||=i.redacted,o||=i.truncated}return{value:n,redacted:r,truncated:o}}return null}function he(e={}){if(!w(e))throw new a("telemetry attributes must be a plain object");let t={},n=0,r=0,o=0,s=Object.keys(e).sort();for(let i of s){if(Object.keys(t).length>=p.maxAttributes){r+=1;continue}if(i.length>p.maxKeyLength||!de.test(i)||z(i)){r+=1,z(i)&&(n+=1);continue}let c=P(e[i]);if(!c){r+=1;continue}t[i]=c.value,c.redacted&&(n+=1),c.truncated&&(o+=1)}return u({attributes:t,redactedCount:n,droppedCount:r,truncatedCount:o})}function g(e,t){if(!Number.isSafeInteger(e)||e<0)throw new a(`${t} must be a non-negative integer milliseconds value`);return e}function M(e){if(e==null)return null;let t=String(e).trim();if(!/^[a-z0-9][a-z0-9._-]{0,63}$/.test(t))throw new a("outcomeCode is invalid");return t}function Ie({streamKey:e,tenantId:t,workflowId:n,sourceEvent:r}){let o=e??r?.streamKey??null,s=t??r?.tenantId??null,i=n??r?.workflowId??null;if(o!=null){let c=String(o).trim();if(s!=null&&i!=null){let l=I(s,i);if(c!==l)throw new a("streamKey must equal tenantId:workflowId","invalid-stream-key");return l}if(!/^[A-Za-z0-9][A-Za-z0-9._:@-]{0,127}:[A-Za-z0-9][A-Za-z0-9._:@-]{0,127}$/.test(c)||c.split(":").length!==2)throw new a("streamKey must be tenantId:workflowId","invalid-stream-key");return c}return s!=null&&i!=null?I(s,i):null}function U({trace:e,name:t,kind:n,diagnosticOutcome:r=null,outcome:o=null,outcomeCode:s=null,startedAt:i,endedAt:c,attributes:l,authority:d,sourceEvent:m=null,streamKey:F=null,tenantId:W=null,workflowId:Z=null}){f(e);let A=String(t??"").trim();if(!ce.test(A))throw new a("workflow telemetry name is invalid");if(!oe.has(n))throw new a("workflow telemetry kind is invalid");let H=d==="ledger_projection"?o:r;if(!D.has(H))throw new a("workflow telemetry outcome is invalid");let b=g(i,"startedAt"),T=g(c,"endedAt");if(T<b)throw new a("endedAt must not be before startedAt");let y=he(l),B=Ie({streamKey:F,tenantId:W,workflowId:Z,sourceEvent:m}),N={schemaVersion:$,recordType:"oracle.workflow.telemetry",authority:d,streamKey:B,trace:{traceId:e.traceId,spanId:e.spanId,parentSpanId:e.parentSpanId,sampled:e.sampled},correlation:{...e.correlation},name:A,kind:n,...d==="ledger_projection"?{outcome:o,sourceEvent:{...m}}:{diagnosticOutcome:r},outcomeCode:M(s),startedAt:b,endedAt:T,durationMs:T-b,attributes:{...y.attributes},attributePolicy:{redactedCount:y.redactedCount,droppedCount:y.droppedCount,truncatedCount:y.truncatedCount}};return u({...N,recordId:K(N)})}function ge({trace:e,name:t,kind:n="workflow",outcome:r,outcomeCode:o=null,startedAt:s,endedAt:i,attributes:c={},tenantId:l=null,workflowId:d=null,streamKey:m=null}={}){return U({trace:e,name:t,kind:n,diagnosticOutcome:r,outcomeCode:o,startedAt:s,endedAt:i,attributes:c,authority:"diagnostic",tenantId:l,workflowId:d,streamKey:m})}function Le(e,{validateLedgerEvent:t}={}){if(!w(e))throw new a("ledger event must be a plain object","invalid-ledger-event");if(typeof t!="function"||t(e)!==!0)throw new a("ledger event validation failed","invalid-ledger-event");let n=String(e.eventId??"").trim(),r=String(e.eventHash??e.hash??"").trim().toLowerCase();if(!V.test(n)||!se.test(r))throw new a("ledger event id or hash is invalid","invalid-ledger-event");let o=O(e.correlation);for(let d of S)if(o[d]==null)throw new a(`ledger event correlation requires ${d}`,"invalid-ledger-event");if(o.eventId!==n)throw new a("ledger eventId does not match correlation","invalid-ledger-event");if(!D.has(e.outcome))throw new a("ledger event outcome is invalid","invalid-ledger-event");let s=e.tenantId==null?null:String(e.tenantId).trim(),i=e.workflowId==null?null:String(e.workflowId).trim(),c=null;if(s&&i){if(c=I(s,i),e.streamKey!=null&&String(e.streamKey).trim()!==c)throw new a("ledger streamKey must equal tenantId:workflowId","invalid-stream-key")}else if(e.streamKey!=null){let d=String(e.streamKey).split(":");if(d.length!==2)throw new a("ledger streamKey must be tenantId:workflowId","invalid-stream-key");c=I(d[0],d[1])}let l=u({eventId:n,eventHash:r,correlation:o,outcome:e.outcome,outcomeCode:M(e.outcomeCode),startedAt:g(e.startedAt,"ledger event startedAt"),endedAt:g(e.endedAt,"ledger event endedAt"),tenantId:s,workflowId:i,streamKey:c});if(l.endedAt<l.startedAt)throw new a("ledger event endedAt must not be before startedAt","invalid-ledger-event");return v.add(l),l}function $e({sourceEvent:e,trace:t,name:n,kind:r="workflow",attributes:o={}}={}){if(!v.has(e))throw new a("a validated ledger source event is required","unvalidated-ledger-event");f(t);for(let s of S)if(t.correlation[s]!==e.correlation[s])throw new a(`trace correlation ${s} does not match ledger event`,"ledger-correlation-mismatch");return U({trace:t,name:n,kind:r,outcome:e.outcome,outcomeCode:e.outcomeCode,startedAt:e.startedAt,endedAt:e.endedAt,attributes:o,authority:"ledger_projection",sourceEvent:{eventId:e.eventId,eventHash:e.eventHash},tenantId:e.tenantId,workflowId:e.workflowId,streamKey:e.streamKey})}function Se(e){if(!w(e)||!Object.isFrozen(e)||e.schemaVersion!==$||e.recordType!=="oracle.workflow.telemetry")return!1;let{recordId:t,...n}=e;return typeof t=="string"&&t===K(n)}function De({exporter:e=null}={}){if(e!=null&&typeof e!="function"&&typeof e?.export!="function")throw new a("exporter must be a function or expose export(record)");let t=typeof e=="function"?e:e?.export?.bind(e);return Object.freeze({exporterConfigured:!!t,defaultExporter:"none",async emit(n){let r=Se(n)?n:ge(n);if(!t)return Object.freeze({record:r,exported:!1,exporterFailed:!1});try{return await t(r),Object.freeze({record:r,exported:!0,exporterFailed:!1})}catch{return Object.freeze({record:r,exported:!1,exporterFailed:!0})}}})}export{S as CORRELATION_KEYS,p as TELEMETRY_ATTRIBUTE_LIMITS,L as TRACE_CONTEXT_VERSION,re as WORKFLOW_KINDS,ne as WORKFLOW_OUTCOMES,$ as WORKFLOW_TELEMETRY_VERSION,a as WorkflowTelemetryError,Re as createChildTraceContext,je as createRootTraceContext,_ as createTraceContext,De as createWorkflowTelemetry,ge as createWorkflowTelemetryRecord,ze as extractTraceContext,we as formatTraceparent,xe as injectTraceContext,Se as isWorkflowTelemetryRecord,me as parseTraceparent,$e as projectWorkflowTelemetryFromLedgerEvent,he as sanitizeTelemetryAttributes,Le as validateWorkflowTelemetrySourceEvent,I as workflowTelemetryStreamKey};
|
|
1
|
+
import{createHash as ee,randomBytes as te}from"node:crypto";var q=Object.freeze(["owner","operator","agent","viewer"]),X=Object.freeze(["tenant","config","policy","grant","workflow","trade","receipt","audit","telemetry","context","lifecycle"]),J=Object.freeze({read:"read",create:"create",update:"update",delete:"delete",manage:"manage",prepare:"prepare",cancel:"cancel",export:"export",approve:"approve"}),Oe=Object.freeze(["owner"]),be=Object.freeze({ALLOW_ROLE_PERMISSION:"allow.role_permission",DENY_MISSING_CONTEXT:"deny.missing_context",DENY_INVALID_CONTEXT:"deny.invalid_context",DENY_INVALID_REQUEST:"deny.invalid_request",DENY_UNKNOWN_RESOURCE:"deny.unknown_resource",DENY_UNKNOWN_ACTION:"deny.unknown_action",DENY_UNBOUND_OBJECT:"deny.unbound_object",DENY_TENANT_MISMATCH:"deny.tenant_mismatch",DENY_RESOURCE_MISMATCH:"deny.resource_mismatch",DENY_ROLE_PERMISSION:"deny.role_permission",DENY_POLICY_NOT_APPROVER:"deny.policy_not_approver"}),Ae=new Set(q),Te=new Set(X),_e=new Set(Object.values(J));var G=/^[A-Za-z0-9][A-Za-z0-9._:@-]{0,127}$/;var Q=Object.freeze({owner:Object.freeze(["tenant:read","tenant:manage","config:read","config:manage","policy:read","policy:manage","grant:read","grant:create","grant:update","grant:delete","grant:manage","workflow:read","workflow:create","workflow:update","workflow:delete","workflow:cancel","workflow:approve","trade:read","trade:prepare","receipt:read","receipt:export","audit:read","audit:export","telemetry:read","telemetry:create","telemetry:export","context:read","context:create","context:update","context:delete","context:manage","context:export","lifecycle:read","lifecycle:create","lifecycle:update","lifecycle:delete","lifecycle:manage","lifecycle:approve","lifecycle:export"]),operator:Object.freeze(["tenant:read","config:read","policy:read","grant:read","workflow:read","workflow:create","workflow:update","workflow:cancel","trade:read","trade:prepare","receipt:read","audit:read","telemetry:read","telemetry:create","context:read","context:create","context:update","context:delete","lifecycle:read","lifecycle:create","lifecycle:update","lifecycle:manage"]),agent:Object.freeze(["tenant:read","config:read","policy:read","grant:read","workflow:read","workflow:create","workflow:update","trade:read","trade:prepare","receipt:read","telemetry:create","context:read","context:create","context:update","lifecycle:read"]),viewer:Object.freeze(["tenant:read","config:read","grant:read","workflow:read","trade:read","receipt:read","audit:read","telemetry:read","context:read","lifecycle:read"])}),Ee=Object.freeze(Object.fromEntries(Object.entries(Q).map(([e,t])=>[e,Object.freeze([...t])]))),h=class extends Error{constructor(t,n="invalid-context"){super(t),this.name="TenantContextError",this.code=n}};function x(e,t){let n=String(e??"").trim();if(!G.test(n))throw new h(`${t} is invalid`);return n}function C(e,t){let n=x(e,"tenantId"),r=x(t,"workflowId");if(n.includes(":")||r.includes(":"))throw new h("stream key parts must not contain ':'","invalid-stream-key");return`${n}:${r}`}var L=1,$=1,ne=Object.freeze(["succeeded","denied","invalid","failed","cancelled","timed_out","unavailable","skipped"]),re=Object.freeze(["workflow","task","intent","plan","run","event","eval"]),S=Object.freeze(["taskId","intentId","planId","runId","eventId"]);function g(e,t){return C(e,t)}var p=Object.freeze({maxAttributes:24,maxKeyLength:48,maxStringLength:256,maxArrayLength:8}),v=new Set(ne),oe=new Set(re),ae=new Set(S),ie=/^[0-9a-f]{32}$/,k=/^[0-9a-f]{16}$/,se=/^[0-9a-f]{64}$/,D=new WeakSet,ce=/^[A-Za-z0-9][A-Za-z0-9._:/-]{0,95}$/,V=/^[A-Za-z0-9][A-Za-z0-9._:@/-]{0,127}$/,de=/^[A-Za-z][A-Za-z0-9_.-]*$/,le=Object.freeze(["authorization","bearer","cookie","credential","password","passphrase","secret","token","privatekey","privkey","seed","mnemonic","keystore","signature","prompt","systemmessage","usermessage","assistantmessage","rawtransaction","signedtransaction","serializedtransaction","transactionbytes","calldata","callbytes","inputdata"]),ue=/(?:^|\s)Bearer\s+\S+|-----BEGIN [A-Z ]*PRIVATE KEY-----|\bxprv[0-9A-Za-z]{20,}\b|\bsk-[A-Za-z0-9_-]{16,}\b|[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{6,}\.[A-Za-z0-9_-]{16,}/i,fe=/(?:0x)?[0-9a-fA-F]{66,}/,pe=/[A-Za-z0-9+/=_-]{96,}/,a=class extends Error{constructor(t,n="invalid-telemetry"){super(t),this.name="WorkflowTelemetryError",this.code=n}};function w(e){return!!e&&typeof e=="object"&&!Array.isArray(e)&&Object.getPrototypeOf(e)===Object.prototype}function u(e){if(e&&typeof e=="object"&&!Object.isFrozen(e)){Object.freeze(e);for(let t of Object.values(e))u(t)}return e}function T(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map(T).join(",")}]`:`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${T(e[t])}`).join(",")}}`}function K(e){return ee("sha256").update(T(e)).digest("hex")}function j(e,t,n){let r=n?n(e,t):te(e).toString("hex");return String(r??"").trim().toLowerCase()}function O(e={}){if(e==null)return{};if(!w(e))throw new a("correlation must be a plain object");let t=Object.keys(e).filter(r=>!ae.has(r));if(t.length)throw new a(`unknown correlation fields: ${t.sort().join(", ")}`);let n={};for(let r of S){if(e[r]==null)continue;let o=String(e[r]).trim();if(!V.test(o))throw new a(`${r} is invalid`);n[r]=o}return n}function f(e){if(!w(e)||e.schemaVersion!==L)throw new a("trace context version is invalid","invalid-trace");if(!ie.test(e.traceId||"")||!k.test(e.spanId||"")||/^0+$/.test(e.traceId)||/^0+$/.test(e.spanId))throw new a("trace or span id is invalid","invalid-trace");if(e.parentSpanId!==null&&!k.test(e.parentSpanId||""))throw new a("parent span id is invalid","invalid-trace");if(typeof e.sampled!="boolean")throw new a("sampled must be boolean","invalid-trace");return O(e.correlation),e}function _({traceId:e,spanId:t,parentSpanId:n=null,sampled:r=!1,correlation:o={}}={},{idFactory:s}={}){let i=e==null?j(16,"trace",s):String(e).trim().toLowerCase(),c=t==null?j(8,"span",s):String(t).trim().toLowerCase(),l=n==null?null:String(n).trim().toLowerCase(),d=u({schemaVersion:L,traceId:i,spanId:c,parentSpanId:l,sampled:r===!0,correlation:O(o)});return f(d)}var ke=_;function je(e,{spanId:t,correlation:n={}}={},{idFactory:r}={}){f(e);let o=O(n),s={...e.correlation};for(let[i,c]of Object.entries(o)){if(s[i]!=null&&s[i]!==c)throw new a(`correlation ${i} cannot change inside a trace`,"correlation-conflict");s[i]=c}return _({traceId:e.traceId,spanId:t,parentSpanId:e.spanId,sampled:e.sampled,correlation:s},{idFactory:r})}function we(e){return f(e),`00-${e.traceId}-${e.spanId}-${e.sampled?"01":"00"}`}function me(e,{correlation:t={}}={}){let n=/^00-([0-9a-f]{32})-([0-9a-f]{16})-(0[01])$/.exec(String(e??"").trim().toLowerCase());if(!n||/^0+$/.test(n[1])||/^0+$/.test(n[2]))throw new a("traceparent is invalid","invalid-traceparent");return _({traceId:n[1],spanId:n[2],sampled:n[3]==="01",correlation:t})}var Y=Object.freeze({taskId:"x-oracle-task-id",intentId:"x-oracle-intent-id",planId:"x-oracle-plan-id",runId:"x-oracle-run-id",eventId:"x-oracle-event-id"});function R(e,t){if(e?.get&&typeof e.get=="function")return e.get(t);if(!e||typeof e!="object")return null;let n=t.toLowerCase();for(let[r,o]of Object.entries(e))if(r.toLowerCase()===n)return o;return null}function Re(e,t={}){f(e);let n={};n.traceparent=we(e);for(let[r,o]of Object.entries(Y))e.correlation[r]!=null&&(n[o]=e.correlation[r]);return u(n)}function ze(e){let t={};for(let[n,r]of Object.entries(Y)){let o=R(e,r);o!=null&&String(o).trim()&&(t[n]=String(o).trim())}return me(R(e,"traceparent"),{correlation:t})}function z(e){let t=String(e).replace(/[^a-z0-9]/gi,"").toLowerCase();return le.some(n=>t.includes(n))}function ye(e){return ue.test(e)||fe.test(e)||pe.test(e)?{value:"[REDACTED]",redacted:!0,truncated:!1}:e.length>p.maxStringLength?{value:`${e.slice(0,p.maxStringLength-1)}\u2026`,redacted:!1,truncated:!0}:{value:e,redacted:!1,truncated:!1}}function P(e){if(typeof e=="string")return ye(e);if(typeof e=="boolean")return{value:e,redacted:!1,truncated:!1};if(typeof e=="number"&&Number.isFinite(e))return{value:e,redacted:!1,truncated:!1};if(Array.isArray(e)){let t=e.slice(0,p.maxArrayLength),n=[],r=!1,o=e.length>t.length;for(let s of t){if(!["string","boolean","number"].includes(typeof s))return null;let i=P(s);if(!i)return null;n.push(i.value),r||=i.redacted,o||=i.truncated}return{value:n,redacted:r,truncated:o}}return null}function he(e={}){if(!w(e))throw new a("telemetry attributes must be a plain object");let t={},n=0,r=0,o=0,s=Object.keys(e).sort();for(let i of s){if(Object.keys(t).length>=p.maxAttributes){r+=1;continue}if(i.length>p.maxKeyLength||!de.test(i)||z(i)){r+=1,z(i)&&(n+=1);continue}let c=P(e[i]);if(!c){r+=1;continue}t[i]=c.value,c.redacted&&(n+=1),c.truncated&&(o+=1)}return u({attributes:t,redactedCount:n,droppedCount:r,truncatedCount:o})}function I(e,t){if(!Number.isSafeInteger(e)||e<0)throw new a(`${t} must be a non-negative integer milliseconds value`);return e}function M(e){if(e==null)return null;let t=String(e).trim();if(!/^[a-z0-9][a-z0-9._-]{0,63}$/.test(t))throw new a("outcomeCode is invalid");return t}function ge({streamKey:e,tenantId:t,workflowId:n,sourceEvent:r}){let o=e??r?.streamKey??null,s=t??r?.tenantId??null,i=n??r?.workflowId??null;if(o!=null){let c=String(o).trim();if(s!=null&&i!=null){let l=g(s,i);if(c!==l)throw new a("streamKey must equal tenantId:workflowId","invalid-stream-key");return l}if(!/^[A-Za-z0-9][A-Za-z0-9._:@-]{0,127}:[A-Za-z0-9][A-Za-z0-9._:@-]{0,127}$/.test(c)||c.split(":").length!==2)throw new a("streamKey must be tenantId:workflowId","invalid-stream-key");return c}return s!=null&&i!=null?g(s,i):null}function U({trace:e,name:t,kind:n,diagnosticOutcome:r=null,outcome:o=null,outcomeCode:s=null,startedAt:i,endedAt:c,attributes:l,authority:d,sourceEvent:m=null,streamKey:W=null,tenantId:F=null,workflowId:Z=null}){f(e);let E=String(t??"").trim();if(!ce.test(E))throw new a("workflow telemetry name is invalid");if(!oe.has(n))throw new a("workflow telemetry kind is invalid");let H=d==="ledger_projection"?o:r;if(!v.has(H))throw new a("workflow telemetry outcome is invalid");let b=I(i,"startedAt"),A=I(c,"endedAt");if(A<b)throw new a("endedAt must not be before startedAt");let y=he(l),B=ge({streamKey:W,tenantId:F,workflowId:Z,sourceEvent:m}),N={schemaVersion:$,recordType:"oracle.workflow.telemetry",authority:d,streamKey:B,trace:{traceId:e.traceId,spanId:e.spanId,parentSpanId:e.parentSpanId,sampled:e.sampled},correlation:{...e.correlation},name:E,kind:n,...d==="ledger_projection"?{outcome:o,sourceEvent:{...m}}:{diagnosticOutcome:r},outcomeCode:M(s),startedAt:b,endedAt:A,durationMs:A-b,attributes:{...y.attributes},attributePolicy:{redactedCount:y.redactedCount,droppedCount:y.droppedCount,truncatedCount:y.truncatedCount}};return u({...N,recordId:K(N)})}function Ie({trace:e,name:t,kind:n="workflow",outcome:r,outcomeCode:o=null,startedAt:s,endedAt:i,attributes:c={},tenantId:l=null,workflowId:d=null,streamKey:m=null}={}){return U({trace:e,name:t,kind:n,diagnosticOutcome:r,outcomeCode:o,startedAt:s,endedAt:i,attributes:c,authority:"diagnostic",tenantId:l,workflowId:d,streamKey:m})}function Le(e,{validateLedgerEvent:t}={}){if(!w(e))throw new a("ledger event must be a plain object","invalid-ledger-event");if(typeof t!="function"||t(e)!==!0)throw new a("ledger event validation failed","invalid-ledger-event");let n=String(e.eventId??"").trim(),r=String(e.eventHash??e.hash??"").trim().toLowerCase();if(!V.test(n)||!se.test(r))throw new a("ledger event id or hash is invalid","invalid-ledger-event");let o=O(e.correlation);for(let d of S)if(o[d]==null)throw new a(`ledger event correlation requires ${d}`,"invalid-ledger-event");if(o.eventId!==n)throw new a("ledger eventId does not match correlation","invalid-ledger-event");if(!v.has(e.outcome))throw new a("ledger event outcome is invalid","invalid-ledger-event");let s=e.tenantId==null?null:String(e.tenantId).trim(),i=e.workflowId==null?null:String(e.workflowId).trim(),c=null;if(s&&i){if(c=g(s,i),e.streamKey!=null&&String(e.streamKey).trim()!==c)throw new a("ledger streamKey must equal tenantId:workflowId","invalid-stream-key")}else if(e.streamKey!=null){let d=String(e.streamKey).split(":");if(d.length!==2)throw new a("ledger streamKey must be tenantId:workflowId","invalid-stream-key");c=g(d[0],d[1])}let l=u({eventId:n,eventHash:r,correlation:o,outcome:e.outcome,outcomeCode:M(e.outcomeCode),startedAt:I(e.startedAt,"ledger event startedAt"),endedAt:I(e.endedAt,"ledger event endedAt"),tenantId:s,workflowId:i,streamKey:c});if(l.endedAt<l.startedAt)throw new a("ledger event endedAt must not be before startedAt","invalid-ledger-event");return D.add(l),l}function $e({sourceEvent:e,trace:t,name:n,kind:r="workflow",attributes:o={}}={}){if(!D.has(e))throw new a("a validated ledger source event is required","unvalidated-ledger-event");f(t);for(let s of S)if(t.correlation[s]!==e.correlation[s])throw new a(`trace correlation ${s} does not match ledger event`,"ledger-correlation-mismatch");return U({trace:t,name:n,kind:r,outcome:e.outcome,outcomeCode:e.outcomeCode,startedAt:e.startedAt,endedAt:e.endedAt,attributes:o,authority:"ledger_projection",sourceEvent:{eventId:e.eventId,eventHash:e.eventHash},tenantId:e.tenantId,workflowId:e.workflowId,streamKey:e.streamKey})}function Se(e){if(!w(e)||!Object.isFrozen(e)||e.schemaVersion!==$||e.recordType!=="oracle.workflow.telemetry")return!1;let{recordId:t,...n}=e;return typeof t=="string"&&t===K(n)}function ve({exporter:e=null}={}){if(e!=null&&typeof e!="function"&&typeof e?.export!="function")throw new a("exporter must be a function or expose export(record)");let t=typeof e=="function"?e:e?.export?.bind(e);return Object.freeze({exporterConfigured:!!t,defaultExporter:"none",async emit(n){let r=Se(n)?n:Ie(n);if(!t)return Object.freeze({record:r,exported:!1,exporterFailed:!1});try{return await t(r),Object.freeze({record:r,exported:!0,exporterFailed:!1})}catch{return Object.freeze({record:r,exported:!1,exporterFailed:!0})}}})}export{S as CORRELATION_KEYS,p as TELEMETRY_ATTRIBUTE_LIMITS,L as TRACE_CONTEXT_VERSION,re as WORKFLOW_KINDS,ne as WORKFLOW_OUTCOMES,$ as WORKFLOW_TELEMETRY_VERSION,a as WorkflowTelemetryError,je as createChildTraceContext,ke as createRootTraceContext,_ as createTraceContext,ve as createWorkflowTelemetry,Ie as createWorkflowTelemetryRecord,ze as extractTraceContext,we as formatTraceparent,Re as injectTraceContext,Se as isWorkflowTelemetryRecord,me as parseTraceparent,$e as projectWorkflowTelemetryFromLedgerEvent,he as sanitizeTelemetryAttributes,Le as validateWorkflowTelemetrySourceEvent,g as workflowTelemetryStreamKey};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oracle-agent/oracle",
|
|
3
|
-
"version": "0.35.
|
|
3
|
+
"version": "0.35.22",
|
|
4
4
|
"description": "Oracle: standalone multichain agent control plane with an optional encrypted, loopback-only self-hosted signer.",
|
|
5
5
|
"license": "BUSL-1.1",
|
|
6
6
|
"type": "module",
|
|
@@ -64,6 +64,8 @@
|
|
|
64
64
|
"./chains": "./dist/chains.mjs",
|
|
65
65
|
"./scanner": "./dist/scanner/index.mjs",
|
|
66
66
|
"./router": "./dist/router/index.mjs",
|
|
67
|
+
"./lp-rebalance": "./dist/data/providers/lp-liquidity-ranker.mjs",
|
|
68
|
+
"./lp-destination-discovery": "./dist/data/providers/lp-destination-discovery.mjs",
|
|
67
69
|
"./prepare-bridge": "./dist/router/prepare-bridge.mjs",
|
|
68
70
|
"./equities": "./dist/equities/index.mjs",
|
|
69
71
|
"./action-semantics": "./dist/action-semantics.mjs",
|
|
@@ -96,6 +98,8 @@
|
|
|
96
98
|
"./session-orchestrator": "./dist/public-control/session-orchestrator.mjs",
|
|
97
99
|
"./control-plane": "./dist/control-plane/index.mjs",
|
|
98
100
|
"./tenant-rbac": "./dist/tenant-rbac.mjs",
|
|
101
|
+
"./context-graph": "./dist/context-graph.mjs",
|
|
102
|
+
"./agent-lifecycle": "./dist/agent-lifecycle.mjs",
|
|
99
103
|
"./workflow-telemetry": "./dist/workflow-telemetry.mjs",
|
|
100
104
|
"./local-signer": "./dist/local-signer/index.mjs",
|
|
101
105
|
"./local-marketplace": "./dist/local-marketplace.mjs",
|
package/public/eval-report.json
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"node": "v26.7.0"
|
|
9
9
|
},
|
|
10
10
|
"package": "@oracle-agent/oracle",
|
|
11
|
-
"packageVersion": "0.35.
|
|
11
|
+
"packageVersion": "0.35.22",
|
|
12
12
|
"methodology": "Reproduce locally: npx @oracle-agent/oracle eval guards|adversarial|fidelity --json. Dated, commit-stamped output; no chain state or live keys involved. A report is evidence of the pinned commit only.",
|
|
13
13
|
"suites": {
|
|
14
14
|
"guards": {
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1325,8 +1325,8 @@ footer{margin-top:clamp(72px,12vh,120px);border-top:1px solid var(--line);paddin
|
|
|
1325
1325
|
|
|
1326
1326
|
<div class="home-stats rv" aria-label="Oracle surface metrics">
|
|
1327
1327
|
<div class="home-stat"><b id="hero-protocol-count" data-count="220">220</b><span>protocols / venues wired</span></div>
|
|
1328
|
-
<div class="home-stat"><b id="hero-provider-count" data-count="
|
|
1329
|
-
<div class="home-stat"><b id="hero-op-count" data-count="
|
|
1328
|
+
<div class="home-stat"><b id="hero-provider-count" data-count="125">125</b><span>data providers</span></div>
|
|
1329
|
+
<div class="home-stat"><b id="hero-op-count" data-count="537">537</b><span>data operations</span></div>
|
|
1330
1330
|
<div class="home-stat"><b id="hero-chain-count">14 + EVM</b><span>chains wired</span></div>
|
|
1331
1331
|
</div>
|
|
1332
1332
|
</div>
|
|
@@ -2068,14 +2068,14 @@ var BRAND = "brand/";
|
|
|
2068
2068
|
{ n: "Derive V2", img: "derive", cap: "read", u: "https://app.derive.xyz" },
|
|
2069
2069
|
{ n: "PancakeSwap AMM", img: "pancakeswap", cap: "read + quote", u: "https://pancakeswap.finance/" },
|
|
2070
2070
|
{ n: "Lista Lending", img: "lista", cap: "read + quote", u: "https://lista.org/lending" },
|
|
2071
|
-
{ n: "Silhouette", cap: "read", u: "https://silhouette.exchange/" },
|
|
2072
|
-
{ n: "Nest Exchange", cap: "read", u: "https://
|
|
2071
|
+
{ n: "Silhouette", img: "silhouette", cap: "read", u: "https://silhouette.exchange/" },
|
|
2072
|
+
{ n: "Nest Exchange", img: "nest", cap: "read", u: "https://usenest.xyz/" },
|
|
2073
2073
|
{ n: "Lista CDP", img: "lista", cap: "read", u: "https://lista.org/" },
|
|
2074
2074
|
{ n: "Benqi Lending", img: "benqi", cap: "read", u: "https://benqi.fi" },
|
|
2075
2075
|
{ n: "Pharaoh V3", img: "pharaoh", cap: "read + quote", u: "https://www.phar.gg/" },
|
|
2076
|
-
{ n: "Trade XYZ", cap: "read", u: "https://trade.xyz/" },
|
|
2077
|
-
{ n: "Markets by Kinetiq", cap: "read", u: "https://markets.xyz/" },
|
|
2078
|
-
{ n: "Outcome", cap: "read", u: "https://outcome.xyz/" },
|
|
2076
|
+
{ n: "Trade XYZ", img: "tradexyz", cap: "read", u: "https://trade.xyz/" },
|
|
2077
|
+
{ n: "Markets by Kinetiq", img: "markets", cap: "read", u: "https://markets.xyz/" },
|
|
2078
|
+
{ n: "Outcome", img: "outcome", cap: "read", u: "https://outcome.xyz/" },
|
|
2079
2079
|
{ n: "Polymarket", wm: "polymarket.png", cap: "read", u: "https://polymarket.com/" },
|
|
2080
2080
|
{ n: "XSY", img: "xsy", cap: "read", u: "https://xsy.fi" },
|
|
2081
2081
|
{ n: "Balancer V2", wm: "balancer.svg", cap: "read + quote", u: "https://balancer.fi/" },
|
|
@@ -2102,8 +2102,8 @@ var BRAND = "brand/";
|
|
|
2102
2102
|
{ n: "Odos", wm: "odos.svg", cap: "read + route source", u: "https://app.odos.xyz" },
|
|
2103
2103
|
{ n: "Jupiter", wm: "jupiter.svg", cap: "solana route source", u: "https://jup.ag/" },
|
|
2104
2104
|
{ n: "Stargate", wm: "stargate.svg", cap: "read + bridge route", u: "https://stargate.finance/" },
|
|
2105
|
-
{ n: "Motion", cap: "read", u: "https://
|
|
2106
|
-
{ n: "LiquidLaunch", cap: "read", u: "https://liquidlaunch.app/" },
|
|
2105
|
+
{ n: "Motion", img: "motion", cap: "read", u: "https://motion.meme/" },
|
|
2106
|
+
{ n: "LiquidLaunch", img: "liquidlaunch", cap: "read", u: "https://liquidlaunch.app/" },
|
|
2107
2107
|
];
|
|
2108
2108
|
var PROTOS_B = [
|
|
2109
2109
|
{ n: "Uniswap V3 LP", img: "uniswap", cap: "preview + mint/collect prepare", u: "https://app.uniswap.org/" },
|
package/server.json
CHANGED
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
"name": "io.github.demi-hl/oracle",
|
|
4
4
|
"description": "Keyless multichain crypto desk: chain reads + prepare-only unsigned txs. Your wallet signs.",
|
|
5
5
|
"websiteUrl": "https://oracle.demi.la",
|
|
6
|
-
"version": "0.35.
|
|
6
|
+
"version": "0.35.22",
|
|
7
7
|
"packages": [
|
|
8
8
|
{
|
|
9
9
|
"registryType": "npm",
|
|
10
10
|
"identifier": "@oracle-agent/oracle",
|
|
11
|
-
"version": "0.35.
|
|
11
|
+
"version": "0.35.22",
|
|
12
12
|
"transport": {
|
|
13
13
|
"type": "stdio"
|
|
14
14
|
},
|