echoclaw-relay-agent 0.2.2 → 0.3.0

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.
Files changed (2) hide show
  1. package/dist/main.js +3151 -127
  2. package/package.json +4 -1
package/dist/main.js CHANGED
@@ -6,6 +6,9 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
6
  var __getOwnPropNames = Object.getOwnPropertyNames;
7
7
  var __getProtoOf = Object.getPrototypeOf;
8
8
  var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __commonJS = (cb, mod) => function __require() {
10
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
11
+ };
9
12
  var __copyProps = (to, from, except, desc) => {
10
13
  if (from && typeof from === "object" || typeof from === "function") {
11
14
  for (let key of __getOwnPropNames(from))
@@ -23,8 +26,1120 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
23
26
  mod
24
27
  ));
25
28
 
29
+ // ../../node_modules/.pnpm/json5@2.2.3/node_modules/json5/lib/unicode.js
30
+ var require_unicode = __commonJS({
31
+ "../../node_modules/.pnpm/json5@2.2.3/node_modules/json5/lib/unicode.js"(exports2, module2) {
32
+ module2.exports.Space_Separator = /[\u1680\u2000-\u200A\u202F\u205F\u3000]/;
33
+ module2.exports.ID_Start = /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE83\uDE86-\uDE89\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]/;
34
+ module2.exports.ID_Continue = /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u08D4-\u08E1\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u09FC\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9-\u0AFF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C80-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D00-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D54-\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1CD0-\u1CD2\u1CD4-\u1CF9\u1D00-\u1DF9\u1DFB-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE3E\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC00-\uDC4A\uDC50-\uDC59\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDE00-\uDE3E\uDE47\uDE50-\uDE83\uDE86-\uDE99\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC40\uDC50-\uDC59\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD47\uDD50-\uDD59]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6\uDD00-\uDD4A\uDD50-\uDD59]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/;
35
+ }
36
+ });
37
+
38
+ // ../../node_modules/.pnpm/json5@2.2.3/node_modules/json5/lib/util.js
39
+ var require_util = __commonJS({
40
+ "../../node_modules/.pnpm/json5@2.2.3/node_modules/json5/lib/util.js"(exports2, module2) {
41
+ var unicode = require_unicode();
42
+ module2.exports = {
43
+ isSpaceSeparator(c) {
44
+ return typeof c === "string" && unicode.Space_Separator.test(c);
45
+ },
46
+ isIdStartChar(c) {
47
+ return typeof c === "string" && (c >= "a" && c <= "z" || c >= "A" && c <= "Z" || c === "$" || c === "_" || unicode.ID_Start.test(c));
48
+ },
49
+ isIdContinueChar(c) {
50
+ return typeof c === "string" && (c >= "a" && c <= "z" || c >= "A" && c <= "Z" || c >= "0" && c <= "9" || c === "$" || c === "_" || c === "\u200C" || c === "\u200D" || unicode.ID_Continue.test(c));
51
+ },
52
+ isDigit(c) {
53
+ return typeof c === "string" && /[0-9]/.test(c);
54
+ },
55
+ isHexDigit(c) {
56
+ return typeof c === "string" && /[0-9A-Fa-f]/.test(c);
57
+ }
58
+ };
59
+ }
60
+ });
61
+
62
+ // ../../node_modules/.pnpm/json5@2.2.3/node_modules/json5/lib/parse.js
63
+ var require_parse = __commonJS({
64
+ "../../node_modules/.pnpm/json5@2.2.3/node_modules/json5/lib/parse.js"(exports2, module2) {
65
+ var util = require_util();
66
+ var source;
67
+ var parseState;
68
+ var stack;
69
+ var pos;
70
+ var line;
71
+ var column;
72
+ var token;
73
+ var key;
74
+ var root;
75
+ module2.exports = function parse(text, reviver) {
76
+ source = String(text);
77
+ parseState = "start";
78
+ stack = [];
79
+ pos = 0;
80
+ line = 1;
81
+ column = 0;
82
+ token = void 0;
83
+ key = void 0;
84
+ root = void 0;
85
+ do {
86
+ token = lex();
87
+ parseStates[parseState]();
88
+ } while (token.type !== "eof");
89
+ if (typeof reviver === "function") {
90
+ return internalize({ "": root }, "", reviver);
91
+ }
92
+ return root;
93
+ };
94
+ function internalize(holder, name, reviver) {
95
+ const value = holder[name];
96
+ if (value != null && typeof value === "object") {
97
+ if (Array.isArray(value)) {
98
+ for (let i = 0; i < value.length; i++) {
99
+ const key2 = String(i);
100
+ const replacement = internalize(value, key2, reviver);
101
+ if (replacement === void 0) {
102
+ delete value[key2];
103
+ } else {
104
+ Object.defineProperty(value, key2, {
105
+ value: replacement,
106
+ writable: true,
107
+ enumerable: true,
108
+ configurable: true
109
+ });
110
+ }
111
+ }
112
+ } else {
113
+ for (const key2 in value) {
114
+ const replacement = internalize(value, key2, reviver);
115
+ if (replacement === void 0) {
116
+ delete value[key2];
117
+ } else {
118
+ Object.defineProperty(value, key2, {
119
+ value: replacement,
120
+ writable: true,
121
+ enumerable: true,
122
+ configurable: true
123
+ });
124
+ }
125
+ }
126
+ }
127
+ }
128
+ return reviver.call(holder, name, value);
129
+ }
130
+ var lexState;
131
+ var buffer;
132
+ var doubleQuote;
133
+ var sign;
134
+ var c;
135
+ function lex() {
136
+ lexState = "default";
137
+ buffer = "";
138
+ doubleQuote = false;
139
+ sign = 1;
140
+ for (; ; ) {
141
+ c = peek();
142
+ const token2 = lexStates[lexState]();
143
+ if (token2) {
144
+ return token2;
145
+ }
146
+ }
147
+ }
148
+ function peek() {
149
+ if (source[pos]) {
150
+ return String.fromCodePoint(source.codePointAt(pos));
151
+ }
152
+ }
153
+ function read() {
154
+ const c2 = peek();
155
+ if (c2 === "\n") {
156
+ line++;
157
+ column = 0;
158
+ } else if (c2) {
159
+ column += c2.length;
160
+ } else {
161
+ column++;
162
+ }
163
+ if (c2) {
164
+ pos += c2.length;
165
+ }
166
+ return c2;
167
+ }
168
+ var lexStates = {
169
+ default() {
170
+ switch (c) {
171
+ case " ":
172
+ case "\v":
173
+ case "\f":
174
+ case " ":
175
+ case "\xA0":
176
+ case "\uFEFF":
177
+ case "\n":
178
+ case "\r":
179
+ case "\u2028":
180
+ case "\u2029":
181
+ read();
182
+ return;
183
+ case "/":
184
+ read();
185
+ lexState = "comment";
186
+ return;
187
+ case void 0:
188
+ read();
189
+ return newToken("eof");
190
+ }
191
+ if (util.isSpaceSeparator(c)) {
192
+ read();
193
+ return;
194
+ }
195
+ return lexStates[parseState]();
196
+ },
197
+ comment() {
198
+ switch (c) {
199
+ case "*":
200
+ read();
201
+ lexState = "multiLineComment";
202
+ return;
203
+ case "/":
204
+ read();
205
+ lexState = "singleLineComment";
206
+ return;
207
+ }
208
+ throw invalidChar(read());
209
+ },
210
+ multiLineComment() {
211
+ switch (c) {
212
+ case "*":
213
+ read();
214
+ lexState = "multiLineCommentAsterisk";
215
+ return;
216
+ case void 0:
217
+ throw invalidChar(read());
218
+ }
219
+ read();
220
+ },
221
+ multiLineCommentAsterisk() {
222
+ switch (c) {
223
+ case "*":
224
+ read();
225
+ return;
226
+ case "/":
227
+ read();
228
+ lexState = "default";
229
+ return;
230
+ case void 0:
231
+ throw invalidChar(read());
232
+ }
233
+ read();
234
+ lexState = "multiLineComment";
235
+ },
236
+ singleLineComment() {
237
+ switch (c) {
238
+ case "\n":
239
+ case "\r":
240
+ case "\u2028":
241
+ case "\u2029":
242
+ read();
243
+ lexState = "default";
244
+ return;
245
+ case void 0:
246
+ read();
247
+ return newToken("eof");
248
+ }
249
+ read();
250
+ },
251
+ value() {
252
+ switch (c) {
253
+ case "{":
254
+ case "[":
255
+ return newToken("punctuator", read());
256
+ case "n":
257
+ read();
258
+ literal("ull");
259
+ return newToken("null", null);
260
+ case "t":
261
+ read();
262
+ literal("rue");
263
+ return newToken("boolean", true);
264
+ case "f":
265
+ read();
266
+ literal("alse");
267
+ return newToken("boolean", false);
268
+ case "-":
269
+ case "+":
270
+ if (read() === "-") {
271
+ sign = -1;
272
+ }
273
+ lexState = "sign";
274
+ return;
275
+ case ".":
276
+ buffer = read();
277
+ lexState = "decimalPointLeading";
278
+ return;
279
+ case "0":
280
+ buffer = read();
281
+ lexState = "zero";
282
+ return;
283
+ case "1":
284
+ case "2":
285
+ case "3":
286
+ case "4":
287
+ case "5":
288
+ case "6":
289
+ case "7":
290
+ case "8":
291
+ case "9":
292
+ buffer = read();
293
+ lexState = "decimalInteger";
294
+ return;
295
+ case "I":
296
+ read();
297
+ literal("nfinity");
298
+ return newToken("numeric", Infinity);
299
+ case "N":
300
+ read();
301
+ literal("aN");
302
+ return newToken("numeric", NaN);
303
+ case '"':
304
+ case "'":
305
+ doubleQuote = read() === '"';
306
+ buffer = "";
307
+ lexState = "string";
308
+ return;
309
+ }
310
+ throw invalidChar(read());
311
+ },
312
+ identifierNameStartEscape() {
313
+ if (c !== "u") {
314
+ throw invalidChar(read());
315
+ }
316
+ read();
317
+ const u = unicodeEscape();
318
+ switch (u) {
319
+ case "$":
320
+ case "_":
321
+ break;
322
+ default:
323
+ if (!util.isIdStartChar(u)) {
324
+ throw invalidIdentifier();
325
+ }
326
+ break;
327
+ }
328
+ buffer += u;
329
+ lexState = "identifierName";
330
+ },
331
+ identifierName() {
332
+ switch (c) {
333
+ case "$":
334
+ case "_":
335
+ case "\u200C":
336
+ case "\u200D":
337
+ buffer += read();
338
+ return;
339
+ case "\\":
340
+ read();
341
+ lexState = "identifierNameEscape";
342
+ return;
343
+ }
344
+ if (util.isIdContinueChar(c)) {
345
+ buffer += read();
346
+ return;
347
+ }
348
+ return newToken("identifier", buffer);
349
+ },
350
+ identifierNameEscape() {
351
+ if (c !== "u") {
352
+ throw invalidChar(read());
353
+ }
354
+ read();
355
+ const u = unicodeEscape();
356
+ switch (u) {
357
+ case "$":
358
+ case "_":
359
+ case "\u200C":
360
+ case "\u200D":
361
+ break;
362
+ default:
363
+ if (!util.isIdContinueChar(u)) {
364
+ throw invalidIdentifier();
365
+ }
366
+ break;
367
+ }
368
+ buffer += u;
369
+ lexState = "identifierName";
370
+ },
371
+ sign() {
372
+ switch (c) {
373
+ case ".":
374
+ buffer = read();
375
+ lexState = "decimalPointLeading";
376
+ return;
377
+ case "0":
378
+ buffer = read();
379
+ lexState = "zero";
380
+ return;
381
+ case "1":
382
+ case "2":
383
+ case "3":
384
+ case "4":
385
+ case "5":
386
+ case "6":
387
+ case "7":
388
+ case "8":
389
+ case "9":
390
+ buffer = read();
391
+ lexState = "decimalInteger";
392
+ return;
393
+ case "I":
394
+ read();
395
+ literal("nfinity");
396
+ return newToken("numeric", sign * Infinity);
397
+ case "N":
398
+ read();
399
+ literal("aN");
400
+ return newToken("numeric", NaN);
401
+ }
402
+ throw invalidChar(read());
403
+ },
404
+ zero() {
405
+ switch (c) {
406
+ case ".":
407
+ buffer += read();
408
+ lexState = "decimalPoint";
409
+ return;
410
+ case "e":
411
+ case "E":
412
+ buffer += read();
413
+ lexState = "decimalExponent";
414
+ return;
415
+ case "x":
416
+ case "X":
417
+ buffer += read();
418
+ lexState = "hexadecimal";
419
+ return;
420
+ }
421
+ return newToken("numeric", sign * 0);
422
+ },
423
+ decimalInteger() {
424
+ switch (c) {
425
+ case ".":
426
+ buffer += read();
427
+ lexState = "decimalPoint";
428
+ return;
429
+ case "e":
430
+ case "E":
431
+ buffer += read();
432
+ lexState = "decimalExponent";
433
+ return;
434
+ }
435
+ if (util.isDigit(c)) {
436
+ buffer += read();
437
+ return;
438
+ }
439
+ return newToken("numeric", sign * Number(buffer));
440
+ },
441
+ decimalPointLeading() {
442
+ if (util.isDigit(c)) {
443
+ buffer += read();
444
+ lexState = "decimalFraction";
445
+ return;
446
+ }
447
+ throw invalidChar(read());
448
+ },
449
+ decimalPoint() {
450
+ switch (c) {
451
+ case "e":
452
+ case "E":
453
+ buffer += read();
454
+ lexState = "decimalExponent";
455
+ return;
456
+ }
457
+ if (util.isDigit(c)) {
458
+ buffer += read();
459
+ lexState = "decimalFraction";
460
+ return;
461
+ }
462
+ return newToken("numeric", sign * Number(buffer));
463
+ },
464
+ decimalFraction() {
465
+ switch (c) {
466
+ case "e":
467
+ case "E":
468
+ buffer += read();
469
+ lexState = "decimalExponent";
470
+ return;
471
+ }
472
+ if (util.isDigit(c)) {
473
+ buffer += read();
474
+ return;
475
+ }
476
+ return newToken("numeric", sign * Number(buffer));
477
+ },
478
+ decimalExponent() {
479
+ switch (c) {
480
+ case "+":
481
+ case "-":
482
+ buffer += read();
483
+ lexState = "decimalExponentSign";
484
+ return;
485
+ }
486
+ if (util.isDigit(c)) {
487
+ buffer += read();
488
+ lexState = "decimalExponentInteger";
489
+ return;
490
+ }
491
+ throw invalidChar(read());
492
+ },
493
+ decimalExponentSign() {
494
+ if (util.isDigit(c)) {
495
+ buffer += read();
496
+ lexState = "decimalExponentInteger";
497
+ return;
498
+ }
499
+ throw invalidChar(read());
500
+ },
501
+ decimalExponentInteger() {
502
+ if (util.isDigit(c)) {
503
+ buffer += read();
504
+ return;
505
+ }
506
+ return newToken("numeric", sign * Number(buffer));
507
+ },
508
+ hexadecimal() {
509
+ if (util.isHexDigit(c)) {
510
+ buffer += read();
511
+ lexState = "hexadecimalInteger";
512
+ return;
513
+ }
514
+ throw invalidChar(read());
515
+ },
516
+ hexadecimalInteger() {
517
+ if (util.isHexDigit(c)) {
518
+ buffer += read();
519
+ return;
520
+ }
521
+ return newToken("numeric", sign * Number(buffer));
522
+ },
523
+ string() {
524
+ switch (c) {
525
+ case "\\":
526
+ read();
527
+ buffer += escape();
528
+ return;
529
+ case '"':
530
+ if (doubleQuote) {
531
+ read();
532
+ return newToken("string", buffer);
533
+ }
534
+ buffer += read();
535
+ return;
536
+ case "'":
537
+ if (!doubleQuote) {
538
+ read();
539
+ return newToken("string", buffer);
540
+ }
541
+ buffer += read();
542
+ return;
543
+ case "\n":
544
+ case "\r":
545
+ throw invalidChar(read());
546
+ case "\u2028":
547
+ case "\u2029":
548
+ separatorChar(c);
549
+ break;
550
+ case void 0:
551
+ throw invalidChar(read());
552
+ }
553
+ buffer += read();
554
+ },
555
+ start() {
556
+ switch (c) {
557
+ case "{":
558
+ case "[":
559
+ return newToken("punctuator", read());
560
+ }
561
+ lexState = "value";
562
+ },
563
+ beforePropertyName() {
564
+ switch (c) {
565
+ case "$":
566
+ case "_":
567
+ buffer = read();
568
+ lexState = "identifierName";
569
+ return;
570
+ case "\\":
571
+ read();
572
+ lexState = "identifierNameStartEscape";
573
+ return;
574
+ case "}":
575
+ return newToken("punctuator", read());
576
+ case '"':
577
+ case "'":
578
+ doubleQuote = read() === '"';
579
+ lexState = "string";
580
+ return;
581
+ }
582
+ if (util.isIdStartChar(c)) {
583
+ buffer += read();
584
+ lexState = "identifierName";
585
+ return;
586
+ }
587
+ throw invalidChar(read());
588
+ },
589
+ afterPropertyName() {
590
+ if (c === ":") {
591
+ return newToken("punctuator", read());
592
+ }
593
+ throw invalidChar(read());
594
+ },
595
+ beforePropertyValue() {
596
+ lexState = "value";
597
+ },
598
+ afterPropertyValue() {
599
+ switch (c) {
600
+ case ",":
601
+ case "}":
602
+ return newToken("punctuator", read());
603
+ }
604
+ throw invalidChar(read());
605
+ },
606
+ beforeArrayValue() {
607
+ if (c === "]") {
608
+ return newToken("punctuator", read());
609
+ }
610
+ lexState = "value";
611
+ },
612
+ afterArrayValue() {
613
+ switch (c) {
614
+ case ",":
615
+ case "]":
616
+ return newToken("punctuator", read());
617
+ }
618
+ throw invalidChar(read());
619
+ },
620
+ end() {
621
+ throw invalidChar(read());
622
+ }
623
+ };
624
+ function newToken(type, value) {
625
+ return {
626
+ type,
627
+ value,
628
+ line,
629
+ column
630
+ };
631
+ }
632
+ function literal(s) {
633
+ for (const c2 of s) {
634
+ const p = peek();
635
+ if (p !== c2) {
636
+ throw invalidChar(read());
637
+ }
638
+ read();
639
+ }
640
+ }
641
+ function escape() {
642
+ const c2 = peek();
643
+ switch (c2) {
644
+ case "b":
645
+ read();
646
+ return "\b";
647
+ case "f":
648
+ read();
649
+ return "\f";
650
+ case "n":
651
+ read();
652
+ return "\n";
653
+ case "r":
654
+ read();
655
+ return "\r";
656
+ case "t":
657
+ read();
658
+ return " ";
659
+ case "v":
660
+ read();
661
+ return "\v";
662
+ case "0":
663
+ read();
664
+ if (util.isDigit(peek())) {
665
+ throw invalidChar(read());
666
+ }
667
+ return "\0";
668
+ case "x":
669
+ read();
670
+ return hexEscape();
671
+ case "u":
672
+ read();
673
+ return unicodeEscape();
674
+ case "\n":
675
+ case "\u2028":
676
+ case "\u2029":
677
+ read();
678
+ return "";
679
+ case "\r":
680
+ read();
681
+ if (peek() === "\n") {
682
+ read();
683
+ }
684
+ return "";
685
+ case "1":
686
+ case "2":
687
+ case "3":
688
+ case "4":
689
+ case "5":
690
+ case "6":
691
+ case "7":
692
+ case "8":
693
+ case "9":
694
+ throw invalidChar(read());
695
+ case void 0:
696
+ throw invalidChar(read());
697
+ }
698
+ return read();
699
+ }
700
+ function hexEscape() {
701
+ let buffer2 = "";
702
+ let c2 = peek();
703
+ if (!util.isHexDigit(c2)) {
704
+ throw invalidChar(read());
705
+ }
706
+ buffer2 += read();
707
+ c2 = peek();
708
+ if (!util.isHexDigit(c2)) {
709
+ throw invalidChar(read());
710
+ }
711
+ buffer2 += read();
712
+ return String.fromCodePoint(parseInt(buffer2, 16));
713
+ }
714
+ function unicodeEscape() {
715
+ let buffer2 = "";
716
+ let count = 4;
717
+ while (count-- > 0) {
718
+ const c2 = peek();
719
+ if (!util.isHexDigit(c2)) {
720
+ throw invalidChar(read());
721
+ }
722
+ buffer2 += read();
723
+ }
724
+ return String.fromCodePoint(parseInt(buffer2, 16));
725
+ }
726
+ var parseStates = {
727
+ start() {
728
+ if (token.type === "eof") {
729
+ throw invalidEOF();
730
+ }
731
+ push();
732
+ },
733
+ beforePropertyName() {
734
+ switch (token.type) {
735
+ case "identifier":
736
+ case "string":
737
+ key = token.value;
738
+ parseState = "afterPropertyName";
739
+ return;
740
+ case "punctuator":
741
+ pop();
742
+ return;
743
+ case "eof":
744
+ throw invalidEOF();
745
+ }
746
+ },
747
+ afterPropertyName() {
748
+ if (token.type === "eof") {
749
+ throw invalidEOF();
750
+ }
751
+ parseState = "beforePropertyValue";
752
+ },
753
+ beforePropertyValue() {
754
+ if (token.type === "eof") {
755
+ throw invalidEOF();
756
+ }
757
+ push();
758
+ },
759
+ beforeArrayValue() {
760
+ if (token.type === "eof") {
761
+ throw invalidEOF();
762
+ }
763
+ if (token.type === "punctuator" && token.value === "]") {
764
+ pop();
765
+ return;
766
+ }
767
+ push();
768
+ },
769
+ afterPropertyValue() {
770
+ if (token.type === "eof") {
771
+ throw invalidEOF();
772
+ }
773
+ switch (token.value) {
774
+ case ",":
775
+ parseState = "beforePropertyName";
776
+ return;
777
+ case "}":
778
+ pop();
779
+ }
780
+ },
781
+ afterArrayValue() {
782
+ if (token.type === "eof") {
783
+ throw invalidEOF();
784
+ }
785
+ switch (token.value) {
786
+ case ",":
787
+ parseState = "beforeArrayValue";
788
+ return;
789
+ case "]":
790
+ pop();
791
+ }
792
+ },
793
+ end() {
794
+ }
795
+ };
796
+ function push() {
797
+ let value;
798
+ switch (token.type) {
799
+ case "punctuator":
800
+ switch (token.value) {
801
+ case "{":
802
+ value = {};
803
+ break;
804
+ case "[":
805
+ value = [];
806
+ break;
807
+ }
808
+ break;
809
+ case "null":
810
+ case "boolean":
811
+ case "numeric":
812
+ case "string":
813
+ value = token.value;
814
+ break;
815
+ }
816
+ if (root === void 0) {
817
+ root = value;
818
+ } else {
819
+ const parent = stack[stack.length - 1];
820
+ if (Array.isArray(parent)) {
821
+ parent.push(value);
822
+ } else {
823
+ Object.defineProperty(parent, key, {
824
+ value,
825
+ writable: true,
826
+ enumerable: true,
827
+ configurable: true
828
+ });
829
+ }
830
+ }
831
+ if (value !== null && typeof value === "object") {
832
+ stack.push(value);
833
+ if (Array.isArray(value)) {
834
+ parseState = "beforeArrayValue";
835
+ } else {
836
+ parseState = "beforePropertyName";
837
+ }
838
+ } else {
839
+ const current = stack[stack.length - 1];
840
+ if (current == null) {
841
+ parseState = "end";
842
+ } else if (Array.isArray(current)) {
843
+ parseState = "afterArrayValue";
844
+ } else {
845
+ parseState = "afterPropertyValue";
846
+ }
847
+ }
848
+ }
849
+ function pop() {
850
+ stack.pop();
851
+ const current = stack[stack.length - 1];
852
+ if (current == null) {
853
+ parseState = "end";
854
+ } else if (Array.isArray(current)) {
855
+ parseState = "afterArrayValue";
856
+ } else {
857
+ parseState = "afterPropertyValue";
858
+ }
859
+ }
860
+ function invalidChar(c2) {
861
+ if (c2 === void 0) {
862
+ return syntaxError(`JSON5: invalid end of input at ${line}:${column}`);
863
+ }
864
+ return syntaxError(`JSON5: invalid character '${formatChar(c2)}' at ${line}:${column}`);
865
+ }
866
+ function invalidEOF() {
867
+ return syntaxError(`JSON5: invalid end of input at ${line}:${column}`);
868
+ }
869
+ function invalidIdentifier() {
870
+ column -= 5;
871
+ return syntaxError(`JSON5: invalid identifier character at ${line}:${column}`);
872
+ }
873
+ function separatorChar(c2) {
874
+ console.warn(`JSON5: '${formatChar(c2)}' in strings is not valid ECMAScript; consider escaping`);
875
+ }
876
+ function formatChar(c2) {
877
+ const replacements = {
878
+ "'": "\\'",
879
+ '"': '\\"',
880
+ "\\": "\\\\",
881
+ "\b": "\\b",
882
+ "\f": "\\f",
883
+ "\n": "\\n",
884
+ "\r": "\\r",
885
+ " ": "\\t",
886
+ "\v": "\\v",
887
+ "\0": "\\0",
888
+ "\u2028": "\\u2028",
889
+ "\u2029": "\\u2029"
890
+ };
891
+ if (replacements[c2]) {
892
+ return replacements[c2];
893
+ }
894
+ if (c2 < " ") {
895
+ const hexString = c2.charCodeAt(0).toString(16);
896
+ return "\\x" + ("00" + hexString).substring(hexString.length);
897
+ }
898
+ return c2;
899
+ }
900
+ function syntaxError(message) {
901
+ const err2 = new SyntaxError(message);
902
+ err2.lineNumber = line;
903
+ err2.columnNumber = column;
904
+ return err2;
905
+ }
906
+ }
907
+ });
908
+
909
+ // ../../node_modules/.pnpm/json5@2.2.3/node_modules/json5/lib/stringify.js
910
+ var require_stringify = __commonJS({
911
+ "../../node_modules/.pnpm/json5@2.2.3/node_modules/json5/lib/stringify.js"(exports2, module2) {
912
+ var util = require_util();
913
+ module2.exports = function stringify(value, replacer, space) {
914
+ const stack = [];
915
+ let indent = "";
916
+ let propertyList;
917
+ let replacerFunc;
918
+ let gap = "";
919
+ let quote;
920
+ if (replacer != null && typeof replacer === "object" && !Array.isArray(replacer)) {
921
+ space = replacer.space;
922
+ quote = replacer.quote;
923
+ replacer = replacer.replacer;
924
+ }
925
+ if (typeof replacer === "function") {
926
+ replacerFunc = replacer;
927
+ } else if (Array.isArray(replacer)) {
928
+ propertyList = [];
929
+ for (const v of replacer) {
930
+ let item;
931
+ if (typeof v === "string") {
932
+ item = v;
933
+ } else if (typeof v === "number" || v instanceof String || v instanceof Number) {
934
+ item = String(v);
935
+ }
936
+ if (item !== void 0 && propertyList.indexOf(item) < 0) {
937
+ propertyList.push(item);
938
+ }
939
+ }
940
+ }
941
+ if (space instanceof Number) {
942
+ space = Number(space);
943
+ } else if (space instanceof String) {
944
+ space = String(space);
945
+ }
946
+ if (typeof space === "number") {
947
+ if (space > 0) {
948
+ space = Math.min(10, Math.floor(space));
949
+ gap = " ".substr(0, space);
950
+ }
951
+ } else if (typeof space === "string") {
952
+ gap = space.substr(0, 10);
953
+ }
954
+ return serializeProperty("", { "": value });
955
+ function serializeProperty(key, holder) {
956
+ let value2 = holder[key];
957
+ if (value2 != null) {
958
+ if (typeof value2.toJSON5 === "function") {
959
+ value2 = value2.toJSON5(key);
960
+ } else if (typeof value2.toJSON === "function") {
961
+ value2 = value2.toJSON(key);
962
+ }
963
+ }
964
+ if (replacerFunc) {
965
+ value2 = replacerFunc.call(holder, key, value2);
966
+ }
967
+ if (value2 instanceof Number) {
968
+ value2 = Number(value2);
969
+ } else if (value2 instanceof String) {
970
+ value2 = String(value2);
971
+ } else if (value2 instanceof Boolean) {
972
+ value2 = value2.valueOf();
973
+ }
974
+ switch (value2) {
975
+ case null:
976
+ return "null";
977
+ case true:
978
+ return "true";
979
+ case false:
980
+ return "false";
981
+ }
982
+ if (typeof value2 === "string") {
983
+ return quoteString(value2, false);
984
+ }
985
+ if (typeof value2 === "number") {
986
+ return String(value2);
987
+ }
988
+ if (typeof value2 === "object") {
989
+ return Array.isArray(value2) ? serializeArray(value2) : serializeObject(value2);
990
+ }
991
+ return void 0;
992
+ }
993
+ function quoteString(value2) {
994
+ const quotes = {
995
+ "'": 0.1,
996
+ '"': 0.2
997
+ };
998
+ const replacements = {
999
+ "'": "\\'",
1000
+ '"': '\\"',
1001
+ "\\": "\\\\",
1002
+ "\b": "\\b",
1003
+ "\f": "\\f",
1004
+ "\n": "\\n",
1005
+ "\r": "\\r",
1006
+ " ": "\\t",
1007
+ "\v": "\\v",
1008
+ "\0": "\\0",
1009
+ "\u2028": "\\u2028",
1010
+ "\u2029": "\\u2029"
1011
+ };
1012
+ let product = "";
1013
+ for (let i = 0; i < value2.length; i++) {
1014
+ const c = value2[i];
1015
+ switch (c) {
1016
+ case "'":
1017
+ case '"':
1018
+ quotes[c]++;
1019
+ product += c;
1020
+ continue;
1021
+ case "\0":
1022
+ if (util.isDigit(value2[i + 1])) {
1023
+ product += "\\x00";
1024
+ continue;
1025
+ }
1026
+ }
1027
+ if (replacements[c]) {
1028
+ product += replacements[c];
1029
+ continue;
1030
+ }
1031
+ if (c < " ") {
1032
+ let hexString = c.charCodeAt(0).toString(16);
1033
+ product += "\\x" + ("00" + hexString).substring(hexString.length);
1034
+ continue;
1035
+ }
1036
+ product += c;
1037
+ }
1038
+ const quoteChar = quote || Object.keys(quotes).reduce((a, b) => quotes[a] < quotes[b] ? a : b);
1039
+ product = product.replace(new RegExp(quoteChar, "g"), replacements[quoteChar]);
1040
+ return quoteChar + product + quoteChar;
1041
+ }
1042
+ function serializeObject(value2) {
1043
+ if (stack.indexOf(value2) >= 0) {
1044
+ throw TypeError("Converting circular structure to JSON5");
1045
+ }
1046
+ stack.push(value2);
1047
+ let stepback = indent;
1048
+ indent = indent + gap;
1049
+ let keys = propertyList || Object.keys(value2);
1050
+ let partial = [];
1051
+ for (const key of keys) {
1052
+ const propertyString = serializeProperty(key, value2);
1053
+ if (propertyString !== void 0) {
1054
+ let member = serializeKey(key) + ":";
1055
+ if (gap !== "") {
1056
+ member += " ";
1057
+ }
1058
+ member += propertyString;
1059
+ partial.push(member);
1060
+ }
1061
+ }
1062
+ let final;
1063
+ if (partial.length === 0) {
1064
+ final = "{}";
1065
+ } else {
1066
+ let properties;
1067
+ if (gap === "") {
1068
+ properties = partial.join(",");
1069
+ final = "{" + properties + "}";
1070
+ } else {
1071
+ let separator = ",\n" + indent;
1072
+ properties = partial.join(separator);
1073
+ final = "{\n" + indent + properties + ",\n" + stepback + "}";
1074
+ }
1075
+ }
1076
+ stack.pop();
1077
+ indent = stepback;
1078
+ return final;
1079
+ }
1080
+ function serializeKey(key) {
1081
+ if (key.length === 0) {
1082
+ return quoteString(key, true);
1083
+ }
1084
+ const firstChar = String.fromCodePoint(key.codePointAt(0));
1085
+ if (!util.isIdStartChar(firstChar)) {
1086
+ return quoteString(key, true);
1087
+ }
1088
+ for (let i = firstChar.length; i < key.length; i++) {
1089
+ if (!util.isIdContinueChar(String.fromCodePoint(key.codePointAt(i)))) {
1090
+ return quoteString(key, true);
1091
+ }
1092
+ }
1093
+ return key;
1094
+ }
1095
+ function serializeArray(value2) {
1096
+ if (stack.indexOf(value2) >= 0) {
1097
+ throw TypeError("Converting circular structure to JSON5");
1098
+ }
1099
+ stack.push(value2);
1100
+ let stepback = indent;
1101
+ indent = indent + gap;
1102
+ let partial = [];
1103
+ for (let i = 0; i < value2.length; i++) {
1104
+ const propertyString = serializeProperty(String(i), value2);
1105
+ partial.push(propertyString !== void 0 ? propertyString : "null");
1106
+ }
1107
+ let final;
1108
+ if (partial.length === 0) {
1109
+ final = "[]";
1110
+ } else {
1111
+ if (gap === "") {
1112
+ let properties = partial.join(",");
1113
+ final = "[" + properties + "]";
1114
+ } else {
1115
+ let separator = ",\n" + indent;
1116
+ let properties = partial.join(separator);
1117
+ final = "[\n" + indent + properties + ",\n" + stepback + "]";
1118
+ }
1119
+ }
1120
+ stack.pop();
1121
+ indent = stepback;
1122
+ return final;
1123
+ }
1124
+ };
1125
+ }
1126
+ });
1127
+
1128
+ // ../../node_modules/.pnpm/json5@2.2.3/node_modules/json5/lib/index.js
1129
+ var require_lib = __commonJS({
1130
+ "../../node_modules/.pnpm/json5@2.2.3/node_modules/json5/lib/index.js"(exports2, module2) {
1131
+ var parse = require_parse();
1132
+ var stringify = require_stringify();
1133
+ var JSON52 = {
1134
+ parse,
1135
+ stringify
1136
+ };
1137
+ module2.exports = JSON52;
1138
+ }
1139
+ });
1140
+
26
1141
  // src/relay/client.ts
