@kynver-app/runtime 0.2.101 → 0.2.114
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chat/chat-access-change-record.js +1 -0
- package/dist/chat/chat-turn-envelope.js +1 -0
- package/dist/cli.js +319 -154
- package/dist/desktop-entry.js +271 -112
- package/dist/index.js +321 -156
- package/dist/local-run-store/index.js +17 -15
- package/dist/server/cleanup.js +14 -14
- package/dist/server/default-repo.js +1 -1
- package/dist/server/dispatch-routing.js +3 -3
- package/dist/server/model-routing.js +3 -3
- package/dist/server/monitor.js +7 -7
- package/dist/server/worker-policy.js +2 -2
- package/package.json +12 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{verify as I,createPublicKey as k}from"node:crypto";function u(e){return JSON.stringify(f(e))}function f(e){if(Array.isArray(e))return e.map(f);if(e&&typeof e=="object"){let n={};for(let r of Object.keys(e).sort())n[r]=f(e[r]);return n}return e}function c(e){if(!e)return null;let n=e.trim();if(!n)return null;if(/^[0-9a-fA-F]{64}$/.test(n))return new Uint8Array(n.match(/.{2}/g).map(r=>parseInt(r,16)));try{let r=Buffer.from(n,"base64");if(r.length===32)return new Uint8Array(r)}catch{}return null}function g(e=process.env){if(e.NODE_ENV==="production")return!1;let n=e.KYNVER_ALLOW_DEV_SIGNING_KEYS?.trim().toLowerCase();return n==="1"||n==="true"||n==="yes"||n==="on"?!0:e.NODE_ENV==="test"||e.VITEST==="true"}import{createHash as b,createPublicKey as B,verify as E}from"node:crypto";var w=Buffer.from("302a300506032b6570032100","hex"),p="ca-6297fb8e1773",A={[p]:"16ae5cb2a61f8c94cf1b86e8258f9c2f2ff6aba5e6136250a422209b6e866881","ca-456fd128f3b3":"f29cbd559410c2578d7f9732ccd86570073355ccdb36af0d1b7dff15908466e7"};function C(e){return`ca-${b("sha256").update(Buffer.from(e)).digest("hex").slice(0,12)}`}function y(e,n=process.env){let r=c(n.KYNVER_COMMAND_AUTH_PUBLIC_KEY);if(r)return C(r)!==e?null:r;let t=A[e];return!t||e===p&&!g(n)?null:c(t)}var V=720*60*60,x="change",P=Buffer.from("302a300506032b6570032100","hex");function _(e){if(!e||typeof e!="object"||Array.isArray(e))return!1;let n=e;if(typeof n.signature!="string"||!n.signature||typeof n.publicKeyId!="string"||!n.publicKeyId)return!1;let r=n.payload;return!(!r||typeof r!="object"||r.v!==1||r.kind!=="chat-access-change"||typeof r.agentOsId!="string"||!r.agentOsId||typeof r.boxId!="string"||!r.boxId||typeof r.access!="string"||!r.access||!Array.isArray(r.folders)||!r.folders.every(t=>typeof t=="string")||typeof r.changedAt!="string"||Number.isNaN(Date.parse(r.changedAt))||typeof r.exp!="number"||!Number.isFinite(r.exp)||typeof r.nonce!="string"||!r.nonce)}function j(e){return!e||typeof e!="object"||Array.isArray(e)?null:e[x]??null}function R(e,n){return e.length===n.length&&e.every((r,t)=>r===n[t])}function S(e,n){let r=Date.parse(e),t=Date.parse(n);return Number.isNaN(r)?!1:Number.isNaN(t)?!0:r>t}function U(e,n,r={}){let t=r.env??process.env,h=r.nowSec??Math.floor(Date.now()/1e3);if(e==null)return{ok:!1,code:"missing",reason:"the turn carries no signed settings-change record for this raise"};if(!_(e))return{ok:!1,code:"malformed",reason:"malformed settings-change record"};let{payload:o}=e;if(o.agentOsId!==n.agentOsId)return{ok:!1,code:"mismatch",reason:"settings-change record is for another workspace"};if(o.boxId!==n.boxId)return{ok:!1,code:"mismatch",reason:"settings-change record is for another computer"};if(o.access!==n.access||!R(o.folders,n.folders))return{ok:!1,code:"mismatch",reason:"settings-change record does not match the access the turn asks for"};if(o.exp<=h)return{ok:!1,code:"expired",reason:"settings-change record expired \u2014 save the setting again in Computers settings"};let d=y(e.publicKeyId,t);if(!d)return{ok:!1,code:"no_verification_key",reason:`no verification key for publicKeyId "${e.publicKeyId}"`};let a;try{a=Buffer.from(e.signature,"base64url")}catch{return{ok:!1,code:"bad_signature",reason:"signature is not base64url"}}if(a.length!==64)return{ok:!1,code:"bad_signature",reason:"signature is not a 64-byte Ed25519 signature"};let l=!1;try{let i=Buffer.from(u(o),"utf8"),m=k({key:Buffer.concat([P,Buffer.from(d)]),format:"der",type:"spki"});l=I(null,i,m,a)}catch(i){return{ok:!1,code:"bad_signature",reason:`signature verification failed: ${i.message}`}}if(!l)return{ok:!1,code:"bad_signature",reason:"Ed25519 signature mismatch"};let s=r.lastApplied??null;return s&&(s.nonce===o.nonce||!S(o.changedAt,s.changedAt))?{ok:!1,code:"replayed",reason:"settings-change record is not newer than the one this computer last applied"}:{ok:!0,payload:o}}export{x as CHAT_ACCESS_CHANGE_RECORD_FIELD,V as CHAT_ACCESS_CHANGE_RECORD_TTL_SEC,S as isChangedAtAfter,_ as isSignedChatAccessChangeRecordShape,j as readChatAccessChangeRecord,U as verifyChatAccessChangeRecord};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createHash as A,verify as _,createPublicKey as E}from"node:crypto";function i(r){return JSON.stringify(c(r))}function c(r){if(Array.isArray(r))return r.map(c);if(r&&typeof r=="object"){let e={};for(let n of Object.keys(r).sort())e[n]=c(r[n]);return e}return r}function d(r){if(!r)return null;let e=r.trim();if(!e)return null;if(/^[0-9a-fA-F]{64}$/.test(e))return new Uint8Array(e.match(/.{2}/g).map(n=>parseInt(n,16)));try{let n=Buffer.from(e,"base64");if(n.length===32)return new Uint8Array(n)}catch{}return null}function h(r=process.env){if(r.NODE_ENV==="production")return!1;let e=r.KYNVER_ALLOW_DEV_SIGNING_KEYS?.trim().toLowerCase();return e==="1"||e==="true"||e==="yes"||e==="on"?!0:r.NODE_ENV==="test"||r.VITEST==="true"}import{createHash as v,createPublicKey as j,verify as L}from"node:crypto";var V=Buffer.from("302a300506032b6570032100","hex"),m="ca-6297fb8e1773",x={[m]:"16ae5cb2a61f8c94cf1b86e8258f9c2f2ff6aba5e6136250a422209b6e866881","ca-456fd128f3b3":"f29cbd559410c2578d7f9732ccd86570073355ccdb36af0d1b7dff15908466e7"};function C(r){return`ca-${v("sha256").update(Buffer.from(r)).digest("hex").slice(0,12)}`}function b(r,e=process.env){let n=d(e.KYNVER_COMMAND_AUTH_PUBLIC_KEY);if(n)return C(n)!==r?null:n;let o=x[r];return!o||r===m&&!h(e)?null:d(o)}var F=900,k="turnEnvelope",T=Buffer.from("302a300506032b6570032100","hex");function P(r){if(!r||typeof r!="object"||Array.isArray(r))return r;let e={...r};return delete e[k],e}function S(r){return A("sha256").update(i(P(r)),"utf8").digest("hex")}function w(r){return!r||typeof r!="object"||Array.isArray(r)?null:r[k]??null}function R(r){if(!r||typeof r!="object")return!1;let e=r;if(typeof e.signature!="string"||!e.signature||typeof e.publicKeyId!="string"||!e.publicKeyId)return!1;let n=e.payload;return!(!n||typeof n!="object"||n.v!==1||n.kind!=="chat-turn"||typeof n.turnId!="string"||!n.turnId||typeof n.agentOsId!="string"||!n.agentOsId||n.userId!==null&&(typeof n.userId!="string"||!n.userId)||n.boxId!==null&&typeof n.boxId!="string"||n.access!==null&&(!n.access||typeof n.access!="object"||Array.isArray(n.access))||typeof n.payloadHash!="string"||!/^[0-9a-f]{64}$/.test(n.payloadHash)||typeof n.exp!="number"||!Number.isFinite(n.exp)||typeof n.nonce!="string"||!n.nonce)}function N(r,e){let n=r&&typeof r=="object"&&!Array.isArray(r)?r.computerAccess??null:null;return n===null&&e===null?!0:n===null||e===null?!1:i(n)===i(e)}var I=class{constructor(e=1e4){this.maxEntries=e}maxEntries;byNonce=new Map;byTurn=new Map;consume(e){let n=e.nowSec??Math.floor(Date.now()/1e3);this.purge(n);let o=this.byNonce.get(e.nonce);if(o)return o.turnId!==e.turnId?{ok:!1,replay:p(o,"turn_mismatch")}:o.state==="verified"?{ok:!0,redelivered:!0}:{ok:!1,replay:p(o,o.state==="started"?"in_flight":"already_ran")};let a=this.byTurn.get(e.turnId);if(a){if(a.state!=="verified")return{ok:!1,replay:p(a,a.state==="started"?"in_flight":"already_ran")};this.byNonce.delete(a.nonce);let t={...a,nonce:e.nonce,untilSec:Math.max(a.untilSec,e.expSec+60)};return this.byNonce.set(e.nonce,t),this.byTurn.set(e.turnId,t),{ok:!0,redelivered:!0}}if(this.byNonce.size>=this.maxEntries){let t=this.byNonce.values().next().value;t&&this.forget(t)}let s={nonce:e.nonce,turnId:e.turnId,firstSeenSec:n,state:"verified",untilSec:e.expSec+60};return this.byNonce.set(e.nonce,s),this.byTurn.set(e.turnId,s),{ok:!0,redelivered:!1}}markStarted(e){let n=this.byTurn.get(e);return n?(n.state==="verified"&&(n.state="started"),!0):!1}markFinished(e){let n=this.byTurn.get(e);return n?(n.state="finished",!0):!1}stateOf(e){return this.byTurn.get(e)?.state??null}purge(e=Math.floor(Date.now()/1e3)){for(let n of[...this.byNonce.values()])n.untilSec<=e&&this.forget(n)}forget(e){this.byNonce.delete(e.nonce),this.byTurn.get(e.turnId)===e&&this.byTurn.delete(e.turnId)}get size(){return this.byNonce.size}};function p(r,e){return{state:e,firstSeenAt:new Date(r.firstSeenSec*1e3).toISOString(),turnId:r.turnId}}function K(r){return E({key:Buffer.concat([T,Buffer.from(r)]),format:"der",type:"spki"})}function Y(r,e,n={}){let o=n.env??process.env,a=n.nowSec??Math.floor(Date.now()/1e3),s=w(r);if(s===null)return{ok:!1,code:"unsigned",reason:"turn carries no signed envelope"};if(!R(s))return{ok:!1,code:"malformed",reason:"malformed chat-turn envelope"};let t=s;if(t.payload.agentOsId!==e.agentOsId)return{ok:!1,code:"agent_os_mismatch",reason:"envelope is for another workspace"};if(t.payload.turnId!==e.turnId)return{ok:!1,code:"turn_id_mismatch",reason:"envelope is for another turn"};if(t.payload.exp<=a)return{ok:!1,code:"expired",reason:"envelope expired"};let y=b(t.publicKeyId,o);if(!y)return{ok:!1,code:"no_verification_key",reason:`no verification key for publicKeyId "${t.publicKeyId}"`};let f;try{f=Buffer.from(t.signature,"base64url")}catch{return{ok:!1,code:"bad_signature",reason:"signature is not base64url"}}if(f.length!==64)return{ok:!1,code:"bad_signature",reason:"signature is not a 64-byte Ed25519 signature"};let g=!1;try{let l=Buffer.from(i(t.payload),"utf8");g=_(null,l,K(y),f)}catch(l){return{ok:!1,code:"bad_signature",reason:`signature verification failed: ${l.message}`}}if(!g)return{ok:!1,code:"bad_signature",reason:"Ed25519 signature mismatch"};if(S(r)!==t.payload.payloadHash)return{ok:!1,code:"payload_tampered",reason:"turn payload does not match its signed hash"};if(!N(r,t.payload.access))return{ok:!1,code:"access_mismatch",reason:"computer access on the turn differs from the signed setting"};if(!n.nonces)return{ok:!0,payload:t.payload,redelivered:!1};let u=n.nonces.consume({nonce:t.payload.nonce,turnId:t.payload.turnId,expSec:t.payload.exp,nowSec:a});return u.ok?{ok:!0,payload:t.payload,redelivered:u.redelivered}:{ok:!1,code:"replayed",reason:`envelope nonce already used on this computer (${B(u.replay)})`,replay:u.replay}}function B(r){return`${r.state==="in_flight"?"this computer is running that turn now":r.state==="already_ran"?"that turn already ran here":`the nonce belongs to turn ${r.turnId}`}; first seen ${r.firstSeenAt}`}export{k as CHAT_TURN_ENVELOPE_FIELD,F as CHAT_TURN_ENVELOPE_TTL_SEC,I as ChatTurnNonceCache,N as chatTurnAccessMatches,S as hashChatTurnPayload,R as isSignedChatTurnEnvelopeShape,w as readChatTurnEnvelope,P as stripChatTurnEnvelope,Y as verifyChatTurnEnvelope};
|