27
- var import_ws = __toESM(require("ws"));
1142
+ var import_ws2 = __toESM(require("ws"));
28
1143
 
29
1144
  // ../../packages/crypto/src/x25519.ts
30
1145
  var subtle = globalThis.crypto.subtle;
@@ -185,8 +1300,8 @@ async function forwardToBridge(bridgeUrl, request) {
185
1300
  body: Buffer.from(bodyText, "utf-8").toString("base64"),
186
1301
  final: true
187
1302
  };
188
- } catch (err) {
189
- const errMsg = err instanceof Error ? err.message : "Bridge unreachable";
1303
+ } catch (err2) {
1304
+ const errMsg = err2 instanceof Error ? err2.message : "Bridge unreachable";
190
1305
  console.error(`[tunnel] Failed to reach ${url}: ${errMsg}`);
191
1306
  return {
192
1307
  request_id: request.request_id,
@@ -245,8 +1360,8 @@ async function loadSession() {
245
1360
  bridgeUrl: data.bridgeUrl,
246
1361
  pairingCode: data.pairingCode
247
1362
  };
248
- } catch (err) {
249
- console.warn(`[session] Failed to load session: ${err.message}`);
1363
+ } catch (err2) {
1364
+ console.warn(`[session] Failed to load session: ${err2.message}`);
250
1365
  return null;
251
1366
  }
252
1367
  }
@@ -265,6 +1380,1616 @@ function getConfigDir() {
265
1380
  return CONFIG_DIR;
266
1381
  }
267
1382
 
1383
+ // src/gateway/connect.ts
1384
+ var import_ws = __toESM(require("ws"));
1385
+ var import_fs3 = __toESM(require("fs"));
1386
+ var import_path3 = __toESM(require("path"));
1387
+ var import_events = require("events");
1388
+
1389
+ // ../../node_modules/.pnpm/@noble+ed25519@2.3.0/node_modules/@noble/ed25519/index.js
1390
+ var ed25519_CURVE = {
1391
+ p: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffedn,
1392
+ n: 0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3edn,
1393
+ h: 8n,
1394
+ a: 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffecn,
1395
+ d: 0x52036cee2b6ffe738cc740797779e89800700a4d4141d8ab75eb4dca135978a3n,
1396
+ Gx: 0x216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51an,
1397
+ Gy: 0x6666666666666666666666666666666666666666666666666666666666666658n
1398
+ };
1399
+ var { p: P, n: N, Gx, Gy, a: _a, d: _d } = ed25519_CURVE;
1400
+ var h = 8n;
1401
+ var L = 32;
1402
+ var L2 = 64;
1403
+ var err = (m = "") => {
1404
+ throw new Error(m);
1405
+ };
1406
+ var isBig = (n) => typeof n === "bigint";
1407
+ var isStr = (s) => typeof s === "string";
1408
+ var isBytes = (a) => a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array";
1409
+ var abytes = (a, l) => !isBytes(a) || typeof l === "number" && l > 0 && a.length !== l ? err("Uint8Array expected") : a;
1410
+ var u8n = (len) => new Uint8Array(len);
1411
+ var u8fr = (buf) => Uint8Array.from(buf);
1412
+ var padh = (n, pad) => n.toString(16).padStart(pad, "0");
1413
+ var bytesToHex = (b) => Array.from(abytes(b)).map((e) => padh(e, 2)).join("");
1414
+ var C = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 };
1415
+ var _ch = (ch) => {
1416
+ if (ch >= C._0 && ch <= C._9)
1417
+ return ch - C._0;
1418
+ if (ch >= C.A && ch <= C.F)
1419
+ return ch - (C.A - 10);
1420
+ if (ch >= C.a && ch <= C.f)
1421
+ return ch - (C.a - 10);
1422
+ return;
1423
+ };
1424
+ var hexToBytes = (hex) => {
1425
+ const e = "hex invalid";
1426
+ if (!isStr(hex))
1427
+ return err(e);
1428
+ const hl = hex.length;
1429
+ const al = hl / 2;
1430
+ if (hl % 2)
1431
+ return err(e);
1432
+ const array = u8n(al);
1433
+ for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {
1434
+ const n1 = _ch(hex.charCodeAt(hi));
1435
+ const n2 = _ch(hex.charCodeAt(hi + 1));
1436
+ if (n1 === void 0 || n2 === void 0)
1437
+ return err(e);
1438
+ array[ai] = n1 * 16 + n2;
1439
+ }
1440
+ return array;
1441
+ };
1442
+ var toU8 = (a, len) => abytes(isStr(a) ? hexToBytes(a) : u8fr(abytes(a)), len);
1443
+ var cr = () => globalThis?.crypto;
1444
+ var subtle4 = () => cr()?.subtle ?? err("crypto.subtle must be defined");
1445
+ var concatBytes = (...arrs) => {
1446
+ const r = u8n(arrs.reduce((sum, a) => sum + abytes(a).length, 0));
1447
+ let pad = 0;
1448
+ arrs.forEach((a) => {
1449
+ r.set(a, pad);
1450
+ pad += a.length;
1451
+ });
1452
+ return r;
1453
+ };
1454
+ var randomBytes = (len = L) => {
1455
+ const c = cr();
1456
+ return c.getRandomValues(u8n(len));
1457
+ };
1458
+ var big = BigInt;
1459
+ var arange = (n, min, max, msg = "bad number: out of range") => isBig(n) && min <= n && n < max ? n : err(msg);
1460
+ var M = (a, b = P) => {
1461
+ const r = a % b;
1462
+ return r >= 0n ? r : b + r;
1463
+ };
1464
+ var modN = (a) => M(a, N);
1465
+ var invert = (num, md) => {
1466
+ if (num === 0n || md <= 0n)
1467
+ err("no inverse n=" + num + " mod=" + md);
1468
+ let a = M(num, md), b = md, x = 0n, y = 1n, u = 1n, v = 0n;
1469
+ while (a !== 0n) {
1470
+ const q = b / a, r = b % a;
1471
+ const m = x - u * q, n = y - v * q;
1472
+ b = a, a = r, x = u, y = v, u = m, v = n;
1473
+ }
1474
+ return b === 1n ? M(x, md) : err("no inverse");
1475
+ };
1476
+ var callHash = (name) => {
1477
+ const fn = etc[name];
1478
+ if (typeof fn !== "function")
1479
+ err("hashes." + name + " not set");
1480
+ return fn;
1481
+ };
1482
+ var apoint = (p) => p instanceof Point ? p : err("Point expected");
1483
+ var B256 = 2n ** 256n;
1484
+ var Point = class _Point {
1485
+ static BASE;
1486
+ static ZERO;
1487
+ ex;
1488
+ ey;
1489
+ ez;
1490
+ et;
1491
+ constructor(ex, ey, ez, et) {
1492
+ const max = B256;
1493
+ this.ex = arange(ex, 0n, max);
1494
+ this.ey = arange(ey, 0n, max);
1495
+ this.ez = arange(ez, 1n, max);
1496
+ this.et = arange(et, 0n, max);
1497
+ Object.freeze(this);
1498
+ }
1499
+ static fromAffine(p) {
1500
+ return new _Point(p.x, p.y, 1n, M(p.x * p.y));
1501
+ }
1502
+ /** RFC8032 5.1.3: Uint8Array to Point. */
1503
+ static fromBytes(hex, zip215 = false) {
1504
+ const d = _d;
1505
+ const normed = u8fr(abytes(hex, L));
1506
+ const lastByte = hex[31];
1507
+ normed[31] = lastByte & ~128;
1508
+ const y = bytesToNumLE(normed);
1509
+ const max = zip215 ? B256 : P;
1510
+ arange(y, 0n, max);
1511
+ const y2 = M(y * y);
1512
+ const u = M(y2 - 1n);
1513
+ const v = M(d * y2 + 1n);
1514
+ let { isValid, value: x } = uvRatio(u, v);
1515
+ if (!isValid)
1516
+ err("bad point: y not sqrt");
1517
+ const isXOdd = (x & 1n) === 1n;
1518
+ const isLastByteOdd = (lastByte & 128) !== 0;
1519
+ if (!zip215 && x === 0n && isLastByteOdd)
1520
+ err("bad point: x==0, isLastByteOdd");
1521
+ if (isLastByteOdd !== isXOdd)
1522
+ x = M(-x);
1523
+ return new _Point(x, y, 1n, M(x * y));
1524
+ }
1525
+ /** Checks if the point is valid and on-curve. */
1526
+ assertValidity() {
1527
+ const a = _a;
1528
+ const d = _d;
1529
+ const p = this;
1530
+ if (p.is0())
1531
+ throw new Error("bad point: ZERO");
1532
+ const { ex: X, ey: Y, ez: Z, et: T } = p;
1533
+ const X2 = M(X * X);
1534
+ const Y2 = M(Y * Y);
1535
+ const Z2 = M(Z * Z);
1536
+ const Z4 = M(Z2 * Z2);
1537
+ const aX2 = M(X2 * a);
1538
+ const left = M(Z2 * M(aX2 + Y2));
1539
+ const right = M(Z4 + M(d * M(X2 * Y2)));
1540
+ if (left !== right)
1541
+ throw new Error("bad point: equation left != right (1)");
1542
+ const XY = M(X * Y);
1543
+ const ZT = M(Z * T);
1544
+ if (XY !== ZT)
1545
+ throw new Error("bad point: equation left != right (2)");
1546
+ return this;
1547
+ }
1548
+ /** Equality check: compare points P&Q. */
1549
+ equals(other) {
1550
+ const { ex: X1, ey: Y1, ez: Z1 } = this;
1551
+ const { ex: X2, ey: Y2, ez: Z2 } = apoint(other);
1552
+ const X1Z2 = M(X1 * Z2);
1553
+ const X2Z1 = M(X2 * Z1);
1554
+ const Y1Z2 = M(Y1 * Z2);
1555
+ const Y2Z1 = M(Y2 * Z1);
1556
+ return X1Z2 === X2Z1 && Y1Z2 === Y2Z1;
1557
+ }
1558
+ is0() {
1559
+ return this.equals(I);
1560
+ }
1561
+ /** Flip point over y coordinate. */
1562
+ negate() {
1563
+ return new _Point(M(-this.ex), this.ey, this.ez, M(-this.et));
1564
+ }
1565
+ /** Point doubling. Complete formula. Cost: `4M + 4S + 1*a + 6add + 1*2`. */
1566
+ double() {
1567
+ const { ex: X1, ey: Y1, ez: Z1 } = this;
1568
+ const a = _a;
1569
+ const A = M(X1 * X1);
1570
+ const B = M(Y1 * Y1);
1571
+ const C2 = M(2n * M(Z1 * Z1));
1572
+ const D = M(a * A);
1573
+ const x1y1 = X1 + Y1;
1574
+ const E = M(M(x1y1 * x1y1) - A - B);
1575
+ const G2 = D + B;
1576
+ const F = G2 - C2;
1577
+ const H = D - B;
1578
+ const X3 = M(E * F);
1579
+ const Y3 = M(G2 * H);
1580
+ const T3 = M(E * H);
1581
+ const Z3 = M(F * G2);
1582
+ return new _Point(X3, Y3, Z3, T3);
1583
+ }
1584
+ /** Point addition. Complete formula. Cost: `8M + 1*k + 8add + 1*2`. */
1585
+ add(other) {
1586
+ const { ex: X1, ey: Y1, ez: Z1, et: T1 } = this;
1587
+ const { ex: X2, ey: Y2, ez: Z2, et: T2 } = apoint(other);
1588
+ const a = _a;
1589
+ const d = _d;
1590
+ const A = M(X1 * X2);
1591
+ const B = M(Y1 * Y2);
1592
+ const C2 = M(T1 * d * T2);
1593
+ const D = M(Z1 * Z2);
1594
+ const E = M((X1 + Y1) * (X2 + Y2) - A - B);
1595
+ const F = M(D - C2);
1596
+ const G2 = M(D + C2);
1597
+ const H = M(B - a * A);
1598
+ const X3 = M(E * F);
1599
+ const Y3 = M(G2 * H);
1600
+ const T3 = M(E * H);
1601
+ const Z3 = M(F * G2);
1602
+ return new _Point(X3, Y3, Z3, T3);
1603
+ }
1604
+ /**
1605
+ * Point-by-scalar multiplication. Scalar must be in range 1 <= n < CURVE.n.
1606
+ * Uses {@link wNAF} for base point.
1607
+ * Uses fake point to mitigate side-channel leakage.
1608
+ * @param n scalar by which point is multiplied
1609
+ * @param safe safe mode guards against timing attacks; unsafe mode is faster
1610
+ */
1611
+ multiply(n, safe = true) {
1612
+ if (!safe && (n === 0n || this.is0()))
1613
+ return I;
1614
+ arange(n, 1n, N);
1615
+ if (n === 1n)
1616
+ return this;
1617
+ if (this.equals(G))
1618
+ return wNAF(n).p;
1619
+ let p = I;
1620
+ let f = G;
1621
+ for (let d = this; n > 0n; d = d.double(), n >>= 1n) {
1622
+ if (n & 1n)
1623
+ p = p.add(d);
1624
+ else if (safe)
1625
+ f = f.add(d);
1626
+ }
1627
+ return p;
1628
+ }
1629
+ /** Convert point to 2d xy affine point. (X, Y, Z) ∋ (x=X/Z, y=Y/Z) */
1630
+ toAffine() {
1631
+ const { ex: x, ey: y, ez: z } = this;
1632
+ if (this.equals(I))
1633
+ return { x: 0n, y: 1n };
1634
+ const iz = invert(z, P);
1635
+ if (M(z * iz) !== 1n)
1636
+ err("invalid inverse");
1637
+ return { x: M(x * iz), y: M(y * iz) };
1638
+ }
1639
+ toBytes() {
1640
+ const { x, y } = this.assertValidity().toAffine();
1641
+ const b = numTo32bLE(y);
1642
+ b[31] |= x & 1n ? 128 : 0;
1643
+ return b;
1644
+ }
1645
+ toHex() {
1646
+ return bytesToHex(this.toBytes());
1647
+ }
1648
+ // encode to hex string
1649
+ clearCofactor() {
1650
+ return this.multiply(big(h), false);
1651
+ }
1652
+ isSmallOrder() {
1653
+ return this.clearCofactor().is0();
1654
+ }
1655
+ isTorsionFree() {
1656
+ let p = this.multiply(N / 2n, false).double();
1657
+ if (N % 2n)
1658
+ p = p.add(this);
1659
+ return p.is0();
1660
+ }
1661
+ static fromHex(hex, zip215) {
1662
+ return _Point.fromBytes(toU8(hex), zip215);
1663
+ }
1664
+ get x() {
1665
+ return this.toAffine().x;
1666
+ }
1667
+ get y() {
1668
+ return this.toAffine().y;
1669
+ }
1670
+ toRawBytes() {
1671
+ return this.toBytes();
1672
+ }
1673
+ };
1674
+ var G = new Point(Gx, Gy, 1n, M(Gx * Gy));
1675
+ var I = new Point(0n, 1n, 1n, 0n);
1676
+ Point.BASE = G;
1677
+ Point.ZERO = I;
1678
+ var numTo32bLE = (num) => hexToBytes(padh(arange(num, 0n, B256), L2)).reverse();
1679
+ var bytesToNumLE = (b) => big("0x" + bytesToHex(u8fr(abytes(b)).reverse()));
1680
+ var pow2 = (x, power) => {
1681
+ let r = x;
1682
+ while (power-- > 0n) {
1683
+ r *= r;
1684
+ r %= P;
1685
+ }
1686
+ return r;
1687
+ };
1688
+ var pow_2_252_3 = (x) => {
1689
+ const x2 = x * x % P;
1690
+ const b2 = x2 * x % P;
1691
+ const b4 = pow2(b2, 2n) * b2 % P;
1692
+ const b5 = pow2(b4, 1n) * x % P;
1693
+ const b10 = pow2(b5, 5n) * b5 % P;
1694
+ const b20 = pow2(b10, 10n) * b10 % P;
1695
+ const b40 = pow2(b20, 20n) * b20 % P;
1696
+ const b80 = pow2(b40, 40n) * b40 % P;
1697
+ const b160 = pow2(b80, 80n) * b80 % P;
1698
+ const b240 = pow2(b160, 80n) * b80 % P;
1699
+ const b250 = pow2(b240, 10n) * b10 % P;
1700
+ const pow_p_5_8 = pow2(b250, 2n) * x % P;
1701
+ return { pow_p_5_8, b2 };
1702
+ };
1703
+ var RM1 = 0x2b8324804fc1df0b2b4d00993dfbd7a72f431806ad2fe478c4ee1b274a0ea0b0n;
1704
+ var uvRatio = (u, v) => {
1705
+ const v3 = M(v * v * v);
1706
+ const v7 = M(v3 * v3 * v);
1707
+ const pow = pow_2_252_3(u * v7).pow_p_5_8;
1708
+ let x = M(u * v3 * pow);
1709
+ const vx2 = M(v * x * x);
1710
+ const root1 = x;
1711
+ const root2 = M(x * RM1);
1712
+ const useRoot1 = vx2 === u;
1713
+ const useRoot2 = vx2 === M(-u);
1714
+ const noRoot = vx2 === M(-u * RM1);
1715
+ if (useRoot1)
1716
+ x = root1;
1717
+ if (useRoot2 || noRoot)
1718
+ x = root2;
1719
+ if ((M(x) & 1n) === 1n)
1720
+ x = M(-x);
1721
+ return { isValid: useRoot1 || useRoot2, value: x };
1722
+ };
1723
+ var modL_LE = (hash) => modN(bytesToNumLE(hash));
1724
+ var sha512a = (...m) => etc.sha512Async(...m);
1725
+ var sha512s = (...m) => callHash("sha512Sync")(...m);
1726
+ var hash2extK = (hashed) => {
1727
+ const head = hashed.slice(0, L);
1728
+ head[0] &= 248;
1729
+ head[31] &= 127;
1730
+ head[31] |= 64;
1731
+ const prefix = hashed.slice(L, L2);
1732
+ const scalar = modL_LE(head);
1733
+ const point = G.multiply(scalar);
1734
+ const pointBytes = point.toBytes();
1735
+ return { head, prefix, scalar, point, pointBytes };
1736
+ };
1737
+ var getExtendedPublicKeyAsync = (priv) => sha512a(toU8(priv, L)).then(hash2extK);
1738
+ var getExtendedPublicKey = (priv) => hash2extK(sha512s(toU8(priv, L)));
1739
+ var getPublicKeyAsync = (priv) => getExtendedPublicKeyAsync(priv).then((p) => p.pointBytes);
1740
+ var hashFinishA = (res) => sha512a(res.hashable).then(res.finish);
1741
+ var _sign = (e, rBytes, msg) => {
1742
+ const { pointBytes: P2, scalar: s } = e;
1743
+ const r = modL_LE(rBytes);
1744
+ const R = G.multiply(r).toBytes();
1745
+ const hashable = concatBytes(R, P2, msg);
1746
+ const finish = (hashed) => {
1747
+ const S = modN(r + modL_LE(hashed) * s);
1748
+ return abytes(concatBytes(R, numTo32bLE(S)), L2);
1749
+ };
1750
+ return { hashable, finish };
1751
+ };
1752
+ var signAsync = async (msg, privKey) => {
1753
+ const m = toU8(msg);
1754
+ const e = await getExtendedPublicKeyAsync(privKey);
1755
+ const rBytes = await sha512a(e.prefix, m);
1756
+ return hashFinishA(_sign(e, rBytes, m));
1757
+ };
1758
+ var etc = {
1759
+ sha512Async: async (...messages) => {
1760
+ const s = subtle4();
1761
+ const m = concatBytes(...messages);
1762
+ return u8n(await s.digest("SHA-512", m.buffer));
1763
+ },
1764
+ sha512Sync: void 0,
1765
+ bytesToHex,
1766
+ hexToBytes,
1767
+ concatBytes,
1768
+ mod: M,
1769
+ invert,
1770
+ randomBytes
1771
+ };
1772
+ var utils = {
1773
+ getExtendedPublicKeyAsync,
1774
+ getExtendedPublicKey,
1775
+ randomPrivateKey: () => randomBytes(L),
1776
+ precompute: (w = 8, p = G) => {
1777
+ p.multiply(3n);
1778
+ w;
1779
+ return p;
1780
+ }
1781
+ // no-op
1782
+ };
1783
+ var W = 8;
1784
+ var scalarBits = 256;
1785
+ var pwindows = Math.ceil(scalarBits / W) + 1;
1786
+ var pwindowSize = 2 ** (W - 1);
1787
+ var precompute = () => {
1788
+ const points = [];
1789
+ let p = G;
1790
+ let b = p;
1791
+ for (let w = 0; w < pwindows; w++) {
1792
+ b = p;
1793
+ points.push(b);
1794
+ for (let i = 1; i < pwindowSize; i++) {
1795
+ b = b.add(p);
1796
+ points.push(b);
1797
+ }
1798
+ p = b.double();
1799
+ }
1800
+ return points;
1801
+ };
1802
+ var Gpows = void 0;
1803
+ var ctneg = (cnd, p) => {
1804
+ const n = p.negate();
1805
+ return cnd ? n : p;
1806
+ };
1807
+ var wNAF = (n) => {
1808
+ const comp = Gpows || (Gpows = precompute());
1809
+ let p = I;
1810
+ let f = G;
1811
+ const pow_2_w = 2 ** W;
1812
+ const maxNum = pow_2_w;
1813
+ const mask = big(pow_2_w - 1);
1814
+ const shiftBy = big(W);
1815
+ for (let w = 0; w < pwindows; w++) {
1816
+ let wbits = Number(n & mask);
1817
+ n >>= shiftBy;
1818
+ if (wbits > pwindowSize) {
1819
+ wbits -= maxNum;
1820
+ n += 1n;
1821
+ }
1822
+ const off = w * pwindowSize;
1823
+ const offF = off;
1824
+ const offP = off + Math.abs(wbits) - 1;
1825
+ const isEven = w % 2 !== 0;
1826
+ const isNeg = wbits < 0;
1827
+ if (wbits === 0) {
1828
+ f = f.add(ctneg(isEven, comp[offF]));
1829
+ } else {
1830
+ p = p.add(ctneg(isNeg, comp[offP]));
1831
+ }
1832
+ }
1833
+ return { p, f };
1834
+ };
1835
+
1836
+ // ../../node_modules/.pnpm/@noble+hashes@1.8.0/node_modules/@noble/hashes/esm/utils.js
1837
+ function isBytes2(a) {
1838
+ return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array";
1839
+ }
1840
+ function abytes2(b, ...lengths) {
1841
+ if (!isBytes2(b))
1842
+ throw new Error("Uint8Array expected");
1843
+ if (lengths.length > 0 && !lengths.includes(b.length))
1844
+ throw new Error("Uint8Array expected of length " + lengths + ", got length=" + b.length);
1845
+ }
1846
+ function aexists(instance, checkFinished = true) {
1847
+ if (instance.destroyed)
1848
+ throw new Error("Hash instance has been destroyed");
1849
+ if (checkFinished && instance.finished)
1850
+ throw new Error("Hash#digest() has already been called");
1851
+ }
1852
+ function aoutput(out, instance) {
1853
+ abytes2(out);
1854
+ const min = instance.outputLen;
1855
+ if (out.length < min) {
1856
+ throw new Error("digestInto() expects output buffer of length at least " + min);
1857
+ }
1858
+ }
1859
+ function clean(...arrays) {
1860
+ for (let i = 0; i < arrays.length; i++) {
1861
+ arrays[i].fill(0);
1862
+ }
1863
+ }
1864
+ function createView(arr) {
1865
+ return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
1866
+ }
1867
+ function rotr(word, shift) {
1868
+ return word << 32 - shift | word >>> shift;
1869
+ }
1870
+ var hasHexBuiltin = /* @__PURE__ */ (() => (
1871
+ // @ts-ignore
1872
+ typeof Uint8Array.from([]).toHex === "function" && typeof Uint8Array.fromHex === "function"
1873
+ ))();
1874
+ var hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, "0"));
1875
+ function bytesToHex2(bytes) {
1876
+ abytes2(bytes);
1877
+ if (hasHexBuiltin)
1878
+ return bytes.toHex();
1879
+ let hex = "";
1880
+ for (let i = 0; i < bytes.length; i++) {
1881
+ hex += hexes[bytes[i]];
1882
+ }
1883
+ return hex;
1884
+ }
1885
+ var asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 };
1886
+ function asciiToBase16(ch) {
1887
+ if (ch >= asciis._0 && ch <= asciis._9)
1888
+ return ch - asciis._0;
1889
+ if (ch >= asciis.A && ch <= asciis.F)
1890
+ return ch - (asciis.A - 10);
1891
+ if (ch >= asciis.a && ch <= asciis.f)
1892
+ return ch - (asciis.a - 10);
1893
+ return;
1894
+ }
1895
+ function hexToBytes2(hex) {
1896
+ if (typeof hex !== "string")
1897
+ throw new Error("hex string expected, got " + typeof hex);
1898
+ if (hasHexBuiltin)
1899
+ return Uint8Array.fromHex(hex);
1900
+ const hl = hex.length;
1901
+ const al = hl / 2;
1902
+ if (hl % 2)
1903
+ throw new Error("hex string expected, got unpadded hex of length " + hl);
1904
+ const array = new Uint8Array(al);
1905
+ for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {
1906
+ const n1 = asciiToBase16(hex.charCodeAt(hi));
1907
+ const n2 = asciiToBase16(hex.charCodeAt(hi + 1));
1908
+ if (n1 === void 0 || n2 === void 0) {
1909
+ const char = hex[hi] + hex[hi + 1];
1910
+ throw new Error('hex string expected, got non-hex character "' + char + '" at index ' + hi);
1911
+ }
1912
+ array[ai] = n1 * 16 + n2;
1913
+ }
1914
+ return array;
1915
+ }
1916
+ function utf8ToBytes(str) {
1917
+ if (typeof str !== "string")
1918
+ throw new Error("string expected");
1919
+ return new Uint8Array(new TextEncoder().encode(str));
1920
+ }
1921
+ function toBytes(data) {
1922
+ if (typeof data === "string")
1923
+ data = utf8ToBytes(data);
1924
+ abytes2(data);
1925
+ return data;
1926
+ }
1927
+ var Hash = class {
1928
+ };
1929
+ function createHasher(hashCons) {
1930
+ const hashC = (msg) => hashCons().update(toBytes(msg)).digest();
1931
+ const tmp = hashCons();
1932
+ hashC.outputLen = tmp.outputLen;
1933
+ hashC.blockLen = tmp.blockLen;
1934
+ hashC.create = () => hashCons();
1935
+ return hashC;
1936
+ }
1937
+
1938
+ // ../../node_modules/.pnpm/@noble+hashes@1.8.0/node_modules/@noble/hashes/esm/_md.js
1939
+ function setBigUint64(view, byteOffset, value, isLE) {
1940
+ if (typeof view.setBigUint64 === "function")
1941
+ return view.setBigUint64(byteOffset, value, isLE);
1942
+ const _32n2 = BigInt(32);
1943
+ const _u32_max = BigInt(4294967295);
1944
+ const wh = Number(value >> _32n2 & _u32_max);
1945
+ const wl = Number(value & _u32_max);
1946
+ const h2 = isLE ? 4 : 0;
1947
+ const l = isLE ? 0 : 4;
1948
+ view.setUint32(byteOffset + h2, wh, isLE);
1949
+ view.setUint32(byteOffset + l, wl, isLE);
1950
+ }
1951
+ function Chi(a, b, c) {
1952
+ return a & b ^ ~a & c;
1953
+ }
1954
+ function Maj(a, b, c) {
1955
+ return a & b ^ a & c ^ b & c;
1956
+ }
1957
+ var HashMD = class extends Hash {
1958
+ constructor(blockLen, outputLen, padOffset, isLE) {
1959
+ super();
1960
+ this.finished = false;
1961
+ this.length = 0;
1962
+ this.pos = 0;
1963
+ this.destroyed = false;
1964
+ this.blockLen = blockLen;
1965
+ this.outputLen = outputLen;
1966
+ this.padOffset = padOffset;
1967
+ this.isLE = isLE;
1968
+ this.buffer = new Uint8Array(blockLen);
1969
+ this.view = createView(this.buffer);
1970
+ }
1971
+ update(data) {
1972
+ aexists(this);
1973
+ data = toBytes(data);
1974
+ abytes2(data);
1975
+ const { view, buffer, blockLen } = this;
1976
+ const len = data.length;
1977
+ for (let pos = 0; pos < len; ) {
1978
+ const take = Math.min(blockLen - this.pos, len - pos);
1979
+ if (take === blockLen) {
1980
+ const dataView = createView(data);
1981
+ for (; blockLen <= len - pos; pos += blockLen)
1982
+ this.process(dataView, pos);
1983
+ continue;
1984
+ }
1985
+ buffer.set(data.subarray(pos, pos + take), this.pos);
1986
+ this.pos += take;
1987
+ pos += take;
1988
+ if (this.pos === blockLen) {
1989
+ this.process(view, 0);
1990
+ this.pos = 0;
1991
+ }
1992
+ }
1993
+ this.length += data.length;
1994
+ this.roundClean();
1995
+ return this;
1996
+ }
1997
+ digestInto(out) {
1998
+ aexists(this);
1999
+ aoutput(out, this);
2000
+ this.finished = true;
2001
+ const { buffer, view, blockLen, isLE } = this;
2002
+ let { pos } = this;
2003
+ buffer[pos++] = 128;
2004
+ clean(this.buffer.subarray(pos));
2005
+ if (this.padOffset > blockLen - pos) {
2006
+ this.process(view, 0);
2007
+ pos = 0;
2008
+ }
2009
+ for (let i = pos; i < blockLen; i++)
2010
+ buffer[i] = 0;
2011
+ setBigUint64(view, blockLen - 8, BigInt(this.length * 8), isLE);
2012
+ this.process(view, 0);
2013
+ const oview = createView(out);
2014
+ const len = this.outputLen;
2015
+ if (len % 4)
2016
+ throw new Error("_sha2: outputLen should be aligned to 32bit");
2017
+ const outLen = len / 4;
2018
+ const state = this.get();
2019
+ if (outLen > state.length)
2020
+ throw new Error("_sha2: outputLen bigger than state");
2021
+ for (let i = 0; i < outLen; i++)
2022
+ oview.setUint32(4 * i, state[i], isLE);
2023
+ }
2024
+ digest() {
2025
+ const { buffer, outputLen } = this;
2026
+ this.digestInto(buffer);
2027
+ const res = buffer.slice(0, outputLen);
2028
+ this.destroy();
2029
+ return res;
2030
+ }
2031
+ _cloneInto(to) {
2032
+ to || (to = new this.constructor());
2033
+ to.set(...this.get());
2034
+ const { blockLen, buffer, length, finished, destroyed, pos } = this;
2035
+ to.destroyed = destroyed;
2036
+ to.finished = finished;
2037
+ to.length = length;
2038
+ to.pos = pos;
2039
+ if (length % blockLen)
2040
+ to.buffer.set(buffer);
2041
+ return to;
2042
+ }
2043
+ clone() {
2044
+ return this._cloneInto();
2045
+ }
2046
+ };
2047
+ var SHA256_IV = /* @__PURE__ */ Uint32Array.from([
2048
+ 1779033703,
2049
+ 3144134277,
2050
+ 1013904242,
2051
+ 2773480762,
2052
+ 1359893119,
2053
+ 2600822924,
2054
+ 528734635,
2055
+ 1541459225
2056
+ ]);
2057
+ var SHA512_IV = /* @__PURE__ */ Uint32Array.from([
2058
+ 1779033703,
2059
+ 4089235720,
2060
+ 3144134277,
2061
+ 2227873595,
2062
+ 1013904242,
2063
+ 4271175723,
2064
+ 2773480762,
2065
+ 1595750129,
2066
+ 1359893119,
2067
+ 2917565137,
2068
+ 2600822924,
2069
+ 725511199,
2070
+ 528734635,
2071
+ 4215389547,
2072
+ 1541459225,
2073
+ 327033209
2074
+ ]);
2075
+
2076
+ // ../../node_modules/.pnpm/@noble+hashes@1.8.0/node_modules/@noble/hashes/esm/_u64.js
2077
+ var U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);
2078
+ var _32n = /* @__PURE__ */ BigInt(32);
2079
+ function fromBig(n, le = false) {
2080
+ if (le)
2081
+ return { h: Number(n & U32_MASK64), l: Number(n >> _32n & U32_MASK64) };
2082
+ return { h: Number(n >> _32n & U32_MASK64) | 0, l: Number(n & U32_MASK64) | 0 };
2083
+ }
2084
+ function split(lst, le = false) {
2085
+ const len = lst.length;
2086
+ let Ah = new Uint32Array(len);
2087
+ let Al = new Uint32Array(len);
2088
+ for (let i = 0; i < len; i++) {
2089
+ const { h: h2, l } = fromBig(lst[i], le);
2090
+ [Ah[i], Al[i]] = [h2, l];
2091
+ }
2092
+ return [Ah, Al];
2093
+ }
2094
+ var shrSH = (h2, _l, s) => h2 >>> s;
2095
+ var shrSL = (h2, l, s) => h2 << 32 - s | l >>> s;
2096
+ var rotrSH = (h2, l, s) => h2 >>> s | l << 32 - s;
2097
+ var rotrSL = (h2, l, s) => h2 << 32 - s | l >>> s;
2098
+ var rotrBH = (h2, l, s) => h2 << 64 - s | l >>> s - 32;
2099
+ var rotrBL = (h2, l, s) => h2 >>> s - 32 | l << 64 - s;
2100
+ function add(Ah, Al, Bh, Bl) {
2101
+ const l = (Al >>> 0) + (Bl >>> 0);
2102
+ return { h: Ah + Bh + (l / 2 ** 32 | 0) | 0, l: l | 0 };
2103
+ }
2104
+ var add3L = (Al, Bl, Cl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0);
2105
+ var add3H = (low, Ah, Bh, Ch) => Ah + Bh + Ch + (low / 2 ** 32 | 0) | 0;
2106
+ var add4L = (Al, Bl, Cl, Dl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0);
2107
+ var add4H = (low, Ah, Bh, Ch, Dh) => Ah + Bh + Ch + Dh + (low / 2 ** 32 | 0) | 0;
2108
+ var add5L = (Al, Bl, Cl, Dl, El) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0) + (El >>> 0);
2109
+ var add5H = (low, Ah, Bh, Ch, Dh, Eh) => Ah + Bh + Ch + Dh + Eh + (low / 2 ** 32 | 0) | 0;
2110
+
2111
+ // ../../node_modules/.pnpm/@noble+hashes@1.8.0/node_modules/@noble/hashes/esm/sha2.js
2112
+ var SHA256_K = /* @__PURE__ */ Uint32Array.from([
2113
+ 1116352408,
2114
+ 1899447441,
2115
+ 3049323471,
2116
+ 3921009573,
2117
+ 961987163,
2118
+ 1508970993,
2119
+ 2453635748,
2120
+ 2870763221,
2121
+ 3624381080,
2122
+ 310598401,
2123
+ 607225278,
2124
+ 1426881987,
2125
+ 1925078388,
2126
+ 2162078206,
2127
+ 2614888103,
2128
+ 3248222580,
2129
+ 3835390401,
2130
+ 4022224774,
2131
+ 264347078,
2132
+ 604807628,
2133
+ 770255983,
2134
+ 1249150122,
2135
+ 1555081692,
2136
+ 1996064986,
2137
+ 2554220882,
2138
+ 2821834349,
2139
+ 2952996808,
2140
+ 3210313671,
2141
+ 3336571891,
2142
+ 3584528711,
2143
+ 113926993,
2144
+ 338241895,
2145
+ 666307205,
2146
+ 773529912,
2147
+ 1294757372,
2148
+ 1396182291,
2149
+ 1695183700,
2150
+ 1986661051,
2151
+ 2177026350,
2152
+ 2456956037,
2153
+ 2730485921,
2154
+ 2820302411,
2155
+ 3259730800,
2156
+ 3345764771,
2157
+ 3516065817,
2158
+ 3600352804,
2159
+ 4094571909,
2160
+ 275423344,
2161
+ 430227734,
2162
+ 506948616,
2163
+ 659060556,
2164
+ 883997877,
2165
+ 958139571,
2166
+ 1322822218,
2167
+ 1537002063,
2168
+ 1747873779,
2169
+ 1955562222,
2170
+ 2024104815,
2171
+ 2227730452,
2172
+ 2361852424,
2173
+ 2428436474,
2174
+ 2756734187,
2175
+ 3204031479,
2176
+ 3329325298
2177
+ ]);
2178
+ var SHA256_W = /* @__PURE__ */ new Uint32Array(64);
2179
+ var SHA256 = class extends HashMD {
2180
+ constructor(outputLen = 32) {
2181
+ super(64, outputLen, 8, false);
2182
+ this.A = SHA256_IV[0] | 0;
2183
+ this.B = SHA256_IV[1] | 0;
2184
+ this.C = SHA256_IV[2] | 0;
2185
+ this.D = SHA256_IV[3] | 0;
2186
+ this.E = SHA256_IV[4] | 0;
2187
+ this.F = SHA256_IV[5] | 0;
2188
+ this.G = SHA256_IV[6] | 0;
2189
+ this.H = SHA256_IV[7] | 0;
2190
+ }
2191
+ get() {
2192
+ const { A, B, C: C2, D, E, F, G: G2, H } = this;
2193
+ return [A, B, C2, D, E, F, G2, H];
2194
+ }
2195
+ // prettier-ignore
2196
+ set(A, B, C2, D, E, F, G2, H) {
2197
+ this.A = A | 0;
2198
+ this.B = B | 0;
2199
+ this.C = C2 | 0;
2200
+ this.D = D | 0;
2201
+ this.E = E | 0;
2202
+ this.F = F | 0;
2203
+ this.G = G2 | 0;
2204
+ this.H = H | 0;
2205
+ }
2206
+ process(view, offset) {
2207
+ for (let i = 0; i < 16; i++, offset += 4)
2208
+ SHA256_W[i] = view.getUint32(offset, false);
2209
+ for (let i = 16; i < 64; i++) {
2210
+ const W15 = SHA256_W[i - 15];
2211
+ const W2 = SHA256_W[i - 2];
2212
+ const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ W15 >>> 3;
2213
+ const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ W2 >>> 10;
2214
+ SHA256_W[i] = s1 + SHA256_W[i - 7] + s0 + SHA256_W[i - 16] | 0;
2215
+ }
2216
+ let { A, B, C: C2, D, E, F, G: G2, H } = this;
2217
+ for (let i = 0; i < 64; i++) {
2218
+ const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25);
2219
+ const T1 = H + sigma1 + Chi(E, F, G2) + SHA256_K[i] + SHA256_W[i] | 0;
2220
+ const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22);
2221
+ const T2 = sigma0 + Maj(A, B, C2) | 0;
2222
+ H = G2;
2223
+ G2 = F;
2224
+ F = E;
2225
+ E = D + T1 | 0;
2226
+ D = C2;
2227
+ C2 = B;
2228
+ B = A;
2229
+ A = T1 + T2 | 0;
2230
+ }
2231
+ A = A + this.A | 0;
2232
+ B = B + this.B | 0;
2233
+ C2 = C2 + this.C | 0;
2234
+ D = D + this.D | 0;
2235
+ E = E + this.E | 0;
2236
+ F = F + this.F | 0;
2237
+ G2 = G2 + this.G | 0;
2238
+ H = H + this.H | 0;
2239
+ this.set(A, B, C2, D, E, F, G2, H);
2240
+ }
2241
+ roundClean() {
2242
+ clean(SHA256_W);
2243
+ }
2244
+ destroy() {
2245
+ this.set(0, 0, 0, 0, 0, 0, 0, 0);
2246
+ clean(this.buffer);
2247
+ }
2248
+ };
2249
+ var K512 = /* @__PURE__ */ (() => split([
2250
+ "0x428a2f98d728ae22",
2251
+ "0x7137449123ef65cd",
2252
+ "0xb5c0fbcfec4d3b2f",
2253
+ "0xe9b5dba58189dbbc",
2254
+ "0x3956c25bf348b538",
2255
+ "0x59f111f1b605d019",
2256
+ "0x923f82a4af194f9b",
2257
+ "0xab1c5ed5da6d8118",
2258
+ "0xd807aa98a3030242",
2259
+ "0x12835b0145706fbe",
2260
+ "0x243185be4ee4b28c",
2261
+ "0x550c7dc3d5ffb4e2",
2262
+ "0x72be5d74f27b896f",
2263
+ "0x80deb1fe3b1696b1",
2264
+ "0x9bdc06a725c71235",
2265
+ "0xc19bf174cf692694",
2266
+ "0xe49b69c19ef14ad2",
2267
+ "0xefbe4786384f25e3",
2268
+ "0x0fc19dc68b8cd5b5",
2269
+ "0x240ca1cc77ac9c65",
2270
+ "0x2de92c6f592b0275",
2271
+ "0x4a7484aa6ea6e483",
2272
+ "0x5cb0a9dcbd41fbd4",
2273
+ "0x76f988da831153b5",
2274
+ "0x983e5152ee66dfab",
2275
+ "0xa831c66d2db43210",
2276
+ "0xb00327c898fb213f",
2277
+ "0xbf597fc7beef0ee4",
2278
+ "0xc6e00bf33da88fc2",
2279
+ "0xd5a79147930aa725",
2280
+ "0x06ca6351e003826f",
2281
+ "0x142929670a0e6e70",
2282
+ "0x27b70a8546d22ffc",
2283
+ "0x2e1b21385c26c926",
2284
+ "0x4d2c6dfc5ac42aed",
2285
+ "0x53380d139d95b3df",
2286
+ "0x650a73548baf63de",
2287
+ "0x766a0abb3c77b2a8",
2288
+ "0x81c2c92e47edaee6",
2289
+ "0x92722c851482353b",
2290
+ "0xa2bfe8a14cf10364",
2291
+ "0xa81a664bbc423001",
2292
+ "0xc24b8b70d0f89791",
2293
+ "0xc76c51a30654be30",
2294
+ "0xd192e819d6ef5218",
2295
+ "0xd69906245565a910",
2296
+ "0xf40e35855771202a",
2297
+ "0x106aa07032bbd1b8",
2298
+ "0x19a4c116b8d2d0c8",
2299
+ "0x1e376c085141ab53",
2300
+ "0x2748774cdf8eeb99",
2301
+ "0x34b0bcb5e19b48a8",
2302
+ "0x391c0cb3c5c95a63",
2303
+ "0x4ed8aa4ae3418acb",
2304
+ "0x5b9cca4f7763e373",
2305
+ "0x682e6ff3d6b2b8a3",
2306
+ "0x748f82ee5defb2fc",
2307
+ "0x78a5636f43172f60",
2308
+ "0x84c87814a1f0ab72",
2309
+ "0x8cc702081a6439ec",
2310
+ "0x90befffa23631e28",
2311
+ "0xa4506cebde82bde9",
2312
+ "0xbef9a3f7b2c67915",
2313
+ "0xc67178f2e372532b",
2314
+ "0xca273eceea26619c",
2315
+ "0xd186b8c721c0c207",
2316
+ "0xeada7dd6cde0eb1e",
2317
+ "0xf57d4f7fee6ed178",
2318
+ "0x06f067aa72176fba",
2319
+ "0x0a637dc5a2c898a6",
2320
+ "0x113f9804bef90dae",
2321
+ "0x1b710b35131c471b",
2322
+ "0x28db77f523047d84",
2323
+ "0x32caab7b40c72493",
2324
+ "0x3c9ebe0a15c9bebc",
2325
+ "0x431d67c49c100d4c",
2326
+ "0x4cc5d4becb3e42b6",
2327
+ "0x597f299cfc657e2a",
2328
+ "0x5fcb6fab3ad6faec",
2329
+ "0x6c44198c4a475817"
2330
+ ].map((n) => BigInt(n))))();
2331
+ var SHA512_Kh = /* @__PURE__ */ (() => K512[0])();
2332
+ var SHA512_Kl = /* @__PURE__ */ (() => K512[1])();
2333
+ var SHA512_W_H = /* @__PURE__ */ new Uint32Array(80);
2334
+ var SHA512_W_L = /* @__PURE__ */ new Uint32Array(80);
2335
+ var SHA512 = class extends HashMD {
2336
+ constructor(outputLen = 64) {
2337
+ super(128, outputLen, 16, false);
2338
+ this.Ah = SHA512_IV[0] | 0;
2339
+ this.Al = SHA512_IV[1] | 0;
2340
+ this.Bh = SHA512_IV[2] | 0;
2341
+ this.Bl = SHA512_IV[3] | 0;
2342
+ this.Ch = SHA512_IV[4] | 0;
2343
+ this.Cl = SHA512_IV[5] | 0;
2344
+ this.Dh = SHA512_IV[6] | 0;
2345
+ this.Dl = SHA512_IV[7] | 0;
2346
+ this.Eh = SHA512_IV[8] | 0;
2347
+ this.El = SHA512_IV[9] | 0;
2348
+ this.Fh = SHA512_IV[10] | 0;
2349
+ this.Fl = SHA512_IV[11] | 0;
2350
+ this.Gh = SHA512_IV[12] | 0;
2351
+ this.Gl = SHA512_IV[13] | 0;
2352
+ this.Hh = SHA512_IV[14] | 0;
2353
+ this.Hl = SHA512_IV[15] | 0;
2354
+ }
2355
+ // prettier-ignore
2356
+ get() {
2357
+ const { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;
2358
+ return [Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl];
2359
+ }
2360
+ // prettier-ignore
2361
+ set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl) {
2362
+ this.Ah = Ah | 0;
2363
+ this.Al = Al | 0;
2364
+ this.Bh = Bh | 0;
2365
+ this.Bl = Bl | 0;
2366
+ this.Ch = Ch | 0;
2367
+ this.Cl = Cl | 0;
2368
+ this.Dh = Dh | 0;
2369
+ this.Dl = Dl | 0;
2370
+ this.Eh = Eh | 0;
2371
+ this.El = El | 0;
2372
+ this.Fh = Fh | 0;
2373
+ this.Fl = Fl | 0;
2374
+ this.Gh = Gh | 0;
2375
+ this.Gl = Gl | 0;
2376
+ this.Hh = Hh | 0;
2377
+ this.Hl = Hl | 0;
2378
+ }
2379
+ process(view, offset) {
2380
+ for (let i = 0; i < 16; i++, offset += 4) {
2381
+ SHA512_W_H[i] = view.getUint32(offset);
2382
+ SHA512_W_L[i] = view.getUint32(offset += 4);
2383
+ }
2384
+ for (let i = 16; i < 80; i++) {
2385
+ const W15h = SHA512_W_H[i - 15] | 0;
2386
+ const W15l = SHA512_W_L[i - 15] | 0;
2387
+ const s0h = rotrSH(W15h, W15l, 1) ^ rotrSH(W15h, W15l, 8) ^ shrSH(W15h, W15l, 7);
2388
+ const s0l = rotrSL(W15h, W15l, 1) ^ rotrSL(W15h, W15l, 8) ^ shrSL(W15h, W15l, 7);
2389
+ const W2h = SHA512_W_H[i - 2] | 0;
2390
+ const W2l = SHA512_W_L[i - 2] | 0;
2391
+ const s1h = rotrSH(W2h, W2l, 19) ^ rotrBH(W2h, W2l, 61) ^ shrSH(W2h, W2l, 6);
2392
+ const s1l = rotrSL(W2h, W2l, 19) ^ rotrBL(W2h, W2l, 61) ^ shrSL(W2h, W2l, 6);
2393
+ const SUMl = add4L(s0l, s1l, SHA512_W_L[i - 7], SHA512_W_L[i - 16]);
2394
+ const SUMh = add4H(SUMl, s0h, s1h, SHA512_W_H[i - 7], SHA512_W_H[i - 16]);
2395
+ SHA512_W_H[i] = SUMh | 0;
2396
+ SHA512_W_L[i] = SUMl | 0;
2397
+ }
2398
+ let { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;
2399
+ for (let i = 0; i < 80; i++) {
2400
+ const sigma1h = rotrSH(Eh, El, 14) ^ rotrSH(Eh, El, 18) ^ rotrBH(Eh, El, 41);
2401
+ const sigma1l = rotrSL(Eh, El, 14) ^ rotrSL(Eh, El, 18) ^ rotrBL(Eh, El, 41);
2402
+ const CHIh = Eh & Fh ^ ~Eh & Gh;
2403
+ const CHIl = El & Fl ^ ~El & Gl;
2404
+ const T1ll = add5L(Hl, sigma1l, CHIl, SHA512_Kl[i], SHA512_W_L[i]);
2405
+ const T1h = add5H(T1ll, Hh, sigma1h, CHIh, SHA512_Kh[i], SHA512_W_H[i]);
2406
+ const T1l = T1ll | 0;
2407
+ const sigma0h = rotrSH(Ah, Al, 28) ^ rotrBH(Ah, Al, 34) ^ rotrBH(Ah, Al, 39);
2408
+ const sigma0l = rotrSL(Ah, Al, 28) ^ rotrBL(Ah, Al, 34) ^ rotrBL(Ah, Al, 39);
2409
+ const MAJh = Ah & Bh ^ Ah & Ch ^ Bh & Ch;
2410
+ const MAJl = Al & Bl ^ Al & Cl ^ Bl & Cl;
2411
+ Hh = Gh | 0;
2412
+ Hl = Gl | 0;
2413
+ Gh = Fh | 0;
2414
+ Gl = Fl | 0;
2415
+ Fh = Eh | 0;
2416
+ Fl = El | 0;
2417
+ ({ h: Eh, l: El } = add(Dh | 0, Dl | 0, T1h | 0, T1l | 0));
2418
+ Dh = Ch | 0;
2419
+ Dl = Cl | 0;
2420
+ Ch = Bh | 0;
2421
+ Cl = Bl | 0;
2422
+ Bh = Ah | 0;
2423
+ Bl = Al | 0;
2424
+ const All = add3L(T1l, sigma0l, MAJl);
2425
+ Ah = add3H(All, T1h, sigma0h, MAJh);
2426
+ Al = All | 0;
2427
+ }
2428
+ ({ h: Ah, l: Al } = add(this.Ah | 0, this.Al | 0, Ah | 0, Al | 0));
2429
+ ({ h: Bh, l: Bl } = add(this.Bh | 0, this.Bl | 0, Bh | 0, Bl | 0));
2430
+ ({ h: Ch, l: Cl } = add(this.Ch | 0, this.Cl | 0, Ch | 0, Cl | 0));
2431
+ ({ h: Dh, l: Dl } = add(this.Dh | 0, this.Dl | 0, Dh | 0, Dl | 0));
2432
+ ({ h: Eh, l: El } = add(this.Eh | 0, this.El | 0, Eh | 0, El | 0));
2433
+ ({ h: Fh, l: Fl } = add(this.Fh | 0, this.Fl | 0, Fh | 0, Fl | 0));
2434
+ ({ h: Gh, l: Gl } = add(this.Gh | 0, this.Gl | 0, Gh | 0, Gl | 0));
2435
+ ({ h: Hh, l: Hl } = add(this.Hh | 0, this.Hl | 0, Hh | 0, Hl | 0));
2436
+ this.set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl);
2437
+ }
2438
+ roundClean() {
2439
+ clean(SHA512_W_H, SHA512_W_L);
2440
+ }
2441
+ destroy() {
2442
+ clean(this.buffer);
2443
+ this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
2444
+ }
2445
+ };
2446
+ var sha256 = /* @__PURE__ */ createHasher(() => new SHA256());
2447
+ var sha512 = /* @__PURE__ */ createHasher(() => new SHA512());
2448
+
2449
+ // ../../node_modules/.pnpm/@noble+hashes@1.8.0/node_modules/@noble/hashes/esm/sha512.js
2450
+ var sha5122 = sha512;
2451
+
2452
+ // ../../node_modules/.pnpm/@noble+hashes@1.8.0/node_modules/@noble/hashes/esm/sha256.js
2453
+ var sha2562 = sha256;
2454
+
2455
+ // src/gateway/device-identity.ts
2456
+ var import_fs2 = __toESM(require("fs"));
2457
+ var import_path2 = __toESM(require("path"));
2458
+ etc.sha512Sync = (...m) => sha5122(etc.concatBytes(...m));
2459
+ var CONFIG_DIR2 = import_path2.default.join(
2460
+ process.env.HOME || process.env.USERPROFILE || ".",
2461
+ ".echoclaw"
2462
+ );
2463
+ var DEVICE_FILE = import_path2.default.join(CONFIG_DIR2, "device.json");
2464
+ function ensureDir2() {
2465
+ if (!import_fs2.default.existsSync(CONFIG_DIR2)) {
2466
+ import_fs2.default.mkdirSync(CONFIG_DIR2, { recursive: true, mode: 448 });
2467
+ }
2468
+ }
2469
+ function deriveDeviceId(publicKeyBytes) {
2470
+ return bytesToHex2(sha2562(publicKeyBytes));
2471
+ }
2472
+ function toBase64Url(bytes) {
2473
+ let binary = "";
2474
+ for (let i = 0; i < bytes.length; i++) {
2475
+ binary += String.fromCharCode(bytes[i]);
2476
+ }
2477
+ return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
2478
+ }
2479
+ async function signPayload(privateKeyHex, payload) {
2480
+ const privKey = hexToBytes2(privateKeyHex);
2481
+ const message = new TextEncoder().encode(payload);
2482
+ const signature = await signAsync(message, privKey);
2483
+ return toBase64Url(signature);
2484
+ }
2485
+ async function generateKeypairAsync() {
2486
+ const privateKeyBytes = utils.randomPrivateKey();
2487
+ const publicKeyBytes = await getPublicKeyAsync(privateKeyBytes);
2488
+ const privateKey = bytesToHex2(privateKeyBytes);
2489
+ const publicKey = bytesToHex2(publicKeyBytes);
2490
+ const deviceId = deriveDeviceId(publicKeyBytes);
2491
+ return { privateKey, publicKey, deviceId };
2492
+ }
2493
+ function saveDevice(device) {
2494
+ ensureDir2();
2495
+ const tmpPath = DEVICE_FILE + ".tmp";
2496
+ import_fs2.default.writeFileSync(tmpPath, JSON.stringify(device, null, 2), { mode: 384 });
2497
+ import_fs2.default.renameSync(tmpPath, DEVICE_FILE);
2498
+ console.log(`[device] Saved keypair to ${DEVICE_FILE}`);
2499
+ }
2500
+ function loadDevice() {
2501
+ if (!import_fs2.default.existsSync(DEVICE_FILE)) return null;
2502
+ try {
2503
+ const raw = import_fs2.default.readFileSync(DEVICE_FILE, "utf-8");
2504
+ const data = JSON.parse(raw);
2505
+ if (!data.privateKey || !data.publicKey || !data.deviceId) {
2506
+ console.warn("[device] Invalid device.json \u2014 regenerating");
2507
+ return null;
2508
+ }
2509
+ return data;
2510
+ } catch (err2) {
2511
+ console.warn(`[device] Failed to read device.json: ${err2.message}`);
2512
+ return null;
2513
+ }
2514
+ }
2515
+ async function loadOrCreateDeviceIdentity() {
2516
+ const existing = loadDevice();
2517
+ if (existing) {
2518
+ console.log(`[device] Loaded identity (deviceId: ${existing.deviceId.slice(0, 12)}...)`);
2519
+ return existing;
2520
+ }
2521
+ console.log("[device] Generating new Ed25519 keypair...");
2522
+ const device = await generateKeypairAsync();
2523
+ saveDevice(device);
2524
+ console.log(`[device] New deviceId: ${device.deviceId.slice(0, 12)}...`);
2525
+ return device;
2526
+ }
2527
+ function publicKeyBase64Url(device) {
2528
+ return toBase64Url(hexToBytes2(device.publicKey));
2529
+ }
2530
+
2531
+ // src/gateway/connect.ts
2532
+ var SESSION_DIR = import_path3.default.join(
2533
+ process.env.HOME || process.env.USERPROFILE || ".",
2534
+ ".echoclaw"
2535
+ );
2536
+ var SESSION_FILE2 = import_path3.default.join(SESSION_DIR, "gateway-session.json");
2537
+ var MAX_RECONNECT_ATTEMPTS = 20;
2538
+ var MAX_AUTH_FAILURES_BEFORE_STOP = 9;
2539
+ var BASE_BACKOFF_MS = 1e3;
2540
+ var MAX_BACKOFF_MS = 6e4;
2541
+ var HEARTBEAT_INTERVAL_MS = 15e3;
2542
+ var CONNECT_TIMEOUT_MS = 1e4;
2543
+ var CLIENT_ID = "echoclaw-relay-agent";
2544
+ var CLIENT_VERSION = "1.0.0";
2545
+ var CLIENT_MODE = "operator";
2546
+ var ROLE = "operator";
2547
+ var SCOPES = ["operator.read", "operator.write"];
2548
+ var GatewayConnection = class extends import_events.EventEmitter {
2549
+ ws = null;
2550
+ config;
2551
+ state = "disconnected";
2552
+ connectNonce = null;
2553
+ cachedDeviceToken = null;
2554
+ reconnectAttempts = 0;
2555
+ authFailures = 0;
2556
+ reconnectTimer = null;
2557
+ heartbeatTimer = null;
2558
+ generation = 0;
2559
+ // increments on each reconnect, old streams fail-fast
2560
+ _stopped = false;
2561
+ constructor(config2) {
2562
+ super();
2563
+ this.config = config2;
2564
+ this.cachedDeviceToken = this.loadSession()?.deviceToken ?? null;
2565
+ }
2566
+ get currentState() {
2567
+ return this.state;
2568
+ }
2569
+ get currentGeneration() {
2570
+ return this.generation;
2571
+ }
2572
+ get isReady() {
2573
+ return this.state === "ready" && this.ws?.readyState === import_ws.default.OPEN;
2574
+ }
2575
+ // ── Public API ───────────────────────────────────────────
2576
+ /** Start connection to Gateway. */
2577
+ async connect() {
2578
+ if (this._stopped) return;
2579
+ this.setState("connecting");
2580
+ this.generation++;
2581
+ const url = this.config.gatewayUrl;
2582
+ console.log(`[gateway] Connecting to ${url} (gen=${this.generation})...`);
2583
+ try {
2584
+ this.ws = new import_ws.default(url, {
2585
+ handshakeTimeout: CONNECT_TIMEOUT_MS
2586
+ });
2587
+ this.ws.on("open", () => {
2588
+ console.log("[gateway] WebSocket connected, waiting for challenge...");
2589
+ this.setState("challenging");
2590
+ this.reconnectAttempts = 0;
2591
+ });
2592
+ this.ws.on("message", (raw) => {
2593
+ this.handleMessage(raw);
2594
+ });
2595
+ this.ws.on("close", (code, reason) => {
2596
+ const reasonStr = reason?.toString() || "";
2597
+ console.log(`[gateway] Disconnected (code=${code}${reasonStr ? `, reason=${reasonStr}` : ""})`);
2598
+ this.stopHeartbeat();
2599
+ if (!this._stopped) {
2600
+ this.scheduleReconnect();
2601
+ }
2602
+ });
2603
+ this.ws.on("error", (err2) => {
2604
+ console.error(`[gateway] WebSocket error: ${err2.message}`);
2605
+ });
2606
+ } catch (err2) {
2607
+ console.error(`[gateway] Connection failed: ${err2.message}`);
2608
+ this.scheduleReconnect();
2609
+ }
2610
+ }
2611
+ /** Send a JSON-RPC frame to Gateway. */
2612
+ send(frame) {
2613
+ if (!this.ws || this.ws.readyState !== import_ws.default.OPEN) return false;
2614
+ if (this.ws.bufferedAmount > 5 * 1024 * 1024) {
2615
+ console.warn("[gateway] Backpressure: bufferedAmount > 5MB, dropping frame");
2616
+ return false;
2617
+ }
2618
+ this.ws.send(JSON.stringify(frame));
2619
+ return true;
2620
+ }
2621
+ /** Gracefully disconnect. */
2622
+ disconnect() {
2623
+ this._stopped = true;
2624
+ this.stopHeartbeat();
2625
+ if (this.reconnectTimer) {
2626
+ clearTimeout(this.reconnectTimer);
2627
+ this.reconnectTimer = null;
2628
+ }
2629
+ if (this.ws) {
2630
+ this.ws.close(1e3, "agent shutdown");
2631
+ this.ws = null;
2632
+ }
2633
+ this.setState("disconnected");
2634
+ }
2635
+ // ── Message Handling ─────────────────────────────────────
2636
+ async handleMessage(raw) {
2637
+ let frame;
2638
+ try {
2639
+ frame = JSON.parse(raw.toString());
2640
+ } catch {
2641
+ console.warn("[gateway] Invalid JSON frame");
2642
+ return;
2643
+ }
2644
+ if (frame.type === "event" && frame.event === "connect.challenge") {
2645
+ this.connectNonce = frame.payload?.nonce;
2646
+ console.log(`[gateway] Received challenge (nonce: ${this.connectNonce?.slice(0, 8)}...)`);
2647
+ await this.sendConnectFrame();
2648
+ return;
2649
+ }
2650
+ if (frame.type === "res" && frame.id === "connect-1") {
2651
+ if (frame.ok) {
2652
+ this.handleConnectSuccess(frame);
2653
+ } else {
2654
+ this.handleConnectFailure(frame);
2655
+ }
2656
+ return;
2657
+ }
2658
+ if (this.state === "ready") {
2659
+ this.emit("frame", frame, this.generation);
2660
+ }
2661
+ }
2662
+ async sendConnectFrame() {
2663
+ if (!this.connectNonce || !this.ws) return;
2664
+ const token = this.resolveAuthToken();
2665
+ const signedAt = Date.now();
2666
+ const device = this.config.device;
2667
+ const pubKeyB64 = publicKeyBase64Url(device);
2668
+ const signaturePayload = [
2669
+ "v2",
2670
+ device.deviceId,
2671
+ CLIENT_ID,
2672
+ CLIENT_MODE,
2673
+ ROLE,
2674
+ SCOPES.join(","),
2675
+ String(signedAt),
2676
+ token ?? "",
2677
+ this.connectNonce
2678
+ ].join("|");
2679
+ const signature = await signPayload(device.privateKey, signaturePayload);
2680
+ const connectFrame = {
2681
+ type: "req",
2682
+ id: "connect-1",
2683
+ method: "connect",
2684
+ params: {
2685
+ minProtocol: 3,
2686
+ maxProtocol: 3,
2687
+ client: {
2688
+ id: CLIENT_ID,
2689
+ version: CLIENT_VERSION,
2690
+ platform: process.platform === "darwin" ? "macos" : process.platform,
2691
+ mode: CLIENT_MODE
2692
+ },
2693
+ role: ROLE,
2694
+ scopes: SCOPES,
2695
+ caps: [],
2696
+ auth: {
2697
+ ...this.cachedDeviceToken ? { deviceToken: this.cachedDeviceToken } : { token: token ?? void 0 }
2698
+ },
2699
+ device: {
2700
+ id: device.deviceId,
2701
+ publicKey: pubKeyB64,
2702
+ signature,
2703
+ signedAt,
2704
+ nonce: this.connectNonce
2705
+ }
2706
+ }
2707
+ };
2708
+ console.log(`[gateway] Sending connect frame (auth: ${this.cachedDeviceToken ? "deviceToken" : "gateway-token"})...`);
2709
+ this.ws.send(JSON.stringify(connectFrame));
2710
+ }
2711
+ handleConnectSuccess(frame) {
2712
+ const payload = frame.payload;
2713
+ const deviceToken = payload?.auth?.deviceToken;
2714
+ const tickInterval = payload?.policy?.tickIntervalMs || HEARTBEAT_INTERVAL_MS;
2715
+ console.log("[gateway] \u2705 Connected to OpenClaw Gateway");
2716
+ console.log(`[gateway] Protocol: ${payload?.protocol}`);
2717
+ console.log(`[gateway] Heartbeat: ${tickInterval}ms`);
2718
+ if (deviceToken) {
2719
+ this.cachedDeviceToken = deviceToken;
2720
+ this.saveSession({
2721
+ deviceToken,
2722
+ gatewayUrl: this.config.gatewayUrl,
2723
+ savedAt: (/* @__PURE__ */ new Date()).toISOString()
2724
+ });
2725
+ }
2726
+ this.authFailures = 0;
2727
+ this.setState("ready");
2728
+ this.startHeartbeat(tickInterval);
2729
+ this.emit("connected", payload);
2730
+ }
2731
+ handleConnectFailure(frame) {
2732
+ const error = frame.error;
2733
+ const code = error?.details?.code || error?.code || "unknown";
2734
+ const message = error?.message || "unknown error";
2735
+ console.error(`[gateway] \u274C Connect failed: ${code} \u2014 ${message}`);
2736
+ this.authFailures++;
2737
+ if (this.cachedDeviceToken && (code === "INVALID_TOKEN" || code === "auth_failed")) {
2738
+ console.log("[gateway] deviceToken rejected \u2014 clearing cache, will retry with gateway token");
2739
+ this.cachedDeviceToken = null;
2740
+ this.clearSession();
2741
+ this.authFailures = Math.max(0, this.authFailures - 1);
2742
+ this.ws?.close(4e3, "retry-with-gateway-token");
2743
+ return;
2744
+ }
2745
+ if (this.authFailures >= MAX_AUTH_FAILURES_BEFORE_STOP) {
2746
+ console.error(`[gateway] \u26D4 ${this.authFailures} auth failures \u2014 stopping to avoid rate limit lockout`);
2747
+ console.error(" Check your gateway token: openclaw config get gateway.auth.token");
2748
+ this.setState("auth_failed");
2749
+ this._stopped = true;
2750
+ this.ws?.close(4001, "auth-failed-hard-stop");
2751
+ return;
2752
+ }
2753
+ this.ws?.close(4e3, "auth-failed");
2754
+ }
2755
+ // ── Auth Token Resolution ────────────────────────────────
2756
+ resolveAuthToken() {
2757
+ if (this.config.manualToken) return this.config.manualToken;
2758
+ return this.config.gatewayToken;
2759
+ }
2760
+ // ── Heartbeat ────────────────────────────────────────────
2761
+ startHeartbeat(intervalMs) {
2762
+ this.stopHeartbeat();
2763
+ this.heartbeatTimer = setInterval(() => {
2764
+ if (this.ws?.readyState === import_ws.default.OPEN) {
2765
+ this.ws.ping();
2766
+ }
2767
+ }, intervalMs);
2768
+ }
2769
+ stopHeartbeat() {
2770
+ if (this.heartbeatTimer) {
2771
+ clearInterval(this.heartbeatTimer);
2772
+ this.heartbeatTimer = null;
2773
+ }
2774
+ }
2775
+ // ── Reconnection ─────────────────────────────────────────
2776
+ scheduleReconnect() {
2777
+ if (this._stopped) return;
2778
+ this.reconnectAttempts++;
2779
+ if (this.reconnectAttempts > MAX_RECONNECT_ATTEMPTS) {
2780
+ console.error("[gateway] Max reconnect attempts reached \u2014 stopping");
2781
+ this.setState("disconnected");
2782
+ return;
2783
+ }
2784
+ const base = Math.min(BASE_BACKOFF_MS * Math.pow(2, this.reconnectAttempts - 1), MAX_BACKOFF_MS);
2785
+ const jitter = Math.random() * base * 0.3;
2786
+ const delay = Math.round(base + jitter);
2787
+ console.log(`[gateway] Reconnecting in ${delay}ms (attempt ${this.reconnectAttempts}/${MAX_RECONNECT_ATTEMPTS})...`);
2788
+ this.setState("reconnecting");
2789
+ this.reconnectTimer = setTimeout(() => {
2790
+ this.reconnectTimer = null;
2791
+ this.connect();
2792
+ }, delay);
2793
+ }
2794
+ // ── State Management ─────────────────────────────────────
2795
+ setState(newState) {
2796
+ if (this.state === newState) return;
2797
+ const oldState = this.state;
2798
+ this.state = newState;
2799
+ this.emit("state", newState, oldState);
2800
+ }
2801
+ // ── Session Persistence ──────────────────────────────────
2802
+ loadSession() {
2803
+ if (!import_fs3.default.existsSync(SESSION_FILE2)) return null;
2804
+ try {
2805
+ const raw = import_fs3.default.readFileSync(SESSION_FILE2, "utf-8");
2806
+ return JSON.parse(raw);
2807
+ } catch {
2808
+ return null;
2809
+ }
2810
+ }
2811
+ saveSession(session) {
2812
+ try {
2813
+ if (!import_fs3.default.existsSync(SESSION_DIR)) {
2814
+ import_fs3.default.mkdirSync(SESSION_DIR, { recursive: true, mode: 448 });
2815
+ }
2816
+ const tmpPath = SESSION_FILE2 + ".tmp";
2817
+ import_fs3.default.writeFileSync(tmpPath, JSON.stringify(session, null, 2), { mode: 384 });
2818
+ import_fs3.default.renameSync(tmpPath, SESSION_FILE2);
2819
+ console.log(`[gateway] Saved deviceToken to ${SESSION_FILE2}`);
2820
+ } catch (err2) {
2821
+ console.warn(`[gateway] Failed to save session: ${err2.message}`);
2822
+ }
2823
+ }
2824
+ clearSession() {
2825
+ try {
2826
+ if (import_fs3.default.existsSync(SESSION_FILE2)) {
2827
+ import_fs3.default.unlinkSync(SESSION_FILE2);
2828
+ console.log("[gateway] Cleared cached deviceToken");
2829
+ }
2830
+ } catch {
2831
+ }
2832
+ }
2833
+ };
2834
+
2835
+ // src/gateway/rpc-proxy.ts
2836
+ var import_events2 = require("events");
2837
+ var MAX_FRAMES_PER_STREAM = 256;
2838
+ var MAX_BYTES_PER_STREAM = 1 * 1024 * 1024;
2839
+ var GatewayRpcProxy = class extends import_events2.EventEmitter {
2840
+ gateway;
2841
+ streams = /* @__PURE__ */ new Map();
2842
+ // rpcId → stream
2843
+ requestToRpc = /* @__PURE__ */ new Map();
2844
+ // requestId → rpcId
2845
+ constructor(gateway) {
2846
+ super();
2847
+ this.gateway = gateway;
2848
+ this.gateway.on("frame", (frame, generation) => {
2849
+ this.handleGatewayFrame(frame, generation);
2850
+ });
2851
+ this.gateway.on("state", (newState) => {
2852
+ if (newState === "connecting" || newState === "disconnected") {
2853
+ this.cleanupAllStreams("gateway_reconnect");
2854
+ }
2855
+ });
2856
+ }
2857
+ /**
2858
+ * Forward a Desktop request to the Gateway.
2859
+ * The TunnelPayload should have type='ws-rpc' and contain a frame field.
2860
+ */
2861
+ forwardToGateway(payload) {
2862
+ if (!this.gateway.isReady) {
2863
+ console.warn("[rpc-proxy] Gateway not ready, cannot forward request");
2864
+ return false;
2865
+ }
2866
+ const frame = payload.frame;
2867
+ if (!frame) {
2868
+ console.warn("[rpc-proxy] TunnelPayload missing frame field");
2869
+ return false;
2870
+ }
2871
+ if (frame.type === "req") {
2872
+ const stream = {
2873
+ requestId: payload.request_id,
2874
+ rpcId: frame.id,
2875
+ generation: this.gateway.currentGeneration,
2876
+ frameCount: 0,
2877
+ byteCount: 0,
2878
+ createdAt: Date.now()
2879
+ };
2880
+ this.streams.set(frame.id, stream);
2881
+ this.requestToRpc.set(payload.request_id, frame.id);
2882
+ }
2883
+ return this.gateway.send(frame);
2884
+ }
2885
+ /**
2886
+ * Handle a cancel signal from Desktop for a specific stream.
2887
+ */
2888
+ cancelStream(requestId) {
2889
+ const rpcId = this.requestToRpc.get(requestId);
2890
+ if (!rpcId) return;
2891
+ if (this.gateway.isReady) {
2892
+ this.gateway.send({
2893
+ type: "req",
2894
+ id: `cancel-${rpcId}`,
2895
+ method: "chat.cancel",
2896
+ params: { streamId: rpcId }
2897
+ });
2898
+ }
2899
+ this.removeStream(rpcId, "cancelled");
2900
+ }
2901
+ /**
2902
+ * Get current active stream count (for diagnostics).
2903
+ */
2904
+ get activeStreamCount() {
2905
+ return this.streams.size;
2906
+ }
2907
+ /**
2908
+ * Clean up all streams (e.g. on disconnect).
2909
+ */
2910
+ cleanupAllStreams(reason) {
2911
+ if (this.streams.size === 0) return;
2912
+ console.log(`[rpc-proxy] Cleaning up ${this.streams.size} streams (${reason})`);
2913
+ for (const [rpcId, stream] of this.streams) {
2914
+ this.emitTunnelResponse(stream.requestId, {
2915
+ type: "res",
2916
+ id: rpcId,
2917
+ ok: false,
2918
+ error: {
2919
+ code: "STREAM_RESET",
2920
+ message: `Stream reset: ${reason}`,
2921
+ retryable: true
2922
+ }
2923
+ }, true);
2924
+ }
2925
+ this.streams.clear();
2926
+ this.requestToRpc.clear();
2927
+ }
2928
+ // ── Internal: Gateway frame handling ───────────────────────
2929
+ handleGatewayFrame(frame, generation) {
2930
+ if (frame.type === "res") {
2931
+ this.handleResponse(frame, generation);
2932
+ } else if (frame.type === "event") {
2933
+ this.handleEvent(frame, generation);
2934
+ }
2935
+ }
2936
+ handleResponse(frame, generation) {
2937
+ const stream = this.streams.get(frame.id);
2938
+ if (!stream) return;
2939
+ if (stream.generation !== generation) {
2940
+ console.warn(`[rpc-proxy] Dropping stale response for ${frame.id} (gen ${stream.generation} vs ${generation})`);
2941
+ this.removeStream(frame.id, "stale");
2942
+ return;
2943
+ }
2944
+ this.emitTunnelResponse(stream.requestId, frame, true);
2945
+ this.removeStream(frame.id, "complete");
2946
+ }
2947
+ handleEvent(frame, generation) {
2948
+ const streamId = frame.payload?.streamId || frame.payload?.id;
2949
+ const stream = streamId ? this.streams.get(streamId) : null;
2950
+ if (!stream) {
2951
+ this.emit("gateway_event", frame);
2952
+ return;
2953
+ }
2954
+ if (stream.generation !== generation) {
2955
+ console.warn(`[rpc-proxy] Dropping stale event for ${streamId}`);
2956
+ return;
2957
+ }
2958
+ const frameSize = JSON.stringify(frame).length;
2959
+ stream.frameCount++;
2960
+ stream.byteCount += frameSize;
2961
+ if (stream.frameCount > MAX_FRAMES_PER_STREAM || stream.byteCount > MAX_BYTES_PER_STREAM) {
2962
+ console.warn(`[rpc-proxy] Stream ${streamId} exceeded limits (frames=${stream.frameCount}, bytes=${stream.byteCount})`);
2963
+ this.cancelStream(stream.requestId);
2964
+ return;
2965
+ }
2966
+ const state = frame.payload?.state;
2967
+ const isFinal = state === "final" || state === "aborted" || state === "error";
2968
+ this.emitTunnelResponse(stream.requestId, frame, isFinal);
2969
+ if (isFinal) {
2970
+ this.removeStream(streamId, state);
2971
+ }
2972
+ }
2973
+ // ── Internal: emit tunnel response ─────────────────────────
2974
+ emitTunnelResponse(requestId, frame, isFinal) {
2975
+ const response = {
2976
+ request_id: requestId,
2977
+ direction: "response",
2978
+ type: "ws-rpc",
2979
+ frame,
2980
+ final: isFinal
2981
+ };
2982
+ this.emit("response", response);
2983
+ }
2984
+ // ── Internal: stream lifecycle ─────────────────────────────
2985
+ removeStream(rpcId, reason) {
2986
+ const stream = this.streams.get(rpcId);
2987
+ if (!stream) return;
2988
+ this.streams.delete(rpcId);
2989
+ this.requestToRpc.delete(stream.requestId);
2990
+ }
2991
+ };
2992
+
268
2993
  // src/relay/client.ts
269
2994
  var ws = null;
270
2995
  var keyPair = null;
@@ -275,7 +3000,9 @@ var reconnect;
275
3000
  var config;
276
3001
  var _stopped = false;
277
3002
  var _heartbeatTimer = null;
278
- var HEARTBEAT_INTERVAL_MS = 25e3;
3003
+ var HEARTBEAT_INTERVAL_MS2 = 25e3;
3004
+ var gatewayConn = null;
3005
+ var rpcProxy = null;
279
3006
  var _onPaired = null;
280
3007
  function onPaired(cb) {
281
3008
  _onPaired = cb;
@@ -291,6 +3018,9 @@ async function startRelayClient(cfg) {
291
3018
  }
292
3019
  keyPair = await generateKeyPair();
293
3020
  console.log("[relay-agent] X25519 key pair generated");
3021
+ if (cfg.gatewayConfig) {
3022
+ startGateway(cfg.gatewayConfig);
3023
+ }
294
3024
  connect();
295
3025
  }
296
3026
  function stopRelayClient() {
@@ -303,17 +3033,60 @@ function stopRelayClient() {
303
3033
  ws.close(1e3, "agent shutdown");
304
3034
  ws = null;
305
3035
  }
3036
+ if (gatewayConn) {
3037
+ gatewayConn.disconnect();
3038
+ gatewayConn = null;
3039
+ }
3040
+ rpcProxy = null;
306
3041
  sessionKey = null;
307
3042
  keyPair = null;
308
3043
  reconnect?.reset();
309
3044
  }
3045
+ function startGateway(gwConfig) {
3046
+ gatewayConn = new GatewayConnection(gwConfig);
3047
+ rpcProxy = new GatewayRpcProxy(gatewayConn);
3048
+ rpcProxy.on("response", (response) => {
3049
+ sendEncryptedPayload(response);
3050
+ });
3051
+ gatewayConn.on("state", (newState, oldState) => {
3052
+ console.log(`[relay-agent] Gateway: ${oldState} \u2192 ${newState}`);
3053
+ broadcastControlState();
3054
+ });
3055
+ gatewayConn.on("connected", () => {
3056
+ console.log("[relay-agent] Gateway connected \u2014 ws-rpc routing enabled");
3057
+ broadcastControlState();
3058
+ });
3059
+ gatewayConn.connect().catch((err2) => {
3060
+ console.error(`[relay-agent] Gateway connect error: ${err2.message}`);
3061
+ });
3062
+ }
3063
+ function broadcastControlState() {
3064
+ if (!sessionKey) return;
3065
+ const control = {
3066
+ request_id: `ctrl-${Date.now().toString(36)}`,
3067
+ direction: "response",
3068
+ type: "control",
3069
+ frame: {
3070
+ type: "event",
3071
+ event: "state_update",
3072
+ payload: {
3073
+ action: "state_update",
3074
+ gateway_state: gatewayConn?.currentState ?? "disconnected",
3075
+ bridge_state: "ready"
3076
+ // Bridge is always assumed reachable (we check on demand)
3077
+ }
3078
+ },
3079
+ final: true
3080
+ };
3081
+ sendEncryptedPayload(control);
3082
+ }
310
3083
  function startHeartbeat() {
311
3084
  if (_heartbeatTimer) clearInterval(_heartbeatTimer);
312
3085
  _heartbeatTimer = setInterval(() => {
313
- if (ws?.readyState === import_ws.default.OPEN) {
3086
+ if (ws?.readyState === import_ws2.default.OPEN) {
314
3087
  sendRaw({ version: 1, session_id: sessionId ?? "", msg_id: makeId(), type: "PING", sender_role: "agent" });
315
3088
  }
316
- }, HEARTBEAT_INTERVAL_MS);
3089
+ }, HEARTBEAT_INTERVAL_MS2);
317
3090
  }
318
3091
  function stopHeartbeat() {
319
3092
  if (_heartbeatTimer) {
@@ -326,7 +3099,7 @@ function connect() {
326
3099
  reconnect.setState("connecting");
327
3100
  const resumeId = sessionId || config.sessionId;
328
3101
  const url = resumeId ? `${config.relayUrl}${config.relayUrl.includes("?") ? "&" : "?"}resume=${resumeId}` : config.relayUrl;
329
- ws = new import_ws.default(url);
3102
+ ws = new import_ws2.default(url);
330
3103
  ws.on("open", () => {
331
3104
  reconnect.setState("connected");
332
3105
  startHeartbeat();
@@ -345,12 +3118,24 @@ function connect() {
345
3118
  handleMessage(data.toString());
346
3119
  });
347
3120
  ws.on("close", (code, reason) => {
348
- console.log(`[relay-agent] Disconnected (code=${code}, reason=${reason.toString()})`);
3121
+ const reasonStr = reason.toString();
349
3122
  stopHeartbeat();
3123
+ if (code === 4004) {
3124
+ if (!_stopped) {
3125
+ console.error("[relay-agent] \u274C Pairing code rejected by server. Session may have expired.");
3126
+ console.error(" Please re-pair: npx echoclaw-relay-agent (without --code)");
3127
+ sessionKey = null;
3128
+ sessionId = null;
3129
+ _stopped = true;
3130
+ clearSession();
3131
+ }
3132
+ return;
3133
+ }
3134
+ console.log(`[relay-agent] Disconnected (code=${code}${reasonStr ? `, reason=${reasonStr}` : ""})`);
350
3135
  scheduleReconnect();
351
3136
  });
352
- ws.on("error", (err) => {
353
- console.error(`[relay-agent] WebSocket error: ${err.message}`);
3137
+ ws.on("error", (err2) => {
3138
+ console.error(`[relay-agent] WebSocket error: ${err2.message}`);
354
3139
  });
355
3140
  }
356
3141
  function scheduleReconnect() {
@@ -379,9 +3164,17 @@ async function handleMessage(raw) {
379
3164
  sendRaw({ version: 1, session_id: msg.session_id, msg_id: makeId(), type: "PING", sender_role: "agent" });
380
3165
  break;
381
3166
  case "CLOSE":
382
- console.log("[relay-agent] Session closed by peer");
383
- sessionKey = null;
384
- reconnect.setState("connected");
3167
+ if (msg.payload === "INVALID_CODE") {
3168
+ console.error("[relay-agent] \u274C Session expired or pairing code is invalid.");
3169
+ console.error(" Please re-pair with a new code from EchoClaw Desktop.");
3170
+ sessionKey = null;
3171
+ sessionId = null;
3172
+ _stopped = true;
3173
+ clearSession();
3174
+ } else {
3175
+ console.log("[relay-agent] Session closed by peer");
3176
+ sessionKey = null;
3177
+ }
385
3178
  break;
386
3179
  }
387
3180
  }
@@ -426,9 +3219,10 @@ async function handleHello(msg) {
426
3219
  config.bridgeUrl,
427
3220
  pairingCode ?? void 0
428
3221
  );
429
- } catch (err) {
430
- console.warn("[relay-agent] Failed to persist session:", err.message);
3222
+ } catch (err2) {
3223
+ console.warn("[relay-agent] Failed to persist session:", err2.message);
431
3224
  }
3225
+ broadcastControlState();
432
3226
  if (_onPaired) {
433
3227
  try {
434
3228
  _onPaired();
@@ -456,8 +3250,115 @@ async function handleData(msg) {
456
3250
  console.warn("[relay-agent] Unexpected payload direction:", tunnelPayload.direction);
457
3251
  return;
458
3252
  }
459
- const response = await forwardToBridge(config.bridgeUrl, tunnelPayload);
460
- const responseBytes = new TextEncoder().encode(JSON.stringify(response));
3253
+ await routePayload(tunnelPayload);
3254
+ } catch (err2) {
3255
+ console.error("[relay-agent] Failed to process DATA message:", err2.message);
3256
+ }
3257
+ }
3258
+ async function routePayload(payload) {
3259
+ const payloadType = payload.type || "http";
3260
+ switch (payloadType) {
3261
+ case "http":
3262
+ await routeHttp(payload);
3263
+ break;
3264
+ case "ws-rpc":
3265
+ routeWsRpc(payload);
3266
+ break;
3267
+ case "control":
3268
+ handleControl(payload);
3269
+ break;
3270
+ default:
3271
+ console.warn(`[relay-agent] Unknown payload type: ${payloadType}`);
3272
+ }
3273
+ }
3274
+ async function routeHttp(payload) {
3275
+ const response = await forwardToBridge(config.bridgeUrl, payload);
3276
+ await sendEncryptedPayload(response);
3277
+ }
3278
+ function routeWsRpc(payload) {
3279
+ if (!rpcProxy || !gatewayConn?.isReady) {
3280
+ const errorResponse = {
3281
+ request_id: payload.request_id,
3282
+ direction: "response",
3283
+ type: "ws-rpc",
3284
+ frame: {
3285
+ type: "res",
3286
+ id: payload.frame?.id || "unknown",
3287
+ ok: false,
3288
+ error: {
3289
+ code: "GATEWAY_UNAVAILABLE",
3290
+ message: "OpenClaw Gateway is not connected. Is OpenClaw running on this machine?",
3291
+ retryable: true,
3292
+ retryAfterMs: 3e3
3293
+ }
3294
+ },
3295
+ final: true
3296
+ };
3297
+ sendEncryptedPayload(errorResponse);
3298
+ return;
3299
+ }
3300
+ const ok = rpcProxy.forwardToGateway(payload);
3301
+ if (!ok) {
3302
+ const errorResponse = {
3303
+ request_id: payload.request_id,
3304
+ direction: "response",
3305
+ type: "ws-rpc",
3306
+ frame: {
3307
+ type: "res",
3308
+ id: payload.frame?.id || "unknown",
3309
+ ok: false,
3310
+ error: {
3311
+ code: "GATEWAY_SEND_FAILED",
3312
+ message: "Failed to send to Gateway (backpressure or disconnected)",
3313
+ retryable: true
3314
+ }
3315
+ },
3316
+ final: true
3317
+ };
3318
+ sendEncryptedPayload(errorResponse);
3319
+ }
3320
+ }
3321
+ function handleControl(payload) {
3322
+ const control = payload.frame?.payload;
3323
+ if (!control) return;
3324
+ switch (control.action) {
3325
+ case "cancel_stream":
3326
+ if (control.stream_id && rpcProxy) {
3327
+ rpcProxy.cancelStream(control.stream_id);
3328
+ }
3329
+ break;
3330
+ case "capability":
3331
+ const caps = {
3332
+ request_id: payload.request_id,
3333
+ direction: "response",
3334
+ type: "control",
3335
+ frame: {
3336
+ type: "event",
3337
+ event: "capability",
3338
+ payload: {
3339
+ action: "capability",
3340
+ capabilities: [
3341
+ "http",
3342
+ // Bridge HTTP forwarding
3343
+ gatewayConn?.isReady ? "ws-rpc" : void 0
3344
+ // Gateway WS-RPC
3345
+ ].filter(Boolean),
3346
+ gateway_state: gatewayConn?.currentState ?? "disconnected"
3347
+ }
3348
+ },
3349
+ final: true
3350
+ };
3351
+ sendEncryptedPayload(caps);
3352
+ break;
3353
+ case "state_update":
3354
+ broadcastControlState();
3355
+ break;
3356
+ }
3357
+ }
3358
+ async function sendEncryptedPayload(payload) {
3359
+ if (!sessionKey || !ws || ws.readyState !== import_ws2.default.OPEN) return;
3360
+ try {
3361
+ const responseBytes = new TextEncoder().encode(JSON.stringify(payload));
461
3362
  const encrypted = await encrypt(sessionKey, responseBytes);
462
3363
  const responseMsg = {
463
3364
  version: 1,
@@ -470,8 +3371,8 @@ async function handleData(msg) {
470
3371
  timestamp: Date.now()
471
3372
  };
472
3373
  sendRaw(responseMsg);
473
- } catch (err) {
474
- console.error("[relay-agent] Failed to process DATA message:", err.message);
3374
+ } catch (err2) {
3375
+ console.error("[relay-agent] Failed to encrypt/send response:", err2.message);
475
3376
  }
476
3377
  }
477
3378
  var _counter = 0;
@@ -479,36 +3380,36 @@ function makeId() {
479
3380
  return `ra-${++_counter}-${Date.now().toString(36)}`;
480
3381
  }
481
3382
  function sendRaw(msg) {
482
- if (ws?.readyState === import_ws.default.OPEN) {
3383
+ if (ws?.readyState === import_ws2.default.OPEN) {
483
3384
  ws.send(JSON.stringify(msg));
484
3385
  }
485
3386
  }
486
3387
 
487
3388
  // src/service/installer.ts
488
- var import_fs2 = __toESM(require("fs"));
489
- var import_path2 = __toESM(require("path"));
3389
+ var import_fs4 = __toESM(require("fs"));
3390
+ var import_path4 = __toESM(require("path"));
490
3391
  var import_child_process = require("child_process");
491
3392
  var SERVICE_NAME = "me.echoclaw.relay-agent";
492
3393
  var LABEL = "EchoClaw Relay Agent";
493
3394
  function getInstallDir() {
494
- return import_path2.default.join(getConfigDir(), "bin");
3395
+ return import_path4.default.join(getConfigDir(), "bin");
495
3396
  }
496
3397
  function freezeRuntime() {
497
3398
  const installDir = getInstallDir();
498
- if (!import_fs2.default.existsSync(installDir)) {
499
- import_fs2.default.mkdirSync(installDir, { recursive: true, mode: 493 });
3399
+ if (!import_fs4.default.existsSync(installDir)) {
3400
+ import_fs4.default.mkdirSync(installDir, { recursive: true, mode: 493 });
500
3401
  }
501
3402
  const sourceScript = process.argv[1];
502
- const destScript = import_path2.default.join(installDir, "agent.js");
503
- if (sourceScript && import_fs2.default.existsSync(sourceScript)) {
504
- import_fs2.default.copyFileSync(sourceScript, destScript);
505
- import_fs2.default.chmodSync(destScript, 493);
3403
+ const destScript = import_path4.default.join(installDir, "agent.js");
3404
+ if (sourceScript && import_fs4.default.existsSync(sourceScript)) {
3405
+ import_fs4.default.copyFileSync(sourceScript, destScript);
3406
+ import_fs4.default.chmodSync(destScript, 493);
506
3407
  } else {
507
3408
  throw new Error("Cannot locate the running agent script to install.");
508
3409
  }
509
3410
  const nodePath = process.execPath;
510
- const nodeInfoPath = import_path2.default.join(installDir, "node-path.txt");
511
- import_fs2.default.writeFileSync(nodeInfoPath, nodePath, { mode: 420 });
3411
+ const nodeInfoPath = import_path4.default.join(installDir, "node-path.txt");
3412
+ import_fs4.default.writeFileSync(nodeInfoPath, nodePath, { mode: 420 });
512
3413
  console.log(` Copied agent to: ${destScript}`);
513
3414
  console.log(` Node runtime: ${nodePath}`);
514
3415
  return { nodePath, agentScript: destScript };
@@ -516,10 +3417,10 @@ function freezeRuntime() {
516
3417
  function macosInstall() {
517
3418
  const { nodePath, agentScript } = freezeRuntime();
518
3419
  const logDir = getConfigDir();
519
- const plistDir = import_path2.default.join(process.env.HOME, "Library", "LaunchAgents");
520
- const plistPath = import_path2.default.join(plistDir, `${SERVICE_NAME}.plist`);
521
- if (!import_fs2.default.existsSync(plistDir)) {
522
- import_fs2.default.mkdirSync(plistDir, { recursive: true });
3420
+ const plistDir = import_path4.default.join(process.env.HOME, "Library", "LaunchAgents");
3421
+ const plistPath = import_path4.default.join(plistDir, `${SERVICE_NAME}.plist`);
3422
+ if (!import_fs4.default.existsSync(plistDir)) {
3423
+ import_fs4.default.mkdirSync(plistDir, { recursive: true });
523
3424
  }
524
3425
  const plist = `<?xml version="1.0" encoding="UTF-8"?>
525
3426
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
@@ -556,12 +3457,12 @@ function macosInstall() {
556
3457
  </dict>
557
3458
  </dict>
558
3459
  </plist>`;
559
- import_fs2.default.writeFileSync(plistPath, plist, { mode: 420 });
3460
+ import_fs4.default.writeFileSync(plistPath, plist, { mode: 420 });
560
3461
  try {
561
3462
  (0, import_child_process.execSync)(`launchctl unload "${plistPath}" 2>/dev/null || true`);
562
3463
  (0, import_child_process.execSync)(`launchctl load "${plistPath}"`);
563
- } catch (err) {
564
- console.error(`[install] Failed to load LaunchAgent: ${err.message}`);
3464
+ } catch (err2) {
3465
+ console.error(`[install] Failed to load LaunchAgent: ${err2.message}`);
565
3466
  console.log(`[install] Plist written to ${plistPath} \u2014 load manually:`);
566
3467
  console.log(` launchctl load "${plistPath}"`);
567
3468
  return;
@@ -576,13 +3477,13 @@ function macosInstall() {
576
3477
  console.log("");
577
3478
  }
578
3479
  function macosUninstall() {
579
- const plistPath = import_path2.default.join(
3480
+ const plistPath = import_path4.default.join(
580
3481
  process.env.HOME,
581
3482
  "Library",
582
3483
  "LaunchAgents",
583
3484
  `${SERVICE_NAME}.plist`
584
3485
  );
585
- if (!import_fs2.default.existsSync(plistPath)) {
3486
+ if (!import_fs4.default.existsSync(plistPath)) {
586
3487
  console.log("[uninstall] No LaunchAgent found \u2014 nothing to remove.");
587
3488
  return;
588
3489
  }
@@ -590,10 +3491,10 @@ function macosUninstall() {
590
3491
  (0, import_child_process.execSync)(`launchctl unload "${plistPath}" 2>/dev/null || true`);
591
3492
  } catch {
592
3493
  }
593
- import_fs2.default.unlinkSync(plistPath);
3494
+ import_fs4.default.unlinkSync(plistPath);
594
3495
  const installDir = getInstallDir();
595
- if (import_fs2.default.existsSync(installDir)) {
596
- import_fs2.default.rmSync(installDir, { recursive: true, force: true });
3496
+ if (import_fs4.default.existsSync(installDir)) {
3497
+ import_fs4.default.rmSync(installDir, { recursive: true, force: true });
597
3498
  }
598
3499
  console.log("");
599
3500
  console.log(" \u2705 Uninstalled macOS LaunchAgent");
@@ -601,13 +3502,13 @@ function macosUninstall() {
601
3502
  console.log("");
602
3503
  }
603
3504
  function macosStatus() {
604
- const plistPath = import_path2.default.join(
3505
+ const plistPath = import_path4.default.join(
605
3506
  process.env.HOME,
606
3507
  "Library",
607
3508
  "LaunchAgents",
608
3509
  `${SERVICE_NAME}.plist`
609
3510
  );
610
- if (!import_fs2.default.existsSync(plistPath)) {
3511
+ if (!import_fs4.default.existsSync(plistPath)) {
611
3512
  console.log(" Service: not installed");
612
3513
  return;
613
3514
  }
@@ -625,15 +3526,15 @@ function macosStatus() {
625
3526
  function linuxInstall() {
626
3527
  const { nodePath, agentScript } = freezeRuntime();
627
3528
  const logDir = getConfigDir();
628
- const serviceDir = import_path2.default.join(
3529
+ const serviceDir = import_path4.default.join(
629
3530
  process.env.HOME,
630
3531
  ".config",
631
3532
  "systemd",
632
3533
  "user"
633
3534
  );
634
- const servicePath = import_path2.default.join(serviceDir, `${SERVICE_NAME}.service`);
635
- if (!import_fs2.default.existsSync(serviceDir)) {
636
- import_fs2.default.mkdirSync(serviceDir, { recursive: true });
3535
+ const servicePath = import_path4.default.join(serviceDir, `${SERVICE_NAME}.service`);
3536
+ if (!import_fs4.default.existsSync(serviceDir)) {
3537
+ import_fs4.default.mkdirSync(serviceDir, { recursive: true });
637
3538
  }
638
3539
  const unit = `[Unit]
639
3540
  Description=${LABEL}
@@ -653,13 +3554,13 @@ Environment=HOME=${process.env.HOME}
653
3554
  [Install]
654
3555
  WantedBy=default.target
655
3556
  `;
656
- import_fs2.default.writeFileSync(servicePath, unit, { mode: 420 });
3557
+ import_fs4.default.writeFileSync(servicePath, unit, { mode: 420 });
657
3558
  try {
658
3559
  (0, import_child_process.execSync)("systemctl --user daemon-reload");
659
3560
  (0, import_child_process.execSync)(`systemctl --user enable ${SERVICE_NAME}.service`);
660
3561
  (0, import_child_process.execSync)(`systemctl --user start ${SERVICE_NAME}.service`);
661
- } catch (err) {
662
- console.error(`[install] Failed to start service: ${err.message}`);
3562
+ } catch (err2) {
3563
+ console.error(`[install] Failed to start service: ${err2.message}`);
663
3564
  console.log(`[install] Service file written to ${servicePath}`);
664
3565
  console.log(" Enable manually:");
665
3566
  console.log(` systemctl --user enable --now ${SERVICE_NAME}.service`);
@@ -682,14 +3583,14 @@ WantedBy=default.target
682
3583
  console.log("");
683
3584
  }
684
3585
  function linuxUninstall() {
685
- const servicePath = import_path2.default.join(
3586
+ const servicePath = import_path4.default.join(
686
3587
  process.env.HOME,
687
3588
  ".config",
688
3589
  "systemd",
689
3590
  "user",
690
3591
  `${SERVICE_NAME}.service`
691
3592
  );
692
- if (!import_fs2.default.existsSync(servicePath)) {
3593
+ if (!import_fs4.default.existsSync(servicePath)) {
693
3594
  console.log("[uninstall] No systemd service found \u2014 nothing to remove.");
694
3595
  return;
695
3596
  }
@@ -698,14 +3599,14 @@ function linuxUninstall() {
698
3599
  (0, import_child_process.execSync)(`systemctl --user disable ${SERVICE_NAME}.service 2>/dev/null || true`);
699
3600
  } catch {
700
3601
  }
701
- import_fs2.default.unlinkSync(servicePath);
3602
+ import_fs4.default.unlinkSync(servicePath);
702
3603
  try {
703
3604
  (0, import_child_process.execSync)("systemctl --user daemon-reload");
704
3605
  } catch {
705
3606
  }
706
3607
  const installDir = getInstallDir();
707
- if (import_fs2.default.existsSync(installDir)) {
708
- import_fs2.default.rmSync(installDir, { recursive: true, force: true });
3608
+ if (import_fs4.default.existsSync(installDir)) {
3609
+ import_fs4.default.rmSync(installDir, { recursive: true, force: true });
709
3610
  }
710
3611
  console.log("");
711
3612
  console.log(" \u2705 Uninstalled systemd user service");
@@ -713,14 +3614,14 @@ function linuxUninstall() {
713
3614
  console.log("");
714
3615
  }
715
3616
  function linuxStatus() {
716
- const servicePath = import_path2.default.join(
3617
+ const servicePath = import_path4.default.join(
717
3618
  process.env.HOME,
718
3619
  ".config",
719
3620
  "systemd",
720
3621
  "user",
721
3622
  `${SERVICE_NAME}.service`
722
3623
  );
723
- if (!import_fs2.default.existsSync(servicePath)) {
3624
+ if (!import_fs4.default.existsSync(servicePath)) {
724
3625
  console.log(" Service: not installed");
725
3626
  return;
726
3627
  }
@@ -751,8 +3652,8 @@ function windowsInstall() {
751
3652
  { encoding: "utf-8" }
752
3653
  );
753
3654
  (0, import_child_process.execSync)(`schtasks /Run /TN "${SERVICE_NAME}"`, { encoding: "utf-8" });
754
- } catch (err) {
755
- console.error(`[install] Failed to create scheduled task: ${err.message}`);
3655
+ } catch (err2) {
3656
+ console.error(`[install] Failed to create scheduled task: ${err2.message}`);
756
3657
  console.log(" You may need to run this command as Administrator.");
757
3658
  return;
758
3659
  }
@@ -772,8 +3673,8 @@ function windowsUninstall() {
772
3673
  return;
773
3674
  }
774
3675
  const installDir = getInstallDir();
775
- if (import_fs2.default.existsSync(installDir)) {
776
- import_fs2.default.rmSync(installDir, { recursive: true, force: true });
3676
+ if (import_fs4.default.existsSync(installDir)) {
3677
+ import_fs4.default.rmSync(installDir, { recursive: true, force: true });
777
3678
  }
778
3679
  console.log("");
779
3680
  console.log(" \u2705 Uninstalled Windows Scheduled Task");
@@ -850,7 +3751,7 @@ function restartService() {
850
3751
  const platform = getPlatform();
851
3752
  switch (platform) {
852
3753
  case "macos": {
853
- const plistPath = import_path2.default.join(
3754
+ const plistPath = import_path4.default.join(
854
3755
  process.env.HOME,
855
3756
  "Library",
856
3757
  "LaunchAgents",
@@ -859,24 +3760,24 @@ function restartService() {
859
3760
  try {
860
3761
  (0, import_child_process.execSync)(`launchctl unload "${plistPath}" 2>/dev/null || true`);
861
3762
  (0, import_child_process.execSync)(`launchctl load "${plistPath}"`);
862
- } catch (err) {
863
- console.error(`[restart] Failed: ${err.message}`);
3763
+ } catch (err2) {
3764
+ console.error(`[restart] Failed: ${err2.message}`);
864
3765
  }
865
3766
  break;
866
3767
  }
867
3768
  case "linux":
868
3769
  try {
869
3770
  (0, import_child_process.execSync)(`systemctl --user restart ${SERVICE_NAME}.service`);
870
- } catch (err) {
871
- console.error(`[restart] Failed: ${err.message}`);
3771
+ } catch (err2) {
3772
+ console.error(`[restart] Failed: ${err2.message}`);
872
3773
  }
873
3774
  break;
874
3775
  case "windows":
875
3776
  try {
876
3777
  (0, import_child_process.execSync)(`schtasks /End /TN "${SERVICE_NAME}" 2>nul`, { stdio: "pipe" });
877
3778
  (0, import_child_process.execSync)(`schtasks /Run /TN "${SERVICE_NAME}"`, { encoding: "utf-8" });
878
- } catch (err) {
879
- console.error(`[restart] Failed: ${err.message}`);
3779
+ } catch (err2) {
3780
+ console.error(`[restart] Failed: ${err2.message}`);
880
3781
  }
881
3782
  break;
882
3783
  }
@@ -885,12 +3786,12 @@ function isServiceInstalled() {
885
3786
  const platform = getPlatform();
886
3787
  switch (platform) {
887
3788
  case "macos":
888
- return import_fs2.default.existsSync(
889
- import_path2.default.join(process.env.HOME, "Library", "LaunchAgents", `${SERVICE_NAME}.plist`)
3789
+ return import_fs4.default.existsSync(
3790
+ import_path4.default.join(process.env.HOME, "Library", "LaunchAgents", `${SERVICE_NAME}.plist`)
890
3791
  );
891
3792
  case "linux":
892
- return import_fs2.default.existsSync(
893
- import_path2.default.join(process.env.HOME, ".config", "systemd", "user", `${SERVICE_NAME}.service`)
3793
+ return import_fs4.default.existsSync(
3794
+ import_path4.default.join(process.env.HOME, ".config", "systemd", "user", `${SERVICE_NAME}.service`)
894
3795
  );
895
3796
  case "windows":
896
3797
  try {
@@ -902,14 +3803,76 @@ function isServiceInstalled() {
902
3803
  }
903
3804
  }
904
3805
 
3806
+ // src/gateway/token-discovery.ts
3807
+ var import_fs5 = __toESM(require("fs"));
3808
+ var import_path5 = __toESM(require("path"));
3809
+ var import_json5 = __toESM(require_lib());
3810
+ var OPENCLAW_CONFIG_PATH = import_path5.default.join(
3811
+ process.env.HOME || process.env.USERPROFILE || ".",
3812
+ ".openclaw",
3813
+ "openclaw.json"
3814
+ );
3815
+ async function discoverGatewayToken() {
3816
+ try {
3817
+ if (import_fs5.default.existsSync(OPENCLAW_CONFIG_PATH)) {
3818
+ const raw = import_fs5.default.readFileSync(OPENCLAW_CONFIG_PATH, "utf-8");
3819
+ const config2 = import_json5.default.parse(raw);
3820
+ const token = config2?.gateway?.auth?.token;
3821
+ if (typeof token === "string" && token.length > 0) {
3822
+ if (token.startsWith("${") && token.endsWith("}")) {
3823
+ const envKey = token.slice(2, -1);
3824
+ const envVal = process.env[envKey];
3825
+ if (envVal) {
3826
+ console.log(`[token] Resolved gateway token from env: ${envKey}`);
3827
+ return envVal;
3828
+ }
3829
+ console.warn(`[token] Config references env ${envKey} but it is not set`);
3830
+ } else {
3831
+ console.log(`[token] Found gateway token in ${OPENCLAW_CONFIG_PATH}`);
3832
+ return token;
3833
+ }
3834
+ }
3835
+ const mode = config2?.gateway?.auth?.mode;
3836
+ if (mode === "none") {
3837
+ console.log('[token] Gateway auth.mode is "none" \u2014 no token needed');
3838
+ return null;
3839
+ }
3840
+ }
3841
+ } catch (err2) {
3842
+ console.warn(`[token] Failed to read ${OPENCLAW_CONFIG_PATH}: ${err2.message}`);
3843
+ await new Promise((r) => setTimeout(r, 200));
3844
+ try {
3845
+ const raw = import_fs5.default.readFileSync(OPENCLAW_CONFIG_PATH, "utf-8");
3846
+ const config2 = import_json5.default.parse(raw);
3847
+ const token = config2?.gateway?.auth?.token;
3848
+ if (typeof token === "string" && token.length > 0 && !token.startsWith("${")) {
3849
+ console.log(`[token] Found gateway token on retry`);
3850
+ return token;
3851
+ }
3852
+ } catch {
3853
+ }
3854
+ }
3855
+ if (process.env.OPENCLAW_GATEWAY_TOKEN) {
3856
+ console.log("[token] Found gateway token from OPENCLAW_GATEWAY_TOKEN env");
3857
+ return process.env.OPENCLAW_GATEWAY_TOKEN;
3858
+ }
3859
+ console.warn('[token] No gateway token found. If auth.mode is "token", connection will fail.');
3860
+ console.warn(" Options:");
3861
+ console.warn(" a) Set OPENCLAW_GATEWAY_TOKEN env var");
3862
+ console.warn(" b) Run: openclaw config get gateway.auth.token");
3863
+ console.warn(" c) Pass: --gateway-token <token>");
3864
+ return null;
3865
+ }
3866
+
905
3867
  // src/main.ts
906
- var VERSION = "0.2.2";
3868
+ var VERSION = "0.3.0";
907
3869
  function parseArgs() {
908
3870
  const args = process.argv.slice(2);
909
3871
  const opts = {
910
3872
  relayUrl: "wss://relay.echoclaw.me/agent/connect",
911
- bridgeUrl: ""
3873
+ bridgeUrl: "",
912
3874
  // auto-discover if not specified
3875
+ gatewayUrl: "ws://127.0.0.1:18789"
913
3876
  };
914
3877
  for (let i = 0; i < args.length; i++) {
915
3878
  const arg = args[i];
@@ -917,6 +3880,10 @@ function parseArgs() {
917
3880
  opts.code = arg.slice("--code=".length).toUpperCase().trim();
918
3881
  continue;
919
3882
  }
3883
+ if (arg.startsWith("--gateway-token=")) {
3884
+ opts.gatewayToken = arg.slice("--gateway-token=".length).trim();
3885
+ continue;
3886
+ }
920
3887
  switch (arg) {
921
3888
  case "--code":
922
3889
  case "-c":
@@ -930,6 +3897,13 @@ function parseArgs() {
930
3897
  case "-b":
931
3898
  opts.bridgeUrl = args[++i] || opts.bridgeUrl;
932
3899
  break;
3900
+ case "--gateway":
3901
+ case "-g":
3902
+ opts.gatewayUrl = args[++i] || opts.gatewayUrl;
3903
+ break;
3904
+ case "--gateway-token":
3905
+ opts.gatewayToken = args[++i] || void 0;
3906
+ break;
933
3907
  case "--install":
934
3908
  opts.command = "install";
935
3909
  break;
@@ -968,22 +3942,28 @@ function printHelp() {
968
3942
  echoclaw-relay-agent [options]
969
3943
 
970
3944
  OPTIONS
971
- --code, -c <code> Join an existing session by pairing code (e.g. ABC-1234).
972
- If omitted, resumes a saved session or creates a new one.
3945
+ --code, -c <code> Join an existing session by pairing code (e.g. ABC-1234).
3946
+ If omitted, resumes a saved session or creates a new one.
3947
+
3948
+ --relay, -r <url> Relay server WebSocket URL
3949
+ (default: wss://relay.echoclaw.me/agent/connect)
973
3950
 
974
- --relay, -r <url> Relay server WebSocket URL
975
- (default: wss://relay.echoclaw.me/agent/connect)
3951
+ --bridge, -b <url> Local OpenClaw bridge HTTP URL
3952
+ (default: auto-discover on port 8013)
976
3953
 
977
- --bridge, -b <url> Local OpenClaw bridge HTTP URL
978
- (default: auto-discover on port 18789, 8013)
3954
+ --gateway, -g <url> Local OpenClaw Gateway WebSocket URL
3955
+ (default: ws://127.0.0.1:18789)
979
3956
 
980
- --install Install as system service (auto-start on boot)
981
- --restart Restart the system service (repair connection)
982
- --uninstall Remove system service and saved session
983
- --status Show service and connection status
3957
+ --gateway-token <token> Gateway auth token (overrides auto-discovery from
3958
+ ~/.openclaw/openclaw.json)
984
3959
 
985
- --help, -h Show this help message
986
- --version, -v Show version
3960
+ --install Install as system service (auto-start on boot)
3961
+ --restart Restart the system service (repair connection)
3962
+ --uninstall Remove system service and saved session
3963
+ --status Show service and connection status
3964
+
3965
+ --help, -h Show this help message
3966
+ --version, -v Show version
987
3967
 
988
3968
  EXAMPLES
989
3969
  echoclaw-relay-agent --code ABC-1234 # Pair and connect
@@ -992,27 +3972,49 @@ function printHelp() {
992
3972
  echoclaw-relay-agent --status # Check status
993
3973
  echoclaw-relay-agent --uninstall # Remove service
994
3974
 
3975
+ ARCHITECTURE
3976
+ The agent connects two local OpenClaw services to the relay:
3977
+ \u2022 Bridge (HTTP, port 8013) \u2014 app management, file serving
3978
+ \u2022 Gateway (WS-RPC, port 18789) \u2014 chat, conversations, AI
3979
+
995
3980
  SECURITY
996
3981
  All communication is end-to-end encrypted (X25519 + AES-256-GCM).
997
3982
  The relay server cannot read your messages \u2014 it only forwards ciphertext.
3983
+ Gateway auth uses Ed25519 device signatures (keypair in ~/.echoclaw/device.json).
998
3984
  `);
999
3985
  }
1000
- var BRIDGE_PORTS = [18789, 8013];
1001
3986
  async function discoverBridge() {
1002
- for (const port of BRIDGE_PORTS) {
1003
- const url = `http://localhost:${port}`;
1004
- try {
1005
- const res = await fetch(`${url}/health`, {
1006
- signal: AbortSignal.timeout(1500)
1007
- });
1008
- if (res.ok) {
1009
- return url;
1010
- }
1011
- } catch {
1012
- }
3987
+ const url = "http://localhost:8013";
3988
+ try {
3989
+ const res = await fetch(`${url}/health`, {
3990
+ signal: AbortSignal.timeout(1500)
3991
+ });
3992
+ if (res.ok) return url;
3993
+ } catch {
1013
3994
  }
1014
3995
  return null;
1015
3996
  }
3997
+ async function checkGateway(url) {
3998
+ return new Promise((resolve) => {
3999
+ const { URL } = require("url");
4000
+ const parsed = new URL(url);
4001
+ const net = require("net");
4002
+ const socket = net.createConnection(
4003
+ { host: parsed.hostname, port: parseInt(parsed.port || "18789"), timeout: 2e3 },
4004
+ () => {
4005
+ socket.destroy();
4006
+ resolve(true);
4007
+ }
4008
+ );
4009
+ socket.on("error", () => {
4010
+ resolve(false);
4011
+ });
4012
+ socket.on("timeout", () => {
4013
+ socket.destroy();
4014
+ resolve(false);
4015
+ });
4016
+ });
4017
+ }
1016
4018
  function handleInstall() {
1017
4019
  console.log("");
1018
4020
  console.log(" \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510");
@@ -1090,30 +4092,44 @@ async function main() {
1090
4092
  const discovered = await discoverBridge();
1091
4093
  if (discovered) {
1092
4094
  opts.bridgeUrl = discovered;
1093
- console.log(` \u2705 Found OpenClaw bridge at ${discovered}`);
4095
+ console.log(` \u2705 Found OpenClaw Bridge at ${discovered}`);
1094
4096
  } else {
1095
- opts.bridgeUrl = `http://localhost:${BRIDGE_PORTS[0]}`;
1096
- console.warn(` \u26A0\uFE0F Cannot find OpenClaw bridge (tried ports ${BRIDGE_PORTS.join(", ")})`);
1097
- console.warn(" Will retry when messages arrive. Or specify: --bridge http://localhost:<port>");
4097
+ opts.bridgeUrl = "http://localhost:8013";
4098
+ console.warn(" \u26A0\uFE0F Bridge not responding on port 8013");
4099
+ console.warn(" Will retry when HTTP requests arrive.");
1098
4100
  }
4101
+ }
4102
+ console.log("");
4103
+ console.log(" Setting up Gateway connection...");
4104
+ const device = await loadOrCreateDeviceIdentity();
4105
+ console.log(` Device ID: ${device.deviceId.slice(0, 16)}...`);
4106
+ const autoToken = await discoverGatewayToken();
4107
+ const gatewayToken = opts.gatewayToken || autoToken;
4108
+ if (gatewayToken) {
4109
+ console.log(` \u2705 Gateway token: ${opts.gatewayToken ? "CLI override" : "auto-discovered"}`);
1099
4110
  } else {
1100
- try {
1101
- const healthRes = await fetch(`${opts.bridgeUrl}/health`, {
1102
- signal: AbortSignal.timeout(3e3)
1103
- });
1104
- if (healthRes.ok) {
1105
- console.log(` \u2705 Bridge reachable at ${opts.bridgeUrl}`);
1106
- } else {
1107
- console.warn(` \u26A0\uFE0F Bridge returned HTTP ${healthRes.status} \u2014 starting anyway`);
1108
- }
1109
- } catch {
1110
- console.warn(` \u26A0\uFE0F Cannot reach ${opts.bridgeUrl} \u2014 will retry when messages arrive`);
1111
- }
4111
+ console.warn(" \u26A0\uFE0F No gateway token found \u2014 Gateway auth may fail");
4112
+ console.warn(" Set OPENCLAW_GATEWAY_TOKEN or use --gateway-token");
4113
+ }
4114
+ const gatewayUp = await checkGateway(opts.gatewayUrl);
4115
+ if (gatewayUp) {
4116
+ console.log(` \u2705 Gateway reachable at ${opts.gatewayUrl}`);
4117
+ } else {
4118
+ console.warn(` \u26A0\uFE0F Gateway not responding at ${opts.gatewayUrl}`);
4119
+ console.warn(" Will keep retrying in background.");
1112
4120
  }
1113
- console.log(` Relay: ${opts.relayUrl}`);
1114
- console.log(` Bridge: ${opts.bridgeUrl}`);
4121
+ const gatewayConfig = {
4122
+ gatewayUrl: opts.gatewayUrl,
4123
+ device,
4124
+ gatewayToken,
4125
+ manualToken: opts.gatewayToken || void 0
4126
+ };
4127
+ console.log("");
4128
+ console.log(` Relay: ${opts.relayUrl}`);
4129
+ console.log(` Bridge: ${opts.bridgeUrl}`);
4130
+ console.log(` Gateway: ${opts.gatewayUrl}`);
1115
4131
  if (opts.code) {
1116
- console.log(` Code: ${opts.code} (joining existing session)`);
4132
+ console.log(` Code: ${opts.code} (joining existing session)`);
1117
4133
  }
1118
4134
  console.log("");
1119
4135
  let relayUrl = opts.relayUrl;
@@ -1131,7 +4147,6 @@ async function main() {
1131
4147
  console.log("");
1132
4148
  resumeSessionKey = saved.sessionKey;
1133
4149
  resumeSessionId = saved.sessionId;
1134
- relayUrl = opts.relayUrl;
1135
4150
  }
1136
4151
  }
1137
4152
  if (opts.installAfterPairing) {
@@ -1140,8 +4155,8 @@ async function main() {
1140
4155
  console.log("[relay-agent] Pairing successful \u2014 installing system service...");
1141
4156
  try {
1142
4157
  installService();
1143
- } catch (err) {
1144
- console.error("[relay-agent] Service install failed:", err.message);
4158
+ } catch (err2) {
4159
+ console.error("[relay-agent] Service install failed:", err2.message);
1145
4160
  }
1146
4161
  });
1147
4162
  }
@@ -1149,7 +4164,8 @@ async function main() {
1149
4164
  relayUrl,
1150
4165
  bridgeUrl: opts.bridgeUrl,
1151
4166
  sessionId: resumeSessionId,
1152
- resumeSessionKey
4167
+ resumeSessionKey,
4168
+ gatewayConfig
1153
4169
  });
1154
4170
  }
1155
4171
  process.on("SIGINT", () => {
@@ -1162,7 +4178,15 @@ process.on("SIGTERM", () => {
1162
4178
  stopRelayClient();
1163
4179
  process.exit(0);
1164
4180
  });
1165
- main().catch((err) => {
1166
- console.error("[relay-agent] Fatal error:", err);
4181
+ main().catch((err2) => {
4182
+ console.error("[relay-agent] Fatal error:", err2);
1167
4183
  process.exit(1);
1168
4184
  });
4185
+ /*! Bundled license information:
4186
+
4187
+ @noble/ed25519/index.js:
4188
+ (*! noble-ed25519 - MIT License (c) 2019 Paul Miller (paulmillr.com) *)
4189
+
4190
+ @noble/hashes/esm/utils.js:
4191
+ (*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
4192
+ */