@peac/adapter-openclaw 0.10.12 → 0.10.14

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts","../src/mapper.ts","../src/hooks.ts","../src/emitter.ts","../src/plugin.ts","../src/tools.ts","../src/activate.ts","../src/keygen.ts"],"names":["canonicalize","toInteractionEvidence","base64urlDecode","sign","fs","createHasher","createCaptureSession","path","createFsSpoolStore","createFsDedupeIndex","getFsSpoolDiagnostics","generateKeypair","base64urlEncode","fs2","path2"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmPO,IAAM,uBAAA,GAA0B;AAAA;AAAA,EAErC,OAAA,EAAS,sBAAA;AAAA;AAAA,EAGT,YAAA,EAAc;AAChB;AAsBO,IAAM,oBAAA,GAAuB;AAAA;AAAA,EAElC,aAAA,EAAe,0BAAA;AAAA;AAAA,EAGf,aAAA,EAAe,0BAAA;AAAA;AAAA,EAGf,oBAAA,EAAsB,iCAAA;AAAA;AAAA,EAGtB,cAAA,EAAgB,2BAAA;AAAA;AAAA,EAGhB,sBAAA,EAAwB;AAC1B;AAWO,IAAM,sBAAA,GAAyB;AAAA;AAAA,EAEpC,iBAAA,EAAmB,8BAAA;AAAA;AAAA,EAGnB,oBAAA,EAAsB,iCAAA;AAAA;AAAA,EAGtB,sBAAA,EAAwB,mCAAA;AAAA;AAAA,EAGxB,gBAAA,EAAkB,6BAAA;AAAA;AAAA,EAGlB,gBAAA,EAAkB;AACpB;ACnSA,IAAM,gBAAA,GAAmB,UAAA;AACzB,IAAM,YAAA,GAAe,WAAA;AAad,SAAS,gBAAA,CACd,OACA,MAAA,EACe;AACf,EAAA,MAAM,WAA6B,EAAC;AAGpC,EAAA,MAAM,eAAA,GAAkB,uBAAuB,KAAK,CAAA;AACpD,EAAA,IAAI,eAAA,EAAiB;AACnB,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,KAAA;AAAA,MACT,YAAY,eAAA,CAAgB,IAAA;AAAA,MAC5B,eAAe,eAAA,CAAgB;AAAA,KACjC;AAAA,EACF;AAGA,EAAA,MAAM,aAAA,GAAgB,mBAAmB,KAAK,CAAA;AAG9C,EAAA,MAAM,WAAA,GAAc,MAAA,EAAQ,OAAA,EAAS,IAAA,IAAQ,WAAA;AAC7C,EAAA,MAAM,SAAA,GAAY,MAAA,EAAQ,OAAA,EAAS,SAAA,IAAa,EAAC;AACjD,EAAA,MAAM,cAAA,GAAiB,MAAA,EAAQ,OAAA,EAAS,gBAAA,IAAoB,IAAA,GAAO,IAAA;AAGnE,EAAA,MAAM,gBAAgB,WAAA,KAAgB,WAAA,IAAe,SAAA,CAAU,QAAA,CAAS,MAAM,SAAS,CAAA;AAGvF,EAAA,MAAM,WAAA,GAAc,0BAAA;AAAA,IAClB,KAAA,CAAM,KAAA;AAAA,IACN,cAAA;AAAA,IACA,aAAA;AAAA,IACA;AAAA,GACF;AACA,EAAA,MAAM,YAAA,GACJ,KAAA,CAAM,MAAA,KAAW,MAAA,GACb,0BAAA,CAA2B,MAAM,MAAA,EAAQ,cAAA,EAAgB,aAAA,EAAe,QAAQ,CAAA,GAChF,MAAA;AAGN,EAAA,IAAI,YAAY,OAAA,EAAS;AACvB,IAAA,QAAA,CAAS,IAAA,CAAK,YAAY,OAAO,CAAA;AAAA,EACnC;AACA,EAAA,IAAI,cAAc,OAAA,EAAS;AACzB,IAAA,QAAA,CAAS,IAAA,CAAK,aAAa,OAAO,CAAA;AAAA,EACpC;AAEA,EAAA,MAAM,aAAa,WAAA,CAAY,KAAA;AAC/B,EAAA,MAAM,cAAc,YAAA,EAAc,KAAA;AAGlC,EAAA,MAAM,QAAA,GAAW,QAAQ,QAAA,IAAY,gBAAA;AACrC,EAAA,MAAM,kBAAkB,MAAA,EAAQ,gBAAA;AAChC,EAAA,MAAM,WAAW,MAAA,EAAQ,SAAA;AAGzB,EAAA,MAAM,UAAA,GAAa,gBAAgB,KAAK,CAAA;AAGxC,EAAA,MAAM,MAAA,GAAyB;AAAA,IAC7B,EAAA,EAAI,aAAA;AAAA,IACJ,IAAA,EAAM,YAAA;AAAA,IACN,QAAA;AAAA,IACA,YAAY,KAAA,CAAM,UAAA;AAAA,IAClB,cAAc,KAAA,CAAM,YAAA;AAAA,IACpB,WAAW,KAAA,CAAM,SAAA;AAAA,IACjB,eAAe,KAAA,CAAM,aAAA;AAAA,IACrB,WAAA,EAAa,UAAA;AAAA,IACb,YAAA,EAAc,WAAA;AAAA,IACd,QAAQ,KAAA,CAAM,MAAA;AAAA,IACd,YAAY,KAAA,CAAM,UAAA;AAAA,IAClB,WAAW,KAAA,CAAM,SAAA;AAAA,IACjB,QAAA,EAAU;AAAA;AAAA,MAER,GAAI,eAAA,IAAmB,EAAE,gBAAA,EAAkB,eAAA,EAAgB;AAAA,MAC3D,GAAI,QAAA,IAAY,EAAE,SAAA,EAAW,QAAA,EAAS;AAAA;AAAA,MAGtC,GAAI,KAAA,CAAM,YAAA,IAAgB,EAAE,YAAA,EAAc,MAAM,YAAA,EAAa;AAAA;AAAA,MAG7D,GAAI,MAAM,MAAA,IAAU;AAAA,QAClB,eAAA,EAAiB,MAAM,MAAA,CAAO,QAAA;AAAA,QAC9B,eAAA,EAAiB,MAAM,MAAA,CAAO,eAAA;AAAA,QAC9B,QAAA,EAAU,MAAM,MAAA,CAAO,QAAA;AAAA,QACvB,WAAA,EAAa,MAAM,MAAA,CAAO;AAAA,OAC5B;AAAA;AAAA,MAGA,GAAG;AAAA;AACL,GACF;AAEA,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,IAAA;AAAA,IACT,MAAA;AAAA,IACA,QAAA,EAAU,QAAA,CAAS,MAAA,GAAS,CAAA,GAAI,QAAA,GAAW;AAAA,GAC7C;AACF;AASO,SAAS,qBAAA,CACd,QACA,MAAA,EACiB;AACjB,EAAA,OAAO,OAAO,GAAA,CAAI,CAAC,UAAU,gBAAA,CAAiB,KAAA,EAAO,MAAM,CAAC,CAAA;AAC9D;AASA,SAAS,uBACP,KAAA,EAC0C;AAC1C,EAAA,IAAI,CAAC,MAAM,YAAA,EAAc;AACvB,IAAA,OAAO;AAAA,MACL,MAAM,oBAAA,CAAqB,aAAA;AAAA,MAC3B,OAAA,EAAS;AAAA,KACX;AAAA,EACF;AAEA,EAAA,IAAI,CAAC,MAAM,MAAA,EAAQ;AACjB,IAAA,OAAO;AAAA,MACL,MAAM,oBAAA,CAAqB,aAAA;AAAA,MAC3B,OAAA,EAAS;AAAA,KACX;AAAA,EACF;AAEA,EAAA,IAAI,CAAC,MAAM,SAAA,EAAW;AACpB,IAAA,OAAO;AAAA,MACL,MAAM,oBAAA,CAAqB,aAAA;AAAA,MAC3B,OAAA,EAAS;AAAA,KACX;AAAA,EACF;AAEA,EAAA,IAAI,CAAC,MAAM,UAAA,EAAY;AACrB,IAAA,OAAO;AAAA,MACL,MAAM,oBAAA,CAAqB,aAAA;AAAA,MAC3B,OAAA,EAAS;AAAA,KACX;AAAA,EACF;AAEA,EAAA,IAAI,CAAC,MAAM,MAAA,EAAQ;AACjB,IAAA,OAAO;AAAA,MACL,MAAM,oBAAA,CAAqB,aAAA;AAAA,MAC3B,OAAA,EAAS;AAAA,KACX;AAAA,EACF;AAGA,EAAA,MAAM,aAAA,GAAgB,CAAC,IAAA,EAAM,OAAA,EAAS,WAAW,UAAU,CAAA;AAC3D,EAAA,IAAI,CAAC,aAAA,CAAc,QAAA,CAAS,KAAA,CAAM,MAAM,CAAA,EAAG;AACzC,IAAA,OAAO;AAAA,MACL,MAAM,oBAAA,CAAqB,aAAA;AAAA,MAC3B,OAAA,EAAS,mBAAmB,KAAA,CAAM,MAAM,sBAAsB,aAAA,CAAc,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,KACxF;AAAA,EACF;AAGA,EAAA,IAAI,CAAC,cAAA,CAAe,KAAA,CAAM,UAAU,CAAA,EAAG;AACrC,IAAA,OAAO;AAAA,MACL,MAAM,oBAAA,CAAqB,aAAA;AAAA,MAC3B,OAAA,EAAS,CAAA,8BAAA,EAAiC,KAAA,CAAM,UAAU,CAAA,2BAAA;AAAA,KAC5D;AAAA,EACF;AAEA,EAAA,IAAI,MAAM,YAAA,IAAgB,CAAC,cAAA,CAAe,KAAA,CAAM,YAAY,CAAA,EAAG;AAC7D,IAAA,OAAO;AAAA,MACL,MAAM,oBAAA,CAAqB,aAAA;AAAA,MAC3B,OAAA,EAAS,CAAA,gCAAA,EAAmC,KAAA,CAAM,YAAY,CAAA,2BAAA;AAAA,KAChE;AAAA,EACF;AAEA,EAAA,OAAO,IAAA;AACT;AAUA,SAAS,mBAAmB,KAAA,EAAsC;AAChE,EAAA,MAAM,YAAA,GAAe,eAAA,CAAgB,KAAA,CAAM,MAAM,CAAA;AACjD,EAAA,MAAM,iBAAA,GAAoB,eAAA,CAAgB,KAAA,CAAM,YAAY,CAAA;AAC5D,EAAA,OAAO,CAAA,SAAA,EAAY,YAAY,CAAA,CAAA,EAAI,iBAAiB,CAAA,CAAA;AACtD;AAMA,SAAS,gBAAgB,GAAA,EAAqB;AAE5C,EAAA,MAAM,KAAA,GAAQ,IAAI,WAAA,EAAY,CAAE,OAAO,GAAG,CAAA;AAE1C,EAAA,MAAM,SAAS,IAAA,CAAK,MAAA,CAAO,YAAA,CAAa,GAAG,KAAK,CAAC,CAAA;AAEjD,EAAA,OAAO,MAAA,CAAO,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA,CAAE,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA,CAAE,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA;AACzE;AAwBA,SAAS,0BAAA,CACP,OAAA,EACA,cAAA,EACA,aAAA,EACA,SAAA,EACqB;AACrB,EAAA,IAAI,YAAY,MAAA,EAAW;AACzB,IAAA,OAAO,EAAC;AAAA,EACV;AAIA,EAAA,IAAI,KAAA;AACJ,EAAA,IAAI;AACF,IAAA,MAAM,IAAA,GAAOA,oBAAa,OAAO,CAAA;AACjC,IAAA,KAAA,GAAQ,IAAI,WAAA,EAAY,CAAE,MAAA,CAAO,IAAI,CAAA;AAAA,EACvC,CAAA,CAAA,MAAQ;AAEN,IAAA,OAAO;AAAA,MACL,OAAA,EAAS;AAAA,QACP,MAAM,sBAAA,CAAuB,oBAAA;AAAA,QAC7B,OAAA,EAAS,GAAG,SAAS,CAAA,6DAAA,CAAA;AAAA,QACrB,KAAA,EAAO;AAAA;AACT,KACF;AAAA,EACF;AAGA,EAAA,IAAI,SAAA,GAAY,KAAA;AAChB,EAAA,IAAI,KAAA,CAAM,SAAS,cAAA,EAAgB;AACjC,IAAA,KAAA,GAAQ,KAAA,CAAM,KAAA,CAAM,CAAA,EAAG,cAAc,CAAA;AACrC,IAAA,SAAA,GAAY,IAAA;AAAA,EACd;AAKA,EAAA,MAAM,MAAA,GAA8B,EAAE,KAAA,EAAO,SAAA,EAAU;AAEvD,EAAA,IAAI,SAAA,EAAW;AACb,IAAA,MAAA,CAAO,OAAA,GAAU;AAAA,MACf,MAAM,sBAAA,CAAuB,iBAAA;AAAA,MAC7B,OAAA,EAAS,CAAA,EAAG,SAAS,CAAA,kBAAA,EAAqB,cAAc,CAAA,wBAAA,CAAA;AAAA,MACxD,KAAA,EAAO;AAAA,KACT;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT;AAKA,SAAS,gBAAgB,KAAA,EAAuD;AAC9E,EAAA,MAAM,aAAsC,EAAC;AAG7C,EAAA,IAAI,MAAM,OAAA,EAAS;AACjB,IAAA,MAAM,UAAA,GAAuC;AAAA,MAC3C,GAAI,MAAM,OAAA,CAAQ,OAAA,IAAW,EAAE,OAAA,EAAS,KAAA,CAAM,QAAQ,OAAA,EAAQ;AAAA,MAC9D,GAAI,MAAM,OAAA,CAAQ,gBAAA,IAAoB,EAAE,gBAAA,EAAkB,KAAA,CAAM,QAAQ,gBAAA,EAAiB;AAAA,MACzF,GAAI,MAAM,OAAA,CAAQ,eAAA,IAAmB,EAAE,eAAA,EAAiB,KAAA,CAAM,QAAQ,eAAA,EAAgB;AAAA,MACtF,cAAc,KAAA,CAAM;AAAA,KACtB;AAEA,IAAA,IAAI,MAAA,CAAO,IAAA,CAAK,UAAU,CAAA,CAAE,SAAS,CAAA,EAAG;AACtC,MAAA,UAAA,CAAW,uBAAA,CAAwB,OAAO,CAAA,GAAI,UAAA;AAAA,IAChD;AAAA,EACF,CAAA,MAAO;AAEL,IAAA,UAAA,CAAW,uBAAA,CAAwB,OAAO,CAAA,GAAI;AAAA,MAC5C,cAAc,KAAA,CAAM;AAAA,KACtB;AAAA,EACF;AAGA,EAAA,IAAI,KAAA,CAAM,SAAS,YAAA,EAAc;AAC/B,IAAA,UAAA,CAAW,uBAAA,CAAwB,YAAY,CAAA,GAAI,KAAA,CAAM,OAAA,CAAQ,YAAA;AAAA,EACnE;AAEA,EAAA,OAAO,UAAA;AACT;AAKA,SAAS,eAAe,SAAA,EAA4B;AAElD,EAAA,MAAM,cAAA,GAAiB,kEAAA;AACvB,EAAA,IAAI,CAAC,cAAA,CAAe,IAAA,CAAK,SAAS,CAAA,EAAG;AACnC,IAAA,OAAO,KAAA;AAAA,EACT;AAGA,EAAA,MAAM,IAAA,GAAO,IAAI,IAAA,CAAK,SAAS,CAAA;AAC/B,EAAA,OAAO,CAAC,KAAA,CAAM,IAAA,CAAK,OAAA,EAAS,CAAA;AAC9B;AAWO,SAAS,kBAAkB,KAAA,EAAkD;AAClF,EAAA,OAAO,KAAA,CAAM,WAAA;AACf;AAKO,SAAS,qBACd,KAAA,EACqC;AACrC,EAAA,IAAI,CAAC,MAAM,WAAA,EAAa;AACtB,IAAA,OAAO,MAAA;AAAA,EACT;AAEA,EAAA,OAAO;AAAA,IACL,aAAa,KAAA,CAAM,WAAA;AAAA,IACnB,SAAS,KAAA,CAAM,YAAA;AAAA,IACf,WAAW,KAAA,CAAM,SAAA;AAAA,IACjB,SAAA,EAAW;AAAA,GACb;AACF;;;ACzUO,SAAS,kBAAkB,aAAA,EAAuD;AACvF,EAAA,MAAM,EAAE,OAAA,EAAS,MAAA,EAAQ,SAAA,EAAW,gBAAe,GAAI,aAAA;AAEvD,EAAA,OAAO;AAAA,IACL,MAAM,cAAc,KAAA,EAA0D;AAE5E,MAAA,MAAM,aAAA,GAAgB,gBAAA,CAAiB,KAAA,EAAO,MAAM,CAAA;AAEpD,MAAA,IAAI,CAAC,aAAA,CAAc,OAAA,IAAW,CAAC,cAAc,MAAA,EAAQ;AAEnD,QAAA,IAAI,cAAA,EAAgB;AAClB,UAAA,cAAA,CAAe,eAAe,KAAK,CAAA;AAAA,QACrC;AAEA,QAAA,OAAO;AAAA,UACL,OAAA,EAAS,KAAA;AAAA,UACT,IAAA,EAAM,cAAc,UAAA,IAAc,2BAAA;AAAA,UAClC,OAAA,EAAS,cAAc,aAAA,IAAiB;AAAA,SAC1C;AAAA,MACF;AAGA,MAAA,MAAM,aAAA,GAAgB,MAAM,OAAA,CAAQ,OAAA,CAAQ,cAAc,MAAM,CAAA;AAGhE,MAAA,MAAM,aAAgC,aAAA,CAAc,OAAA,GAChD,EAAE,OAAA,EAAS,IAAA,EAAM,OAAO,aAAA,CAAc,KAAA,EAAM,GAC5C,EAAE,SAAS,KAAA,EAAO,IAAA,EAAM,cAAc,IAAA,EAAM,OAAA,EAAS,cAAc,OAAA,EAAQ;AAG/E,MAAA,IAAI,SAAA,EAAW;AACb,QAAA,SAAA,CAAU,YAAY,KAAK,CAAA;AAAA,MAC7B;AAEA,MAAA,OAAO,UAAA;AAAA,IACT,CAAA;AAAA,IAEA,UAAA,GAA6B;AAC3B,MAAA,OAAO,OAAA;AAAA,IACT,CAAA;AAAA,IAEA,MAAM,KAAA,GAAuB;AAC3B,MAAA,MAAM,QAAQ,KAAA,EAAM;AAAA,IACtB;AAAA,GACF;AACF;AAgBA,eAAsB,YAAA,CACpB,SACA,MAAA,EAC8B;AAC9B,EAAA,MAAM,UAA+B,EAAC;AAEtC,EAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,IAAA,MAAM,MAAA,GAAS,MAAM,OAAA,CAAQ,aAAA,CAAc,KAAK,CAAA;AAChD,IAAA,OAAA,CAAQ,KAAK,MAAM,CAAA;AAAA,EACrB;AAEA,EAAA,OAAO,OAAA;AACT;AAYA,eAAsB,eAAA,CACpB,SACA,MAAA,EAC8B;AAC9B,EAAA,OAAO,OAAA,CAAQ,GAAA,CAAI,MAAA,CAAO,GAAA,CAAI,CAAC,UAAU,OAAA,CAAQ,aAAA,CAAc,KAAK,CAAC,CAAC,CAAA;AACxE;AAoDO,SAAS,2BAA2B,YAAA,EAAkD;AAC3F,EAAA,MAAM,EAAE,OAAA,EAAS,SAAA,EAAW,iBAAiB,GAAA,EAAM,YAAA,EAAc,SAAQ,GAAI,YAAA;AAE7E,EAAA,IAAI,OAAA,GAAU,KAAA;AACd,EAAA,IAAI,QAAA,GAAW,KAAA;AACf,EAAA,IAAI,WAAA;AACJ,EAAA,IAAI,cAAA;AAEJ,EAAA,MAAM,OAAO,YAAY;AAGvB,IAAA,IAAI,QAAA,EAAU;AAEd,IAAA,QAAA,GAAW,IAAA;AACX,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,YAAA,CAAa,SAAA,EAAW,WAAW,CAAA;AAExD,MAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAE1B,QAAA,IAAI,CAAC,OAAA,EAAS;AAEd,QAAA,MAAM,OAAA,CAAQ,cAAc,KAAK,CAAA;AACjC,QAAA,WAAA,GAAc,KAAA,CAAM,YAAA;AAAA,MACtB;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,IAAI,OAAA,EAAS;AACX,QAAA,OAAA,CAAQ,KAAA,YAAiB,QAAQ,KAAA,GAAQ,IAAI,MAAM,MAAA,CAAO,KAAK,CAAC,CAAC,CAAA;AAAA,MACnE;AAAA,IACF,CAAA,SAAE;AACA,MAAA,QAAA,GAAW,KAAA;AAAA,IACb;AAAA,EACF,CAAA;AAEA,EAAA,OAAO;AAAA,IACL,KAAA,GAAc;AACZ,MAAA,IAAI,OAAA,EAAS;AACb,MAAA,OAAA,GAAU,IAAA;AACV,MAAA,cAAA,GAAiB,WAAA,CAAY,MAAM,cAAc,CAAA;AAEjD,MAAA,IAAA,EAAK;AAAA,IACP,CAAA;AAAA,IAEA,IAAA,GAAa;AACX,MAAA,IAAI,CAAC,OAAA,EAAS;AACd,MAAA,OAAA,GAAU,KAAA;AACV,MAAA,IAAI,cAAA,EAAgB;AAClB,QAAA,aAAA,CAAc,cAAc,CAAA;AAC5B,QAAA,cAAA,GAAiB,MAAA;AAAA,MACnB;AAAA,IACF,CAAA;AAAA,IAEA,cAAA,GAAqC;AACnC,MAAA,OAAO,WAAA;AAAA,IACT,CAAA;AAAA,IAEA,SAAA,GAAqB;AACnB,MAAA,OAAO,OAAA;AAAA,IACT;AAAA,GACF;AACF;ACjKO,SAAS,qBAAqB,aAAA,EAA8C;AACjF,EAAA,MAAM,EAAE,MAAA,EAAQ,MAAA,EAAQ,MAAA,EAAQ,SAAQ,GAAI,aAAA;AAE5C,EAAA,IAAI,MAAA,GAAS,KAAA;AAEb,EAAA,OAAO;AAAA,IACL,MAAM,KAAK,KAAA,EAAwC;AACjD,MAAA,IAAI,MAAA,EAAQ;AACV,QAAA,OAAO;AAAA,UACL,OAAA,EAAS,KAAA;AAAA,UACT,UAAA,EAAY,kBAAA;AAAA,UACZ,aAAA,EAAe;AAAA,SACjB;AAAA,MACF;AAEA,MAAA,IAAI;AAGF,QAAA,MAAM,WAAA,GAAcC,kCAAsB,KAAK,CAAA;AAG/C,QAAA,MAAM,cAAA,GAAiB,mBAAA,CAAoB,WAAA,EAAa,KAAA,EAAO,MAAM,CAAA;AAGrE,QAAA,MAAM,GAAA,GAAM,MAAM,MAAA,CAAO,IAAA,CAAK,cAAc,CAAA;AAG5C,QAAA,MAAM,aAAA,GAA+B;AAAA,UACnC,KAAK,cAAA,CAAe,GAAA;AAAA,UACpB,GAAA;AAAA,UACA,cAAA,EAAgB,MAAM,MAAA,CAAO,EAAA;AAAA,UAC7B,cAAc,KAAA,CAAM;AAAA,SACtB;AAGA,QAAA,MAAM,WAAA,GAAc,MAAM,MAAA,CAAO,KAAA,CAAM,aAAa,CAAA;AAEpD,QAAA,MAAM,MAAA,GAAqB;AAAA,UACzB,OAAA,EAAS,IAAA;AAAA,UACT,YAAA,EAAc,WAAA;AAAA,UACd,YAAY,cAAA,CAAe;AAAA,SAC7B;AAEA,QAAA,IAAI,MAAA,EAAQ;AACV,UAAA,MAAA,CAAO,QAAQ,KAAK,CAAA;AAAA,QACtB;AAEA,QAAA,OAAO,MAAA;AAAA,MACT,SAAS,KAAA,EAAO;AACd,QAAA,MAAM,eAAe,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AAE1E,QAAA,IAAI,OAAA,EAAS;AACX,UAAA,OAAA,CAAQ,iBAAiB,KAAA,GAAQ,KAAA,GAAQ,IAAI,KAAA,CAAM,YAAY,GAAG,KAAK,CAAA;AAAA,QACzE;AAEA,QAAA,OAAO;AAAA,UACL,OAAA,EAAS,KAAA;AAAA,UACT,YAAY,oBAAA,CAAqB,cAAA;AAAA,UACjC,aAAA,EAAe,2BAA2B,YAAY,CAAA;AAAA,SACxD;AAAA,MACF;AAAA,IACF,CAAA;AAAA,IAEA,MAAM,KAAA,GAAuB;AAAA,IAG7B,CAAA;AAAA,IAEA,MAAM,KAAA,GAAuB;AAC3B,MAAA,MAAA,GAAS,IAAA;AACT,MAAA,MAAM,OAAO,KAAA,EAAM;AAAA,IACrB;AAAA,GACF;AACF;AAiCA,SAAS,mBAAA,CACP,WAAA,EACA,KAAA,EACA,MAAA,EACgB;AAChB,EAAA,MAAM,MAAM,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,GAAA,KAAQ,GAAI,CAAA;AACxC,EAAA,MAAM,GAAA,GAAM,iBAAA,CAAkB,KAAA,CAAM,YAAY,CAAA;AAEhD,EAAA,MAAM,OAAA,GAA0B;AAAA,IAC9B,GAAA,EAAK,OAAO,SAAA,EAAU;AAAA,IACtB,GAAA,EAAK,GAAA;AAAA,IACL,GAAA;AAAA,IACA,QAAA,EAAU;AAAA,MACR,UAAA,EAAY;AAAA,QACV,kCAAA,EAAoC;AAAA;AACtC;AACF,GACF;AAEA,EAAA,MAAM,QAAA,GAAW,OAAO,WAAA,EAAY;AACpC,EAAA,IAAI,QAAA,EAAU;AACZ,IAAA,OAAA,CAAQ,GAAA,GAAM,QAAA;AAAA,EAChB;AAEA,EAAA,OAAO,OAAA;AACT;AAYA,SAAS,kBAAkB,WAAA,EAA6B;AAGtD,EAAA,OAAO,CAAA,EAAA,EAAK,WAAA,CAAY,KAAA,CAAM,CAAA,EAAG,EAAE,CAAC,CAAA,CAAA;AACtC;AAqEO,SAAS,wBACd,aAAA,EAC0B;AAC1B,EAAA,MAAM;AAAA,IACJ,OAAA;AAAA,IACA,iBAAA;AAAA,IACA,WAAA;AAAA,IACA,eAAA,GAAkB,GAAA;AAAA,IAClB;AAAA,GACF,GAAI,aAAA;AAEJ,EAAA,IAAI,OAAA,GAAU,KAAA;AACd,EAAA,IAAI,QAAA,GAAW,KAAA;AACf,EAAA,IAAI,QAAA,GAAW,KAAA;AACf,EAAA,IAAI,cAAA;AACJ,EAAA,MAAM,KAAA,GAAsB;AAAA,IAC1B,OAAA,EAAS,CAAA;AAAA,IACT,MAAA,EAAQ;AAAA,GACV;AAEA,EAAA,MAAM,YAAY,YAAY;AAG5B,IAAA,IAAI,QAAA,EAAU;AAEd,IAAA,QAAA,GAAW,IAAA;AACX,IAAA,IAAI;AACF,MAAA,MAAM,OAAA,GAAU,MAAM,iBAAA,EAAkB;AAExC,MAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAE3B,QAAA,IAAI,QAAA,EAAU;AAEd,QAAA,MAAM,MAAA,GAAS,MAAM,OAAA,CAAQ,IAAA,CAAK,KAAK,CAAA;AAEvC,QAAA,IAAI,OAAO,OAAA,EAAS;AAClB,UAAA,MAAM,WAAA,CAAY,MAAM,YAAY,CAAA;AACpC,UAAA,KAAA,CAAM,OAAA,EAAA;AACN,UAAA,KAAA,CAAM,YAAA,uBAAmB,IAAA,EAAK;AAAA,QAChC,CAAA,MAAO;AACL,UAAA,KAAA,CAAM,MAAA,EAAA;AACN,UAAA,KAAA,CAAM,YAAY,MAAA,CAAO,aAAA;AAAA,QAC3B;AAAA,MACF;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,KAAA,CAAM,YAAY,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AACvE,MAAA,IAAI,OAAA,EAAS;AACX,QAAA,OAAA,CAAQ,KAAA,YAAiB,QAAQ,KAAA,GAAQ,IAAI,MAAM,MAAA,CAAO,KAAK,CAAC,CAAC,CAAA;AAAA,MACnE;AAAA,IACF,CAAA,SAAE;AACA,MAAA,QAAA,GAAW,KAAA;AAAA,IACb;AAAA,EACF,CAAA;AAEA,EAAA,OAAO;AAAA,IACL,KAAA,GAAc;AACZ,MAAA,IAAI,OAAA,EAAS;AACb,MAAA,OAAA,GAAU,IAAA;AACV,MAAA,cAAA,GAAiB,WAAA,CAAY,WAAW,eAAe,CAAA;AAEvD,MAAA,SAAA,EAAU;AAAA,IACZ,CAAA;AAAA,IAEA,IAAA,GAAa;AACX,MAAA,IAAI,CAAC,OAAA,EAAS;AACd,MAAA,QAAA,GAAW,IAAA;AACX,MAAA,OAAA,GAAU,KAAA;AACV,MAAA,IAAI,cAAA,EAAgB;AAClB,QAAA,aAAA,CAAc,cAAc,CAAA;AAC5B,QAAA,cAAA,GAAiB,MAAA;AAAA,MACnB;AAAA,IACF,CAAA;AAAA,IAEA,MAAM,KAAA,GAAuB;AAC3B,MAAA,MAAM,SAAA,EAAU;AAAA,IAClB,CAAA;AAAA,IAEA,SAAA,GAAqB;AACnB,MAAA,OAAO,OAAA;AAAA,IACT,CAAA;AAAA,IAEA,QAAA,GAAyB;AACvB,MAAA,OAAO,EAAE,GAAG,KAAA,EAAM;AAAA,IACpB;AAAA,GACF;AACF;AC1PO,SAAS,eAAA,CAAgB,GAAA,EAAU,MAAA,EAAgB,QAAA,EAA2B;AACnF,EAAA,MAAM,GAAA,GAAM,GAAA,CAAI,GAAA,IAAO,aAAA,CAAc,GAAG,CAAA;AAGxC,EAAA,IAAI,CAAC,IAAI,CAAA,EAAG;AACV,IAAA,MAAM,IAAI,MAAM,4CAA4C,CAAA;AAAA,EAC9D;AAGA,EAAA,MAAM,eAAA,GAAkBC,sBAAA,CAAgB,GAAA,CAAI,CAAC,CAAA;AAE7C,EAAA,OAAO;AAAA,IACL,MAAM,KAAK,OAAA,EAAmC;AAC5C,MAAA,OAAOC,WAAA,CAAK,OAAA,EAAS,eAAA,EAAiB,GAAG,CAAA;AAAA,IAC3C,CAAA;AAAA,IAEA,QAAA,GAAmB;AACjB,MAAA,OAAO,GAAA;AAAA,IACT,CAAA;AAAA,IAEA,SAAA,GAAoB;AAClB,MAAA,OAAO,MAAA;AAAA,IACT,CAAA;AAAA,IAEA,WAAA,GAAkC;AAChC,MAAA,OAAO,QAAA;AAAA,IACT;AAAA,GACF;AACF;AAcA,eAAsB,aAAA,CACpB,MAAA,EACA,MAAA,EACA,QAAA,EACiB;AACjB,EAAA,MAAM,UAAA,GAAa,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAA;AACrC,EAAA,IAAI,eAAe,EAAA,EAAI;AACrB,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,8BAAA,EAAiC,MAAM,CAAA,uBAAA,CAAyB,CAAA;AAAA,EAClF;AAEA,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,UAAU,CAAA;AACzC,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,KAAA,CAAM,UAAA,GAAa,CAAC,CAAA;AAEzC,EAAA,QAAQ,MAAA;AAAQ,IACd,KAAK,KAAA,EAAO;AACV,MAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,GAAA,CAAI,KAAK,CAAA;AACjC,MAAA,IAAI,CAAC,OAAA,EAAS;AACZ,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,qBAAA,EAAwB,KAAK,CAAA,wBAAA,CAA0B,CAAA;AAAA,MACzE;AACA,MAAA,MAAM,GAAA,GAAM,IAAA,CAAK,KAAA,CAAM,OAAO,CAAA;AAC9B,MAAA,OAAO,eAAA,CAAgB,GAAA,EAAK,MAAA,EAAQ,QAAQ,CAAA;AAAA,IAC9C;AAAA,IAEA,KAAK,MAAA,EAAQ;AACX,MAAA,MAAMC,GAAAA,GAAK,MAAM,OAAO,IAAI,CAAA;AAC5B,MAAA,MAAM,UAAU,MAAMA,GAAAA,CAAG,QAAA,CAAS,QAAA,CAAS,OAAO,OAAO,CAAA;AACzD,MAAA,MAAM,GAAA,GAAM,IAAA,CAAK,KAAA,CAAM,OAAO,CAAA;AAC9B,MAAA,OAAO,eAAA,CAAgB,GAAA,EAAK,MAAA,EAAQ,QAAQ,CAAA;AAAA,IAC9C;AAAA,IAEA,KAAK,UAAA;AACH,MAAA,MAAM,IAAI,MAAM,iEAAiE,CAAA;AAAA,IAEnF,KAAK,SAAA;AACH,MAAA,MAAM,IAAI,MAAM,gEAAgE,CAAA;AAAA,IAElF;AACE,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,8BAAA,EAAiC,MAAM,CAAA,mBAAA,CAAqB,CAAA;AAAA;AAElF;AAKO,SAAS,cAAc,GAAA,EAAkB;AAC9C,EAAA,MAAM,UAAA,GAAa,IAAI,CAAA,IAAK,EAAA;AAC5B,EAAA,IAAI,IAAA,GAAO,CAAA;AACX,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,UAAA,CAAW,QAAQ,CAAA,EAAA,EAAK;AAC1C,IAAA,MAAM,IAAA,GAAO,UAAA,CAAW,UAAA,CAAW,CAAC,CAAA;AACpC,IAAA,IAAA,GAAA,CAAQ,IAAA,IAAQ,KAAK,IAAA,GAAO,IAAA;AAC5B,IAAA,IAAA,GAAO,IAAA,GAAO,IAAA;AAAA,EAChB;AACA,EAAA,OAAO,CAAA,EAAA,EAAK,IAAA,CAAK,GAAA,CAAI,IAAI,CAAA,CAAE,QAAA,CAAS,EAAE,CAAA,CAAE,QAAA,CAAS,CAAA,EAAG,GAAG,CAAC,CAAA,CAAA;AAC1D;AAeA,eAAsB,wBAAwB,SAAA,EAA2C;AACvF,EAAA,MAAMA,GAAAA,GAAK,MAAM,OAAO,IAAI,CAAA;AAC5B,EAAA,MAAM,UAAA,GAAa,MAAM,OAAO,MAAM,CAAA;AAGtC,EAAA,MAAM,iBAAA,GAAoB,UAAA,CAAW,OAAA,CAAQ,SAAS,CAAA;AAGtD,EAAA,MAAMA,IAAG,QAAA,CAAS,KAAA,CAAM,mBAAmB,EAAE,SAAA,EAAW,MAAM,CAAA;AAE9D,EAAA,OAAO;AAAA,IACL,MAAM,MAAM,OAAA,EAAS;AACnB,MAAA,MAAM,QAAA,GAAW,CAAA,EAAG,OAAA,CAAQ,GAAG,CAAA,UAAA,CAAA;AAC/B,MAAA,MAAM,QAAA,GAAW,UAAA,CAAW,IAAA,CAAK,iBAAA,EAAmB,QAAQ,CAAA;AAC5D,MAAA,MAAM,QAAA,GAAW,GAAG,QAAQ,CAAA,IAAA,CAAA;AAK5B,MAAA,IAAI,OAAA;AACJ,MAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,GAAA,CAAI,KAAA,CAAM,GAAG,CAAA;AACtC,MAAA,IAAI,QAAA,CAAS,WAAW,CAAA,EAAG;AAEzB,QAAA,OAAA,GAAU,IAAA,CAAK,UAAU,EAAE,IAAA,EAAM,QAAQ,GAAA,EAAI,EAAG,MAAM,CAAC,CAAA;AAAA,MACzD,CAAA,MAAO;AACL,QAAA,IAAI;AACF,UAAA,MAAM,WAAA,GAAc,OAAO,IAAA,CAAK,QAAA,CAAS,CAAC,CAAA,EAAG,WAAW,CAAA,CAAE,QAAA,CAAS,OAAO,CAAA;AAC1E,UAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,WAAW,CAAA;AAGtC,UAAA,MAAM,EAAE,QAAA,EAAU,GAAG,IAAA,EAAK,GAAI,OAAA;AAE9B,UAAA,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,EAAE,IAAA,EAAM,QAAA,EAAU,MAAM,OAAA,CAAQ,GAAA,EAAI,EAAG,IAAA,EAAM,CAAC,CAAA;AAAA,QACzE,CAAA,CAAA,MAAQ;AAEN,UAAA,OAAA,GAAU,IAAA,CAAK,UAAU,EAAE,IAAA,EAAM,QAAQ,GAAA,EAAI,EAAG,MAAM,CAAC,CAAA;AAAA,QACzD;AAAA,MACF;AAGA,MAAA,MAAMA,GAAAA,CAAG,QAAA,CAAS,SAAA,CAAU,QAAA,EAAU,SAAS,OAAO,CAAA;AAGtD,MAAA,MAAM,KAAK,MAAMA,GAAAA,CAAG,QAAA,CAAS,IAAA,CAAK,UAAU,GAAG,CAAA;AAC/C,MAAA,MAAM,GAAG,IAAA,EAAK;AACd,MAAA,MAAM,GAAG,KAAA,EAAM;AAGf,MAAA,MAAMA,GAAAA,CAAG,QAAA,CAAS,MAAA,CAAO,QAAA,EAAU,QAAQ,CAAA;AAK3C,MAAA,IAAI;AACF,QAAA,MAAM,QAAQ,MAAMA,GAAAA,CAAG,QAAA,CAAS,IAAA,CAAK,mBAAmB,GAAG,CAAA;AAC3D,QAAA,MAAM,MAAM,IAAA,EAAK;AACjB,QAAA,MAAM,MAAM,KAAA,EAAM;AAAA,MACpB,CAAA,CAAA,MAAQ;AAAA,MAGR;AAEA,MAAA,OAAO,QAAA;AAAA,IACT,CAAA;AAAA,IAEA,MAAM,KAAA,GAAQ;AAAA,IAEd;AAAA,GACF;AACF;AAiEA,eAAsB,qBAAqB,OAAA,EAAuD;AAChG,EAAA,MAAM;AAAA,IACJ,MAAA;AAAA,IACA,MAAA;AAAA,IACA,aAAA;AAAA,IACA,KAAA;AAAA,IACA,MAAA;AAAA,IACA,eAAA,GAAkB,GAAA;AAAA,IAClB,SAAA,GAAY,GAAA;AAAA,IACZ;AAAA,GACF,GAAI,OAAA;AAGJ,EAAA,MAAM,MAAA,GAAS,MAAMC,wBAAA,EAAa;AAGlC,EAAA,MAAM,UAAUC,gCAAA,CAAqB;AAAA,IACnC,KAAA;AAAA,IACA,MAAA;AAAA,IACA;AAAA,GACD,CAAA;AAGD,EAAA,MAAM,KAAA,GAAqB;AAAA,IACzB,aAAA,EAAe,CAAA;AAAA,IACf,iBAAA,EAAmB,CAAA;AAAA,IACnB,YAAA,EAAc,CAAA;AAAA,IACd,YAAA,EAAc,CAAA;AAAA,IACd,WAAA,EAAa,CAAA;AAAA,IACb,KAAA,EAAO,OAAO,QAAA,EAAS;AAAA,IACvB,SAAA,EAAW;AAAA,GACb;AAGA,EAAA,MAAM,cAAc,iBAAA,CAAkB;AAAA,IACpC,OAAA;AAAA,IACA,MAAA,EAAQ,aAAA;AAAA,IACR,SAAA,EAAW,CAAC,MAAA,KAAW;AACrB,MAAA,IAAI,OAAO,OAAA,EAAS;AAClB,QAAA,KAAA,CAAM,aAAA,EAAA;AACN,QAAA,KAAA,CAAM,YAAA,EAAA;AAAA,MACR,CAAA,MAAO;AACL,QAAA,KAAA,CAAM,iBAAA,EAAA;AAAA,MACR;AAAA,IACF;AAAA,GACD,CAAA;AAGD,EAAA,MAAM,UAAU,oBAAA,CAAqB;AAAA,IACnC,MAAA;AAAA,IACA,MAAA;AAAA,IACA,MAAA,EAAQ,CAAC,MAAA,KAAW;AAClB,MAAA,IAAI,OAAO,OAAA,EAAS;AAClB,QAAA,KAAA,CAAM,YAAA,EAAA;AACN,QAAA,KAAA,CAAM,eAAe,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,KAAA,CAAM,eAAe,CAAC,CAAA;AAAA,MACzD;AAAA,IACF,CAAA;AAAA,IACA,OAAA,EAAS,CAAC,KAAA,KAAU;AAClB,MAAA,KAAA,CAAM,WAAA,EAAA;AACN,MAAA,IAAI,OAAA,UAAiB,KAAK,CAAA;AAAA,IAC5B;AAAA,GACD,CAAA;AAID,EAAA,IAAI,mBAAA,GAAsB,CAAA;AAG1B,EAAA,IAAI,eAAA,GAAkB,KAAA;AAKtB,EAAA,MAAM,oBAAoB,uBAAA,CAAwB;AAAA,IAChD,OAAA;AAAA,IACA,eAAA;AAAA,IACA,mBAAmB,YAAY;AAE7B,MAAA,IAAI,eAAA,SAAwB,EAAC;AAC7B,MAAA,eAAA,GAAkB,IAAA;AAElB,MAAA,IAAI;AAEF,QAAA,MAAM,eAAA,GAAkB,MAAM,KAAA,CAAM,WAAA,EAAY;AAChD,QAAA,IAAI,eAAA,IAAmB,mBAAA,EAAqB,OAAO,EAAC;AAGpD,QAAA,MAAM,OAAA,GAAU,MAAM,KAAA,CAAM,IAAA,CAAK,qBAAqB,SAAS,CAAA;AAI/D,QAAA,MAAM,UAAU,EAAC;AACjB,QAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,UAAA,IAAI,KAAA,CAAM,YAAY,mBAAA,EAAqB;AAE3C,UAAA,MAAM,cAAc,MAAM,MAAA,CAAO,GAAA,CAAI,KAAA,CAAM,OAAO,EAAE,CAAA;AACpD,UAAA,IAAI,aAAa,OAAA,EAAS;AAC1B,UAAA,OAAA,CAAQ,KAAK,KAAK,CAAA;AAAA,QACpB;AACA,QAAA,OAAO,OAAA;AAAA,MACT,CAAA,SAAE;AACA,QAAA,eAAA,GAAkB,KAAA;AAAA,MACpB;AAAA,IACF,CAAA;AAAA,IACA,WAAA,EAAa,OAAO,MAAA,KAAW;AAE7B,MAAA,MAAM,OAAA,GAAU,MAAM,KAAA,CAAM,IAAA,CAAK,qBAAqB,SAAS,CAAA;AAC/D,MAAA,MAAM,QAAQ,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,iBAAiB,MAAM,CAAA;AAC3D,MAAA,IAAI,KAAA,EAAO;AAET,QAAA,IAAI,KAAA,CAAM,WAAW,mBAAA,EAAqB;AACxC,UAAA,mBAAA,GAAsB,KAAA,CAAM,QAAA;AAAA,QAC9B;AAEA,QAAA,MAAM,MAAA,CAAO,WAAA,CAAY,KAAA,CAAM,MAAA,CAAO,EAAE,CAAA;AAAA,MAC1C;AAAA,IACF,CAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAA,OAAO;AAAA,IACL,OAAA;AAAA,IACA,WAAA;AAAA,IACA,iBAAA;AAAA,IAEA,KAAA,GAAQ;AACN,MAAA,KAAA,CAAM,SAAA,GAAY,IAAA;AAClB,MAAA,iBAAA,CAAkB,KAAA,EAAM;AAAA,IAC1B,CAAA;AAAA,IAEA,MAAM,IAAA,GAAO;AACX,MAAA,iBAAA,CAAkB,IAAA,EAAK;AACvB,MAAA,MAAM,kBAAkB,KAAA,EAAM;AAC9B,MAAA,MAAM,YAAY,KAAA,EAAM;AACxB,MAAA,KAAA,CAAM,SAAA,GAAY,KAAA;AAAA,IACpB,CAAA;AAAA,IAEA,QAAA,GAAW;AACT,MAAA,OAAO,EAAE,GAAG,KAAA,EAAM;AAAA,IACpB;AAAA,GACF;AACF;;;ACjhBA,IAAM,oBAAA,GAAuB,GAAA;AAG7B,IAAM,oBAAA,GAAuB,GAAA;AAG7B,IAAM,mBAAA,GAAsB,KAAK,IAAA,GAAO,IAAA;AAGxC,IAAM,kBAAA,GAAqB,CAAC,OAAA,EAAS,OAAA,EAAS,SAAS,OAAA,EAAS,OAAA,EAAS,SAAS,OAAO,CAAA;AAOzF,SAAS,qBAAqB,OAAA,EAGrB;AACP,EAAA,MAAM,MAAM,OAAA,CAAQ,IAAA;AACpB,EAAA,IAAI,OAAO,GAAA,KAAQ,QAAA,EAAU,OAAO,IAAA;AAEpC,EAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,KAAA,CAAM,GAAG,CAAA;AAC3B,EAAA,IAAI,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG,OAAO,IAAA;AAE/B,EAAA,IAAI;AACF,IAAA,MAAM,WAAA,GAAc,OAAO,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA,EAAG,WAAW,CAAA,CAAE,QAAA,CAAS,OAAO,CAAA;AACvE,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,WAAW,CAAA;AACtC,IAAA,MAAM,EAAE,QAAA,EAAU,GAAG,IAAA,EAAK,GAAI,OAAA;AAC9B,IAAA,OAAO,EAAE,MAAM,IAAA,IAAQ,IAAI,QAAA,EAAU,QAAA,IAAY,EAAC,EAAE;AAAA,EACtD,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAGA,IAAM,gBAAA,GAAoE;AAAA,EACxE,KAAA,EAAO,EAAE,GAAA,EAAK,KAAA,EAAO,KAAK,CAAC,SAAA,EAAW,OAAO,CAAA,EAAE;AAAA,EAC/C,OAAO,EAAE,GAAA,EAAK,MAAM,GAAA,EAAK,CAAC,OAAO,CAAA,EAAE;AAAA,EACnC,OAAO,EAAE,GAAA,EAAK,MAAM,GAAA,EAAK,CAAC,OAAO,CAAA,EAAE;AAAA,EACnC,OAAO,EAAE,GAAA,EAAK,MAAM,GAAA,EAAK,CAAC,OAAO,CAAA,EAAE;AAAA,EACnC,KAAA,EAAO,EAAE,GAAA,EAAK,KAAA,EAAM;AAAA,EACpB,KAAA,EAAO,EAAE,GAAA,EAAK,KAAA,EAAM;AAAA,EACpB,KAAA,EAAO,EAAE,GAAA,EAAK,KAAA;AAChB,CAAA;AA+BO,SAAS,gBAAA,CACd,UACA,SAAA,EACY;AACZ,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,sBAAA;AAAA,IACN,WAAA,EAAa,0EAAA;AAAA,IACb,YAAY,EAAC;AAAA,IAEb,MAAM,OAAA,GAAiC;AACrC,MAAA,MAAM,KAAA,GAAQ,OAAO,QAAA,KAAa,UAAA,GAAa,UAAS,GAAI,QAAA;AAC5D,MAAA,MAAMF,GAAAA,GAAK,MAAM,OAAO,IAAI,CAAA;AAC5B,MAAA,MAAM,UAAA,GAAa,MAAM,OAAO,MAAM,CAAA;AAGtC,MAAA,MAAM,iBAAA,GAAoB,UAAA,CAAW,OAAA,CAAQ,SAAS,CAAA;AAGtD,MAAA,IAAI,YAAA,GAAe,CAAA;AACnB,MAAA,IAAI,eAAA,GAAiC,IAAA;AACrC,MAAA,IAAI,iBAAA,GAAmC,IAAA;AACvC,MAAA,IAAI,gBAAA,GAAmB,KAAA;AAEvB,MAAA,IAAI;AACF,QAAA,MAAM,KAAA,GAAQ,MAAMA,GAAAA,CAAG,QAAA,CAAS,QAAQ,iBAAiB,CAAA;AACzD,QAAA,MAAM,YAAA,GAAe,MAAM,MAAA,CAAO,CAAC,MAAM,CAAA,CAAE,QAAA,CAAS,YAAY,CAAC,CAAA;AACjE,QAAA,YAAA,GAAe,YAAA,CAAa,MAAA;AAG5B,QAAA,MAAM,WAAA,GAAc,YAAA,CAAa,KAAA,CAAM,CAAA,EAAG,oBAAoB,CAAA;AAC9D,QAAA,gBAAA,GAAmB,aAAa,MAAA,GAAS,oBAAA;AAEzC,QAAA,IAAI,WAAA,CAAY,SAAS,CAAA,EAAG;AAE1B,UAAA,MAAM,SAAA,GAAY,MAAM,OAAA,CAAQ,GAAA;AAAA,YAC9B,WAAA,CAAY,GAAA,CAAI,OAAO,CAAA,KAAM;AAC3B,cAAA,MAAM,IAAA,GAAO,MAAMA,GAAAA,CAAG,QAAA,CAAS,KAAK,UAAA,CAAW,IAAA,CAAK,iBAAA,EAAmB,CAAC,CAAC,CAAA;AACzE,cAAA,OAAO,EAAE,IAAA,EAAM,CAAA,EAAG,KAAA,EAAO,KAAK,KAAA,EAAM;AAAA,YACtC,CAAC;AAAA,WACH;AAEA,UAAA,SAAA,CAAU,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,KAAA,CAAM,OAAA,EAAQ,GAAI,CAAA,CAAE,KAAA,CAAM,OAAA,EAAS,CAAA;AAC9D,UAAA,eAAA,GAAkB,SAAA,CAAU,CAAC,CAAA,CAAE,KAAA,CAAM,WAAA,EAAY;AACjD,UAAA,iBAAA,GAAoB,UAAU,SAAA,CAAU,MAAA,GAAS,CAAC,CAAA,CAAE,MAAM,WAAA,EAAY;AAAA,QACxE;AAAA,MACF,CAAA,CAAA,MAAQ;AAAA,MAER;AAEA,MAAA,OAAO;AAAA,QACL,MAAA,EAAQ,IAAA;AAAA,QACR,KAAA,EAAO;AAAA,UACL,iBAAiB,KAAA,CAAM,YAAA;AAAA,UACvB,gBAAgB,KAAA,CAAM,aAAA;AAAA,UACtB,oBAAoB,KAAA,CAAM;AAAA,SAC5B;AAAA,QACA,QAAA,EAAU;AAAA,UACR,KAAA,EAAO,YAAA;AAAA,UACP,iBAAA,EAAmB,gBAAA;AAAA,UACnB,UAAA,EAAY,iBAAA;AAAA,UACZ,iBAAA,EAAmB,eAAA;AAAA,UACnB,mBAAA,EAAqB;AAAA,SACvB;AAAA,QACA,OAAA,EAAS;AAAA,UACP,eAAe,KAAA,CAAM,YAAA;AAAA,UACrB,cAAc,KAAA,CAAM,WAAA;AAAA,UACpB,YAAY,KAAA,CAAM,SAAA;AAAA,UAClB,QAAQ,KAAA,CAAM;AAAA;AAChB,OACF;AAAA,IACF;AAAA,GACF;AACF;AAmCO,SAAS,sBAAA,CAAuB,WAAmB,MAAA,EAAkC;AAC1F,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,6BAAA;AAAA,IACN,WAAA,EAAa,6EAAA;AAAA,IACb,UAAA,EAAY;AAAA,MACV,IAAA,EAAM,QAAA;AAAA,MACN,UAAA,EAAY;AAAA,QACV,WAAA,EAAa;AAAA,UACX,IAAA,EAAM,QAAA;AAAA,UACN,WAAA,EAAa;AAAA,SACf;AAAA,QACA,KAAA,EAAO;AAAA,UACL,IAAA,EAAM,QAAA;AAAA,UACN,WAAA,EAAa;AAAA,SACf;AAAA,QACA,KAAA,EAAO;AAAA,UACL,IAAA,EAAM,QAAA;AAAA,UACN,WAAA,EAAa;AAAA,SACf;AAAA,QACA,WAAA,EAAa;AAAA,UACX,IAAA,EAAM,QAAA;AAAA,UACN,WAAA,EAAa;AAAA;AACf;AACF,KACF;AAAA,IAEA,MAAM,QAAQ,MAAA,EAAyD;AACrE,MAAA,MAAMA,GAAAA,GAAK,MAAM,OAAO,IAAI,CAAA;AAC5B,MAAA,MAAM,UAAA,GAAa,MAAM,OAAO,MAAM,CAAA;AAGtC,MAAA,MAAM,iBAAA,GAAoB,UAAA,CAAW,OAAA,CAAQ,SAAS,CAAA;AAEtD,MAAA,IAAI;AAEF,QAAA,MAAM,KAAA,GAAQ,MAAMA,GAAAA,CAAG,QAAA,CAAS,QAAQ,iBAAiB,CAAA;AACzD,QAAA,MAAM,YAAA,GAAe,MAAM,MAAA,CAAO,CAAC,MAAM,CAAA,CAAE,QAAA,CAAS,YAAY,CAAC,CAAA;AAEjE,QAAA,IAAI,YAAA,CAAa,WAAW,CAAA,EAAG;AAC7B,UAAA,OAAO;AAAA,YACL,MAAA,EAAQ,IAAA;AAAA,YACR,OAAA,EAAS,uBAAA;AAAA,YACT,aAAA,EAAe;AAAA,WACjB;AAAA,QACF;AAGA,QAAA,MAAM,WAAmE,EAAC;AAC1E,QAAA,MAAM,cAAA,GAAiB,EAAE,UAAA,EAAY,CAAA,EAAG,cAAc,CAAA,EAAG,aAAA,EAAe,CAAA,EAAG,QAAA,EAAU,CAAA,EAAE;AACvF,QAAA,MAAM,eAAyB,EAAC;AAEhC,QAAA,KAAA,MAAW,QAAQ,YAAA,EAAc;AAC/B,UAAA,MAAM,QAAA,GAAW,UAAA,CAAW,IAAA,CAAK,iBAAA,EAAmB,IAAI,CAAA;AACxD,UAAA,IAAI,IAAA;AACJ,UAAA,IAAI;AACF,YAAA,IAAA,GAAO,MAAMA,GAAAA,CAAG,QAAA,CAAS,IAAA,CAAK,QAAQ,CAAA;AAAA,UACxC,CAAA,CAAA,MAAQ;AACN,YAAA,cAAA,CAAe,UAAA,EAAA;AACf,YAAA,YAAA,CAAa,KAAK,IAAI,CAAA;AACtB,YAAA;AAAA,UACF;AAGA,UAAA,IAAI,MAAA,CAAO,SAAS,IAAA,CAAK,KAAA,GAAQ,IAAI,IAAA,CAAK,MAAA,CAAO,KAAK,CAAA,EAAG;AACvD,YAAA,cAAA,CAAe,QAAA,EAAA;AACf,YAAA;AAAA,UACF;AACA,UAAA,IAAI,MAAA,CAAO,SAAS,IAAA,CAAK,KAAA,GAAQ,IAAI,IAAA,CAAK,MAAA,CAAO,KAAK,CAAA,EAAG;AACvD,YAAA,cAAA,CAAe,QAAA,EAAA;AACf,YAAA;AAAA,UACF;AAGA,UAAA,IAAI,OAAA;AACJ,UAAA,IAAI;AACF,YAAA,OAAA,GAAU,IAAA,CAAK,MAAM,MAAMA,GAAAA,CAAG,SAAS,QAAA,CAAS,QAAA,EAAU,OAAO,CAAC,CAAA;AAAA,UACpE,CAAA,CAAA,MAAQ;AACN,YAAA,MAAA,CAAO,IAAA,CAAK,CAAA,yBAAA,EAA4B,IAAI,CAAA,CAAE,CAAA;AAC9C,YAAA,cAAA,CAAe,YAAA,EAAA;AACf,YAAA,YAAA,CAAa,KAAK,IAAI,CAAA;AACtB,YAAA;AAAA,UACF;AAGA,UAAA,IAAI,OAAO,WAAA,EAAa;AACtB,YAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,IAAA,GAAO,oBAAA,CAAqB,OAAO,CAAA,GAAI,IAAA;AAE/D,YAAA,IAAI,OAAA,CAAQ,IAAA,IAAQ,CAAC,OAAA,EAAS;AAC5B,cAAA,MAAA,CAAO,IAAA,CAAK,CAAA,SAAA,EAAY,IAAI,CAAA,4BAAA,CAA8B,CAAA;AAC1D,cAAA,cAAA,CAAe,aAAA,EAAA;AACf,cAAA,YAAA,CAAa,KAAK,IAAI,CAAA;AACtB,cAAA;AAAA,YACF;AACA,YAAA,MAAM,SAAA,GAAa,OAAA,EAAS,IAAA,IAAQ,OAAA,EAAS,IAAA;AAG7C,YAAA,MAAM,aAAa,SAAA,EAAW,UAAA;AAC9B,YAAA,MAAM,WAAA,GAAc,aAAa,2BAA2B,CAAA;AAG5D,YAAA,IAAI,WAAA,EAAa,WAAA,KAAgB,MAAA,CAAO,WAAA,EAAa;AACnD,cAAA,cAAA,CAAe,QAAA,EAAA;AACf,cAAA;AAAA,YACF;AAAA,UACF;AAEA,UAAA,QAAA,CAAS,KAAK,EAAE,IAAA,EAAM,SAAS,KAAA,EAAO,IAAA,CAAK,OAAO,CAAA;AAAA,QACpD;AAEA,QAAA,IAAI,QAAA,CAAS,WAAW,CAAA,EAAG;AACzB,UAAA,OAAO;AAAA,YACL,MAAA,EAAQ,IAAA;AAAA,YACR,OAAA,EAAS,uCAAA;AAAA,YACT,aAAA,EAAe,CAAA;AAAA,YACf,eAAe,YAAA,CAAa,MAAA;AAAA,YAC5B,cAAA,EAAgB,CAAA;AAAA,YAChB,eACE,cAAA,CAAe,UAAA,GACf,eAAe,YAAA,GACf,cAAA,CAAe,gBACf,cAAA,CAAe,QAAA;AAAA,YACjB,eAAA,EAAiB,cAAA;AAAA,YACjB,aAAA,EAAe,aAAa,MAAA,GAAS,CAAA,GAAI,aAAa,KAAA,CAAM,CAAA,EAAG,GAAG,CAAA,GAAI,KAAA;AAAA,WACxE;AAAA,QACF;AAGA,QAAA,MAAM,QAAA,GAAW;AAAA,UACf,OAAA,EAAS,KAAA;AAAA,UACT,MAAA,EAAQ,uBAAA;AAAA,UACR,UAAA,EAAA,iBAAY,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AAAA,UACnC,eAAe,QAAA,CAAS,MAAA;AAAA,UACxB,OAAA,EAAS;AAAA,YACP,WAAA,EAAa,OAAO,WAAA,IAAe,IAAA;AAAA,YACnC,KAAA,EAAO,OAAO,KAAA,IAAS,IAAA;AAAA,YACvB,KAAA,EAAO,OAAO,KAAA,IAAS;AAAA,WACzB;AAAA,UACA,QAAA,EAAU,QAAA,CAAS,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,YAC7B,MAAM,CAAA,CAAE,IAAA;AAAA,YACR,KAAA,EAAO,CAAA,CAAE,KAAA,CAAM,WAAA;AAAY,WAC7B,CAAE;AAAA,SACJ;AAGA,QAAA,MAAM,SAAA,GAAA,qBAAgB,IAAA,EAAK,EAAE,aAAY,CAAE,OAAA,CAAQ,SAAS,GAAG,CAAA;AAC/D,QAAA,MAAM,SAAA,GAAY,MAAA,CAAO,WAAA,GACrB,UAAA,CAAW,OAAA,CAAQ,MAAA,CAAO,WAAW,CAAA,GACrC,UAAA,CAAW,IAAA,CAAK,iBAAA,EAAmB,CAAA,YAAA,EAAe,SAAS,CAAA,CAAE,CAAA;AAEjE,QAAA,MAAMA,IAAG,QAAA,CAAS,KAAA,CAAM,WAAW,EAAE,SAAA,EAAW,MAAM,CAAA;AAGtD,QAAA,MAAMA,IAAG,QAAA,CAAS,SAAA;AAAA,UAChB,UAAA,CAAW,IAAA,CAAK,SAAA,EAAW,eAAe,CAAA;AAAA,UAC1C,IAAA,CAAK,SAAA,CAAU,QAAA,EAAU,IAAA,EAAM,CAAC;AAAA,SAClC;AAGA,QAAA,MAAM,WAAA,GAAc,UAAA,CAAW,IAAA,CAAK,SAAA,EAAW,UAAU,CAAA;AACzD,QAAA,MAAMA,IAAG,QAAA,CAAS,KAAA,CAAM,aAAa,EAAE,SAAA,EAAW,MAAM,CAAA;AAExD,QAAA,KAAA,MAAW,WAAW,QAAA,EAAU;AAC9B,UAAA,MAAMA,IAAG,QAAA,CAAS,SAAA;AAAA,YAChB,UAAA,CAAW,IAAA,CAAK,WAAA,EAAa,OAAA,CAAQ,IAAI,CAAA;AAAA,YACzC,IAAA,CAAK,SAAA,CAAU,OAAA,CAAQ,OAAA,EAAS,MAAM,CAAC;AAAA,WACzC;AAAA,QACF;AAEA,QAAA,MAAA,CAAO,KAAK,CAAA,SAAA,EAAY,QAAA,CAAS,MAAM,CAAA,aAAA,EAAgB,SAAS,CAAA,CAAE,CAAA;AAElE,QAAA,OAAO;AAAA,UACL,MAAA,EAAQ,IAAA;AAAA,UACR,OAAA,EAAS,CAAA,SAAA,EAAY,QAAA,CAAS,MAAM,CAAA,sBAAA,CAAA;AAAA,UACpC,eAAe,QAAA,CAAS,MAAA;AAAA,UACxB,WAAA,EAAa,SAAA;AAAA,UACb,eAAe,YAAA,CAAa,MAAA;AAAA,UAC5B,gBAAgB,QAAA,CAAS,MAAA;AAAA,UACzB,eACE,cAAA,CAAe,UAAA,GACf,eAAe,YAAA,GACf,cAAA,CAAe,gBACf,cAAA,CAAe,QAAA;AAAA,UACjB,eAAA,EAAiB,cAAA;AAAA,UACjB,aAAA,EAAe,aAAa,MAAA,GAAS,CAAA,GAAI,aAAa,KAAA,CAAM,CAAA,EAAG,GAAG,CAAA,GAAI,KAAA;AAAA,SACxE;AAAA,MACF,SAAS,KAAA,EAAO;AACd,QAAA,MAAA,CAAO,KAAA,CAAM,yBAAyB,KAAK,CAAA;AAC3C,QAAA,OAAO;AAAA,UACL,MAAA,EAAQ,OAAA;AAAA,UACR,OAAA,EAAS,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,eAAA;AAAA,UAClD,aAAA,EAAe;AAAA,SACjB;AAAA,MACF;AAAA,IACF;AAAA,GACF;AACF;AAkCO,SAAS,iBAAiB,MAAA,EAAkC;AACjE,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,sBAAA;AAAA,IACN,WAAA,EAAa,oCAAA;AAAA,IACb,UAAA,EAAY;AAAA,MACV,IAAA,EAAM,QAAA;AAAA,MACN,UAAA,EAAY;AAAA,QACV,IAAA,EAAM;AAAA,UACJ,IAAA,EAAM,QAAA;AAAA,UACN,WAAA,EAAa;AAAA,SACf;AAAA,QACA,SAAA,EAAW;AAAA,UACT,IAAA,EAAM,QAAA;AAAA,UACN,WAAA,EAAa;AAAA;AACf,OACF;AAAA,MACA,QAAA,EAAU,CAAC,MAAM;AAAA,KACnB;AAAA,IAEA,MAAM,QAAQ,MAAA,EAAwD;AACpE,MAAA,MAAM,YAAA,GAAe,MAAA;AACrB,MAAA,MAAMA,GAAAA,GAAK,MAAM,OAAO,IAAI,CAAA;AAC5B,MAAA,MAAM,UAAA,GAAa,MAAM,OAAO,MAAM,CAAA;AAEtC,MAAA,IAAI;AACF,QAAA,MAAM,OAAO,MAAMA,GAAAA,CAAG,QAAA,CAAS,IAAA,CAAK,aAAa,IAAI,CAAA;AAErD,QAAA,IAAI,IAAA,CAAK,aAAY,EAAG;AAEtB,UAAA,OAAO,MAAM,YAAA;AAAA,YACX,YAAA,CAAa,IAAA;AAAA,YACb,YAAA,CAAa,SAAA;AAAA,YACbA,GAAAA;AAAA,YACA,UAAA;AAAA,YACA;AAAA,WACF;AAAA,QACF,CAAA,MAAO;AAEL,UAAA,OAAO,MAAM,mBAAA,CAAoB,YAAA,CAAa,MAAM,YAAA,CAAa,SAAA,EAAWA,KAAI,MAAM,CAAA;AAAA,QACxF;AAAA,MACF,SAAS,KAAA,EAAO;AACd,QAAA,MAAA,CAAO,KAAA,CAAM,wBAAwB,KAAK,CAAA;AAC1C,QAAA,OAAO;AAAA,UACL,MAAA,EAAQ,OAAA;AAAA,UACR,KAAA,EAAO,KAAA;AAAA,UACP,OAAA,EAAS,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,eAAA;AAAA,UAClD,QAAQ,CAAC,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,UAAU,eAAe;AAAA,SACnE;AAAA,MACF;AAAA,IACF;AAAA,GACF;AACF;AAEA,eAAe,mBAAA,CACb,WAAA,EACA,QAAA,EACAA,GAAAA,EACA,MAAA,EACuB;AAEvB,EAAA,MAAM,IAAA,GAAO,MAAMA,GAAAA,CAAG,QAAA,CAAS,KAAK,WAAW,CAAA;AAC/C,EAAA,IAAI,IAAA,CAAK,OAAO,mBAAA,EAAqB;AACnC,IAAA,OAAO;AAAA,MACL,MAAA,EAAQ,OAAA;AAAA,MACR,KAAA,EAAO,KAAA;AAAA,MACP,OAAA,EAAS,CAAA,gBAAA,EAAmB,IAAA,CAAK,IAAI,2BAA2B,mBAAmB,CAAA,MAAA,CAAA;AAAA,MACnF,QAAQ,CAAC,CAAA,UAAA,EAAa,KAAK,IAAI,CAAA,eAAA,EAAkB,mBAAmB,CAAA,WAAA,CAAa;AAAA,KACnF;AAAA,EACF;AAEA,EAAA,MAAM,UAAU,MAAMA,GAAAA,CAAG,QAAA,CAAS,QAAA,CAAS,aAAa,OAAO,CAAA;AAC/D,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,OAAO,CAAA;AAElC,EAAA,MAAM,SAAmB,EAAC;AAC1B,EAAA,MAAM,WAAqB,EAAC;AAK5B,EAAA,IAAI,IAAA;AACJ,EAAA,IAAI,QAAA;AAEJ,EAAA,IAAI,CAAC,QAAQ,IAAA,EAAM;AAEjB,IAAA,IAAA,GAAO,OAAA,CAAQ,IAAA;AACf,IAAA,QAAA,GAAW,OAAA,CAAQ,QAAA;AACnB,IAAA,QAAA,CAAS,KAAK,uDAAuD,CAAA;AAAA,EACvE,CAAA,MAAO;AACL,IAAA,MAAM,OAAA,GAAU,qBAAqB,OAAO,CAAA;AAC5C,IAAA,IAAI,CAAC,OAAA,EAAS;AAEZ,MAAA,MAAA,CAAO,KAAK,qEAAqE,CAAA;AACjF,MAAA,IAAA,GAAO,MAAA;AACP,MAAA,QAAA,GAAW,MAAA;AAAA,IACb,CAAA,MAAO;AACL,MAAA,IAAA,GAAO,OAAA,CAAQ,IAAA;AACf,MAAA,QAAA,GAAW,OAAA,CAAQ,QAAA;AAKnB,MAAA,IAAI,OAAA,CAAQ,IAAA,KAAS,MAAA,IAAa,OAAA,CAAQ,aAAa,MAAA,EAAW;AAChE,QAAA,MAAM,UAAU,OAAA,CAAQ,IAAA;AACxB,QAAA,MAAM,cAAc,OAAA,CAAQ,QAAA;AAC5B,QAAA,MAAM,SAAA,GACJ,OAAA,KAAY,MAAA,IAAa,IAAA,CAAK,SAAA,CAAU,OAAO,CAAA,KAAM,IAAA,CAAK,SAAA,CAAU,OAAA,CAAQ,IAAI,CAAA;AAClF,QAAA,MAAM,aAAA,GACJ,WAAA,KAAgB,MAAA,IAChB,IAAA,CAAK,SAAA,CAAU,WAAW,CAAA,KAAM,IAAA,CAAK,SAAA,CAAU,OAAA,CAAQ,QAAQ,CAAA;AACjE,QAAA,IAAI,CAAC,SAAA,IAAa,CAAC,aAAA,EAAe;AAChC,UAAA,MAAA,CAAO,IAAA;AAAA,YACL;AAAA,WACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,EAAA,IAAI,CAAC,IAAA,EAAM;AACT,IAAA,MAAA,CAAO,KAAK,oBAAoB,CAAA;AAAA,EAClC;AACA,EAAA,IAAI,CAAC,QAAA,EAAU;AACb,IAAA,MAAA,CAAO,KAAK,wBAAwB,CAAA;AAAA,EACtC;AAGA,EAAA,MAAM,WAAA,GAAc,QAAA;AACpB,EAAA,MAAM,aAAa,WAAA,EAAa,UAAA;AAChC,EAAA,MAAM,WAAA,GAAc,aAAa,kCAAkC,CAAA;AAGnE,EAAA,IAAI,WAAA,EAAa;AAEf,IAAA,IAAI,CAAC,YAAY,cAAA,EAAgB;AAC/B,MAAA,MAAA,CAAO,KAAK,wBAAwB,CAAA;AAAA,IACtC;AACA,IAAA,IAAI,CAAC,YAAY,IAAA,EAAM;AACrB,MAAA,MAAA,CAAO,KAAK,cAAc,CAAA;AAAA,IAC5B;AACA,IAAA,MAAM,WAAW,WAAA,CAAY,QAAA;AAC7B,IAAA,IAAI,CAAC,UAAU,QAAA,EAAU;AACvB,MAAA,MAAA,CAAO,KAAK,2BAA2B,CAAA;AAAA,IACzC;AACA,IAAA,IAAI,CAAC,YAAY,UAAA,EAAY;AAC3B,MAAA,MAAA,CAAO,KAAK,oBAAoB,CAAA;AAAA,IAClC;AAGA,IAAA,IAAI,WAAA,CAAY,YAAA,IAAgB,WAAA,CAAY,UAAA,EAAY;AACtD,MAAA,IACE,IAAI,KAAK,WAAA,CAAY,YAAsB,IAAI,IAAI,IAAA,CAAK,WAAA,CAAY,UAAoB,CAAA,EACxF;AACA,QAAA,MAAA,CAAO,KAAK,mCAAmC,CAAA;AAAA,MACjD;AAAA,IACF;AAGA,IAAA,MAAM,SAAS,WAAA,CAAY,MAAA;AAC3B,IAAA,IAAI,WAAA,CAAY,MAAA,IAAU,CAAC,MAAA,EAAQ,MAAA,EAAQ;AACzC,MAAA,MAAA,CAAO,KAAK,0CAA0C,CAAA;AAAA,IACxD;AAAA,EACF,CAAA,MAAO;AACL,IAAA,QAAA,CAAS,KAAK,+BAA+B,CAAA;AAAA,EAC/C;AAGA,EAAA,IAAI,QAAA,IAAY,QAAQ,IAAA,EAAM;AAC5B,IAAA,IAAI;AACF,MAAA,MAAM,EAAE,QAAQ,eAAA,EAAAF,gBAAAA,EAAiB,uBAAsB,GAAI,MAAM,OAAO,cAAc,CAAA;AACtF,MAAA,MAAM,IAAA,GAAO,KAAK,KAAA,CAAM,MAAME,IAAG,QAAA,CAAS,QAAA,CAAS,QAAA,EAAU,OAAO,CAAC,CAAA;AAGrE,MAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AACvC,MAAA,IAAI,QAAA,CAAS,WAAW,CAAA,EAAG;AACzB,QAAA,MAAA,CAAO,KAAK,uCAAuC,CAAA;AAAA,MACrD,CAAA,MAAO;AACL,QAAA,MAAM,UAAA,GAAa,qBAAA,CAAsB,QAAA,CAAS,CAAC,CAAC,CAAA;AACpD,QAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,UAAU,CAAA;AAGpC,QAAA,IAAI,MAAA,CAAO,QAAQ,MAAA,EAAQ;AACzB,UAAA,MAAA,CAAO,KAAK,iCAAiC,CAAA;AAAA,QAC/C;AAGA,QAAA,IACE,OAAO,GAAA,IACP,CAAC,mBAAmB,QAAA,CAAS,MAAA,CAAO,GAA0C,CAAA,EAC9E;AACA,UAAA,MAAA,CAAO,IAAA;AAAA,YACL,cAAc,MAAA,CAAO,GAAG,6BAA6B,kBAAA,CAAmB,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,WACpF;AAAA,QACF;AAIA,QAAA,IAAI,MAAA,CAAO,IAAA,IAAQ,MAAA,CAAO,IAAA,CAAK,SAAS,CAAA,EAAG;AAEzC,UAAA,MAAM,SAAA,GAAY,MAAA;AAClB,UAAA,MAAM,WAAA,GAAc,OAAO,IAAA,CAAK,MAAA,CAAO,CAAC,CAAA,KAAM,EAAE,KAAK,SAAA,CAAU,CAAA;AAC/D,UAAA,IAAI,WAAA,CAAY,SAAS,CAAA,EAAG;AAC1B,YAAA,MAAA,CAAO,KAAK,CAAA,uCAAA,EAA0C,WAAA,CAAY,IAAA,CAAK,IAAI,CAAC,CAAA,CAAE,CAAA;AAAA,UAChF;AAEA,UAAA,MAAA,CAAO,KAAK,CAAA,8BAAA,EAAiC,MAAA,CAAO,KAAK,IAAA,CAAK,IAAI,CAAC,CAAA,CAAE,CAAA;AAAA,QACvE;AAEA,QAAA,MAAM,YAAY,MAAA,CAAO,GAAA;AAGzB,QAAA,IAAI,MAAA;AAWJ,QAAA,IAAI,CAAC,MAAM,OAAA,CAAQ,IAAA,CAAK,IAAI,CAAA,IAAK,IAAA,CAAK,IAAA,CAAK,MAAA,KAAW,CAAA,EAAG;AACvD,UAAA,MAAA,CAAO,KAAK,kBAAkB,CAAA;AAAA,QAChC,WAAW,SAAA,EAAW;AAEpB,UAAA,MAAA,GAAS,KAAK,IAAA,CAAK,IAAA,CAAK,CAAC,CAAA,KAAwB,CAAA,CAAE,QAAQ,SAAS,CAAA;AACpE,UAAA,IAAI,CAAC,MAAA,EAAQ;AACX,YAAA,MAAA,CAAO,IAAA,CAAK,CAAA,cAAA,EAAiB,SAAS,CAAA,mBAAA,CAAqB,CAAA;AAAA,UAC7D;AAAA,QACF,CAAA,MAAA,IAAW,IAAA,CAAK,IAAA,CAAK,MAAA,KAAW,CAAA,EAAG;AAEjC,UAAA,MAAA,GAAS,IAAA,CAAK,KAAK,CAAC,CAAA;AACpB,UAAA,QAAA,CAAS,KAAK,2CAA2C,CAAA;AAAA,QAC3D,CAAA,MAAO;AAEL,UAAA,MAAA,CAAO,IAAA,CAAK,CAAA,6BAAA,EAAgC,IAAA,CAAK,IAAA,CAAK,MAAM,CAAA,qBAAA,CAAuB,CAAA;AAAA,QACrF;AAGA,QAAA,IAAI,MAAA,IAAU,MAAA,CAAO,GAAA,IAAO,MAAA,CAAO,WAAW,CAAA,EAAG;AAC/C,UAAA,MAAM,eAAA,GAAkB,gBAAA,CAAiB,MAAA,CAAO,GAAG,CAAA;AACnD,UAAA,IAAI,eAAA,EAAiB;AACnB,YAAA,IAAI,MAAA,CAAO,GAAA,KAAQ,eAAA,CAAgB,GAAA,EAAK;AACtC,cAAA,MAAA,CAAO,IAAA;AAAA,gBACL,CAAA,WAAA,EAAc,OAAO,GAAG,CAAA,qBAAA,EAAwB,gBAAgB,GAAG,CAAA,eAAA,EAAkB,OAAO,GAAG,CAAA,CAAA;AAAA,eACjG;AAAA,YACF,CAAA,MAAA,IACE,eAAA,CAAgB,GAAA,IAChB,MAAA,CAAO,GAAA,IACP,CAAC,eAAA,CAAgB,GAAA,CAAI,QAAA,CAAS,MAAA,CAAO,GAAG,CAAA,EACxC;AACA,cAAA,MAAA,CAAO,IAAA;AAAA,gBACL,CAAA,WAAA,EAAc,MAAA,CAAO,GAAG,CAAA,iBAAA,EAAoB,eAAA,CAAgB,GAAA,CAAI,IAAA,CAAK,MAAM,CAAC,CAAA,cAAA,EAAiB,MAAA,CAAO,GAAG,CAAA,CAAA;AAAA,eACzG;AAAA,YACF;AAAA,UACF;AAGA,UAAA,IAAI,MAAA,CAAO,GAAA,IAAO,MAAA,CAAO,GAAA,KAAQ,KAAA,EAAO;AACtC,YAAA,MAAA,CAAO,IAAA;AAAA,cACL,CAAA,SAAA,EAAY,OAAO,GAAG,CAAA,0DAAA;AAAA,aACxB;AAAA,UACF;AAGA,UAAA,IAAI,OAAO,OAAA,IAAW,CAAC,OAAO,OAAA,CAAQ,QAAA,CAAS,QAAQ,CAAA,EAAG;AACxD,YAAA,MAAA,CAAO,KAAK,CAAA,eAAA,EAAkB,IAAA,CAAK,UAAU,MAAA,CAAO,OAAO,CAAC,CAAA,wBAAA,CAA0B,CAAA;AAAA,UACxF;AAAA,QACF;AAEA,QAAA,IAAI,MAAA,IAAU,MAAA,CAAO,MAAA,KAAW,CAAA,EAAG;AAEjC,UAAA,MAAM,cAAA,GAAiB,MAAA,CAAO,CAAA,IAAK,MAAA,CAAO,CAAA;AAC1C,UAAA,IAAI,CAAC,cAAA,EAAgB;AACnB,YAAA,MAAA,CAAO,KAAK,oDAAoD,CAAA;AAAA,UAClE,CAAA,MAAO;AAEL,YAAA,MAAM,cAAA,GAAiBF,iBAAgB,cAAc,CAAA;AACrD,YAAA,MAAM,MAAA,CAAO,OAAA,CAAQ,IAAA,EAAM,cAAc,CAAA;AACzC,YAAA,MAAA,CAAO,IAAA,CAAK,CAAA,4BAAA,EAA+B,MAAA,CAAO,GAAA,IAAO,WAAW,CAAA,CAAE,CAAA;AAAA,UACxE;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,MAAA,CAAO,IAAA;AAAA,QACL,CAAA,+BAAA,EAAkC,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,UAAU,SAAS,CAAA;AAAA,OACtF;AAAA,IACF;AAAA,EACF,CAAA,MAAA,IAAW,CAAC,QAAA,EAAU;AACpB,IAAA,QAAA,CAAS,KAAK,2CAA2C,CAAA;AAAA,EAC3D;AAEA,EAAA,OAAO;AAAA,IACL,MAAA,EAAQ,MAAA,CAAO,MAAA,KAAW,CAAA,GAAI,IAAA,GAAO,OAAA;AAAA,IACrC,KAAA,EAAO,OAAO,MAAA,KAAW,CAAA;AAAA,IACzB,OAAA,EAAS,MAAA,CAAO,MAAA,KAAW,CAAA,GAAI,kBAAA,GAAqB,+BAAA;AAAA,IACpD,MAAA,EAAQ,MAAA,CAAO,MAAA,GAAS,CAAA,GAAI,MAAA,GAAS,MAAA;AAAA,IACrC,QAAA,EAAU,QAAA,CAAS,MAAA,GAAS,CAAA,GAAI,QAAA,GAAW,MAAA;AAAA,IAC3C,YAAa,IAAA,EAAkC,GAAA;AAAA,IAC/C,gBAAiB,WAAA,EAAyC;AAAA,GAC5D;AACF;AAEA,eAAe,YAAA,CACb,UAAA,EACA,QAAA,EACAE,GAAAA,EACA,YACA,MAAA,EACuB;AAEvB,EAAA,MAAM,YAAA,GAAe,UAAA,CAAW,IAAA,CAAK,UAAA,EAAY,eAAe,CAAA;AAChE,EAAA,MAAM,QAAA,GAAW,KAAK,KAAA,CAAM,MAAMA,IAAG,QAAA,CAAS,QAAA,CAAS,YAAA,EAAc,OAAO,CAAC,CAAA;AAE7E,EAAA,MAAM,WAAA,GAAc,UAAA,CAAW,IAAA,CAAK,UAAA,EAAY,UAAU,CAAA;AAC1D,EAAA,MAAM,KAAA,GAAQ,MAAMA,GAAAA,CAAG,QAAA,CAAS,QAAQ,WAAW,CAAA;AAEnD,EAAA,IAAI,UAAA,GAAa,CAAA;AACjB,EAAA,IAAI,YAAA,GAAe,CAAA;AACnB,EAAA,MAAM,YAAsB,EAAC;AAC7B,EAAA,MAAM,cAAwB,EAAC;AAE/B,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,IAAI,CAAC,IAAA,CAAK,QAAA,CAAS,YAAY,CAAA,EAAG;AAElC,IAAA,MAAM,SAAS,MAAM,mBAAA;AAAA,MACnB,UAAA,CAAW,IAAA,CAAK,WAAA,EAAa,IAAI,CAAA;AAAA,MACjC,QAAA;AAAA,MACAA,GAAAA;AAAA,MACA;AAAA,KACF;AAEA,IAAA,IAAI,OAAO,KAAA,EAAO;AAChB,MAAA,UAAA,EAAA;AAAA,IACF,CAAA,MAAO;AACL,MAAA,YAAA,EAAA;AACA,MAAA,IAAI,OAAO,MAAA,EAAQ;AACjB,QAAA,SAAA,CAAU,IAAA,CAAK,GAAG,MAAA,CAAO,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,EAAG,IAAI,CAAA,EAAA,EAAK,CAAC,CAAA,CAAE,CAAC,CAAA;AAAA,MAC7D;AAAA,IACF;AACA,IAAA,IAAI,OAAO,QAAA,EAAU;AACnB,MAAA,WAAA,CAAY,IAAA,CAAK,GAAG,MAAA,CAAO,QAAA,CAAS,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,EAAG,IAAI,CAAA,EAAA,EAAK,CAAC,CAAA,CAAE,CAAC,CAAA;AAAA,IACjE;AAAA,EACF;AAEA,EAAA,OAAO;AAAA,IACL,MAAA,EAAQ,YAAA,KAAiB,CAAA,GAAI,IAAA,GAAO,OAAA;AAAA,IACpC,OAAO,YAAA,KAAiB,CAAA;AAAA,IACxB,OAAA,EAAS,CAAA,qBAAA,EAAwB,UAAU,CAAA,QAAA,EAAW,YAAY,CAAA,QAAA,CAAA;AAAA,IAClE,MAAA,EAAQ,SAAA,CAAU,MAAA,GAAS,CAAA,GAAI,SAAA,GAAY,MAAA;AAAA,IAC3C,QAAA,EAAU,WAAA,CAAY,MAAA,GAAS,CAAA,GAAI,WAAA,GAAc,MAAA;AAAA,IACjD,YAAA,EAAc;AAAA,MACZ,OAAO,UAAA,GAAa,YAAA;AAAA,MACpB,KAAA,EAAO,UAAA;AAAA,MACP,OAAA,EAAS,YAAA;AAAA,MACT,wBAAwB,QAAA,CAAS;AAAA;AACnC,GACF;AACF;AA+BO,SAAS,eAAA,CAAgB,WAAmB,MAAA,EAAkC;AACnF,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,qBAAA;AAAA,IACN,WAAA,EAAa,yDAAA;AAAA,IACb,UAAA,EAAY;AAAA,MACV,IAAA,EAAM,QAAA;AAAA,MACN,UAAA,EAAY;AAAA,QACV,WAAA,EAAa;AAAA,UACX,IAAA,EAAM,QAAA;AAAA,UACN,WAAA,EAAa;AAAA,SACf;AAAA,QACA,SAAA,EAAW;AAAA,UACT,IAAA,EAAM,QAAA;AAAA,UACN,WAAA,EAAa;AAAA,SACf;AAAA,QACA,KAAA,EAAO;AAAA,UACL,IAAA,EAAM,QAAA;AAAA,UACN,WAAA,EAAa;AAAA,SACf;AAAA,QACA,KAAA,EAAO;AAAA,UACL,IAAA,EAAM,QAAA;AAAA,UACN,WAAA,EAAa;AAAA,SACf;AAAA,QACA,MAAA,EAAQ;AAAA,UACN,IAAA,EAAM,QAAA;AAAA,UACN,IAAA,EAAM,CAAC,IAAA,EAAM,OAAA,EAAS,WAAW,UAAU,CAAA;AAAA,UAC3C,WAAA,EAAa;AAAA,SACf;AAAA,QACA,KAAA,EAAO;AAAA,UACL,IAAA,EAAM,SAAA;AAAA,UACN,WAAA,EAAa;AAAA,SACf;AAAA,QACA,MAAA,EAAQ;AAAA,UACN,IAAA,EAAM,SAAA;AAAA,UACN,WAAA,EAAa;AAAA;AACf;AACF,KACF;AAAA,IAEA,MAAM,QAAQ,MAAA,EAA2C;AACvD,MAAA,MAAMA,GAAAA,GAAK,MAAM,OAAO,IAAI,CAAA;AAC5B,MAAA,MAAM,UAAA,GAAa,MAAM,OAAO,MAAM,CAAA;AAGtC,MAAA,MAAM,iBAAA,GAAoB,UAAA,CAAW,OAAA,CAAQ,SAAS,CAAA;AAEtD,MAAA,IAAI;AACF,QAAA,MAAM,KAAA,GAAQ,MAAMA,GAAAA,CAAG,QAAA,CAAS,QAAQ,iBAAiB,CAAA;AACzD,QAAA,MAAM,YAAA,GAAe,MAAM,MAAA,CAAO,CAAC,MAAM,CAAA,CAAE,QAAA,CAAS,YAAY,CAAC,CAAA;AAEjE,QAAA,MAAM,QAAQ,IAAA,CAAK,GAAA,CAAI,MAAA,CAAO,KAAA,IAAS,KAAK,oBAAoB,CAAA;AAChE,QAAA,MAAM,MAAA,GAAS,OAAO,MAAA,IAAU,CAAA;AAIhC,QAAA,MAAM,YAAkD,EAAC;AACzD,QAAA,KAAA,MAAW,IAAA,IAAQ,YAAA,CAAa,KAAA,CAAM,CAAA,EAAG,oBAAoB,CAAA,EAAG;AAC9D,UAAA,IAAI;AACF,YAAA,MAAM,QAAA,GAAW,UAAA,CAAW,IAAA,CAAK,iBAAA,EAAmB,IAAI,CAAA;AACxD,YAAA,MAAM,IAAA,GAAO,MAAMA,GAAAA,CAAG,QAAA,CAAS,KAAK,QAAQ,CAAA;AAG5C,YAAA,IAAI,MAAA,CAAO,SAAS,IAAA,CAAK,KAAA,GAAQ,IAAI,IAAA,CAAK,MAAA,CAAO,KAAK,CAAA,EAAG;AACvD,cAAA;AAAA,YACF;AACA,YAAA,IAAI,MAAA,CAAO,SAAS,IAAA,CAAK,KAAA,GAAQ,IAAI,IAAA,CAAK,MAAA,CAAO,KAAK,CAAA,EAAG;AACvD,cAAA;AAAA,YACF;AAEA,YAAA,SAAA,CAAU,KAAK,EAAE,IAAA,EAAM,KAAA,EAAO,IAAA,CAAK,OAAO,CAAA;AAAA,UAC5C,CAAA,CAAA,MAAQ;AAEN,YAAA;AAAA,UACF;AAAA,QACF;AAGA,QAAA,SAAA,CAAU,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,KAAA,CAAM,OAAA,EAAQ,GAAI,CAAA,CAAE,KAAA,CAAM,OAAA,EAAS,CAAA;AAG9D,QAAA,MAAM,UAAwB,EAAC;AAC/B,QAAA,IAAI,iBAAA,GAAoB,CAAA;AAExB,QAAA,IAAI,mBAAA,GAAsB,CAAA;AAC1B,QAAA,IAAI,0BAAA,GAA6B,CAAA;AACjC,QAAA,IAAI,2BAAA,GAA8B,CAAA;AAClC,QAAA,KAAA,MAAW,EAAE,IAAA,EAAK,IAAK,SAAA,EAAW;AAChC,UAAA,MAAM,QAAA,GAAW,UAAA,CAAW,IAAA,CAAK,iBAAA,EAAmB,IAAI,CAAA;AAGxD,UAAA,IAAI;AACF,YAAA,MAAM,QAAA,GAAW,MAAMA,GAAAA,CAAG,QAAA,CAAS,KAAK,QAAQ,CAAA;AAChD,YAAA,IAAI,QAAA,CAAS,OAAO,mBAAA,EAAqB;AACvC,cAAA,mBAAA,EAAA;AACA,cAAA;AAAA,YACF;AAAA,UACF,CAAA,CAAA,MAAQ;AACN,YAAA;AAAA,UACF;AAGA,UAAA,IAAI,OAAA;AACJ,UAAA,IAAI;AACF,YAAA,OAAA,GAAU,IAAA,CAAK,MAAM,MAAMA,GAAAA,CAAG,SAAS,QAAA,CAAS,QAAA,EAAU,OAAO,CAAC,CAAA;AAAA,UACpE,CAAA,CAAA,MAAQ;AAEN,YAAA,0BAAA,EAAA;AACA,YAAA;AAAA,UACF;AAIA,UAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,IAAA,GAAO,oBAAA,CAAqB,OAAO,CAAA,GAAI,IAAA;AAC/D,UAAA,IAAI,OAAA,CAAQ,IAAA,IAAQ,CAAC,OAAA,EAAS;AAC5B,YAAA,2BAAA,EAAA;AACA,YAAA;AAAA,UACF;AACA,UAAA,MAAM,SAAA,GAAa,OAAA,EAAS,IAAA,IAAQ,OAAA,EAAS,IAAA;AAC7C,UAAA,MAAM,aAAA,GAAiB,OAAA,EAAS,QAAA,IAAY,OAAA,EAAS,QAAA;AAGrD,UAAA,MAAM,qBAAqB,aAAA,EAAe,UAAA;AAG1C,UAAA,MAAM,WAAA,GAAc,qBAAqB,kCAAkC,CAAA;AAG3E,UAAA,MAAM,iBAAiB,SAAA,EAAW,UAAA;AAClC,UAAA,MAAM,QAAA,GAAW,iBAAiB,2BAA2B,CAAA;AAK7D,UAAA,IAAI,MAAA,CAAO,WAAA,IAAe,QAAA,EAAU,WAAA,KAAgB,OAAO,WAAA,EAAa;AACtE,YAAA,iBAAA,EAAA;AACA,YAAA;AAAA,UACF;AAGA,UAAA,MAAM,OAAO,WAAA,EAAa,IAAA;AAC1B,UAAA,IAAI,MAAA,CAAO,SAAA,IAAa,IAAA,EAAM,IAAA,KAAS,OAAO,SAAA,EAAW;AACvD,YAAA,iBAAA,EAAA;AACA,YAAA;AAAA,UACF;AAGA,UAAA,MAAM,SAAS,WAAA,EAAa,MAAA;AAC5B,UAAA,IAAI,MAAA,CAAO,MAAA,IAAU,MAAA,EAAQ,MAAA,KAAW,OAAO,MAAA,EAAQ;AACrD,YAAA,iBAAA,EAAA;AACA,YAAA;AAAA,UACF;AAEA,UAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,YACX,IAAA;AAAA,YACA,YAAY,SAAA,EAAW,GAAA;AAAA,YACvB,gBAAgB,WAAA,EAAa,cAAA;AAAA,YAC7B,aAAa,QAAA,EAAU,WAAA;AAAA,YACvB,WAAW,IAAA,EAAM,IAAA;AAAA,YACjB,QAAQ,MAAA,EAAQ,MAAA;AAAA,YAChB,YAAY,WAAA,EAAa,UAAA;AAAA,YACzB,cAAc,WAAA,EAAa;AAAA,WAC5B,CAAA;AAID,UAAA,IAAI,OAAA,CAAQ,MAAA,IAAU,MAAA,GAAS,KAAA,GAAQ,GAAA,EAAK;AAE1C,YAAA;AAAA,UACF;AAAA,QACF;AAGA,QAAA,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM;AACrB,UAAA,MAAM,KAAA,GAAQ,EAAE,UAAA,GAAa,IAAI,KAAK,CAAA,CAAE,UAAU,CAAA,CAAE,OAAA,EAAQ,GAAI,CAAA;AAChE,UAAA,MAAM,KAAA,GAAQ,EAAE,UAAA,GAAa,IAAI,KAAK,CAAA,CAAE,UAAU,CAAA,CAAE,OAAA,EAAQ,GAAI,CAAA;AAChE,UAAA,IAAI,KAAA,KAAU,KAAA,EAAO,OAAO,KAAA,GAAQ,KAAA;AAEpC,UAAA,OAAO,CAAA,CAAE,IAAA,CAAK,aAAA,CAAc,CAAA,CAAE,IAAI,CAAA;AAAA,QACpC,CAAC,CAAA;AAGD,QAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,KAAA,CAAM,MAAA,EAAQ,SAAS,KAAK,CAAA;AAGtD,QAAA,MAAM,WAAqB,EAAC;AAC5B,QAAA,IAAI,YAAA,CAAa,SAAS,oBAAA,EAAsB;AAC9C,UAAA,QAAA,CAAS,IAAA,CAAK,CAAA,kBAAA,EAAqB,oBAAoB,CAAA,MAAA,CAAQ,CAAA;AAAA,QACjE;AACA,QAAA,IAAI,sBAAsB,CAAA,EAAG;AAC3B,UAAA,QAAA,CAAS,IAAA;AAAA,YACP,CAAA,EAAG,mBAAmB,CAAA,yBAAA,EAA4B,mBAAmB,CAAA,YAAA;AAAA,WACvE;AAAA,QACF;AACA,QAAA,IAAI,6BAA6B,CAAA,EAAG;AAClC,UAAA,QAAA,CAAS,IAAA,CAAK,CAAA,EAAG,0BAA0B,CAAA,6BAAA,CAA+B,CAAA;AAAA,QAC5E;AACA,QAAA,IAAI,8BAA8B,CAAA,EAAG;AACnC,UAAA,QAAA,CAAS,IAAA,CAAK,CAAA,EAAG,2BAA2B,CAAA,8BAAA,CAAgC,CAAA;AAAA,QAC9E;AAEA,QAAA,MAAM,YAAA,GACJ,sBAAsB,0BAAA,GAA6B,2BAAA;AACrD,QAAA,MAAM,aAAA,GAAgB,YAAA,CAAa,MAAA,GAAS,oBAAA,IAAwB,YAAA,GAAe,CAAA;AAEnF,QAAA,OAAO;AAAA,UACL,MAAA,EAAQ,IAAA;AAAA,UACR,OAAO,OAAA,CAAQ,MAAA;AAAA,UACf,MAAA;AAAA,UACA,KAAA;AAAA,UACA,OAAA,EAAS,SAAA;AAAA,UACT,eAAe,SAAA,CAAU,MAAA;AAAA,UACzB,eAAe,OAAA,CAAQ,MAAA;AAAA,UACvB,SAAA,EAAW,aAAA;AAAA,UACX,OAAA,EACE,aAAA,IAAiB,iBAAA,GAAoB,CAAA,GACjC;AAAA,YACE,SAAA,EAAW,mBAAA;AAAA,YACX,YAAA,EAAc,0BAAA;AAAA,YACd,aAAA,EAAe,2BAAA;AAAA,YACf,QAAA,EAAU,iBAAA;AAAA,YACV,QACE,YAAA,CAAa,MAAA,GAAS,oBAAA,GAClB,YAAA,CAAa,SAAS,oBAAA,GACtB;AAAA,WACR,GACA,KAAA,CAAA;AAAA,UACN,GAAI,SAAS,MAAA,GAAS,CAAA,IAAK,EAAE,OAAA,EAAS,QAAA,CAAS,IAAA,CAAK,IAAI,CAAA;AAAE,SAC5D;AAAA,MACF,SAAS,KAAA,EAAO;AACd,QAAA,MAAA,CAAO,KAAA,CAAM,iBAAiB,KAAK,CAAA;AACnC,QAAA,OAAO;AAAA,UACL,MAAA,EAAQ,OAAA;AAAA,UACR,KAAA,EAAO,CAAA;AAAA,UACP,MAAA,EAAQ,CAAA;AAAA,UACR,KAAA,EAAO,OAAO,KAAA,IAAS,GAAA;AAAA,UACvB,SAAS,EAAC;AAAA,UACV,KAAA,EAAO,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU;AAAA,SAClD;AAAA,MACF;AAAA,IACF;AAAA,GACF;AACF;AC/7BA,IAAM,qBAAA,GAAwB,gBAAA;AAC9B,IAAM,cAAA,GAAiB,aAAA;AACvB,IAAM,eAAA,GAAkB,YAAA;AAMxB,SAAS,cAAA,GAAyB;AAChC,EAAA,MAAM,OAAO,OAAA,CAAQ,GAAA,CAAI,IAAA,IAAQ,OAAA,CAAQ,IAAI,WAAA,IAAe,GAAA;AAC5D,EAAA,OAAYG,eAAA,CAAA,IAAA,CAAK,MAAM,qBAAqB,CAAA;AAC9C;AAEA,SAAS,UAAA,GAA2B;AAClC,EAAA,MAAM,OAAO,MAAM;AAAA,EAAC,CAAA;AACpB,EAAA,OAAO,EAAE,OAAO,IAAA,EAAM,IAAA,EAAM,MAAM,IAAA,EAAM,IAAA,EAAM,OAAO,IAAA,EAAK;AAC5D;AAqBA,eAAsB,SAAS,OAAA,EAAmD;AAChF,EAAA,MAAM,EAAE,MAAA,EAAQ,YAAA,EAAa,GAAI,OAAA;AACjC,EAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,MAAA,IAAU,UAAA,EAAW;AAC5C,EAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,OAAA,IAAW,cAAA,EAAe;AAGlD,EAAA,MAASH,cAAA,CAAA,KAAA,CAAM,OAAA,EAAS,EAAE,SAAA,EAAW,MAAM,CAAA;AAG3C,EAAA,IAAI;AACF,IAAA,MAASA,sBAAO,OAAA,EAAA,CAAU,MAAM,OAAO,WAAgB,GAAG,IAAI,CAAA;AAAA,EAChE,CAAA,CAAA,MAAQ;AACN,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,gCAAA,EAAmC,OAAO,CAAA,CAAE,CAAA;AAAA,EAC9D;AAGA,EAAA,MAAA,CAAO,IAAA,CAAK,CAAA,4BAAA,EAA+B,MAAA,CAAO,OAAA,CAAQ,OAAA,CAAQ,MAAM,GAAG,CAAA,CAAE,CAAC,CAAC,CAAA,IAAA,CAAM,CAAA;AACrF,EAAA,MAAM,SAAS,MAAM,aAAA;AAAA,IACnB,OAAO,OAAA,CAAQ,OAAA;AAAA,IACf,OAAO,OAAA,CAAQ,MAAA;AAAA,IACf,OAAO,OAAA,CAAQ;AAAA,GACjB;AACA,EAAA,MAAA,CAAO,IAAA,CAAK,CAAA,2BAAA,EAA8B,MAAA,CAAO,QAAA,EAAU,CAAA,CAAE,CAAA;AAG7D,EAAA,MAAM,SAAA,GAAiBG,eAAA,CAAA,IAAA,CAAK,OAAA,EAAS,cAAc,CAAA;AACnD,EAAA,MAAM,UAAA,GAAkBA,eAAA,CAAA,IAAA,CAAK,OAAA,EAAS,eAAe,CAAA;AAErD,EAAA,MAAM,KAAA,GAAQ,MAAMC,8BAAA,CAAmB;AAAA,IACrC,QAAA,EAAU,SAAA;AAAA,IACV,YAAY,YAAA,EAAc,UAAA;AAAA,IAC1B,cAAc,YAAA,EAAc,YAAA;AAAA,IAC5B,sBAAsB,YAAA,EAAc,oBAAA;AAAA,IACpC,aAAa,YAAA,EAAc,WAAA;AAAA,IAC3B,WAAW,CAAC,GAAA,KAAgB,OAAO,IAAA,CAAK,CAAA,OAAA,EAAU,GAAG,CAAA,CAAE;AAAA,GACxD,CAAA;AAED,EAAA,MAAM,MAAA,GAAS,MAAMC,+BAAA,CAAoB;AAAA,IACvC,QAAA,EAAU;AAAA,GACX,CAAA;AAGD,EAAA,MAAM,SAAA,GAAY,MAAA,CAAO,UAAA,IAAmBF,eAAA,CAAA,IAAA,CAAK,SAAS,UAAU,CAAA;AACpE,EAAA,MAAM,MAAA,GAAS,MAAM,uBAAA,CAAwB,SAAS,CAAA;AAGtD,EAAA,MAAM,QAAA,GAAW,MAAM,oBAAA,CAAqB;AAAA,IAC1C,MAAA;AAAA,IACA,MAAA;AAAA,IACA,aAAA,EAAe,MAAA;AAAA,IACf,KAAA;AAAA,IACA,MAAA;AAAA,IACA,eAAA,EAAiB,OAAO,UAAA,EAAY,iBAAA;AAAA,IACpC,SAAA,EAAW,OAAO,UAAA,EAAY,UAAA;AAAA,IAC9B,OAAA,EAAS,CAAC,GAAA,KAAQ,MAAA,CAAO,MAAM,CAAA,cAAA,EAAiB,GAAA,CAAI,OAAO,CAAA,CAAE;AAAA,GAC9D,CAAA;AAGD,EAAA,MAAM,KAAA,GAAsB;AAAA,IAC1B,gBAAA,CAAiB,MAAM,QAAA,CAAS,QAAA,IAAY,SAAS,CAAA;AAAA,IACrD,sBAAA,CAAuB,WAAW,MAAM,CAAA;AAAA,IACxC,iBAAiB,MAAM,CAAA;AAAA,IACvB,eAAA,CAAgB,WAAW,MAAM;AAAA,GACnC;AAGA,EAAA,MAAM,IAAA,GAAOG,kCAAsB,KAAK,CAAA;AACxC,EAAA,IAAI,IAAA,EAAM;AACR,IAAA,MAAA,CAAO,IAAA;AAAA,MACL,uCACY,IAAA,CAAK,UAAU,aAAa,IAAA,CAAK,SAAS,qBACvC,SAAS,CAAA;AAAA,KAC1B;AAAA,EACF,CAAA,MAAO;AACL,IAAA,MAAA,CAAO,IAAA,CAAK,CAAA,uCAAA,EAA0C,SAAS,CAAA,CAAE,CAAA;AAAA,EACnE;AAGA,EAAA,eAAe,QAAA,GAA0B;AACvC,IAAA,MAAA,CAAO,KAAK,uCAAuC,CAAA;AACnD,IAAA,MAAM,SAAS,IAAA,EAAK;AACpB,IAAA,MAAM,MAAM,KAAA,EAAM;AAClB,IAAA,MAAM,OAAO,KAAA,EAAM;AACnB,IAAA,MAAA,CAAO,KAAK,+BAA+B,CAAA;AAAA,EAC7C;AAEA,EAAA,OAAO;AAAA,IACL,QAAA;AAAA,IACA,KAAA;AAAA,IACA,aAAa,QAAA,CAAS,WAAA;AAAA,IACtB,OAAA;AAAA,IACA,KAAA,EAAO,MAAM,QAAA,CAAS,iBAAA,CAAkB,KAAA,EAAM;AAAA,IAC9C;AAAA,GACF;AACF;ACjLA,IAAM,oBAAA,GAAuB,iBAAA;AAe7B,eAAsB,mBAAmB,OAAA,EAAgD;AACvF,EAAA,MAAM,SAAA,GAAY,SAAS,SAAA,IAAa,GAAA;AACxC,EAAA,MAAM,QAAA,GAAW,SAAS,QAAA,IAAY,oBAAA;AAGtC,EAAA,MAAM,EAAE,UAAA,EAAY,eAAA,EAAiB,WAAW,cAAA,EAAe,GAAI,MAAMC,sBAAA,EAAgB;AAGzF,EAAA,MAAM,CAAA,GAAIC,uBAAgB,eAAe,CAAA;AACzC,EAAA,MAAM,CAAA,GAAIA,uBAAgB,cAAc,CAAA;AAGxC,EAAA,MAAM,UAAA,GAAkB;AAAA,IACtB,GAAA,EAAK,KAAA;AAAA,IACL,GAAA,EAAK,SAAA;AAAA,IACL,CAAA;AAAA,IACA,CAAA;AAAA,IACA,GAAA,EAAK,OAAA;AAAA,IACL,GAAA,EAAK;AAAA,GACP;AAGA,EAAA,MAAM,GAAA,GAAM,cAAc,UAAU,CAAA;AACpC,EAAA,UAAA,CAAW,GAAA,GAAM,GAAA;AAGjB,EAAA,MAAM,SAAA,GAAiB;AAAA,IACrB,GAAA,EAAK,KAAA;AAAA,IACL,GAAA,EAAK,SAAA;AAAA,IACL,CAAA;AAAA,IACA,GAAA;AAAA,IACA,GAAA,EAAK,OAAA;AAAA,IACL,GAAA,EAAK;AAAA,GACP;AAGA,EAAA,MAASC,cAAA,CAAA,KAAA,CAAM,SAAA,EAAW,EAAE,SAAA,EAAW,MAAM,CAAA;AAC7C,EAAA,MAAM,OAAA,GAAeC,eAAA,CAAA,IAAA,CAAK,SAAA,EAAW,QAAQ,CAAA;AAC7C,EAAA,MAASD,cAAA,CAAA,SAAA,CAAU,SAAS,IAAA,CAAK,SAAA,CAAU,YAAY,IAAA,EAAM,CAAC,CAAA,GAAI,IAAA,EAAM,OAAO,CAAA;AAG/E,EAAA,IAAI;AACF,IAAA,MAASA,cAAA,CAAA,KAAA,CAAM,SAAS,GAAK,CAAA;AAAA,EAC/B,CAAA,CAAA,MAAQ;AAEN,IAAA,OAAA,CAAQ,MAAA,CAAO,KAAA;AAAA,MACb,8CAA8C,OAAO,CAAA;AAAA;AAAA,KAEvD;AAAA,EACF;AAEA,EAAA,OAAO,EAAE,GAAA,EAAK,OAAA,EAAS,SAAA,EAAW,UAAA,EAAW;AAC/C;AAUA,eAAsB,UAAU,IAAA,EAA+B;AAC7D,EAAA,IAAI,SAAA;AAEJ,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,QAAQ,CAAA,EAAA,EAAK;AACpC,IAAA,IAAI,KAAK,CAAC,CAAA,KAAM,kBAAkB,CAAA,GAAI,CAAA,GAAI,KAAK,MAAA,EAAQ;AACrD,MAAA,SAAA,GAAY,IAAA,CAAK,IAAI,CAAC,CAAA;AACtB,MAAA,CAAA,EAAA;AAAA,IACF,CAAA,MAAA,IAAW,KAAK,CAAC,CAAA,KAAM,YAAY,IAAA,CAAK,CAAC,MAAM,IAAA,EAAM;AACnD,MAAA,OAAA,CAAQ,MAAA,CAAO,KAAA;AAAA,QACb;AAAA,OAKF;AACA,MAAA;AAAA,IACF;AAAA,EACF;AAEA,EAAA,MAAM,MAAA,GAAS,MAAM,kBAAA,CAAmB,EAAE,WAAW,CAAA;AAErD,EAAA,OAAA,CAAQ,OAAO,KAAA,CAAM,CAAA;AAAA,CAA+B,CAAA;AACpD,EAAA,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,CAAA,YAAA,EAAe,MAAA,CAAO,GAAG;AAAA,CAAI,CAAA;AAClD,EAAA,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,CAAA,YAAA,EAAe,MAAA,CAAO,OAAO;AAAA,CAAI,CAAA;AACtD,EAAA,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,CAAA,YAAA,EAAe,MAAA,CAAO,UAAU,CAAC;AAAA,CAAI,CAAA;AAC1D,EAAA,OAAA,CAAQ,OAAO,KAAA,CAAM;AAAA;AAAA,CAAuC,CAAA;AAC5D,EAAA,OAAA,CAAQ,OAAO,KAAA,CAAM,CAAA,yBAAA,EAAiCC,eAAA,CAAA,OAAA,CAAQ,MAAA,CAAO,OAAO,CAAC,CAAA;AAAA,CAAK,CAAA;AACpF","file":"index.cjs","sourcesContent":["/**\n * @peac/adapter-openclaw - OpenClaw Types\n *\n * Types for OpenClaw tool call events and PEAC integration.\n */\n\n// =============================================================================\n// OpenClaw Event Types (Input from OpenClaw)\n// =============================================================================\n\n/**\n * OpenClaw tool call event - represents a single tool invocation.\n *\n * This is the input format from OpenClaw hooks (after_tool_call, etc.).\n */\nexport interface OpenClawToolCallEvent {\n /** OpenClaw's internal tool call ID */\n tool_call_id: string;\n\n /** Run ID (conversation/session scope) */\n run_id: string;\n\n /** Session key (optional, for workflow correlation) */\n session_key?: string;\n\n /** Tool name */\n tool_name: string;\n\n /** Tool provider (e.g., \"builtin\", \"mcp\", \"custom\") */\n tool_provider?: string;\n\n /** Tool version (if versioned) */\n tool_version?: string;\n\n /** Input parameters (JSON-serializable) */\n input: unknown;\n\n /** Output result (JSON-serializable) */\n output?: unknown;\n\n /** Execution start time (RFC 3339) */\n started_at: string;\n\n /** Execution end time (RFC 3339) */\n completed_at?: string;\n\n /** Duration in milliseconds (from monotonic clock) */\n duration_ms?: number;\n\n /** Execution status */\n status: 'ok' | 'error' | 'timeout' | 'canceled';\n\n /** Error code (if status is error) */\n error_code?: string;\n\n /** Error message (if status is error) */\n error_message?: string;\n\n /** Whether the error is retryable */\n retryable?: boolean;\n\n /** Policy context at execution time */\n policy?: OpenClawPolicyContext;\n\n /** OpenClaw-specific context */\n context?: OpenClawContext;\n}\n\n/**\n * OpenClaw policy context at execution time.\n */\nexport interface OpenClawPolicyContext {\n /** Policy decision (allow/deny/constrained) */\n decision: 'allow' | 'deny' | 'constrained';\n\n /** Whether sandbox mode was enabled */\n sandbox_enabled?: boolean;\n\n /** Whether elevated permissions were used */\n elevated?: boolean;\n\n /** Hash of the effective policy (for audit) */\n policy_hash?: string;\n}\n\n/**\n * OpenClaw-specific context (channel, workspace, etc.).\n */\nexport interface OpenClawContext {\n /** Channel information */\n channel?: {\n kind: 'direct' | 'group' | 'api';\n id?: string;\n };\n\n /** Workspace configuration hash */\n workspace_digest?: string;\n\n /** OpenClaw gateway version */\n gateway_version?: string;\n\n /** Security audit digest (hash of full audit report) */\n audit_digest?: string;\n}\n\n// =============================================================================\n// Adapter Configuration\n// =============================================================================\n\n/**\n * OpenClaw adapter configuration.\n */\nexport interface OpenClawAdapterConfig {\n /** Platform identifier (default: \"openclaw\") */\n platform?: string;\n\n /** Platform version (e.g., \"0.2.0\") */\n platform_version?: string;\n\n /** Plugin ID for provenance tracking */\n plugin_id?: string;\n\n /** Plugin digest for integrity verification */\n plugin_digest?: string;\n\n /** Capture mode configuration */\n capture?: {\n /** Redaction mode for payloads */\n mode: 'hash_only' | 'allowlist';\n\n /** Tool names for plaintext capture (only when mode=allowlist) */\n allowlist?: string[];\n\n /** Maximum payload size to hash (bytes, default: 1MB) */\n max_payload_size?: number;\n };\n\n /** Signing configuration (for background emitter) */\n signing?: {\n /** Key reference (env var, keychain path, sidecar socket) */\n key_ref: string;\n\n /** Issuer URI */\n issuer: string;\n\n /** Audience URI (optional) */\n audience?: string;\n };\n\n /** Correlation options */\n correlation?: {\n /** Include workflow context from session */\n include_workflow?: boolean;\n\n /** Include agent identity attestation */\n include_identity?: boolean;\n\n /** Reference to identity attestation */\n identity_attestation_ref?: string;\n };\n}\n\n// =============================================================================\n// Mapper Output Types\n// =============================================================================\n\n/**\n * Result of mapping an OpenClaw event to a CapturedAction.\n * Includes validation status and any warnings.\n */\nexport interface MappingResult {\n /** Whether the mapping succeeded */\n success: boolean;\n\n /** The mapped action (if success) */\n action?: import('@peac/capture-core').CapturedAction;\n\n /** Error code (if failed) */\n error_code?: string;\n\n /** Error message (if failed) */\n error_message?: string;\n\n /** Warnings (non-fatal issues) */\n warnings?: MappingWarning[];\n}\n\n/**\n * Mapping warning (non-fatal issue).\n */\nexport interface MappingWarning {\n code: string;\n message: string;\n field?: string;\n}\n\n// =============================================================================\n// Emitter Types\n// =============================================================================\n\n/**\n * Receipt emitter interface.\n *\n * Responsible for converting captured actions to signed PEAC receipts.\n */\nexport interface ReceiptEmitter {\n /** Emit a receipt from a spool entry */\n emit(entry: import('@peac/capture-core').SpoolEntry): Promise<EmitResult>;\n\n /** Flush any pending receipts */\n flush(): Promise<void>;\n\n /** Close the emitter */\n close(): Promise<void>;\n}\n\n/**\n * Result of emitting a receipt.\n */\nexport interface EmitResult {\n /** Whether emission succeeded */\n success: boolean;\n\n /** Receipt file path (if success) */\n receipt_path?: string;\n\n /** Receipt ID (rid) */\n receipt_id?: string;\n\n /** Error code (if failed) */\n error_code?: string;\n\n /** Error message (if failed) */\n error_message?: string;\n}\n\n// =============================================================================\n// OpenClaw Extension Keys (for nested extensions)\n// =============================================================================\n\n/**\n * OpenClaw-specific extension keys used in interaction.extensions.\n */\nexport const OPENCLAW_EXTENSION_KEYS = {\n /** OpenClaw context extension */\n CONTEXT: 'org.openclaw/context',\n\n /** Security audit digest */\n AUDIT_DIGEST: 'org.openclaw/audit_digest',\n} as const;\n\n/**\n * OpenClaw context extension data.\n */\nexport interface OpenClawContextExtension {\n channel?: {\n kind: 'direct' | 'group' | 'api';\n id?: string;\n };\n workspace_digest?: string;\n tool_call_id?: string;\n gateway_version?: string;\n}\n\n// =============================================================================\n// Error Codes\n// =============================================================================\n\n/**\n * OpenClaw adapter error codes.\n */\nexport const OPENCLAW_ERROR_CODES = {\n /** Missing required field in OpenClaw event */\n MISSING_FIELD: 'E_OPENCLAW_MISSING_FIELD',\n\n /** Invalid field value in OpenClaw event */\n INVALID_FIELD: 'E_OPENCLAW_INVALID_FIELD',\n\n /** Payload serialization failed */\n SERIALIZATION_FAILED: 'E_OPENCLAW_SERIALIZATION_FAILED',\n\n /** Signing failed */\n SIGNING_FAILED: 'E_OPENCLAW_SIGNING_FAILED',\n\n /** Emitter not configured */\n EMITTER_NOT_CONFIGURED: 'E_OPENCLAW_EMITTER_NOT_CONFIGURED',\n} as const;\n\nexport type OpenClawErrorCode = (typeof OPENCLAW_ERROR_CODES)[keyof typeof OPENCLAW_ERROR_CODES];\n\n// =============================================================================\n// Warning Codes\n// =============================================================================\n\n/**\n * OpenClaw adapter warning codes.\n */\nexport const OPENCLAW_WARNING_CODES = {\n /** Payload exceeded size limit and was truncated for hashing */\n PAYLOAD_TRUNCATED: 'W_OPENCLAW_PAYLOAD_TRUNCATED',\n\n /** Payload serialization failed (circular refs, BigInt, etc.) */\n SERIALIZATION_FAILED: 'W_OPENCLAW_SERIALIZATION_FAILED',\n\n /** Optional field missing (non-critical) */\n OPTIONAL_FIELD_MISSING: 'W_OPENCLAW_OPTIONAL_FIELD_MISSING',\n\n /** Unknown tool provider */\n UNKNOWN_PROVIDER: 'W_OPENCLAW_UNKNOWN_PROVIDER',\n\n /** Payload dropped due to redaction policy (hash_only mode for non-allowlisted tool) */\n PAYLOAD_REDACTED: 'W_OPENCLAW_PAYLOAD_REDACTED',\n} as const;\n\nexport type OpenClawWarningCode =\n (typeof OPENCLAW_WARNING_CODES)[keyof typeof OPENCLAW_WARNING_CODES];\n","/**\n * @peac/adapter-openclaw - Mapper\n *\n * Maps OpenClaw tool call events to PEAC CapturedAction format.\n */\n\nimport { canonicalize } from '@peac/crypto';\nimport type { CapturedAction } from '@peac/capture-core';\nimport type {\n OpenClawToolCallEvent,\n OpenClawAdapterConfig,\n MappingResult,\n MappingWarning,\n OpenClawContextExtension,\n} from './types.js';\nimport { OPENCLAW_ERROR_CODES, OPENCLAW_WARNING_CODES, OPENCLAW_EXTENSION_KEYS } from './types.js';\n\n// =============================================================================\n// Constants\n// =============================================================================\n\nconst DEFAULT_PLATFORM = 'openclaw';\nconst DEFAULT_KIND = 'tool.call';\n\n// =============================================================================\n// Mapper Implementation\n// =============================================================================\n\n/**\n * Map an OpenClaw tool call event to a PEAC CapturedAction.\n *\n * @param event - OpenClaw tool call event\n * @param config - Adapter configuration\n * @returns Mapping result with action or error\n */\nexport function mapToolCallEvent(\n event: OpenClawToolCallEvent,\n config?: OpenClawAdapterConfig\n): MappingResult {\n const warnings: MappingWarning[] = [];\n\n // Validate required fields\n const validationError = validateRequiredFields(event);\n if (validationError) {\n return {\n success: false,\n error_code: validationError.code,\n error_message: validationError.message,\n };\n }\n\n // Build interaction ID (deterministic, for dedupe)\n const interactionId = buildInteractionId(event);\n\n // Get capture policy configuration\n const captureMode = config?.capture?.mode ?? 'hash_only';\n const allowlist = config?.capture?.allowlist ?? [];\n const maxPayloadSize = config?.capture?.max_payload_size ?? 1024 * 1024; // 1MB default\n\n // Check if this tool is allowlisted for plaintext capture\n const isAllowlisted = captureMode === 'allowlist' && allowlist.includes(event.tool_name);\n\n // Serialize input/output to bytes with policy enforcement\n const inputResult = serializePayloadWithPolicy(\n event.input,\n maxPayloadSize,\n isAllowlisted,\n 'input'\n );\n const outputResult =\n event.output !== undefined\n ? serializePayloadWithPolicy(event.output, maxPayloadSize, isAllowlisted, 'output')\n : undefined;\n\n // Collect warnings from serialization\n if (inputResult.warning) {\n warnings.push(inputResult.warning);\n }\n if (outputResult?.warning) {\n warnings.push(outputResult.warning);\n }\n\n const inputBytes = inputResult.bytes;\n const outputBytes = outputResult?.bytes;\n\n // Build platform metadata\n const platform = config?.platform ?? DEFAULT_PLATFORM;\n const platformVersion = config?.platform_version;\n const pluginId = config?.plugin_id;\n\n // Build OpenClaw-specific extensions\n const extensions = buildExtensions(event);\n\n // Build the CapturedAction\n const action: CapturedAction = {\n id: interactionId,\n kind: DEFAULT_KIND,\n platform,\n started_at: event.started_at,\n completed_at: event.completed_at,\n tool_name: event.tool_name,\n tool_provider: event.tool_provider,\n input_bytes: inputBytes,\n output_bytes: outputBytes,\n status: event.status,\n error_code: event.error_code,\n retryable: event.retryable,\n metadata: {\n // Platform metadata\n ...(platformVersion && { platform_version: platformVersion }),\n ...(pluginId && { plugin_id: pluginId }),\n\n // Tool version (not a standard field, stored in metadata)\n ...(event.tool_version && { tool_version: event.tool_version }),\n\n // Policy context\n ...(event.policy && {\n policy_decision: event.policy.decision,\n sandbox_enabled: event.policy.sandbox_enabled,\n elevated: event.policy.elevated,\n policy_hash: event.policy.policy_hash,\n }),\n\n // OpenClaw extensions (will be mapped to interaction.extensions)\n ...extensions,\n },\n };\n\n return {\n success: true,\n action,\n warnings: warnings.length > 0 ? warnings : undefined,\n };\n}\n\n/**\n * Build a batch of CapturedActions from OpenClaw events.\n *\n * @param events - Array of OpenClaw tool call events\n * @param config - Adapter configuration\n * @returns Array of mapping results\n */\nexport function mapToolCallEventBatch(\n events: OpenClawToolCallEvent[],\n config?: OpenClawAdapterConfig\n): MappingResult[] {\n return events.map((event) => mapToolCallEvent(event, config));\n}\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * Validate required fields in OpenClaw event.\n */\nfunction validateRequiredFields(\n event: OpenClawToolCallEvent\n): { code: string; message: string } | null {\n if (!event.tool_call_id) {\n return {\n code: OPENCLAW_ERROR_CODES.MISSING_FIELD,\n message: 'Missing required field: tool_call_id',\n };\n }\n\n if (!event.run_id) {\n return {\n code: OPENCLAW_ERROR_CODES.MISSING_FIELD,\n message: 'Missing required field: run_id',\n };\n }\n\n if (!event.tool_name) {\n return {\n code: OPENCLAW_ERROR_CODES.MISSING_FIELD,\n message: 'Missing required field: tool_name',\n };\n }\n\n if (!event.started_at) {\n return {\n code: OPENCLAW_ERROR_CODES.MISSING_FIELD,\n message: 'Missing required field: started_at',\n };\n }\n\n if (!event.status) {\n return {\n code: OPENCLAW_ERROR_CODES.MISSING_FIELD,\n message: 'Missing required field: status',\n };\n }\n\n // Validate status is a known value\n const validStatuses = ['ok', 'error', 'timeout', 'canceled'];\n if (!validStatuses.includes(event.status)) {\n return {\n code: OPENCLAW_ERROR_CODES.INVALID_FIELD,\n message: `Invalid status: ${event.status}. Expected one of: ${validStatuses.join(', ')}`,\n };\n }\n\n // Validate timestamps are RFC 3339\n if (!isValidRfc3339(event.started_at)) {\n return {\n code: OPENCLAW_ERROR_CODES.INVALID_FIELD,\n message: `Invalid started_at timestamp: ${event.started_at}. Expected RFC 3339 format.`,\n };\n }\n\n if (event.completed_at && !isValidRfc3339(event.completed_at)) {\n return {\n code: OPENCLAW_ERROR_CODES.INVALID_FIELD,\n message: `Invalid completed_at timestamp: ${event.completed_at}. Expected RFC 3339 format.`,\n };\n }\n\n return null;\n}\n\n/**\n * Build a deterministic interaction ID from OpenClaw event.\n *\n * Uses base64url encoding to handle delimiter collisions - if run_id or\n * tool_call_id contains ':', the ID would be ambiguous without encoding.\n *\n * Format: openclaw/{base64url(run_id)}/{base64url(tool_call_id)}\n */\nfunction buildInteractionId(event: OpenClawToolCallEvent): string {\n const runIdEncoded = base64urlEncode(event.run_id);\n const toolCallIdEncoded = base64urlEncode(event.tool_call_id);\n return `openclaw/${runIdEncoded}/${toolCallIdEncoded}`;\n}\n\n/**\n * Base64url encode a string (RFC 4648 section 5).\n * URL-safe: replaces + with -, / with _, removes padding.\n */\nfunction base64urlEncode(str: string): string {\n // Use TextEncoder for proper UTF-8 handling\n const bytes = new TextEncoder().encode(str);\n // Convert to base64\n const base64 = btoa(String.fromCharCode(...bytes));\n // Make URL-safe: replace + with -, / with _, remove =\n return base64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n}\n\n/**\n * Result of payload serialization with policy enforcement.\n */\ninterface SerializationResult {\n bytes?: Uint8Array;\n warning?: MappingWarning;\n truncated?: boolean;\n}\n\n/**\n * Serialize a payload to bytes with policy enforcement.\n *\n * Applies:\n * - Size limits (truncation if exceeds maxPayloadSize)\n * - Redaction policy (hash_only drops bytes for non-allowlisted tools)\n *\n * @param payload - The payload to serialize\n * @param maxPayloadSize - Maximum payload size in bytes\n * @param isAllowlisted - Whether this tool is allowlisted for plaintext capture\n * @param fieldName - Field name for warning messages\n * @returns Serialization result with bytes and/or warning\n */\nfunction serializePayloadWithPolicy(\n payload: unknown,\n maxPayloadSize: number,\n isAllowlisted: boolean,\n fieldName: string\n): SerializationResult {\n if (payload === undefined) {\n return {};\n }\n\n // Try to serialize using canonical JSON (RFC 8785)\n // This ensures deterministic hashes across implementations\n let bytes: Uint8Array;\n try {\n const json = canonicalize(payload);\n bytes = new TextEncoder().encode(json);\n } catch {\n // Serialization failed (circular references, BigInt, functions, etc.)\n return {\n warning: {\n code: OPENCLAW_WARNING_CODES.SERIALIZATION_FAILED,\n message: `${fieldName} payload could not be serialized (circular ref, BigInt, etc.)`,\n field: fieldName,\n },\n };\n }\n\n // Check size limit and truncate if needed\n let truncated = false;\n if (bytes.length > maxPayloadSize) {\n bytes = bytes.slice(0, maxPayloadSize);\n truncated = true;\n }\n\n // Apply redaction policy - capture-core will hash these bytes\n // In hash_only mode for non-allowlisted tools, we still pass bytes\n // for hashing but could add a warning for transparency\n const result: SerializationResult = { bytes, truncated };\n\n if (truncated) {\n result.warning = {\n code: OPENCLAW_WARNING_CODES.PAYLOAD_TRUNCATED,\n message: `${fieldName} payload exceeded ${maxPayloadSize} bytes and was truncated`,\n field: fieldName,\n };\n }\n\n return result;\n}\n\n/**\n * Build OpenClaw-specific extensions for the action metadata.\n */\nfunction buildExtensions(event: OpenClawToolCallEvent): Record<string, unknown> {\n const extensions: Record<string, unknown> = {};\n\n // OpenClaw context extension\n if (event.context) {\n const contextExt: OpenClawContextExtension = {\n ...(event.context.channel && { channel: event.context.channel }),\n ...(event.context.workspace_digest && { workspace_digest: event.context.workspace_digest }),\n ...(event.context.gateway_version && { gateway_version: event.context.gateway_version }),\n tool_call_id: event.tool_call_id,\n };\n\n if (Object.keys(contextExt).length > 0) {\n extensions[OPENCLAW_EXTENSION_KEYS.CONTEXT] = contextExt;\n }\n } else {\n // Always include tool_call_id for correlation\n extensions[OPENCLAW_EXTENSION_KEYS.CONTEXT] = {\n tool_call_id: event.tool_call_id,\n };\n }\n\n // Security audit digest\n if (event.context?.audit_digest) {\n extensions[OPENCLAW_EXTENSION_KEYS.AUDIT_DIGEST] = event.context.audit_digest;\n }\n\n return extensions;\n}\n\n/**\n * Check if a string is a valid RFC 3339 timestamp.\n */\nfunction isValidRfc3339(timestamp: string): boolean {\n // Basic RFC 3339 pattern (not exhaustive but catches common issues)\n const rfc3339Pattern = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?(Z|[+-]\\d{2}:\\d{2})$/;\n if (!rfc3339Pattern.test(timestamp)) {\n return false;\n }\n\n // Verify it parses to a valid date\n const date = new Date(timestamp);\n return !isNaN(date.getTime());\n}\n\n// =============================================================================\n// Utility Functions\n// =============================================================================\n\n/**\n * Extract workflow ID from OpenClaw session key.\n *\n * If session_key is provided, it becomes the workflow_id for correlation.\n */\nexport function extractWorkflowId(event: OpenClawToolCallEvent): string | undefined {\n return event.session_key;\n}\n\n/**\n * Build a PEAC-compatible workflow context from OpenClaw event.\n */\nexport function buildWorkflowContext(\n event: OpenClawToolCallEvent\n): Record<string, unknown> | undefined {\n if (!event.session_key) {\n return undefined;\n }\n\n return {\n workflow_id: event.session_key,\n step_id: event.tool_call_id,\n tool_name: event.tool_name,\n framework: 'openclaw',\n };\n}\n","/**\n * @peac/adapter-openclaw - Hook Bindings\n *\n * Hook bindings for OpenClaw tool call capture.\n * Designed for sync capture (< 10ms target).\n */\n\nimport type { CaptureSession, CaptureResult, SpoolEntry } from '@peac/capture-core';\nimport type { OpenClawToolCallEvent, OpenClawAdapterConfig, MappingResult } from './types.js';\nimport { mapToolCallEvent } from './mapper.js';\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Result of a hook capture operation.\n * More flexible than CaptureResult to allow adapter-specific error codes.\n */\nexport type HookCaptureResult =\n | { success: true; entry: SpoolEntry }\n | { success: false; code: string; message: string };\n\n// =============================================================================\n// Hook Handler Interface\n// =============================================================================\n\n/**\n * Hook handler for OpenClaw tool call events.\n */\nexport interface OpenClawHookHandler {\n /** Handle after_tool_call hook */\n afterToolCall(event: OpenClawToolCallEvent): Promise<HookCaptureResult>;\n\n /** Get the underlying capture session */\n getSession(): CaptureSession;\n\n /** Close the handler */\n close(): Promise<void>;\n}\n\n/**\n * Configuration for creating a hook handler.\n */\nexport interface HookHandlerConfig {\n /** Capture session to use */\n session: CaptureSession;\n\n /** Adapter configuration */\n config?: OpenClawAdapterConfig;\n\n /** Callback for capture events (for telemetry/logging) */\n onCapture?: (result: HookCaptureResult, event: OpenClawToolCallEvent) => void;\n\n /** Callback for mapping errors */\n onMappingError?: (result: MappingResult, event: OpenClawToolCallEvent) => void;\n}\n\n// =============================================================================\n// Hook Handler Implementation\n// =============================================================================\n\n/**\n * Create a hook handler for OpenClaw tool call events.\n *\n * @param handlerConfig - Configuration for the handler\n * @returns Hook handler instance\n */\nexport function createHookHandler(handlerConfig: HookHandlerConfig): OpenClawHookHandler {\n const { session, config, onCapture, onMappingError } = handlerConfig;\n\n return {\n async afterToolCall(event: OpenClawToolCallEvent): Promise<HookCaptureResult> {\n // Map OpenClaw event to CapturedAction\n const mappingResult = mapToolCallEvent(event, config);\n\n if (!mappingResult.success || !mappingResult.action) {\n // Mapping failed - report and return error result\n if (onMappingError) {\n onMappingError(mappingResult, event);\n }\n\n return {\n success: false,\n code: mappingResult.error_code ?? 'E_OPENCLAW_MAPPING_FAILED',\n message: mappingResult.error_message ?? 'Failed to map OpenClaw event',\n };\n }\n\n // Capture the action\n const captureResult = await session.capture(mappingResult.action);\n\n // Convert to HookCaptureResult (compatible types)\n const hookResult: HookCaptureResult = captureResult.success\n ? { success: true, entry: captureResult.entry }\n : { success: false, code: captureResult.code, message: captureResult.message };\n\n // Invoke callback\n if (onCapture) {\n onCapture(hookResult, event);\n }\n\n return hookResult;\n },\n\n getSession(): CaptureSession {\n return session;\n },\n\n async close(): Promise<void> {\n await session.close();\n },\n };\n}\n\n// =============================================================================\n// Batch Capture\n// =============================================================================\n\n/**\n * Capture multiple tool call events in sequence.\n *\n * Note: Events are captured in order. For parallel capture, use individual\n * afterToolCall calls with Promise.all.\n *\n * @param handler - Hook handler\n * @param events - Array of tool call events\n * @returns Array of capture results (same order as events)\n */\nexport async function captureBatch(\n handler: OpenClawHookHandler,\n events: OpenClawToolCallEvent[]\n): Promise<HookCaptureResult[]> {\n const results: HookCaptureResult[] = [];\n\n for (const event of events) {\n const result = await handler.afterToolCall(event);\n results.push(result);\n }\n\n return results;\n}\n\n/**\n * Capture multiple tool call events in parallel.\n *\n * Warning: Parallel capture may result in non-deterministic chain ordering.\n * Use captureBatch for deterministic ordering.\n *\n * @param handler - Hook handler\n * @param events - Array of tool call events\n * @returns Array of capture results (same order as events)\n */\nexport async function captureParallel(\n handler: OpenClawHookHandler,\n events: OpenClawToolCallEvent[]\n): Promise<HookCaptureResult[]> {\n return Promise.all(events.map((event) => handler.afterToolCall(event)));\n}\n\n// =============================================================================\n// Session History Tailer (Fallback)\n// =============================================================================\n\n/**\n * Session history tailer for fallback capture.\n *\n * If OpenClaw hooks don't provide complete event data, this can poll\n * the session history API to backfill missed events.\n */\nexport interface SessionHistoryTailer {\n /** Start tailing session history */\n start(): void;\n\n /** Stop tailing */\n stop(): void;\n\n /** Get the last processed event ID */\n getLastEventId(): string | undefined;\n\n /** Whether the tailer is running */\n isRunning(): boolean;\n}\n\n/**\n * Configuration for session history tailer.\n */\nexport interface TailerConfig {\n /** Hook handler to use for capture */\n handler: OpenClawHookHandler;\n\n /** Session ID to tail */\n sessionId: string;\n\n /** Polling interval in milliseconds (default: 1000) */\n pollIntervalMs?: number;\n\n /** Function to fetch session history */\n fetchHistory: (sessionId: string, afterEventId?: string) => Promise<OpenClawToolCallEvent[]>;\n\n /** Callback for tailer errors */\n onError?: (error: Error) => void;\n}\n\n/**\n * Create a session history tailer.\n *\n * @param tailerConfig - Configuration for the tailer\n * @returns Session history tailer instance\n */\nexport function createSessionHistoryTailer(tailerConfig: TailerConfig): SessionHistoryTailer {\n const { handler, sessionId, pollIntervalMs = 1000, fetchHistory, onError } = tailerConfig;\n\n let running = false;\n let inFlight = false;\n let lastEventId: string | undefined;\n let intervalHandle: ReturnType<typeof setInterval> | undefined;\n\n const poll = async () => {\n // Prevent overlapping polls - if a poll takes longer than the\n // interval, skip this tick rather than double-processing\n if (inFlight) return;\n\n inFlight = true;\n try {\n const events = await fetchHistory(sessionId, lastEventId);\n\n for (const event of events) {\n // Check if tailer was stopped during processing\n if (!running) break;\n\n await handler.afterToolCall(event);\n lastEventId = event.tool_call_id;\n }\n } catch (error) {\n if (onError) {\n onError(error instanceof Error ? error : new Error(String(error)));\n }\n } finally {\n inFlight = false;\n }\n };\n\n return {\n start(): void {\n if (running) return;\n running = true;\n intervalHandle = setInterval(poll, pollIntervalMs);\n // Run immediately on start\n poll();\n },\n\n stop(): void {\n if (!running) return;\n running = false;\n if (intervalHandle) {\n clearInterval(intervalHandle);\n intervalHandle = undefined;\n }\n },\n\n getLastEventId(): string | undefined {\n return lastEventId;\n },\n\n isRunning(): boolean {\n return running;\n },\n };\n}\n","/**\n * @peac/adapter-openclaw - Background Emitter\n *\n * Background service for converting captured actions to signed PEAC receipts.\n * Runs asynchronously to avoid blocking the sync capture path.\n */\n\nimport type { SpoolEntry } from '@peac/capture-core';\nimport { toInteractionEvidence } from '@peac/capture-core';\nimport type { ReceiptEmitter, EmitResult, OpenClawAdapterConfig } from './types.js';\nimport { OPENCLAW_ERROR_CODES } from './types.js';\n\n// =============================================================================\n// Signer Interface\n// =============================================================================\n\n/**\n * Signer interface for receipt signing.\n *\n * Different implementations can support various key storage mechanisms:\n * - Level 1: Environment variable (dev only)\n * - Level 2: OS Keychain\n * - Level 3: Sidecar process\n * - Level 4: Hardware module (YubiKey, TPM, HSM)\n *\n * IMPORTANT: Implementations MUST include the key ID (kid) in the JWS header.\n * The getKeyId() method allows callers to inspect which kid will be used\n * without parsing the resulting JWS.\n */\nexport interface Signer {\n /**\n * Sign a payload and return JWS compact serialization.\n * The JWS header MUST include the 'kid' claim for verifier key selection.\n */\n sign(payload: unknown): Promise<string>;\n\n /** Get the key ID (kid) that will be included in the JWS header */\n getKeyId(): string;\n\n /** Get the issuer URI */\n getIssuer(): string;\n\n /** Get the audience URI (optional) */\n getAudience(): string | undefined;\n}\n\n// =============================================================================\n// Receipt Writer Interface\n// =============================================================================\n\n/**\n * Receipt writer interface for persisting signed receipts.\n */\nexport interface ReceiptWriter {\n /** Write a signed receipt */\n write(receipt: SignedReceipt): Promise<string>;\n\n /** Close the writer */\n close(): Promise<void>;\n}\n\n/**\n * Signed receipt ready for persistence.\n */\nexport interface SignedReceipt {\n /** Receipt ID (rid) */\n rid: string;\n\n /** JWS compact serialization */\n jws: string;\n\n /** Interaction ID (for correlation) */\n interaction_id: string;\n\n /** Entry digest (for verification) */\n entry_digest: string;\n}\n\n// =============================================================================\n// Emitter Implementation\n// =============================================================================\n\n/**\n * Configuration for creating a receipt emitter.\n */\nexport interface EmitterConfig {\n /** Signer for receipt signing */\n signer: Signer;\n\n /** Writer for receipt persistence */\n writer: ReceiptWriter;\n\n /** Adapter configuration */\n config?: OpenClawAdapterConfig;\n\n /** Callback for emit events */\n onEmit?: (result: EmitResult, entry: SpoolEntry) => void;\n\n /** Callback for emit errors */\n onError?: (error: Error, entry: SpoolEntry) => void;\n}\n\n/**\n * Create a receipt emitter.\n *\n * @param emitterConfig - Configuration for the emitter\n * @returns Receipt emitter instance\n */\nexport function createReceiptEmitter(emitterConfig: EmitterConfig): ReceiptEmitter {\n const { signer, writer, onEmit, onError } = emitterConfig;\n\n let closed = false;\n\n return {\n async emit(entry: SpoolEntry): Promise<EmitResult> {\n if (closed) {\n return {\n success: false,\n error_code: 'E_EMITTER_CLOSED',\n error_message: 'Emitter has been closed',\n };\n }\n\n try {\n // Convert SpoolEntry to InteractionEvidence\n // Note: Platform info is already in the entry.action from the mapper\n const interaction = toInteractionEvidence(entry);\n\n // Build the receipt payload\n const receiptPayload = buildReceiptPayload(interaction, entry, signer);\n\n // Sign the receipt\n const jws = await signer.sign(receiptPayload);\n\n // Build signed receipt\n const signedReceipt: SignedReceipt = {\n rid: receiptPayload.rid,\n jws,\n interaction_id: entry.action.id,\n entry_digest: entry.entry_digest,\n };\n\n // Write the receipt\n const receiptPath = await writer.write(signedReceipt);\n\n const result: EmitResult = {\n success: true,\n receipt_path: receiptPath,\n receipt_id: receiptPayload.rid,\n };\n\n if (onEmit) {\n onEmit(result, entry);\n }\n\n return result;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n\n if (onError) {\n onError(error instanceof Error ? error : new Error(errorMessage), entry);\n }\n\n return {\n success: false,\n error_code: OPENCLAW_ERROR_CODES.SIGNING_FAILED,\n error_message: `Failed to emit receipt: ${errorMessage}`,\n };\n }\n },\n\n async flush(): Promise<void> {\n // No-op: entries are emitted immediately via emit()\n // This method exists for API consistency\n },\n\n async close(): Promise<void> {\n closed = true;\n await writer.close();\n },\n };\n}\n\n// =============================================================================\n// Receipt Payload Builder\n// =============================================================================\n\n/**\n * PEAC receipt payload structure.\n */\ninterface ReceiptPayload {\n /** Issuer */\n iss: string;\n\n /** Audience */\n aud?: string;\n\n /** Issued at (Unix timestamp) */\n iat: number;\n\n /** Receipt ID */\n rid: string;\n\n /** Evidence block */\n evidence: {\n extensions: {\n 'org.peacprotocol/interaction@0.1': unknown;\n };\n };\n}\n\n/**\n * Build the receipt payload from interaction evidence.\n */\nfunction buildReceiptPayload(\n interaction: ReturnType<typeof toInteractionEvidence>,\n entry: SpoolEntry,\n signer: Signer\n): ReceiptPayload {\n const now = Math.floor(Date.now() / 1000);\n const rid = generateReceiptId(entry.entry_digest);\n\n const payload: ReceiptPayload = {\n iss: signer.getIssuer(),\n iat: now,\n rid,\n evidence: {\n extensions: {\n 'org.peacprotocol/interaction@0.1': interaction,\n },\n },\n };\n\n const audience = signer.getAudience();\n if (audience) {\n payload.aud = audience;\n }\n\n return payload;\n}\n\n/**\n * Generate a deterministic receipt ID from entry digest.\n *\n * Using a deterministic ID (derived from entry_digest) provides:\n * - Idempotency: same entry always produces same rid\n * - Replay safety: retries don't create duplicates\n * - Correlation: rid can be traced back to spool entry\n *\n * Format: r_{first 32 chars of entry_digest}\n */\nfunction generateReceiptId(entryDigest: string): string {\n // Use first 32 chars of entry digest for reasonable uniqueness\n // while keeping the ID short enough for practical use\n return `r_${entryDigest.slice(0, 32)}`;\n}\n\n// =============================================================================\n// Background Service\n// =============================================================================\n\n/**\n * Background emitter service that periodically drains a spool.\n */\nexport interface BackgroundEmitterService {\n /** Start the background service */\n start(): void;\n\n /** Stop the background service */\n stop(): void;\n\n /** Trigger immediate drain */\n drain(): Promise<void>;\n\n /** Whether the service is running */\n isRunning(): boolean;\n\n /** Get emit statistics */\n getStats(): EmitterStats;\n}\n\n/**\n * Emitter statistics.\n */\nexport interface EmitterStats {\n /** Total entries emitted */\n emitted: number;\n\n /** Total entries failed */\n failed: number;\n\n /** Last emit time */\n lastEmitTime?: Date;\n\n /** Last error */\n lastError?: string;\n}\n\n/**\n * Configuration for background emitter service.\n */\nexport interface BackgroundServiceConfig {\n /** Receipt emitter */\n emitter: ReceiptEmitter;\n\n /** Function to get pending spool entries */\n getPendingEntries: () => Promise<SpoolEntry[]>;\n\n /** Function to mark entry as emitted */\n markEmitted: (entryDigest: string) => Promise<void>;\n\n /** Drain interval in milliseconds (default: 1000) */\n drainIntervalMs?: number;\n\n /** Callback for service errors */\n onError?: (error: Error) => void;\n}\n\n/**\n * Create a background emitter service.\n *\n * @param serviceConfig - Configuration for the service\n * @returns Background emitter service instance\n */\nexport function createBackgroundService(\n serviceConfig: BackgroundServiceConfig\n): BackgroundEmitterService {\n const {\n emitter,\n getPendingEntries,\n markEmitted,\n drainIntervalMs = 1000,\n onError,\n } = serviceConfig;\n\n let running = false;\n let stopping = false;\n let inFlight = false;\n let intervalHandle: ReturnType<typeof setInterval> | undefined;\n const stats: EmitterStats = {\n emitted: 0,\n failed: 0,\n };\n\n const drainOnce = async () => {\n // Prevent overlapping drains - if a drain takes longer than the\n // interval, skip this tick rather than double-processing\n if (inFlight) return;\n\n inFlight = true;\n try {\n const entries = await getPendingEntries();\n\n for (const entry of entries) {\n // Check if service is being stopped during processing\n if (stopping) break;\n\n const result = await emitter.emit(entry);\n\n if (result.success) {\n await markEmitted(entry.entry_digest);\n stats.emitted++;\n stats.lastEmitTime = new Date();\n } else {\n stats.failed++;\n stats.lastError = result.error_message;\n }\n }\n } catch (error) {\n stats.lastError = error instanceof Error ? error.message : String(error);\n if (onError) {\n onError(error instanceof Error ? error : new Error(String(error)));\n }\n } finally {\n inFlight = false;\n }\n };\n\n return {\n start(): void {\n if (running) return;\n running = true;\n intervalHandle = setInterval(drainOnce, drainIntervalMs);\n // Run immediately on start\n drainOnce();\n },\n\n stop(): void {\n if (!running) return;\n stopping = true;\n running = false;\n if (intervalHandle) {\n clearInterval(intervalHandle);\n intervalHandle = undefined;\n }\n },\n\n async drain(): Promise<void> {\n await drainOnce();\n },\n\n isRunning(): boolean {\n return running;\n },\n\n getStats(): EmitterStats {\n return { ...stats };\n },\n };\n}\n","/**\n * @peac/adapter-openclaw - Plugin Entry Point\n *\n * OpenClaw plugin types and utilities for PEAC receipts.\n * This module provides types and factory functions for OpenClaw integration.\n *\n * Note: Full plugin activation requires OpenClaw's plugin runtime.\n * The types and utilities here allow building custom integrations.\n */\n\nimport type { CaptureSession, SpoolStore, DedupeIndex } from '@peac/capture-core';\nimport { createCaptureSession, createHasher } from '@peac/capture-core';\nimport { sign, base64urlDecode } from '@peac/crypto';\nimport type { OpenClawAdapterConfig } from './types.js';\nimport { createHookHandler, type OpenClawHookHandler } from './hooks.js';\nimport {\n createReceiptEmitter,\n createBackgroundService,\n type Signer,\n type ReceiptWriter,\n type BackgroundEmitterService,\n} from './emitter.js';\n\n// =============================================================================\n// JWK Type\n// =============================================================================\n\n/**\n * JSON Web Key structure for signing keys (Ed25519).\n */\nexport interface JWK {\n kty: string;\n crv?: string;\n x?: string;\n d?: string;\n kid?: string;\n alg?: string;\n use?: string;\n}\n\n// =============================================================================\n// Plugin Configuration Types\n// =============================================================================\n\n/**\n * Plugin configuration from openclaw.plugin.json configSchema.\n *\n * @experimental This interface is experimental and may change.\n */\nexport interface PluginConfig {\n enabled?: boolean;\n output_dir?: string;\n capture?: {\n mode?: 'hash_only' | 'allowlist';\n allowlist?: string[];\n max_payload_size?: number;\n };\n signing: {\n key_ref: string;\n issuer: string;\n audience?: string;\n };\n correlation?: {\n include_workflow?: boolean;\n // Note: include_identity and identity_attestation_ref are reserved for future use\n };\n background?: {\n drain_interval_ms?: number;\n batch_size?: number;\n };\n}\n\n/**\n * OpenClaw plugin context provided by the runtime.\n */\nexport interface PluginContext {\n /** Plugin configuration from gateway config */\n config: PluginConfig;\n /** Agent workspace directory */\n workspaceDir: string;\n /** Logger instance */\n logger: PluginLogger;\n /** Register a tool call hook */\n onToolCall: (handler: ToolCallHandler) => void;\n /** Register a tool result hook */\n onToolResult: (handler: ToolResultHandler) => void;\n /** Register tools */\n registerTools: (tools: PluginTool[]) => void;\n}\n\n/**\n * Plugin logger interface.\n */\nexport interface PluginLogger {\n debug: (message: string, ...args: unknown[]) => void;\n info: (message: string, ...args: unknown[]) => void;\n warn: (message: string, ...args: unknown[]) => void;\n error: (message: string, ...args: unknown[]) => void;\n}\n\n/**\n * Tool call event from OpenClaw.\n */\nexport interface ToolCallEvent {\n tool_call_id: string;\n run_id: string;\n session_key?: string;\n tool_name: string;\n tool_provider?: string;\n input: unknown;\n started_at: string;\n}\n\n/**\n * Tool result event from OpenClaw.\n */\nexport interface ToolResultEvent {\n tool_call_id: string;\n run_id: string;\n session_key?: string;\n tool_name: string;\n output: unknown;\n completed_at: string;\n status: 'ok' | 'error' | 'timeout' | 'canceled';\n error_code?: string;\n}\n\n/**\n * Tool call handler function.\n */\nexport type ToolCallHandler = (event: ToolCallEvent) => void | Promise<void>;\n\n/**\n * Tool result handler function.\n */\nexport type ToolResultHandler = (event: ToolResultEvent) => void | Promise<void>;\n\n/**\n * Plugin tool definition.\n */\nexport interface PluginTool {\n name: string;\n description: string;\n parameters?: Record<string, unknown>;\n execute: (params: Record<string, unknown>) => Promise<unknown>;\n}\n\n// =============================================================================\n// Signer Creation\n// =============================================================================\n\n/**\n * Create a signer from a JWK private key.\n *\n * @param jwk - Ed25519 private key in JWK format\n * @param issuer - Issuer URI for receipts\n * @param audience - Optional audience URI\n * @returns Signer instance\n */\nexport function createJwkSigner(jwk: JWK, issuer: string, audience?: string): Signer {\n const kid = jwk.kid || generateKeyId(jwk);\n\n // Extract the private key bytes from JWK\n if (!jwk.d) {\n throw new Error('JWK must include private key (d parameter)');\n }\n\n // Decode base64url to get raw key bytes\n const privateKeyBytes = base64urlDecode(jwk.d);\n\n return {\n async sign(payload: unknown): Promise<string> {\n return sign(payload, privateKeyBytes, kid);\n },\n\n getKeyId(): string {\n return kid;\n },\n\n getIssuer(): string {\n return issuer;\n },\n\n getAudience(): string | undefined {\n return audience;\n },\n };\n}\n\n/**\n * Resolve a signer from a key reference string.\n *\n * Supported formats:\n * - env:VAR_NAME - Load key from environment variable\n * - file:/path - Load from file (development only)\n *\n * @param keyRef - Key reference string\n * @param issuer - Issuer URI\n * @param audience - Optional audience URI\n * @returns Promise resolving to Signer\n */\nexport async function resolveSigner(\n keyRef: string,\n issuer: string,\n audience?: string\n): Promise<Signer> {\n const colonIndex = keyRef.indexOf(':');\n if (colonIndex === -1) {\n throw new Error(`Invalid key reference format: ${keyRef}. Expected scheme:value`);\n }\n\n const scheme = keyRef.slice(0, colonIndex);\n const value = keyRef.slice(colonIndex + 1);\n\n switch (scheme) {\n case 'env': {\n const keyData = process.env[value];\n if (!keyData) {\n throw new Error(`Environment variable ${value} not set for signing key`);\n }\n const jwk = JSON.parse(keyData) as JWK;\n return createJwkSigner(jwk, issuer, audience);\n }\n\n case 'file': {\n const fs = await import('fs');\n const keyData = await fs.promises.readFile(value, 'utf-8');\n const jwk = JSON.parse(keyData) as JWK;\n return createJwkSigner(jwk, issuer, audience);\n }\n\n case 'keychain':\n throw new Error('Keychain signing not yet implemented. Use env: for development.');\n\n case 'sidecar':\n throw new Error('Sidecar signing not yet implemented. Use env: for development.');\n\n default:\n throw new Error(`Unknown key reference scheme: ${scheme}. Use env: or file:`);\n }\n}\n\n/**\n * Generate a key ID from a JWK by hashing its public components.\n */\nexport function generateKeyId(jwk: JWK): string {\n const publicPart = jwk.x || '';\n let hash = 0;\n for (let i = 0; i < publicPart.length; i++) {\n const char = publicPart.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash;\n }\n return `k_${Math.abs(hash).toString(16).padStart(8, '0')}`;\n}\n\n// =============================================================================\n// Receipt Writer\n// =============================================================================\n\n/**\n * Create a file system receipt writer with atomic writes.\n *\n * Writes are atomic: write to .tmp, fsync, rename. This ensures\n * partially written files are never observable.\n *\n * @param outputDir - Directory for receipt files\n * @returns Promise resolving to ReceiptWriter\n */\nexport async function createFileReceiptWriter(outputDir: string): Promise<ReceiptWriter> {\n const fs = await import('fs');\n const pathModule = await import('path');\n\n // Use path.resolve for portability\n const resolvedOutputDir = pathModule.resolve(outputDir);\n\n // Ensure directory exists\n await fs.promises.mkdir(resolvedOutputDir, { recursive: true });\n\n return {\n async write(receipt) {\n const filename = `${receipt.rid}.peac.json`;\n const filepath = pathModule.join(resolvedOutputDir, filename);\n const tempPath = `${filepath}.tmp`;\n\n // Decode the JWS payload to persist the full receipt structure.\n // The verify and export tools expect auth + evidence blocks at the top level.\n // JWS compact serialization: header.payload.signature (base64url)\n let content: string;\n const jwsParts = receipt.jws.split('.');\n if (jwsParts.length !== 3) {\n // Malformed JWS -- write _jws-only receipt (best effort, still recoverable)\n content = JSON.stringify({ _jws: receipt.jws }, null, 2);\n } else {\n try {\n const payloadJson = Buffer.from(jwsParts[1], 'base64url').toString('utf-8');\n const payload = JSON.parse(payloadJson);\n\n // Split payload into auth (identity fields) and evidence (data fields)\n const { evidence, ...auth } = payload;\n\n content = JSON.stringify({ auth, evidence, _jws: receipt.jws }, null, 2);\n } catch {\n // Payload decode failed -- write _jws-only receipt (best effort)\n content = JSON.stringify({ _jws: receipt.jws }, null, 2);\n }\n }\n\n // Atomic write: write to .tmp, fsync, rename, fsync dir\n await fs.promises.writeFile(tempPath, content, 'utf-8');\n\n // fsync file for durability (open, sync, close)\n const fd = await fs.promises.open(tempPath, 'r');\n await fd.sync();\n await fd.close();\n\n // Atomic rename (POSIX guarantees atomicity)\n await fs.promises.rename(tempPath, filepath);\n\n // fsync parent directory for full crash durability (POSIX best practice)\n // This ensures the rename is persisted even on power loss\n // Best-effort: may fail on some platforms (Windows, network FS)\n try {\n const dirFd = await fs.promises.open(resolvedOutputDir, 'r');\n await dirFd.sync();\n await dirFd.close();\n } catch {\n // Directory fsync not supported on this platform - continue anyway\n // Receipt is still atomic via rename, just not fully durable on power loss\n }\n\n return filepath;\n },\n\n async close() {\n // No-op for file writer\n },\n };\n}\n\n// =============================================================================\n// Plugin Instance\n// =============================================================================\n\n/**\n * Plugin instance state.\n */\nexport interface PluginInstance {\n /** Capture session */\n session: CaptureSession;\n /** Hook handler for tool calls */\n hookHandler: OpenClawHookHandler;\n /** Background emitter service */\n backgroundService: BackgroundEmitterService;\n /** Start the plugin */\n start(): void;\n /** Stop the plugin */\n stop(): Promise<void>;\n /** Get plugin stats */\n getStats(): PluginStats;\n}\n\n/**\n * Plugin statistics.\n */\nexport interface PluginStats {\n totalCaptured: number;\n duplicatesSkipped: number;\n pendingCount: number;\n totalEmitted: number;\n totalErrors: number;\n keyId: string;\n isRunning: boolean;\n}\n\n/**\n * Options for creating a plugin instance.\n */\nexport interface CreatePluginOptions {\n /** Signer for receipts */\n signer: Signer;\n /** Receipt writer */\n writer: ReceiptWriter;\n /** Adapter configuration */\n adapterConfig?: OpenClawAdapterConfig;\n /** Spool store implementation (required) */\n store: SpoolStore;\n /** Dedupe index implementation (required) */\n dedupe: DedupeIndex;\n /** Background drain interval in ms (default: 1000) */\n drainIntervalMs?: number;\n /** Batch size for draining (default: 100) */\n batchSize?: number;\n /** Error callback */\n onError?: (error: Error) => void;\n}\n\n/**\n * Create a plugin instance.\n *\n * @param options - Plugin options\n * @returns Plugin instance\n */\nexport async function createPluginInstance(options: CreatePluginOptions): Promise<PluginInstance> {\n const {\n signer,\n writer,\n adapterConfig,\n store,\n dedupe,\n drainIntervalMs = 1000,\n batchSize = 100,\n onError,\n } = options;\n\n // Create hasher\n const hasher = await createHasher();\n\n // Create capture session\n const session = createCaptureSession({\n store,\n dedupe,\n hasher,\n });\n\n // Track stats\n const stats: PluginStats = {\n totalCaptured: 0,\n duplicatesSkipped: 0,\n pendingCount: 0,\n totalEmitted: 0,\n totalErrors: 0,\n keyId: signer.getKeyId(),\n isRunning: false,\n };\n\n // Create hook handler\n const hookHandler = createHookHandler({\n session,\n config: adapterConfig,\n onCapture: (result) => {\n if (result.success) {\n stats.totalCaptured++;\n stats.pendingCount++;\n } else {\n stats.duplicatesSkipped++;\n }\n },\n });\n\n // Create receipt emitter\n const emitter = createReceiptEmitter({\n signer,\n writer,\n onEmit: (result) => {\n if (result.success) {\n stats.totalEmitted++;\n stats.pendingCount = Math.max(0, stats.pendingCount - 1);\n }\n },\n onError: (error) => {\n stats.totalErrors++;\n if (onError) onError(error);\n },\n });\n\n // Track last emitted sequence for cursor-based emission\n // This is the in-memory cursor; on restart, we rebuild from dedupe index\n let lastEmittedSequence = 0;\n\n // Mutex to prevent overlapping drain cycles\n let drainInProgress = false;\n\n // Create background service with proper cursor tracking\n // Note: For full restart safety, the dedupe index should be persistent.\n // The getPendingEntries filters out already-emitted entries using the dedupe index.\n const backgroundService = createBackgroundService({\n emitter,\n drainIntervalMs,\n getPendingEntries: async () => {\n // Prevent overlapping drain cycles\n if (drainInProgress) return [];\n drainInProgress = true;\n\n try {\n // Read entries after the last emitted sequence\n const currentSequence = await store.getSequence();\n if (currentSequence <= lastEmittedSequence) return [];\n\n // Read from cursor position\n const entries = await store.read(lastEmittedSequence, batchSize);\n\n // Filter out entries that are already emitted (restart safety)\n // This uses the persistent dedupe index as source of truth\n const pending = [];\n for (const entry of entries) {\n if (entry.sequence <= lastEmittedSequence) continue;\n // Check if already emitted in dedupe index\n const dedupeEntry = await dedupe.get(entry.action.id);\n if (dedupeEntry?.emitted) continue;\n pending.push(entry);\n }\n return pending;\n } finally {\n drainInProgress = false;\n }\n },\n markEmitted: async (digest) => {\n // Find the entry with this digest and update cursor\n const entries = await store.read(lastEmittedSequence, batchSize);\n const entry = entries.find((e) => e.entry_digest === digest);\n if (entry) {\n // Update in-memory cursor\n if (entry.sequence > lastEmittedSequence) {\n lastEmittedSequence = entry.sequence;\n }\n // Mark in persistent dedupe index (restart-safe)\n await dedupe.markEmitted(entry.action.id);\n }\n },\n onError,\n });\n\n return {\n session,\n hookHandler,\n backgroundService,\n\n start() {\n stats.isRunning = true;\n backgroundService.start();\n },\n\n async stop() {\n backgroundService.stop();\n await backgroundService.drain();\n await hookHandler.close();\n stats.isRunning = false;\n },\n\n getStats() {\n return { ...stats };\n },\n };\n}\n","/**\n * @peac/adapter-openclaw - Plugin Tools\n *\n * Tools exposed by the PEAC receipts plugin for OpenClaw.\n *\n * @experimental This module is experimental and may change.\n */\n\nimport type { PluginTool, PluginLogger } from './plugin.js';\n\n// =============================================================================\n// Constants\n// =============================================================================\n\n/** Maximum files to scan for status (DoS protection) */\nconst MAX_STATUS_FILE_SCAN = 1000;\n\n/** Maximum files to parse for query (DoS protection) */\nconst MAX_QUERY_FILE_PARSE = 10000;\n\n/** Maximum file size in bytes to read (DoS protection) - 10MB */\nconst MAX_FILE_SIZE_BYTES = 10 * 1024 * 1024;\n\n/** Allowed JWS algorithms (security) */\nconst ALLOWED_ALGORITHMS = ['EdDSA', 'ES256', 'ES384', 'ES512', 'RS256', 'RS384', 'RS512'] as const;\n\n/**\n * Decode a receipt file's auth + evidence from the _jws payload.\n * _jws is the source of truth -- top-level auth/evidence are convenience duplicates.\n * Returns null if _jws is missing or cannot be decoded.\n */\nfunction decodeReceiptPayload(receipt: Record<string, unknown>): {\n auth: Record<string, unknown>;\n evidence: Record<string, unknown>;\n} | null {\n const jws = receipt._jws;\n if (typeof jws !== 'string') return null;\n\n const parts = jws.split('.');\n if (parts.length !== 3) return null;\n\n try {\n const payloadJson = Buffer.from(parts[1], 'base64url').toString('utf-8');\n const payload = JSON.parse(payloadJson);\n const { evidence, ...auth } = payload;\n return { auth: auth ?? {}, evidence: evidence ?? {} };\n } catch {\n return null;\n }\n}\n\n/** Algorithm to key type compatibility map */\nconst ALG_KEY_TYPE_MAP: Record<string, { kty: string; crv?: string[] }> = {\n EdDSA: { kty: 'OKP', crv: ['Ed25519', 'Ed448'] },\n ES256: { kty: 'EC', crv: ['P-256'] },\n ES384: { kty: 'EC', crv: ['P-384'] },\n ES512: { kty: 'EC', crv: ['P-521'] },\n RS256: { kty: 'RSA' },\n RS384: { kty: 'RSA' },\n RS512: { kty: 'RSA' },\n};\n\n// =============================================================================\n// Status Tool Types\n// =============================================================================\n\n/**\n * Plugin stats interface matching plugin.ts PluginStats.\n */\ninterface PluginStats {\n totalCaptured: number;\n duplicatesSkipped: number;\n pendingCount: number;\n totalEmitted: number;\n totalErrors: number;\n keyId: string;\n isRunning: boolean;\n}\n\n// =============================================================================\n// Status Tool\n// =============================================================================\n\n/**\n * Create the peac_receipts.status tool.\n * Shows spool size, last receipt time, and config summary.\n *\n * @param getStats - Getter function that returns live stats on each invocation.\n * Accepts either a getter or a static PluginStats for backwards compat.\n * @param outputDir - Directory where receipt files are stored.\n */\nexport function createStatusTool(\n getStats: (() => PluginStats) | PluginStats,\n outputDir: string\n): PluginTool {\n return {\n name: 'peac_receipts.status',\n description: 'Show PEAC receipts status: spool size, last receipt time, config summary',\n parameters: {},\n\n async execute(): Promise<StatusResult> {\n const stats = typeof getStats === 'function' ? getStats() : getStats;\n const fs = await import('fs');\n const pathModule = await import('path');\n\n // Use path.resolve for portability\n const resolvedOutputDir = pathModule.resolve(outputDir);\n\n // Count receipts in output directory (capped for performance)\n let receiptCount = 0;\n let lastReceiptTime: string | null = null;\n let oldestReceiptTime: string | null = null;\n let countApproximate = false;\n\n try {\n const files = await fs.promises.readdir(resolvedOutputDir);\n const receiptFiles = files.filter((f) => f.endsWith('.peac.json'));\n receiptCount = receiptFiles.length;\n\n // Cap the scan for performance\n const filesToScan = receiptFiles.slice(0, MAX_STATUS_FILE_SCAN);\n countApproximate = receiptFiles.length > MAX_STATUS_FILE_SCAN;\n\n if (filesToScan.length > 0) {\n // Get timestamps from file stats (capped)\n const fileStats = await Promise.all(\n filesToScan.map(async (f) => {\n const stat = await fs.promises.stat(pathModule.join(resolvedOutputDir, f));\n return { file: f, mtime: stat.mtime };\n })\n );\n\n fileStats.sort((a, b) => b.mtime.getTime() - a.mtime.getTime());\n lastReceiptTime = fileStats[0].mtime.toISOString();\n oldestReceiptTime = fileStats[fileStats.length - 1].mtime.toISOString();\n }\n } catch {\n // Directory might not exist yet\n }\n\n return {\n status: 'ok',\n spool: {\n pending_entries: stats.pendingCount,\n total_captured: stats.totalCaptured,\n duplicates_skipped: stats.duplicatesSkipped,\n },\n receipts: {\n count: receiptCount,\n count_approximate: countApproximate,\n output_dir: resolvedOutputDir,\n last_receipt_time: lastReceiptTime,\n oldest_receipt_time: oldestReceiptTime,\n },\n emitter: {\n total_emitted: stats.totalEmitted,\n total_errors: stats.totalErrors,\n is_running: stats.isRunning,\n key_id: stats.keyId,\n },\n };\n },\n };\n}\n\ninterface StatusResult {\n status: 'ok' | 'error';\n spool: {\n pending_entries: number;\n total_captured: number;\n duplicates_skipped: number;\n };\n receipts: {\n count: number;\n count_approximate: boolean;\n output_dir: string;\n last_receipt_time: string | null;\n oldest_receipt_time: string | null;\n };\n emitter: {\n total_emitted: number;\n total_errors: number;\n is_running: boolean;\n key_id: string;\n };\n}\n\n// =============================================================================\n// Export Bundle Tool\n// =============================================================================\n\n/**\n * Create the peac_receipts.export_bundle tool.\n * Exports receipts as a bundle directory for audit.\n *\n * Note: Creates a directory structure, not a ZIP archive.\n * Use @peac/audit createDisputeBundle for production ZIP bundles.\n */\nexport function createExportBundleTool(outputDir: string, logger: PluginLogger): PluginTool {\n return {\n name: 'peac_receipts.export_bundle',\n description: 'Export receipts as a bundle directory for audit (manifest.json + receipts/)',\n parameters: {\n type: 'object',\n properties: {\n workflow_id: {\n type: 'string',\n description: 'Filter by workflow ID',\n },\n since: {\n type: 'string',\n description: 'Include receipts since this RFC 3339 timestamp',\n },\n until: {\n type: 'string',\n description: 'Include receipts until this RFC 3339 timestamp',\n },\n output_path: {\n type: 'string',\n description: 'Output path for bundle directory (default: peac-bundle-{timestamp})',\n },\n },\n },\n\n async execute(params: ExportBundleParams): Promise<ExportBundleResult> {\n const fs = await import('fs');\n const pathModule = await import('path');\n\n // Use path.resolve for portability\n const resolvedOutputDir = pathModule.resolve(outputDir);\n\n try {\n // List receipts\n const files = await fs.promises.readdir(resolvedOutputDir);\n const receiptFiles = files.filter((f) => f.endsWith('.peac.json'));\n\n if (receiptFiles.length === 0) {\n return {\n status: 'ok',\n message: 'No receipts to export',\n receipt_count: 0,\n };\n }\n\n // Filter receipts with structured skip tracking\n const receipts: Array<{ file: string; content: unknown; mtime: Date }> = [];\n const skippedReasons = { stat_error: 0, invalid_json: 0, malformed_jws: 0, filtered: 0 };\n const skippedFiles: string[] = [];\n\n for (const file of receiptFiles) {\n const filePath = pathModule.join(resolvedOutputDir, file);\n let stat;\n try {\n stat = await fs.promises.stat(filePath);\n } catch {\n skippedReasons.stat_error++;\n skippedFiles.push(file);\n continue;\n }\n\n // Apply time filters\n if (params.since && stat.mtime < new Date(params.since)) {\n skippedReasons.filtered++;\n continue;\n }\n if (params.until && stat.mtime > new Date(params.until)) {\n skippedReasons.filtered++;\n continue;\n }\n\n // Read and parse receipt (tolerate invalid JSON)\n let content;\n try {\n content = JSON.parse(await fs.promises.readFile(filePath, 'utf-8'));\n } catch {\n logger.warn(`Skipping invalid JSON in ${file}`);\n skippedReasons.invalid_json++;\n skippedFiles.push(file);\n continue;\n }\n\n // Apply workflow filter (derive from _jws when present)\n if (params.workflow_id) {\n const decoded = content._jws ? decodeReceiptPayload(content) : null;\n // If _jws exists but is malformed, skip this receipt (untrusted)\n if (content._jws && !decoded) {\n logger.warn(`Skipping ${file}: _jws present but malformed`);\n skippedReasons.malformed_jws++;\n skippedFiles.push(file);\n continue;\n }\n const authBlock = (decoded?.auth ?? content?.auth) as\n | Record<string, unknown>\n | undefined;\n const extensions = authBlock?.extensions as Record<string, unknown> | undefined;\n const workflowExt = extensions?.['org.peacprotocol/workflow'] as\n | Record<string, unknown>\n | undefined;\n if (workflowExt?.workflow_id !== params.workflow_id) {\n skippedReasons.filtered++;\n continue;\n }\n }\n\n receipts.push({ file, content, mtime: stat.mtime });\n }\n\n if (receipts.length === 0) {\n return {\n status: 'ok',\n message: 'No receipts match the filter criteria',\n receipt_count: 0,\n scanned_count: receiptFiles.length,\n exported_count: 0,\n skipped_count:\n skippedReasons.stat_error +\n skippedReasons.invalid_json +\n skippedReasons.malformed_jws +\n skippedReasons.filtered,\n skipped_reasons: skippedReasons,\n skipped_files: skippedFiles.length > 0 ? skippedFiles.slice(0, 100) : undefined,\n };\n }\n\n // Create bundle manifest\n const manifest = {\n version: '1.0',\n format: 'peac-bundle-directory',\n created_at: new Date().toISOString(),\n receipt_count: receipts.length,\n filters: {\n workflow_id: params.workflow_id || null,\n since: params.since || null,\n until: params.until || null,\n },\n receipts: receipts.map((r) => ({\n file: r.file,\n mtime: r.mtime.toISOString(),\n })),\n };\n\n // Determine output path (directory, not ZIP)\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n const bundleDir = params.output_path\n ? pathModule.resolve(params.output_path)\n : pathModule.join(resolvedOutputDir, `peac-bundle-${timestamp}`);\n\n await fs.promises.mkdir(bundleDir, { recursive: true });\n\n // Write manifest\n await fs.promises.writeFile(\n pathModule.join(bundleDir, 'manifest.json'),\n JSON.stringify(manifest, null, 2)\n );\n\n // Copy receipts\n const receiptsDir = pathModule.join(bundleDir, 'receipts');\n await fs.promises.mkdir(receiptsDir, { recursive: true });\n\n for (const receipt of receipts) {\n await fs.promises.writeFile(\n pathModule.join(receiptsDir, receipt.file),\n JSON.stringify(receipt.content, null, 2)\n );\n }\n\n logger.info(`Exported ${receipts.length} receipts to ${bundleDir}`);\n\n return {\n status: 'ok',\n message: `Exported ${receipts.length} receipts to directory`,\n receipt_count: receipts.length,\n bundle_path: bundleDir,\n scanned_count: receiptFiles.length,\n exported_count: receipts.length,\n skipped_count:\n skippedReasons.stat_error +\n skippedReasons.invalid_json +\n skippedReasons.malformed_jws +\n skippedReasons.filtered,\n skipped_reasons: skippedReasons,\n skipped_files: skippedFiles.length > 0 ? skippedFiles.slice(0, 100) : undefined,\n };\n } catch (error) {\n logger.error('Export bundle failed:', error);\n return {\n status: 'error',\n message: error instanceof Error ? error.message : 'Unknown error',\n receipt_count: 0,\n };\n }\n },\n };\n}\n\ninterface ExportBundleParams {\n workflow_id?: string;\n since?: string;\n until?: string;\n output_path?: string;\n}\n\ninterface ExportBundleResult {\n status: 'ok' | 'error';\n message: string;\n receipt_count: number;\n bundle_path?: string;\n scanned_count?: number;\n exported_count?: number;\n skipped_count?: number;\n skipped_reasons?: {\n stat_error: number;\n invalid_json: number;\n malformed_jws: number;\n filtered: number;\n };\n skipped_files?: string[];\n}\n\n// =============================================================================\n// Verify Tool\n// =============================================================================\n\n/**\n * Create the peac_receipts.verify tool.\n * Verifies a receipt or bundle offline.\n */\nexport function createVerifyTool(logger: PluginLogger): PluginTool {\n return {\n name: 'peac_receipts.verify',\n description: 'Verify a receipt or bundle offline',\n parameters: {\n type: 'object',\n properties: {\n path: {\n type: 'string',\n description: 'Path to receipt file or bundle directory',\n },\n jwks_path: {\n type: 'string',\n description: 'Path to JWKS file for key verification (optional)',\n },\n },\n required: ['path'],\n },\n\n async execute(params: Record<string, unknown>): Promise<VerifyResult> {\n const verifyParams = params as unknown as VerifyParams;\n const fs = await import('fs');\n const pathModule = await import('path');\n\n try {\n const stat = await fs.promises.stat(verifyParams.path);\n\n if (stat.isDirectory()) {\n // Verify bundle\n return await verifyBundle(\n verifyParams.path,\n verifyParams.jwks_path,\n fs,\n pathModule,\n logger\n );\n } else {\n // Verify single receipt\n return await verifySingleReceipt(verifyParams.path, verifyParams.jwks_path, fs, logger);\n }\n } catch (error) {\n logger.error('Verification failed:', error);\n return {\n status: 'error',\n valid: false,\n message: error instanceof Error ? error.message : 'Unknown error',\n errors: [error instanceof Error ? error.message : 'Unknown error'],\n };\n }\n },\n };\n}\n\nasync function verifySingleReceipt(\n receiptPath: string,\n jwksPath: string | undefined,\n fs: typeof import('fs'),\n logger: PluginLogger\n): Promise<VerifyResult> {\n // Check file size before reading (DoS protection)\n const stat = await fs.promises.stat(receiptPath);\n if (stat.size > MAX_FILE_SIZE_BYTES) {\n return {\n status: 'error',\n valid: false,\n message: `File too large: ${stat.size} bytes exceeds limit of ${MAX_FILE_SIZE_BYTES} bytes`,\n errors: [`File size ${stat.size} bytes exceeds ${MAX_FILE_SIZE_BYTES} byte limit`],\n };\n }\n\n const content = await fs.promises.readFile(receiptPath, 'utf-8');\n const receipt = JSON.parse(content);\n\n const errors: string[] = [];\n const warnings: string[] = [];\n\n // Trust boundary: _jws is the source of truth for signed data.\n // If _jws is present but malformed, the receipt is invalid (possible tampering).\n // Only allow unsigned top-level fields when _jws is genuinely absent.\n let auth: unknown;\n let evidence: unknown;\n\n if (!receipt._jws) {\n // No JWS -- use top-level fields (unsigned, best-effort)\n auth = receipt.auth;\n evidence = receipt.evidence;\n warnings.push('Missing _jws field -- using unsigned top-level fields');\n } else {\n const decoded = decodeReceiptPayload(receipt);\n if (!decoded) {\n // _jws exists but is malformed -- receipt is invalid, do not fall back\n errors.push('_jws field present but payload could not be decoded (malformed JWS)');\n auth = undefined;\n evidence = undefined;\n } else {\n auth = decoded.auth;\n evidence = decoded.evidence;\n\n // Dual-representation mismatch check: if top-level auth/evidence also exist,\n // they MUST match the signed payload. A mismatch means the unsigned fields\n // have been tampered with (or carelessly copied), creating ambiguity.\n if (receipt.auth !== undefined || receipt.evidence !== undefined) {\n const topAuth = receipt.auth as Record<string, unknown> | undefined;\n const topEvidence = receipt.evidence as Record<string, unknown> | undefined;\n const authMatch =\n topAuth === undefined || JSON.stringify(topAuth) === JSON.stringify(decoded.auth);\n const evidenceMatch =\n topEvidence === undefined ||\n JSON.stringify(topEvidence) === JSON.stringify(decoded.evidence);\n if (!authMatch || !evidenceMatch) {\n errors.push(\n 'Dual-representation mismatch: top-level auth/evidence differs from _jws payload'\n );\n }\n }\n }\n }\n\n if (!auth) {\n errors.push('Missing auth block');\n }\n if (!evidence) {\n errors.push('Missing evidence block');\n }\n\n // Check for interaction evidence\n const evidenceObj = evidence as Record<string, unknown> | undefined;\n const extensions = evidenceObj?.extensions as Record<string, unknown> | undefined;\n const interaction = extensions?.['org.peacprotocol/interaction@0.1'] as\n | Record<string, unknown>\n | undefined;\n if (interaction) {\n // Validate interaction fields\n if (!interaction.interaction_id) {\n errors.push('Missing interaction_id');\n }\n if (!interaction.kind) {\n errors.push('Missing kind');\n }\n const executor = interaction.executor as Record<string, unknown> | undefined;\n if (!executor?.platform) {\n errors.push('Missing executor.platform');\n }\n if (!interaction.started_at) {\n errors.push('Missing started_at');\n }\n\n // Check timing invariant\n if (interaction.completed_at && interaction.started_at) {\n if (\n new Date(interaction.completed_at as string) < new Date(interaction.started_at as string)\n ) {\n errors.push('completed_at is before started_at');\n }\n }\n\n // Check output requires result\n const result = interaction.result as Record<string, unknown> | undefined;\n if (interaction.output && !result?.status) {\n errors.push('output present but result.status missing');\n }\n } else {\n warnings.push('No interaction evidence found');\n }\n\n // Signature verification (if JWKS provided)\n if (jwksPath && receipt._jws) {\n try {\n const { verify, base64urlDecode, base64urlDecodeString } = await import('@peac/crypto');\n const jwks = JSON.parse(await fs.promises.readFile(jwksPath, 'utf-8'));\n\n // Parse JWS header to get kid and alg\n const jwsParts = receipt._jws.split('.');\n if (jwsParts.length !== 3) {\n errors.push('Invalid JWS format (expected 3 parts)');\n } else {\n const headerJson = base64urlDecodeString(jwsParts[0]);\n const header = JSON.parse(headerJson) as { kid?: string; alg?: string; crit?: string[] };\n\n // Reject 'none' algorithm (security)\n if (header.alg === 'none') {\n errors.push('Algorithm \"none\" is not allowed');\n }\n\n // Reject algorithms not in allowlist\n if (\n header.alg &&\n !ALLOWED_ALGORITHMS.includes(header.alg as (typeof ALLOWED_ALGORITHMS)[number])\n ) {\n errors.push(\n `Algorithm \"${header.alg}\" is not in allowed list: ${ALLOWED_ALGORITHMS.join(', ')}`\n );\n }\n\n // Reject unknown critical headers (JOSE compliance)\n // Per RFC 7515: crit lists headers that MUST be understood, we don't support any\n if (header.crit && header.crit.length > 0) {\n // Check if crit references headers that are missing (per JOSE spec)\n const headerObj = header as Record<string, unknown>;\n const missingCrit = header.crit.filter((h) => !(h in headerObj));\n if (missingCrit.length > 0) {\n errors.push(`Critical headers declared but missing: ${missingCrit.join(', ')}`);\n }\n // Reject all crit headers since we don't understand any extensions\n errors.push(`Unsupported critical headers: ${header.crit.join(', ')}`);\n }\n\n const targetKid = header.kid;\n\n // Strict key selection by kid\n let keyJwk:\n | {\n kid?: string;\n kty?: string;\n crv?: string;\n x?: string;\n n?: string;\n use?: string;\n key_ops?: string[];\n }\n | undefined;\n if (!Array.isArray(jwks.keys) || jwks.keys.length === 0) {\n errors.push('JWKS has no keys');\n } else if (targetKid) {\n // JWS has kid: require exact match\n keyJwk = jwks.keys.find((k: { kid?: string }) => k.kid === targetKid);\n if (!keyJwk) {\n errors.push(`Key with kid \"${targetKid}\" not found in JWKS`);\n }\n } else if (jwks.keys.length === 1) {\n // JWS has no kid but JWKS has exactly 1 key: accept it\n keyJwk = jwks.keys[0];\n warnings.push('JWS has no kid - using only key from JWKS');\n } else {\n // JWS has no kid and JWKS has multiple keys: fail\n errors.push(`JWS missing kid but JWKS has ${jwks.keys.length} keys - cannot select`);\n }\n\n // Verify algorithm matches key type\n if (keyJwk && header.alg && errors.length === 0) {\n const expectedKeyType = ALG_KEY_TYPE_MAP[header.alg];\n if (expectedKeyType) {\n if (keyJwk.kty !== expectedKeyType.kty) {\n errors.push(\n `Algorithm \"${header.alg}\" requires key type \"${expectedKeyType.kty}\" but key has \"${keyJwk.kty}\"`\n );\n } else if (\n expectedKeyType.crv &&\n keyJwk.crv &&\n !expectedKeyType.crv.includes(keyJwk.crv)\n ) {\n errors.push(\n `Algorithm \"${header.alg}\" requires curve ${expectedKeyType.crv.join(' or ')} but key has \"${keyJwk.crv}\"`\n );\n }\n }\n\n // Validate key use if present (must be \"sig\" for signature verification)\n if (keyJwk.use && keyJwk.use !== 'sig') {\n errors.push(\n `Key use \"${keyJwk.use}\" is not valid for signature verification (expected \"sig\")`\n );\n }\n\n // Validate key_ops if present (must include \"verify\")\n if (keyJwk.key_ops && !keyJwk.key_ops.includes('verify')) {\n errors.push(`Key operations ${JSON.stringify(keyJwk.key_ops)} do not include \"verify\"`);\n }\n }\n\n if (keyJwk && errors.length === 0) {\n // Get the public key bytes (x for OKP/EC, n for RSA)\n const publicKeyParam = keyJwk.x || keyJwk.n;\n if (!publicKeyParam) {\n errors.push('Selected key missing public key (x or n parameter)');\n } else {\n // Decode base64url public key bytes\n const publicKeyBytes = base64urlDecode(publicKeyParam);\n await verify(receipt._jws, publicKeyBytes);\n logger.info(`Signature verified with key ${keyJwk.kid || 'anonymous'}`);\n }\n }\n }\n } catch (error) {\n errors.push(\n `Signature verification failed: ${error instanceof Error ? error.message : 'Unknown'}`\n );\n }\n } else if (!jwksPath) {\n warnings.push('No JWKS provided - signature not verified');\n }\n\n return {\n status: errors.length === 0 ? 'ok' : 'error',\n valid: errors.length === 0,\n message: errors.length === 0 ? 'Receipt is valid' : 'Receipt has validation errors',\n errors: errors.length > 0 ? errors : undefined,\n warnings: warnings.length > 0 ? warnings : undefined,\n receipt_id: (auth as Record<string, unknown>)?.rid as string | undefined,\n interaction_id: (interaction as Record<string, unknown>)?.interaction_id as string | undefined,\n };\n}\n\nasync function verifyBundle(\n bundlePath: string,\n jwksPath: string | undefined,\n fs: typeof import('fs'),\n pathModule: typeof import('path'),\n logger: PluginLogger\n): Promise<VerifyResult> {\n // Read manifest\n const manifestPath = pathModule.join(bundlePath, 'manifest.json');\n const manifest = JSON.parse(await fs.promises.readFile(manifestPath, 'utf-8'));\n\n const receiptsDir = pathModule.join(bundlePath, 'receipts');\n const files = await fs.promises.readdir(receiptsDir);\n\n let validCount = 0;\n let invalidCount = 0;\n const allErrors: string[] = [];\n const allWarnings: string[] = [];\n\n for (const file of files) {\n if (!file.endsWith('.peac.json')) continue;\n\n const result = await verifySingleReceipt(\n pathModule.join(receiptsDir, file),\n jwksPath,\n fs,\n logger\n );\n\n if (result.valid) {\n validCount++;\n } else {\n invalidCount++;\n if (result.errors) {\n allErrors.push(...result.errors.map((e) => `${file}: ${e}`));\n }\n }\n if (result.warnings) {\n allWarnings.push(...result.warnings.map((w) => `${file}: ${w}`));\n }\n }\n\n return {\n status: invalidCount === 0 ? 'ok' : 'error',\n valid: invalidCount === 0,\n message: `Bundle verification: ${validCount} valid, ${invalidCount} invalid`,\n errors: allErrors.length > 0 ? allErrors : undefined,\n warnings: allWarnings.length > 0 ? allWarnings : undefined,\n bundle_stats: {\n total: validCount + invalidCount,\n valid: validCount,\n invalid: invalidCount,\n manifest_receipt_count: manifest.receipt_count,\n },\n };\n}\n\ninterface VerifyParams {\n path: string;\n jwks_path?: string;\n}\n\ninterface VerifyResult {\n status: 'ok' | 'error';\n valid: boolean;\n message: string;\n errors?: string[];\n warnings?: string[];\n receipt_id?: string;\n interaction_id?: string;\n bundle_stats?: {\n total: number;\n valid: number;\n invalid: number;\n manifest_receipt_count: number;\n };\n}\n\n// =============================================================================\n// Query Tool\n// =============================================================================\n\n/**\n * Create the peac_receipts.query tool.\n * Query receipts by workflow_id, tool name, or time range.\n */\nexport function createQueryTool(outputDir: string, logger: PluginLogger): PluginTool {\n return {\n name: 'peac_receipts.query',\n description: 'Query receipts by workflow_id, tool name, or time range',\n parameters: {\n type: 'object',\n properties: {\n workflow_id: {\n type: 'string',\n description: 'Filter by workflow ID',\n },\n tool_name: {\n type: 'string',\n description: 'Filter by tool name',\n },\n since: {\n type: 'string',\n description: 'Include receipts since this RFC 3339 timestamp',\n },\n until: {\n type: 'string',\n description: 'Include receipts until this RFC 3339 timestamp',\n },\n status: {\n type: 'string',\n enum: ['ok', 'error', 'timeout', 'canceled'],\n description: 'Filter by result status',\n },\n limit: {\n type: 'integer',\n description: 'Maximum number of results (default: 100)',\n },\n offset: {\n type: 'integer',\n description: 'Skip this many results (for pagination)',\n },\n },\n },\n\n async execute(params: QueryParams): Promise<QueryResult> {\n const fs = await import('fs');\n const pathModule = await import('path');\n\n // Use path.resolve for portability\n const resolvedOutputDir = pathModule.resolve(outputDir);\n\n try {\n const files = await fs.promises.readdir(resolvedOutputDir);\n const receiptFiles = files.filter((f) => f.endsWith('.peac.json'));\n\n const limit = Math.min(params.limit || 100, MAX_QUERY_FILE_PARSE);\n const offset = params.offset || 0;\n\n // If we have time filters, we can sort by mtime first (cheap) to reduce parsing\n // Get file stats first for time-based pre-filtering\n const fileInfos: Array<{ file: string; mtime: Date }> = [];\n for (const file of receiptFiles.slice(0, MAX_QUERY_FILE_PARSE)) {\n try {\n const filePath = pathModule.join(resolvedOutputDir, file);\n const stat = await fs.promises.stat(filePath);\n\n // Apply time filters early (before parsing JSON)\n if (params.since && stat.mtime < new Date(params.since)) {\n continue;\n }\n if (params.until && stat.mtime > new Date(params.until)) {\n continue;\n }\n\n fileInfos.push({ file, mtime: stat.mtime });\n } catch {\n // Skip files that can't be stat'd\n continue;\n }\n }\n\n // Sort by mtime descending (newest first) before parsing\n fileInfos.sort((a, b) => b.mtime.getTime() - a.mtime.getTime());\n\n // Now parse files until we have enough matches\n const matches: QueryMatch[] = [];\n let skippedForFilters = 0;\n\n let filesSkippedForSize = 0;\n let filesSkippedForInvalidJson = 0;\n let filesSkippedForMalformedJws = 0;\n for (const { file } of fileInfos) {\n const filePath = pathModule.join(resolvedOutputDir, file);\n\n // Check file size before reading (DoS protection)\n try {\n const fileStat = await fs.promises.stat(filePath);\n if (fileStat.size > MAX_FILE_SIZE_BYTES) {\n filesSkippedForSize++;\n continue;\n }\n } catch {\n continue;\n }\n\n // Read and parse receipt (tolerate invalid JSON)\n let content;\n try {\n content = JSON.parse(await fs.promises.readFile(filePath, 'utf-8'));\n } catch {\n // Skip invalid JSON files\n filesSkippedForInvalidJson++;\n continue;\n }\n\n // Derive filter data from _jws (source of truth when present).\n // If _jws exists but is malformed, skip this receipt (untrusted).\n const decoded = content._jws ? decodeReceiptPayload(content) : null;\n if (content._jws && !decoded) {\n filesSkippedForMalformedJws++;\n continue;\n }\n const authBlock = (decoded?.auth ?? content?.auth) as Record<string, unknown> | undefined;\n const evidenceBlock = (decoded?.evidence ?? content?.evidence) as\n | Record<string, unknown>\n | undefined;\n const evidenceExtensions = evidenceBlock?.extensions as\n | Record<string, unknown>\n | undefined;\n const interaction = evidenceExtensions?.['org.peacprotocol/interaction@0.1'] as\n | Record<string, unknown>\n | undefined;\n const authExtensions = authBlock?.extensions as Record<string, unknown> | undefined;\n const workflow = authExtensions?.['org.peacprotocol/workflow'] as\n | Record<string, unknown>\n | undefined;\n\n // Apply workflow filter\n if (params.workflow_id && workflow?.workflow_id !== params.workflow_id) {\n skippedForFilters++;\n continue;\n }\n\n // Apply tool filter\n const tool = interaction?.tool as Record<string, unknown> | undefined;\n if (params.tool_name && tool?.name !== params.tool_name) {\n skippedForFilters++;\n continue;\n }\n\n // Apply status filter\n const result = interaction?.result as Record<string, unknown> | undefined;\n if (params.status && result?.status !== params.status) {\n skippedForFilters++;\n continue;\n }\n\n matches.push({\n file,\n receipt_id: authBlock?.rid as string | undefined,\n interaction_id: interaction?.interaction_id as string | undefined,\n workflow_id: workflow?.workflow_id as string | undefined,\n tool_name: tool?.name as string | undefined,\n status: result?.status as string | undefined,\n started_at: interaction?.started_at as string | undefined,\n completed_at: interaction?.completed_at as string | undefined,\n });\n\n // Early exit if we have enough matches (limit + offset)\n // This avoids parsing all files when we only need a few\n if (matches.length >= offset + limit + 100) {\n // Buffer of 100 for sorting stability\n break;\n }\n }\n\n // Final sort by started_at (more accurate than mtime), then by filename for determinism\n matches.sort((a, b) => {\n const aTime = a.started_at ? new Date(a.started_at).getTime() : 0;\n const bTime = b.started_at ? new Date(b.started_at).getTime() : 0;\n if (bTime !== aTime) return bTime - aTime;\n // Secondary sort by filename for deterministic ordering\n return a.file.localeCompare(b.file);\n });\n\n // Apply pagination\n const paginated = matches.slice(offset, offset + limit);\n\n // Build warnings for truncation\n const warnings: string[] = [];\n if (receiptFiles.length > MAX_QUERY_FILE_PARSE) {\n warnings.push(`Results capped at ${MAX_QUERY_FILE_PARSE} files`);\n }\n if (filesSkippedForSize > 0) {\n warnings.push(\n `${filesSkippedForSize} files skipped (exceeded ${MAX_FILE_SIZE_BYTES} byte limit)`\n );\n }\n if (filesSkippedForInvalidJson > 0) {\n warnings.push(`${filesSkippedForInvalidJson} files skipped (invalid JSON)`);\n }\n if (filesSkippedForMalformedJws > 0) {\n warnings.push(`${filesSkippedForMalformedJws} files skipped (malformed JWS)`);\n }\n\n const totalSkipped =\n filesSkippedForSize + filesSkippedForInvalidJson + filesSkippedForMalformedJws;\n const hasTruncation = receiptFiles.length > MAX_QUERY_FILE_PARSE || totalSkipped > 0;\n\n return {\n status: 'ok',\n total: matches.length,\n offset,\n limit,\n results: paginated,\n scanned_count: fileInfos.length,\n matched_count: matches.length,\n truncated: hasTruncation,\n skipped:\n hasTruncation || skippedForFilters > 0\n ? {\n too_large: filesSkippedForSize,\n invalid_json: filesSkippedForInvalidJson,\n malformed_jws: filesSkippedForMalformedJws,\n filtered: skippedForFilters,\n capped:\n receiptFiles.length > MAX_QUERY_FILE_PARSE\n ? receiptFiles.length - MAX_QUERY_FILE_PARSE\n : 0,\n }\n : undefined,\n ...(warnings.length > 0 && { warning: warnings.join('; ') }),\n };\n } catch (error) {\n logger.error('Query failed:', error);\n return {\n status: 'error',\n total: 0,\n offset: 0,\n limit: params.limit || 100,\n results: [],\n error: error instanceof Error ? error.message : 'Unknown error',\n };\n }\n },\n };\n}\n\ninterface QueryParams {\n workflow_id?: string;\n tool_name?: string;\n since?: string;\n until?: string;\n status?: 'ok' | 'error' | 'timeout' | 'canceled';\n limit?: number;\n offset?: number;\n}\n\ninterface QueryMatch {\n file: string;\n receipt_id?: string;\n interaction_id?: string;\n workflow_id?: string;\n tool_name?: string;\n status?: string;\n started_at?: string;\n completed_at?: string;\n}\n\ninterface QueryResult {\n status: 'ok' | 'error';\n total: number;\n offset: number;\n limit: number;\n results: QueryMatch[];\n scanned_count?: number;\n matched_count?: number;\n truncated?: boolean;\n skipped?: {\n too_large: number;\n invalid_json: number;\n malformed_jws: number;\n filtered: number;\n capped: number;\n };\n error?: string;\n warning?: string;\n}\n","/**\n * @peac/adapter-openclaw - Plugin Activation\n *\n * High-level entry point that wires together all adapter components\n * from config. Calls existing functions (resolveSigner, createPluginInstance,\n * createFileReceiptWriter, etc.) -- no logic duplication.\n *\n * Usage:\n * const result = await activate({ config, logger });\n * result.instance.start();\n *\n * When OpenClaw's plugin loader gains a stable activation shape,\n * add a thin validated wrapper at that time.\n */\n\nimport * as path from 'node:path';\nimport * as fs from 'node:fs/promises';\nimport type { OpenClawAdapterConfig } from './types.js';\nimport type { PluginLogger, PluginInstance, PluginTool } from './plugin.js';\nimport type { OpenClawHookHandler } from './hooks.js';\nimport type { FsSpoolStoreOptions } from '@peac/capture-node';\nimport { createFsSpoolStore, createFsDedupeIndex, getFsSpoolDiagnostics } from '@peac/capture-node';\nimport { resolveSigner, createFileReceiptWriter, createPluginInstance } from './plugin.js';\nimport {\n createStatusTool,\n createExportBundleTool,\n createVerifyTool,\n createQueryTool,\n} from './tools.js';\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Options for activating the plugin.\n */\nexport interface ActivateOptions {\n /** Adapter configuration (signing, capture, correlation, background). */\n config: ActivateConfig;\n /** Logger instance. */\n logger?: PluginLogger;\n /** Data directory for spool, dedupe, and signing key. Default: ~/.openclaw/peac/ */\n dataDir?: string;\n /** Spool store options override. */\n spoolOptions?: Partial<\n Pick<\n FsSpoolStoreOptions,\n 'maxEntries' | 'maxFileBytes' | 'autoCommitIntervalMs' | 'lockOptions'\n >\n >;\n}\n\n/**\n * Configuration for activate(). Extends OpenClawAdapterConfig with\n * required signing fields.\n */\nexport interface ActivateConfig extends OpenClawAdapterConfig {\n /** Signing configuration (required for activation). */\n signing: {\n /** Key reference: env:VAR_NAME or file:/path */\n key_ref: string;\n /** Issuer URI for receipts */\n issuer: string;\n /** Optional audience URI */\n audience?: string;\n };\n /** Output directory for receipt files. Default: {dataDir}/receipts/ */\n output_dir?: string;\n /** Background emitter settings. */\n background?: {\n drain_interval_ms?: number;\n batch_size?: number;\n };\n}\n\n/**\n * Result of activating the plugin.\n */\nexport interface ActivateResult {\n /** The running plugin instance. */\n instance: PluginInstance;\n /** The 4 plugin tools (status, export, verify, query). */\n tools: PluginTool[];\n /** Hook handler for tool call events. */\n hookHandler: OpenClawHookHandler;\n /** Data directory used. */\n dataDir: string;\n /** Flush pending spool entries into signed receipts. */\n flush: () => Promise<void>;\n /** Shut down the plugin cleanly. */\n shutdown: () => Promise<void>;\n}\n\n// =============================================================================\n// Defaults\n// =============================================================================\n\nconst DEFAULT_DATA_DIR_NAME = '.openclaw/peac';\nconst SPOOL_FILENAME = 'spool.jsonl';\nconst DEDUPE_FILENAME = 'dedupe.idx';\n\n// =============================================================================\n// Helpers\n// =============================================================================\n\nfunction defaultDataDir(): string {\n const home = process.env.HOME || process.env.USERPROFILE || '.';\n return path.join(home, DEFAULT_DATA_DIR_NAME);\n}\n\nfunction noopLogger(): PluginLogger {\n const noop = () => {};\n return { debug: noop, info: noop, warn: noop, error: noop };\n}\n\n// =============================================================================\n// Activation\n// =============================================================================\n\n/**\n * Activate the PEAC evidence export plugin.\n *\n * This is the single canonical entry point. It:\n * 1. Resolves the signing key from config (env: or file:)\n * 2. Creates durable stores (FsSpoolStore + FsDedupeIndex)\n * 3. Creates the receipt writer\n * 4. Creates the plugin instance (session + hooks + emitter)\n * 5. Creates the 4 plugin tools\n * 6. Logs startup diagnostics\n *\n * @throws If signing key cannot be resolved\n * @throws If data directory is not writable\n * @throws If spool lockfile cannot be acquired\n */\nexport async function activate(options: ActivateOptions): Promise<ActivateResult> {\n const { config, spoolOptions } = options;\n const logger = options.logger ?? noopLogger();\n const dataDir = options.dataDir ?? defaultDataDir();\n\n // 1. Ensure data directory exists\n await fs.mkdir(dataDir, { recursive: true });\n\n // Verify writable\n try {\n await fs.access(dataDir, (await import('node:constants')).W_OK);\n } catch {\n throw new Error(`Data directory is not writable: ${dataDir}`);\n }\n\n // 2. Resolve signing key\n logger.info(`Resolving signing key from: ${config.signing.key_ref.split(':')[0]}:***`);\n const signer = await resolveSigner(\n config.signing.key_ref,\n config.signing.issuer,\n config.signing.audience\n );\n logger.info(`Signing key resolved. kid: ${signer.getKeyId()}`);\n\n // 3. Create durable stores\n const spoolPath = path.join(dataDir, SPOOL_FILENAME);\n const dedupePath = path.join(dataDir, DEDUPE_FILENAME);\n\n const store = await createFsSpoolStore({\n filePath: spoolPath,\n maxEntries: spoolOptions?.maxEntries,\n maxFileBytes: spoolOptions?.maxFileBytes,\n autoCommitIntervalMs: spoolOptions?.autoCommitIntervalMs,\n lockOptions: spoolOptions?.lockOptions,\n onWarning: (msg: string) => logger.warn(`spool: ${msg}`),\n });\n\n const dedupe = await createFsDedupeIndex({\n filePath: dedupePath,\n });\n\n // 4. Create receipt writer\n const outputDir = config.output_dir ?? path.join(dataDir, 'receipts');\n const writer = await createFileReceiptWriter(outputDir);\n\n // 5. Create plugin instance\n const instance = await createPluginInstance({\n signer,\n writer,\n adapterConfig: config,\n store,\n dedupe,\n drainIntervalMs: config.background?.drain_interval_ms,\n batchSize: config.background?.batch_size,\n onError: (err) => logger.error(`plugin error: ${err.message}`),\n });\n\n // 6. Create tools\n const tools: PluginTool[] = [\n createStatusTool(() => instance.getStats(), outputDir),\n createExportBundleTool(outputDir, logger),\n createVerifyTool(logger),\n createQueryTool(outputDir, logger),\n ];\n\n // 7. Log startup diagnostics\n const diag = getFsSpoolDiagnostics(store);\n if (diag) {\n logger.info(\n `PEAC evidence export active. ` +\n `Spool: ${diag.entryCount} entries, ${diag.fileBytes} bytes. ` +\n `Receipts: ${outputDir}`\n );\n } else {\n logger.info(`PEAC evidence export active. Receipts: ${outputDir}`);\n }\n\n // 8. Shutdown handler\n async function shutdown(): Promise<void> {\n logger.info('Shutting down PEAC evidence export...');\n await instance.stop();\n await store.close();\n await dedupe.close();\n logger.info('PEAC evidence export stopped.');\n }\n\n return {\n instance,\n tools,\n hookHandler: instance.hookHandler,\n dataDir,\n flush: () => instance.backgroundService.drain(),\n shutdown,\n };\n}\n","/**\n * @peac/adapter-openclaw - Signing Key Generation\n *\n * Generates an Ed25519 keypair for PEAC receipt signing.\n * Reuses generateKeyId() from plugin.ts for kid derivation.\n *\n * Usage (programmatic):\n * const result = await generateSigningKey({ outputDir: '~/.openclaw/peac' });\n * console.log(result.kid);\n *\n * Usage (CLI):\n * npx @peac/adapter-openclaw keygen\n * npx @peac/adapter-openclaw keygen --output-dir /path/to/dir\n */\n\nimport * as path from 'node:path';\nimport * as fs from 'node:fs/promises';\nimport { generateKeypair, base64urlEncode } from '@peac/crypto';\nimport { generateKeyId, type JWK } from './plugin.js';\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Options for key generation.\n */\nexport interface KeygenOptions {\n /** Directory to write the key file to. Default: current directory. */\n outputDir?: string;\n /** Filename for the private key. Default: signing-key.jwk */\n filename?: string;\n}\n\n/**\n * Result of key generation.\n */\nexport interface KeygenResult {\n /** Key ID (derived from public key). */\n kid: string;\n /** Path where the private key was written. */\n keyPath: string;\n /** The public JWK (safe to share). */\n publicJwk: JWK;\n /** The private JWK (keep secret). */\n privateJwk: JWK;\n}\n\n// =============================================================================\n// Defaults\n// =============================================================================\n\nconst DEFAULT_KEY_FILENAME = 'signing-key.jwk';\n\n// =============================================================================\n// Key Generation\n// =============================================================================\n\n/**\n * Generate an Ed25519 signing keypair and write the private key to disk.\n *\n * - Private key file has 0o600 permissions (owner read/write only).\n * On platforms where chmod fails (Windows), a warning is logged to stderr.\n * - The key ID (kid) is derived from the public key via generateKeyId().\n *\n * @returns KeygenResult with paths and key material\n */\nexport async function generateSigningKey(options?: KeygenOptions): Promise<KeygenResult> {\n const outputDir = options?.outputDir ?? '.';\n const filename = options?.filename ?? DEFAULT_KEY_FILENAME;\n\n // Generate Ed25519 keypair via @peac/crypto\n const { privateKey: privateKeyBytes, publicKey: publicKeyBytes } = await generateKeypair();\n\n // Encode as base64url\n const d = base64urlEncode(privateKeyBytes);\n const x = base64urlEncode(publicKeyBytes);\n\n // Build JWK\n const privateJwk: JWK = {\n kty: 'OKP',\n crv: 'Ed25519',\n x,\n d,\n alg: 'EdDSA',\n use: 'sig',\n };\n\n // Derive key ID from public component\n const kid = generateKeyId(privateJwk);\n privateJwk.kid = kid;\n\n // Public JWK (no private component)\n const publicJwk: JWK = {\n kty: 'OKP',\n crv: 'Ed25519',\n x,\n kid,\n alg: 'EdDSA',\n use: 'sig',\n };\n\n // Write to disk\n await fs.mkdir(outputDir, { recursive: true });\n const keyPath = path.join(outputDir, filename);\n await fs.writeFile(keyPath, JSON.stringify(privateJwk, null, 2) + '\\n', 'utf-8');\n\n // Set restrictive permissions (0o600 = owner read/write only)\n try {\n await fs.chmod(keyPath, 0o600);\n } catch {\n // chmod may fail on Windows -- log warning but don't fail\n process.stderr.write(\n `Warning: Could not set file permissions on ${keyPath}. ` +\n `Ensure the file is not readable by other users.\\n`\n );\n }\n\n return { kid, keyPath, publicJwk, privateJwk };\n}\n\n// =============================================================================\n// CLI Entry Point\n// =============================================================================\n\n/**\n * CLI handler for `peac-keygen` command.\n * Parses args, generates key, prints results.\n */\nexport async function keygenCli(args: string[]): Promise<void> {\n let outputDir: string | undefined;\n\n for (let i = 0; i < args.length; i++) {\n if (args[i] === '--output-dir' && i + 1 < args.length) {\n outputDir = args[i + 1];\n i++;\n } else if (args[i] === '--help' || args[i] === '-h') {\n process.stdout.write(\n 'Usage: peac-keygen [--output-dir <dir>]\\n\\n' +\n 'Generate an Ed25519 signing key for PEAC receipt signing.\\n\\n' +\n 'Options:\\n' +\n ' --output-dir <dir> Directory for key file (default: current directory)\\n' +\n ' --help, -h Show this help message\\n'\n );\n return;\n }\n }\n\n const result = await generateSigningKey({ outputDir });\n\n process.stdout.write(`Key generated successfully.\\n`);\n process.stdout.write(` kid: ${result.kid}\\n`);\n process.stdout.write(` key file: ${result.keyPath}\\n`);\n process.stdout.write(` public x: ${result.publicJwk.x}\\n`);\n process.stdout.write(`\\nTo use with the OpenClaw adapter:\\n`);\n process.stdout.write(` signing.key_ref: \"file:${path.resolve(result.keyPath)}\"\\n`);\n}\n"]}
1
+ {"version":3,"sources":["../src/types.ts","../src/mapper.ts","../src/hooks.ts","../src/emitter.ts","../src/plugin.ts","../src/tools.ts","../src/activate.ts","../src/keygen.ts"],"names":["canonicalize","toInteractionEvidence","crypto","fs","captureCore","base64urlDecode","path","createFsSpoolStore","createFsDedupeIndex","getFsSpoolDiagnostics","generateKeypair","base64urlEncode","fs2","path2"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * @peac/adapter-openclaw - OpenClaw Types\n *\n * Types for OpenClaw tool call events and PEAC integration.\n */\n\n// =============================================================================\n// OpenClaw Event Types (Input from OpenClaw)\n// =============================================================================\n\n/**\n * OpenClaw tool call event - represents a single tool invocation.\n *\n * This is the input format from OpenClaw hooks (after_tool_call, etc.).\n */\nexport interface OpenClawToolCallEvent {\n /** OpenClaw's internal tool call ID */\n tool_call_id: string;\n\n /** Run ID (conversation/session scope) */\n run_id: string;\n\n /** Session key (optional, for workflow correlation) */\n session_key?: string;\n\n /** Tool name */\n tool_name: string;\n\n /** Tool provider (e.g., \"builtin\", \"mcp\", \"custom\") */\n tool_provider?: string;\n\n /** Tool version (if versioned) */\n tool_version?: string;\n\n /** Input parameters (JSON-serializable) */\n input: unknown;\n\n /** Output result (JSON-serializable) */\n output?: unknown;\n\n /** Execution start time (RFC 3339) */\n started_at: string;\n\n /** Execution end time (RFC 3339) */\n completed_at?: string;\n\n /** Duration in milliseconds (from monotonic clock) */\n duration_ms?: number;\n\n /** Execution status */\n status: 'ok' | 'error' | 'timeout' | 'canceled';\n\n /** Error code (if status is error) */\n error_code?: string;\n\n /** Error message (if status is error) */\n error_message?: string;\n\n /** Whether the error is retryable */\n retryable?: boolean;\n\n /** Policy context at execution time */\n policy?: OpenClawPolicyContext;\n\n /** OpenClaw-specific context */\n context?: OpenClawContext;\n}\n\n/**\n * OpenClaw policy context at execution time.\n */\nexport interface OpenClawPolicyContext {\n /** Policy decision (allow/deny/constrained) */\n decision: 'allow' | 'deny' | 'constrained';\n\n /** Whether sandbox mode was enabled */\n sandbox_enabled?: boolean;\n\n /** Whether elevated permissions were used */\n elevated?: boolean;\n\n /** Hash of the effective policy (for audit) */\n policy_hash?: string;\n}\n\n/**\n * OpenClaw-specific context (channel, workspace, etc.).\n */\nexport interface OpenClawContext {\n /** Channel information */\n channel?: {\n kind: 'direct' | 'group' | 'api';\n id?: string;\n };\n\n /** Workspace configuration hash */\n workspace_digest?: string;\n\n /** OpenClaw gateway version */\n gateway_version?: string;\n\n /** Security audit digest (hash of full audit report) */\n audit_digest?: string;\n}\n\n// =============================================================================\n// Adapter Configuration\n// =============================================================================\n\n/**\n * OpenClaw adapter configuration.\n */\nexport interface OpenClawAdapterConfig {\n /** Platform identifier (default: \"openclaw\") */\n platform?: string;\n\n /** Platform version (e.g., \"0.2.0\") */\n platform_version?: string;\n\n /** Plugin ID for provenance tracking */\n plugin_id?: string;\n\n /** Plugin digest for integrity verification */\n plugin_digest?: string;\n\n /** Capture mode configuration */\n capture?: {\n /** Redaction mode for payloads */\n mode: 'hash_only' | 'allowlist';\n\n /** Tool names for plaintext capture (only when mode=allowlist) */\n allowlist?: string[];\n\n /** Maximum payload size to hash (bytes, default: 1MB) */\n max_payload_size?: number;\n };\n\n /** Signing configuration (for background emitter) */\n signing?: {\n /** Key reference (env var, keychain path, sidecar socket) */\n key_ref: string;\n\n /** Issuer URI */\n issuer: string;\n\n /** Audience URI (optional) */\n audience?: string;\n };\n\n /** Correlation options */\n correlation?: {\n /** Include workflow context from session */\n include_workflow?: boolean;\n\n /** Include agent identity attestation */\n include_identity?: boolean;\n\n /** Reference to identity attestation */\n identity_attestation_ref?: string;\n };\n}\n\n// =============================================================================\n// Mapper Output Types\n// =============================================================================\n\n/**\n * Result of mapping an OpenClaw event to a CapturedAction.\n * Includes validation status and any warnings.\n */\nexport interface MappingResult {\n /** Whether the mapping succeeded */\n success: boolean;\n\n /** The mapped action (if success) */\n action?: import('@peac/capture-core').CapturedAction;\n\n /** Error code (if failed) */\n error_code?: string;\n\n /** Error message (if failed) */\n error_message?: string;\n\n /** Warnings (non-fatal issues) */\n warnings?: MappingWarning[];\n}\n\n/**\n * Mapping warning (non-fatal issue).\n */\nexport interface MappingWarning {\n code: string;\n message: string;\n field?: string;\n}\n\n// =============================================================================\n// Emitter Types\n// =============================================================================\n\n/**\n * Receipt emitter interface.\n *\n * Responsible for converting captured actions to signed PEAC receipts.\n */\nexport interface ReceiptEmitter {\n /** Emit a receipt from a spool entry */\n emit(entry: import('@peac/capture-core').SpoolEntry): Promise<EmitResult>;\n\n /** Flush any pending receipts */\n flush(): Promise<void>;\n\n /** Close the emitter */\n close(): Promise<void>;\n}\n\n/**\n * Result of emitting a receipt.\n */\nexport interface EmitResult {\n /** Whether emission succeeded */\n success: boolean;\n\n /** Receipt file path (if success) */\n receipt_path?: string;\n\n /** Receipt ID (rid) */\n receipt_id?: string;\n\n /** Error code (if failed) */\n error_code?: string;\n\n /** Error message (if failed) */\n error_message?: string;\n}\n\n// =============================================================================\n// OpenClaw Extension Keys (for nested extensions)\n// =============================================================================\n\n/**\n * OpenClaw-specific extension keys used in interaction.extensions.\n */\nexport const OPENCLAW_EXTENSION_KEYS = {\n /** OpenClaw context extension */\n CONTEXT: 'org.openclaw/context',\n\n /** Security audit digest */\n AUDIT_DIGEST: 'org.openclaw/audit_digest',\n} as const;\n\n/**\n * OpenClaw context extension data.\n */\nexport interface OpenClawContextExtension {\n channel?: {\n kind: 'direct' | 'group' | 'api';\n id?: string;\n };\n workspace_digest?: string;\n tool_call_id?: string;\n gateway_version?: string;\n}\n\n// =============================================================================\n// Error Codes\n// =============================================================================\n\n/**\n * OpenClaw adapter error codes.\n */\nexport const OPENCLAW_ERROR_CODES = {\n /** Missing required field in OpenClaw event */\n MISSING_FIELD: 'E_OPENCLAW_MISSING_FIELD',\n\n /** Invalid field value in OpenClaw event */\n INVALID_FIELD: 'E_OPENCLAW_INVALID_FIELD',\n\n /** Payload serialization failed */\n SERIALIZATION_FAILED: 'E_OPENCLAW_SERIALIZATION_FAILED',\n\n /** Signing failed */\n SIGNING_FAILED: 'E_OPENCLAW_SIGNING_FAILED',\n\n /** Emitter not configured */\n EMITTER_NOT_CONFIGURED: 'E_OPENCLAW_EMITTER_NOT_CONFIGURED',\n} as const;\n\nexport type OpenClawErrorCode = (typeof OPENCLAW_ERROR_CODES)[keyof typeof OPENCLAW_ERROR_CODES];\n\n// =============================================================================\n// Warning Codes\n// =============================================================================\n\n/**\n * OpenClaw adapter warning codes.\n */\nexport const OPENCLAW_WARNING_CODES = {\n /** Payload exceeded size limit and was truncated for hashing */\n PAYLOAD_TRUNCATED: 'W_OPENCLAW_PAYLOAD_TRUNCATED',\n\n /** Payload serialization failed (circular refs, BigInt, etc.) */\n SERIALIZATION_FAILED: 'W_OPENCLAW_SERIALIZATION_FAILED',\n\n /** Optional field missing (non-critical) */\n OPTIONAL_FIELD_MISSING: 'W_OPENCLAW_OPTIONAL_FIELD_MISSING',\n\n /** Unknown tool provider */\n UNKNOWN_PROVIDER: 'W_OPENCLAW_UNKNOWN_PROVIDER',\n\n /** Payload dropped due to redaction policy (hash_only mode for non-allowlisted tool) */\n PAYLOAD_REDACTED: 'W_OPENCLAW_PAYLOAD_REDACTED',\n} as const;\n\nexport type OpenClawWarningCode =\n (typeof OPENCLAW_WARNING_CODES)[keyof typeof OPENCLAW_WARNING_CODES];\n","/**\n * @peac/adapter-openclaw - Mapper\n *\n * Maps OpenClaw tool call events to PEAC CapturedAction format.\n */\n\nimport { canonicalize } from '@peac/crypto';\nimport type { CapturedAction } from '@peac/capture-core';\nimport type {\n OpenClawToolCallEvent,\n OpenClawAdapterConfig,\n MappingResult,\n MappingWarning,\n OpenClawContextExtension,\n} from './types.js';\nimport { OPENCLAW_ERROR_CODES, OPENCLAW_WARNING_CODES, OPENCLAW_EXTENSION_KEYS } from './types.js';\n\n// =============================================================================\n// Constants\n// =============================================================================\n\nconst DEFAULT_PLATFORM = 'openclaw';\nconst DEFAULT_KIND = 'tool.call';\n\n// =============================================================================\n// Mapper Implementation\n// =============================================================================\n\n/**\n * Map an OpenClaw tool call event to a PEAC CapturedAction.\n *\n * @param event - OpenClaw tool call event\n * @param config - Adapter configuration\n * @returns Mapping result with action or error\n */\nexport function mapToolCallEvent(\n event: OpenClawToolCallEvent,\n config?: OpenClawAdapterConfig\n): MappingResult {\n const warnings: MappingWarning[] = [];\n\n // Validate required fields\n const validationError = validateRequiredFields(event);\n if (validationError) {\n return {\n success: false,\n error_code: validationError.code,\n error_message: validationError.message,\n };\n }\n\n // Build interaction ID (deterministic, for dedupe)\n const interactionId = buildInteractionId(event);\n\n // Get capture policy configuration\n const captureMode = config?.capture?.mode ?? 'hash_only';\n const allowlist = config?.capture?.allowlist ?? [];\n const maxPayloadSize = config?.capture?.max_payload_size ?? 1024 * 1024; // 1MB default\n\n // Check if this tool is allowlisted for plaintext capture\n const isAllowlisted = captureMode === 'allowlist' && allowlist.includes(event.tool_name);\n\n // Serialize input/output to bytes with policy enforcement\n const inputResult = serializePayloadWithPolicy(\n event.input,\n maxPayloadSize,\n isAllowlisted,\n 'input'\n );\n const outputResult =\n event.output !== undefined\n ? serializePayloadWithPolicy(event.output, maxPayloadSize, isAllowlisted, 'output')\n : undefined;\n\n // Collect warnings from serialization\n if (inputResult.warning) {\n warnings.push(inputResult.warning);\n }\n if (outputResult?.warning) {\n warnings.push(outputResult.warning);\n }\n\n const inputBytes = inputResult.bytes;\n const outputBytes = outputResult?.bytes;\n\n // Build platform metadata\n const platform = config?.platform ?? DEFAULT_PLATFORM;\n const platformVersion = config?.platform_version;\n const pluginId = config?.plugin_id;\n\n // Build OpenClaw-specific extensions\n const extensions = buildExtensions(event);\n\n // Build the CapturedAction\n const action: CapturedAction = {\n id: interactionId,\n kind: DEFAULT_KIND,\n platform,\n started_at: event.started_at,\n completed_at: event.completed_at,\n tool_name: event.tool_name,\n tool_provider: event.tool_provider,\n input_bytes: inputBytes,\n output_bytes: outputBytes,\n status: event.status,\n error_code: event.error_code,\n retryable: event.retryable,\n metadata: {\n // Platform metadata\n ...(platformVersion && { platform_version: platformVersion }),\n ...(pluginId && { plugin_id: pluginId }),\n\n // Tool version (not a standard field, stored in metadata)\n ...(event.tool_version && { tool_version: event.tool_version }),\n\n // Policy context\n ...(event.policy && {\n policy_decision: event.policy.decision,\n sandbox_enabled: event.policy.sandbox_enabled,\n elevated: event.policy.elevated,\n policy_hash: event.policy.policy_hash,\n }),\n\n // OpenClaw extensions (will be mapped to interaction.extensions)\n ...extensions,\n },\n };\n\n return {\n success: true,\n action,\n warnings: warnings.length > 0 ? warnings : undefined,\n };\n}\n\n/**\n * Build a batch of CapturedActions from OpenClaw events.\n *\n * @param events - Array of OpenClaw tool call events\n * @param config - Adapter configuration\n * @returns Array of mapping results\n */\nexport function mapToolCallEventBatch(\n events: OpenClawToolCallEvent[],\n config?: OpenClawAdapterConfig\n): MappingResult[] {\n return events.map((event) => mapToolCallEvent(event, config));\n}\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * Validate required fields in OpenClaw event.\n */\nfunction validateRequiredFields(\n event: OpenClawToolCallEvent\n): { code: string; message: string } | null {\n if (!event.tool_call_id) {\n return {\n code: OPENCLAW_ERROR_CODES.MISSING_FIELD,\n message: 'Missing required field: tool_call_id',\n };\n }\n\n if (!event.run_id) {\n return {\n code: OPENCLAW_ERROR_CODES.MISSING_FIELD,\n message: 'Missing required field: run_id',\n };\n }\n\n if (!event.tool_name) {\n return {\n code: OPENCLAW_ERROR_CODES.MISSING_FIELD,\n message: 'Missing required field: tool_name',\n };\n }\n\n if (!event.started_at) {\n return {\n code: OPENCLAW_ERROR_CODES.MISSING_FIELD,\n message: 'Missing required field: started_at',\n };\n }\n\n if (!event.status) {\n return {\n code: OPENCLAW_ERROR_CODES.MISSING_FIELD,\n message: 'Missing required field: status',\n };\n }\n\n // Validate status is a known value\n const validStatuses = ['ok', 'error', 'timeout', 'canceled'];\n if (!validStatuses.includes(event.status)) {\n return {\n code: OPENCLAW_ERROR_CODES.INVALID_FIELD,\n message: `Invalid status: ${event.status}. Expected one of: ${validStatuses.join(', ')}`,\n };\n }\n\n // Validate timestamps are RFC 3339\n if (!isValidRfc3339(event.started_at)) {\n return {\n code: OPENCLAW_ERROR_CODES.INVALID_FIELD,\n message: `Invalid started_at timestamp: ${event.started_at}. Expected RFC 3339 format.`,\n };\n }\n\n if (event.completed_at && !isValidRfc3339(event.completed_at)) {\n return {\n code: OPENCLAW_ERROR_CODES.INVALID_FIELD,\n message: `Invalid completed_at timestamp: ${event.completed_at}. Expected RFC 3339 format.`,\n };\n }\n\n return null;\n}\n\n/**\n * Build a deterministic interaction ID from OpenClaw event.\n *\n * Uses base64url encoding to handle delimiter collisions - if run_id or\n * tool_call_id contains ':', the ID would be ambiguous without encoding.\n *\n * Format: openclaw/{base64url(run_id)}/{base64url(tool_call_id)}\n */\nfunction buildInteractionId(event: OpenClawToolCallEvent): string {\n const runIdEncoded = base64urlEncode(event.run_id);\n const toolCallIdEncoded = base64urlEncode(event.tool_call_id);\n return `openclaw/${runIdEncoded}/${toolCallIdEncoded}`;\n}\n\n/**\n * Base64url encode a string (RFC 4648 section 5).\n * URL-safe: replaces + with -, / with _, removes padding.\n */\nfunction base64urlEncode(str: string): string {\n // Use TextEncoder for proper UTF-8 handling\n const bytes = new TextEncoder().encode(str);\n // Convert to base64\n const base64 = btoa(String.fromCharCode(...bytes));\n // Make URL-safe: replace + with -, / with _, remove =\n return base64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n}\n\n/**\n * Result of payload serialization with policy enforcement.\n */\ninterface SerializationResult {\n bytes?: Uint8Array;\n warning?: MappingWarning;\n truncated?: boolean;\n}\n\n/**\n * Serialize a payload to bytes with policy enforcement.\n *\n * Applies:\n * - Size limits (truncation if exceeds maxPayloadSize)\n * - Redaction policy (hash_only drops bytes for non-allowlisted tools)\n *\n * @param payload - The payload to serialize\n * @param maxPayloadSize - Maximum payload size in bytes\n * @param isAllowlisted - Whether this tool is allowlisted for plaintext capture\n * @param fieldName - Field name for warning messages\n * @returns Serialization result with bytes and/or warning\n */\nfunction serializePayloadWithPolicy(\n payload: unknown,\n maxPayloadSize: number,\n isAllowlisted: boolean,\n fieldName: string\n): SerializationResult {\n if (payload === undefined) {\n return {};\n }\n\n // Try to serialize using canonical JSON (RFC 8785)\n // This ensures deterministic hashes across implementations\n let bytes: Uint8Array;\n try {\n const json = canonicalize(payload);\n bytes = new TextEncoder().encode(json);\n } catch {\n // Serialization failed (circular references, BigInt, functions, etc.)\n return {\n warning: {\n code: OPENCLAW_WARNING_CODES.SERIALIZATION_FAILED,\n message: `${fieldName} payload could not be serialized (circular ref, BigInt, etc.)`,\n field: fieldName,\n },\n };\n }\n\n // Check size limit and truncate if needed\n let truncated = false;\n if (bytes.length > maxPayloadSize) {\n bytes = bytes.slice(0, maxPayloadSize);\n truncated = true;\n }\n\n // Apply redaction policy - capture-core will hash these bytes\n // In hash_only mode for non-allowlisted tools, we still pass bytes\n // for hashing but could add a warning for transparency\n const result: SerializationResult = { bytes, truncated };\n\n if (truncated) {\n result.warning = {\n code: OPENCLAW_WARNING_CODES.PAYLOAD_TRUNCATED,\n message: `${fieldName} payload exceeded ${maxPayloadSize} bytes and was truncated`,\n field: fieldName,\n };\n }\n\n return result;\n}\n\n/**\n * Build OpenClaw-specific extensions for the action metadata.\n */\nfunction buildExtensions(event: OpenClawToolCallEvent): Record<string, unknown> {\n const extensions: Record<string, unknown> = {};\n\n // OpenClaw context extension\n if (event.context) {\n const contextExt: OpenClawContextExtension = {\n ...(event.context.channel && { channel: event.context.channel }),\n ...(event.context.workspace_digest && { workspace_digest: event.context.workspace_digest }),\n ...(event.context.gateway_version && { gateway_version: event.context.gateway_version }),\n tool_call_id: event.tool_call_id,\n };\n\n if (Object.keys(contextExt).length > 0) {\n extensions[OPENCLAW_EXTENSION_KEYS.CONTEXT] = contextExt;\n }\n } else {\n // Always include tool_call_id for correlation\n extensions[OPENCLAW_EXTENSION_KEYS.CONTEXT] = {\n tool_call_id: event.tool_call_id,\n };\n }\n\n // Security audit digest\n if (event.context?.audit_digest) {\n extensions[OPENCLAW_EXTENSION_KEYS.AUDIT_DIGEST] = event.context.audit_digest;\n }\n\n return extensions;\n}\n\n/**\n * Check if a string is a valid RFC 3339 timestamp.\n */\nfunction isValidRfc3339(timestamp: string): boolean {\n // Basic RFC 3339 pattern (not exhaustive but catches common issues)\n const rfc3339Pattern = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?(Z|[+-]\\d{2}:\\d{2})$/;\n if (!rfc3339Pattern.test(timestamp)) {\n return false;\n }\n\n // Verify it parses to a valid date\n const date = new Date(timestamp);\n return !isNaN(date.getTime());\n}\n\n// =============================================================================\n// Utility Functions\n// =============================================================================\n\n/**\n * Extract workflow ID from OpenClaw session key.\n *\n * If session_key is provided, it becomes the workflow_id for correlation.\n */\nexport function extractWorkflowId(event: OpenClawToolCallEvent): string | undefined {\n return event.session_key;\n}\n\n/**\n * Build a PEAC-compatible workflow context from OpenClaw event.\n */\nexport function buildWorkflowContext(\n event: OpenClawToolCallEvent\n): Record<string, unknown> | undefined {\n if (!event.session_key) {\n return undefined;\n }\n\n return {\n workflow_id: event.session_key,\n step_id: event.tool_call_id,\n tool_name: event.tool_name,\n framework: 'openclaw',\n };\n}\n","/**\n * @peac/adapter-openclaw - Hook Bindings\n *\n * Hook bindings for OpenClaw tool call capture.\n * Designed for sync capture (< 10ms target).\n */\n\nimport type { CaptureSession, CaptureResult, SpoolEntry } from '@peac/capture-core';\nimport type { OpenClawToolCallEvent, OpenClawAdapterConfig, MappingResult } from './types.js';\nimport { mapToolCallEvent } from './mapper.js';\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Result of a hook capture operation.\n * More flexible than CaptureResult to allow adapter-specific error codes.\n */\nexport type HookCaptureResult =\n | { success: true; entry: SpoolEntry }\n | { success: false; code: string; message: string };\n\n// =============================================================================\n// Hook Handler Interface\n// =============================================================================\n\n/**\n * Hook handler for OpenClaw tool call events.\n */\nexport interface OpenClawHookHandler {\n /** Handle after_tool_call hook */\n afterToolCall(event: OpenClawToolCallEvent): Promise<HookCaptureResult>;\n\n /** Get the underlying capture session */\n getSession(): CaptureSession;\n\n /** Close the handler */\n close(): Promise<void>;\n}\n\n/**\n * Configuration for creating a hook handler.\n */\nexport interface HookHandlerConfig {\n /** Capture session to use */\n session: CaptureSession;\n\n /** Adapter configuration */\n config?: OpenClawAdapterConfig;\n\n /** Callback for capture events (for telemetry/logging) */\n onCapture?: (result: HookCaptureResult, event: OpenClawToolCallEvent) => void;\n\n /** Callback for mapping errors */\n onMappingError?: (result: MappingResult, event: OpenClawToolCallEvent) => void;\n}\n\n// =============================================================================\n// Hook Handler Implementation\n// =============================================================================\n\n/**\n * Create a hook handler for OpenClaw tool call events.\n *\n * @param handlerConfig - Configuration for the handler\n * @returns Hook handler instance\n */\nexport function createHookHandler(handlerConfig: HookHandlerConfig): OpenClawHookHandler {\n const { session, config, onCapture, onMappingError } = handlerConfig;\n\n return {\n async afterToolCall(event: OpenClawToolCallEvent): Promise<HookCaptureResult> {\n // Map OpenClaw event to CapturedAction\n const mappingResult = mapToolCallEvent(event, config);\n\n if (!mappingResult.success || !mappingResult.action) {\n // Mapping failed - report and return error result\n if (onMappingError) {\n onMappingError(mappingResult, event);\n }\n\n return {\n success: false,\n code: mappingResult.error_code ?? 'E_OPENCLAW_MAPPING_FAILED',\n message: mappingResult.error_message ?? 'Failed to map OpenClaw event',\n };\n }\n\n // Capture the action\n const captureResult = await session.capture(mappingResult.action);\n\n // Convert to HookCaptureResult (compatible types)\n const hookResult: HookCaptureResult = captureResult.success\n ? { success: true, entry: captureResult.entry }\n : { success: false, code: captureResult.code, message: captureResult.message };\n\n // Invoke callback\n if (onCapture) {\n onCapture(hookResult, event);\n }\n\n return hookResult;\n },\n\n getSession(): CaptureSession {\n return session;\n },\n\n async close(): Promise<void> {\n await session.close();\n },\n };\n}\n\n// =============================================================================\n// Batch Capture\n// =============================================================================\n\n/**\n * Capture multiple tool call events in sequence.\n *\n * Note: Events are captured in order. For parallel capture, use individual\n * afterToolCall calls with Promise.all.\n *\n * @param handler - Hook handler\n * @param events - Array of tool call events\n * @returns Array of capture results (same order as events)\n */\nexport async function captureBatch(\n handler: OpenClawHookHandler,\n events: OpenClawToolCallEvent[]\n): Promise<HookCaptureResult[]> {\n const results: HookCaptureResult[] = [];\n\n for (const event of events) {\n const result = await handler.afterToolCall(event);\n results.push(result);\n }\n\n return results;\n}\n\n/**\n * Capture multiple tool call events in parallel.\n *\n * Warning: Parallel capture may result in non-deterministic chain ordering.\n * Use captureBatch for deterministic ordering.\n *\n * @param handler - Hook handler\n * @param events - Array of tool call events\n * @returns Array of capture results (same order as events)\n */\nexport async function captureParallel(\n handler: OpenClawHookHandler,\n events: OpenClawToolCallEvent[]\n): Promise<HookCaptureResult[]> {\n return Promise.all(events.map((event) => handler.afterToolCall(event)));\n}\n\n// =============================================================================\n// Session History Tailer (Fallback)\n// =============================================================================\n\n/**\n * Session history tailer for fallback capture.\n *\n * If OpenClaw hooks don't provide complete event data, this can poll\n * the session history API to backfill missed events.\n */\nexport interface SessionHistoryTailer {\n /** Start tailing session history */\n start(): void;\n\n /** Stop tailing */\n stop(): void;\n\n /** Get the last processed event ID */\n getLastEventId(): string | undefined;\n\n /** Whether the tailer is running */\n isRunning(): boolean;\n}\n\n/**\n * Configuration for session history tailer.\n */\nexport interface TailerConfig {\n /** Hook handler to use for capture */\n handler: OpenClawHookHandler;\n\n /** Session ID to tail */\n sessionId: string;\n\n /** Polling interval in milliseconds (default: 1000) */\n pollIntervalMs?: number;\n\n /** Function to fetch session history */\n fetchHistory: (sessionId: string, afterEventId?: string) => Promise<OpenClawToolCallEvent[]>;\n\n /** Callback for tailer errors */\n onError?: (error: Error) => void;\n}\n\n/**\n * Create a session history tailer.\n *\n * @param tailerConfig - Configuration for the tailer\n * @returns Session history tailer instance\n */\nexport function createSessionHistoryTailer(tailerConfig: TailerConfig): SessionHistoryTailer {\n const { handler, sessionId, pollIntervalMs = 1000, fetchHistory, onError } = tailerConfig;\n\n let running = false;\n let inFlight = false;\n let lastEventId: string | undefined;\n let intervalHandle: ReturnType<typeof setInterval> | undefined;\n\n const poll = async () => {\n // Prevent overlapping polls - if a poll takes longer than the\n // interval, skip this tick rather than double-processing\n if (inFlight) return;\n\n inFlight = true;\n try {\n const events = await fetchHistory(sessionId, lastEventId);\n\n for (const event of events) {\n // Check if tailer was stopped during processing\n if (!running) break;\n\n await handler.afterToolCall(event);\n lastEventId = event.tool_call_id;\n }\n } catch (error) {\n if (onError) {\n onError(error instanceof Error ? error : new Error(String(error)));\n }\n } finally {\n inFlight = false;\n }\n };\n\n return {\n start(): void {\n if (running) return;\n running = true;\n intervalHandle = setInterval(poll, pollIntervalMs);\n // Run immediately on start\n poll();\n },\n\n stop(): void {\n if (!running) return;\n running = false;\n if (intervalHandle) {\n clearInterval(intervalHandle);\n intervalHandle = undefined;\n }\n },\n\n getLastEventId(): string | undefined {\n return lastEventId;\n },\n\n isRunning(): boolean {\n return running;\n },\n };\n}\n","/**\n * @peac/adapter-openclaw - Background Emitter\n *\n * Background service for converting captured actions to signed PEAC receipts.\n * Runs asynchronously to avoid blocking the sync capture path.\n */\n\nimport type { SpoolEntry } from '@peac/capture-core';\nimport { toInteractionEvidence } from '@peac/capture-core';\nimport type { ReceiptEmitter, EmitResult, OpenClawAdapterConfig } from './types.js';\nimport { OPENCLAW_ERROR_CODES } from './types.js';\n\n// =============================================================================\n// Signer Interface\n// =============================================================================\n\n/**\n * Signer interface for receipt signing.\n *\n * Different implementations can support various key storage mechanisms:\n * - Level 1: Environment variable (dev only)\n * - Level 2: OS Keychain\n * - Level 3: Sidecar process\n * - Level 4: Hardware module (YubiKey, TPM, HSM)\n *\n * IMPORTANT: Implementations MUST include the key ID (kid) in the JWS header.\n * The getKeyId() method allows callers to inspect which kid will be used\n * without parsing the resulting JWS.\n */\nexport interface Signer {\n /**\n * Sign a payload and return JWS compact serialization.\n * The JWS header MUST include the 'kid' claim for verifier key selection.\n */\n sign(payload: unknown): Promise<string>;\n\n /** Get the key ID (kid) that will be included in the JWS header */\n getKeyId(): string;\n\n /** Get the issuer URI */\n getIssuer(): string;\n\n /** Get the audience URI (optional) */\n getAudience(): string | undefined;\n}\n\n// =============================================================================\n// Receipt Writer Interface\n// =============================================================================\n\n/**\n * Receipt writer interface for persisting signed receipts.\n */\nexport interface ReceiptWriter {\n /** Write a signed receipt */\n write(receipt: SignedReceipt): Promise<string>;\n\n /** Close the writer */\n close(): Promise<void>;\n}\n\n/**\n * Signed receipt ready for persistence.\n */\nexport interface SignedReceipt {\n /** Receipt ID (rid) */\n rid: string;\n\n /** JWS compact serialization */\n jws: string;\n\n /** Interaction ID (for correlation) */\n interaction_id: string;\n\n /** Entry digest (for verification) */\n entry_digest: string;\n}\n\n// =============================================================================\n// Emitter Implementation\n// =============================================================================\n\n/**\n * Configuration for creating a receipt emitter.\n */\nexport interface EmitterConfig {\n /** Signer for receipt signing */\n signer: Signer;\n\n /** Writer for receipt persistence */\n writer: ReceiptWriter;\n\n /** Adapter configuration */\n config?: OpenClawAdapterConfig;\n\n /** Callback for emit events */\n onEmit?: (result: EmitResult, entry: SpoolEntry) => void;\n\n /** Callback for emit errors */\n onError?: (error: Error, entry: SpoolEntry) => void;\n}\n\n/**\n * Create a receipt emitter.\n *\n * @param emitterConfig - Configuration for the emitter\n * @returns Receipt emitter instance\n */\nexport function createReceiptEmitter(emitterConfig: EmitterConfig): ReceiptEmitter {\n const { signer, writer, onEmit, onError } = emitterConfig;\n\n let closed = false;\n\n return {\n async emit(entry: SpoolEntry): Promise<EmitResult> {\n if (closed) {\n return {\n success: false,\n error_code: 'E_EMITTER_CLOSED',\n error_message: 'Emitter has been closed',\n };\n }\n\n try {\n // Convert SpoolEntry to InteractionEvidence\n // Note: Platform info is already in the entry.action from the mapper\n const interaction = toInteractionEvidence(entry);\n\n // Build the receipt payload\n const receiptPayload = buildReceiptPayload(interaction, entry, signer);\n\n // Sign the receipt\n const jws = await signer.sign(receiptPayload);\n\n // Build signed receipt\n const signedReceipt: SignedReceipt = {\n rid: receiptPayload.rid,\n jws,\n interaction_id: entry.action.id,\n entry_digest: entry.entry_digest,\n };\n\n // Write the receipt\n const receiptPath = await writer.write(signedReceipt);\n\n const result: EmitResult = {\n success: true,\n receipt_path: receiptPath,\n receipt_id: receiptPayload.rid,\n };\n\n if (onEmit) {\n onEmit(result, entry);\n }\n\n return result;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n\n if (onError) {\n onError(error instanceof Error ? error : new Error(errorMessage), entry);\n }\n\n return {\n success: false,\n error_code: OPENCLAW_ERROR_CODES.SIGNING_FAILED,\n error_message: `Failed to emit receipt: ${errorMessage}`,\n };\n }\n },\n\n async flush(): Promise<void> {\n // No-op: entries are emitted immediately via emit()\n // This method exists for API consistency\n },\n\n async close(): Promise<void> {\n closed = true;\n await writer.close();\n },\n };\n}\n\n// =============================================================================\n// Receipt Payload Builder\n// =============================================================================\n\n/**\n * PEAC receipt payload structure.\n */\ninterface ReceiptPayload {\n /** Issuer */\n iss: string;\n\n /** Audience */\n aud?: string;\n\n /** Issued at (Unix timestamp) */\n iat: number;\n\n /** Receipt ID */\n rid: string;\n\n /** Evidence block */\n evidence: {\n extensions: {\n 'org.peacprotocol/interaction@0.1': unknown;\n };\n };\n}\n\n/**\n * Build the receipt payload from interaction evidence.\n */\nfunction buildReceiptPayload(\n interaction: ReturnType<typeof toInteractionEvidence>,\n entry: SpoolEntry,\n signer: Signer\n): ReceiptPayload {\n const now = Math.floor(Date.now() / 1000);\n const rid = generateReceiptId(entry.entry_digest);\n\n const payload: ReceiptPayload = {\n iss: signer.getIssuer(),\n iat: now,\n rid,\n evidence: {\n extensions: {\n 'org.peacprotocol/interaction@0.1': interaction,\n },\n },\n };\n\n const audience = signer.getAudience();\n if (audience) {\n payload.aud = audience;\n }\n\n return payload;\n}\n\n/**\n * Generate a deterministic receipt ID from entry digest.\n *\n * Using a deterministic ID (derived from entry_digest) provides:\n * - Idempotency: same entry always produces same rid\n * - Replay safety: retries don't create duplicates\n * - Correlation: rid can be traced back to spool entry\n *\n * Format: r_{first 32 chars of entry_digest}\n */\nfunction generateReceiptId(entryDigest: string): string {\n // Use first 32 chars of entry digest for reasonable uniqueness\n // while keeping the ID short enough for practical use\n return `r_${entryDigest.slice(0, 32)}`;\n}\n\n// =============================================================================\n// Background Service\n// =============================================================================\n\n/**\n * Background emitter service that periodically drains a spool.\n */\nexport interface BackgroundEmitterService {\n /** Start the background service */\n start(): void;\n\n /** Stop the background service */\n stop(): void;\n\n /** Trigger immediate drain */\n drain(): Promise<void>;\n\n /** Whether the service is running */\n isRunning(): boolean;\n\n /** Get emit statistics */\n getStats(): EmitterStats;\n}\n\n/**\n * Emitter statistics.\n */\nexport interface EmitterStats {\n /** Total entries emitted */\n emitted: number;\n\n /** Total entries failed */\n failed: number;\n\n /** Last emit time */\n lastEmitTime?: Date;\n\n /** Last error */\n lastError?: string;\n}\n\n/**\n * Configuration for background emitter service.\n */\nexport interface BackgroundServiceConfig {\n /** Receipt emitter */\n emitter: ReceiptEmitter;\n\n /** Function to get pending spool entries */\n getPendingEntries: () => Promise<SpoolEntry[]>;\n\n /** Function to mark entry as emitted */\n markEmitted: (entryDigest: string) => Promise<void>;\n\n /** Drain interval in milliseconds (default: 1000) */\n drainIntervalMs?: number;\n\n /** Callback for service errors */\n onError?: (error: Error) => void;\n}\n\n/**\n * Create a background emitter service.\n *\n * @param serviceConfig - Configuration for the service\n * @returns Background emitter service instance\n */\nexport function createBackgroundService(\n serviceConfig: BackgroundServiceConfig\n): BackgroundEmitterService {\n const {\n emitter,\n getPendingEntries,\n markEmitted,\n drainIntervalMs = 1000,\n onError,\n } = serviceConfig;\n\n let running = false;\n let stopping = false;\n let inFlight = false;\n let intervalHandle: ReturnType<typeof setInterval> | undefined;\n const stats: EmitterStats = {\n emitted: 0,\n failed: 0,\n };\n\n const drainOnce = async () => {\n // Prevent overlapping drains - if a drain takes longer than the\n // interval, skip this tick rather than double-processing\n if (inFlight) return;\n\n inFlight = true;\n try {\n const entries = await getPendingEntries();\n\n for (const entry of entries) {\n // Check if service is being stopped during processing\n if (stopping) break;\n\n const result = await emitter.emit(entry);\n\n if (result.success) {\n await markEmitted(entry.entry_digest);\n stats.emitted++;\n stats.lastEmitTime = new Date();\n } else {\n stats.failed++;\n stats.lastError = result.error_message;\n }\n }\n } catch (error) {\n stats.lastError = error instanceof Error ? error.message : String(error);\n if (onError) {\n onError(error instanceof Error ? error : new Error(String(error)));\n }\n } finally {\n inFlight = false;\n }\n };\n\n return {\n start(): void {\n if (running) return;\n running = true;\n intervalHandle = setInterval(drainOnce, drainIntervalMs);\n // Run immediately on start\n drainOnce();\n },\n\n stop(): void {\n if (!running) return;\n stopping = true;\n running = false;\n if (intervalHandle) {\n clearInterval(intervalHandle);\n intervalHandle = undefined;\n }\n },\n\n async drain(): Promise<void> {\n await drainOnce();\n },\n\n isRunning(): boolean {\n return running;\n },\n\n getStats(): EmitterStats {\n return { ...stats };\n },\n };\n}\n","/**\n * @peac/adapter-openclaw - Plugin Entry Point\n *\n * OpenClaw plugin types and utilities for PEAC receipts.\n * This module provides types and factory functions for OpenClaw integration.\n *\n * Note: Full plugin activation requires OpenClaw's plugin runtime.\n * The types and utilities here allow building custom integrations.\n */\n\nimport type { CaptureSession, SpoolStore, DedupeIndex } from '@peac/capture-core';\n// Namespace imports avoid tsup tree-shaking false positives in multi-entry builds\n// where these symbols appear unused in the keygen-cli entry point.\nimport * as captureCore from '@peac/capture-core';\nimport * as crypto from '@peac/crypto';\nimport type { OpenClawAdapterConfig } from './types.js';\nimport { createHookHandler, type OpenClawHookHandler } from './hooks.js';\nimport {\n createReceiptEmitter,\n createBackgroundService,\n type Signer,\n type ReceiptWriter,\n type BackgroundEmitterService,\n} from './emitter.js';\n\n// =============================================================================\n// JWK Type\n// =============================================================================\n\n/**\n * JSON Web Key structure for signing keys (Ed25519).\n */\nexport interface JWK {\n kty: string;\n crv?: string;\n x?: string;\n d?: string;\n kid?: string;\n alg?: string;\n use?: string;\n}\n\n// =============================================================================\n// Plugin Configuration Types\n// =============================================================================\n\n/**\n * Plugin configuration from openclaw.plugin.json configSchema.\n *\n * @experimental This interface is experimental and may change.\n */\nexport interface PluginConfig {\n enabled?: boolean;\n output_dir?: string;\n capture?: {\n mode?: 'hash_only' | 'allowlist';\n allowlist?: string[];\n max_payload_size?: number;\n };\n signing: {\n key_ref: string;\n issuer: string;\n audience?: string;\n };\n correlation?: {\n include_workflow?: boolean;\n // Note: include_identity and identity_attestation_ref are reserved for future use\n };\n background?: {\n drain_interval_ms?: number;\n batch_size?: number;\n };\n}\n\n/**\n * OpenClaw plugin context provided by the runtime.\n */\nexport interface PluginContext {\n /** Plugin configuration from gateway config */\n config: PluginConfig;\n /** Agent workspace directory */\n workspaceDir: string;\n /** Logger instance */\n logger: PluginLogger;\n /** Register a tool call hook */\n onToolCall: (handler: ToolCallHandler) => void;\n /** Register a tool result hook */\n onToolResult: (handler: ToolResultHandler) => void;\n /** Register tools */\n registerTools: (tools: PluginTool[]) => void;\n}\n\n/**\n * Plugin logger interface.\n */\nexport interface PluginLogger {\n debug: (message: string, ...args: unknown[]) => void;\n info: (message: string, ...args: unknown[]) => void;\n warn: (message: string, ...args: unknown[]) => void;\n error: (message: string, ...args: unknown[]) => void;\n}\n\n/**\n * Tool call event from OpenClaw.\n */\nexport interface ToolCallEvent {\n tool_call_id: string;\n run_id: string;\n session_key?: string;\n tool_name: string;\n tool_provider?: string;\n input: unknown;\n started_at: string;\n}\n\n/**\n * Tool result event from OpenClaw.\n */\nexport interface ToolResultEvent {\n tool_call_id: string;\n run_id: string;\n session_key?: string;\n tool_name: string;\n output: unknown;\n completed_at: string;\n status: 'ok' | 'error' | 'timeout' | 'canceled';\n error_code?: string;\n}\n\n/**\n * Tool call handler function.\n */\nexport type ToolCallHandler = (event: ToolCallEvent) => void | Promise<void>;\n\n/**\n * Tool result handler function.\n */\nexport type ToolResultHandler = (event: ToolResultEvent) => void | Promise<void>;\n\n/**\n * Plugin tool definition.\n */\nexport interface PluginTool {\n name: string;\n description: string;\n parameters?: Record<string, unknown>;\n execute: (params: Record<string, unknown>) => Promise<unknown>;\n}\n\n// =============================================================================\n// Signer Creation\n// =============================================================================\n\n/**\n * Create a signer from a JWK private key.\n *\n * @param jwk - Ed25519 private key in JWK format\n * @param issuer - Issuer URI for receipts\n * @param audience - Optional audience URI\n * @returns Signer instance\n */\nexport function createJwkSigner(jwk: JWK, issuer: string, audience?: string): Signer {\n const kid = jwk.kid || generateKeyId(jwk);\n\n // Extract the private key bytes from JWK\n if (!jwk.d) {\n throw new Error('JWK must include private key (d parameter)');\n }\n\n // Decode base64url to get raw key bytes\n const privateKeyBytes = crypto.base64urlDecode(jwk.d);\n\n return {\n async sign(payload: unknown): Promise<string> {\n return crypto.sign(payload, privateKeyBytes, kid);\n },\n\n getKeyId(): string {\n return kid;\n },\n\n getIssuer(): string {\n return issuer;\n },\n\n getAudience(): string | undefined {\n return audience;\n },\n };\n}\n\n/**\n * Resolve a signer from a key reference string.\n *\n * Supported formats:\n * - env:VAR_NAME - Load key from environment variable\n * - file:/path - Load from file (development only)\n *\n * @param keyRef - Key reference string\n * @param issuer - Issuer URI\n * @param audience - Optional audience URI\n * @returns Promise resolving to Signer\n */\nexport async function resolveSigner(\n keyRef: string,\n issuer: string,\n audience?: string\n): Promise<Signer> {\n const colonIndex = keyRef.indexOf(':');\n if (colonIndex === -1) {\n throw new Error(`Invalid key reference format: ${keyRef}. Expected scheme:value`);\n }\n\n const scheme = keyRef.slice(0, colonIndex);\n const value = keyRef.slice(colonIndex + 1);\n\n switch (scheme) {\n case 'env': {\n const keyData = process.env[value];\n if (!keyData) {\n throw new Error(`Environment variable ${value} not set for signing key`);\n }\n const jwk = JSON.parse(keyData) as JWK;\n return createJwkSigner(jwk, issuer, audience);\n }\n\n case 'file': {\n const fs = await import('fs');\n const keyData = await fs.promises.readFile(value, 'utf-8');\n const jwk = JSON.parse(keyData) as JWK;\n return createJwkSigner(jwk, issuer, audience);\n }\n\n case 'keychain':\n throw new Error('Keychain signing not yet implemented. Use env: for development.');\n\n case 'sidecar':\n throw new Error('Sidecar signing not yet implemented. Use env: for development.');\n\n default:\n throw new Error(`Unknown key reference scheme: ${scheme}. Use env: or file:`);\n }\n}\n\n/**\n * Generate a key ID from a JWK by hashing its public components.\n */\nexport function generateKeyId(jwk: JWK): string {\n const publicPart = jwk.x || '';\n let hash = 0;\n for (let i = 0; i < publicPart.length; i++) {\n const char = publicPart.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash;\n }\n return `k_${Math.abs(hash).toString(16).padStart(8, '0')}`;\n}\n\n// =============================================================================\n// Receipt Writer\n// =============================================================================\n\n/**\n * Create a file system receipt writer with atomic writes.\n *\n * Writes are atomic: write to .tmp, fsync, rename. This ensures\n * partially written files are never observable.\n *\n * @param outputDir - Directory for receipt files\n * @returns Promise resolving to ReceiptWriter\n */\nexport async function createFileReceiptWriter(outputDir: string): Promise<ReceiptWriter> {\n const fs = await import('fs');\n const pathModule = await import('path');\n\n // Use path.resolve for portability\n const resolvedOutputDir = pathModule.resolve(outputDir);\n\n // Ensure directory exists\n await fs.promises.mkdir(resolvedOutputDir, { recursive: true });\n\n return {\n async write(receipt) {\n const filename = `${receipt.rid}.peac.json`;\n const filepath = pathModule.join(resolvedOutputDir, filename);\n const tempPath = `${filepath}.tmp`;\n\n // Decode the JWS payload to persist the full receipt structure.\n // The verify and export tools expect auth + evidence blocks at the top level.\n // JWS compact serialization: header.payload.signature (base64url)\n let content: string;\n const jwsParts = receipt.jws.split('.');\n if (jwsParts.length !== 3) {\n // Malformed JWS -- write _jws-only receipt (best effort, still recoverable)\n content = JSON.stringify({ _jws: receipt.jws }, null, 2);\n } else {\n try {\n const payloadJson = Buffer.from(jwsParts[1], 'base64url').toString('utf-8');\n const payload = JSON.parse(payloadJson);\n\n // Split payload into auth (identity fields) and evidence (data fields)\n const { evidence, ...auth } = payload;\n\n content = JSON.stringify({ auth, evidence, _jws: receipt.jws }, null, 2);\n } catch {\n // Payload decode failed -- write _jws-only receipt (best effort)\n content = JSON.stringify({ _jws: receipt.jws }, null, 2);\n }\n }\n\n // Atomic write: write to .tmp, fsync, rename, fsync dir\n await fs.promises.writeFile(tempPath, content, 'utf-8');\n\n // fsync file for durability (open, sync, close)\n const fd = await fs.promises.open(tempPath, 'r');\n await fd.sync();\n await fd.close();\n\n // Atomic rename (POSIX guarantees atomicity)\n await fs.promises.rename(tempPath, filepath);\n\n // fsync parent directory for full crash durability (POSIX best practice)\n // This ensures the rename is persisted even on power loss\n // Best-effort: may fail on some platforms (Windows, network FS)\n try {\n const dirFd = await fs.promises.open(resolvedOutputDir, 'r');\n await dirFd.sync();\n await dirFd.close();\n } catch {\n // Directory fsync not supported on this platform - continue anyway\n // Receipt is still atomic via rename, just not fully durable on power loss\n }\n\n return filepath;\n },\n\n async close() {\n // No-op for file writer\n },\n };\n}\n\n// =============================================================================\n// Plugin Instance\n// =============================================================================\n\n/**\n * Plugin instance state.\n */\nexport interface PluginInstance {\n /** Capture session */\n session: CaptureSession;\n /** Hook handler for tool calls */\n hookHandler: OpenClawHookHandler;\n /** Background emitter service */\n backgroundService: BackgroundEmitterService;\n /** Start the plugin */\n start(): void;\n /** Stop the plugin */\n stop(): Promise<void>;\n /** Get plugin stats */\n getStats(): PluginStats;\n}\n\n/**\n * Plugin statistics.\n */\nexport interface PluginStats {\n totalCaptured: number;\n duplicatesSkipped: number;\n pendingCount: number;\n totalEmitted: number;\n totalErrors: number;\n keyId: string;\n isRunning: boolean;\n}\n\n/**\n * Options for creating a plugin instance.\n */\nexport interface CreatePluginOptions {\n /** Signer for receipts */\n signer: Signer;\n /** Receipt writer */\n writer: ReceiptWriter;\n /** Adapter configuration */\n adapterConfig?: OpenClawAdapterConfig;\n /** Spool store implementation (required) */\n store: SpoolStore;\n /** Dedupe index implementation (required) */\n dedupe: DedupeIndex;\n /** Background drain interval in ms (default: 1000) */\n drainIntervalMs?: number;\n /** Batch size for draining (default: 100) */\n batchSize?: number;\n /** Error callback */\n onError?: (error: Error) => void;\n}\n\n/**\n * Create a plugin instance.\n *\n * @param options - Plugin options\n * @returns Plugin instance\n */\nexport async function createPluginInstance(options: CreatePluginOptions): Promise<PluginInstance> {\n const {\n signer,\n writer,\n adapterConfig,\n store,\n dedupe,\n drainIntervalMs = 1000,\n batchSize = 100,\n onError,\n } = options;\n\n // Create hasher\n const hasher = await captureCore.createHasher();\n\n // Create capture session\n const session = captureCore.createCaptureSession({\n store,\n dedupe,\n hasher,\n });\n\n // Track stats\n const stats: PluginStats = {\n totalCaptured: 0,\n duplicatesSkipped: 0,\n pendingCount: 0,\n totalEmitted: 0,\n totalErrors: 0,\n keyId: signer.getKeyId(),\n isRunning: false,\n };\n\n // Create hook handler\n const hookHandler = createHookHandler({\n session,\n config: adapterConfig,\n onCapture: (result) => {\n if (result.success) {\n stats.totalCaptured++;\n stats.pendingCount++;\n } else {\n stats.duplicatesSkipped++;\n }\n },\n });\n\n // Create receipt emitter\n const emitter = createReceiptEmitter({\n signer,\n writer,\n onEmit: (result) => {\n if (result.success) {\n stats.totalEmitted++;\n stats.pendingCount = Math.max(0, stats.pendingCount - 1);\n }\n },\n onError: (error) => {\n stats.totalErrors++;\n if (onError) onError(error);\n },\n });\n\n // Track last emitted sequence for cursor-based emission\n // This is the in-memory cursor; on restart, we rebuild from dedupe index\n let lastEmittedSequence = 0;\n\n // Mutex to prevent overlapping drain cycles\n let drainInProgress = false;\n\n // Create background service with proper cursor tracking\n // Note: For full restart safety, the dedupe index should be persistent.\n // The getPendingEntries filters out already-emitted entries using the dedupe index.\n const backgroundService = createBackgroundService({\n emitter,\n drainIntervalMs,\n getPendingEntries: async () => {\n // Prevent overlapping drain cycles\n if (drainInProgress) return [];\n drainInProgress = true;\n\n try {\n // Read entries after the last emitted sequence\n const currentSequence = await store.getSequence();\n if (currentSequence <= lastEmittedSequence) return [];\n\n // Read from cursor position\n const entries = await store.read(lastEmittedSequence, batchSize);\n\n // Filter out entries that are already emitted (restart safety)\n // This uses the persistent dedupe index as source of truth\n const pending = [];\n for (const entry of entries) {\n if (entry.sequence <= lastEmittedSequence) continue;\n // Check if already emitted in dedupe index\n const dedupeEntry = await dedupe.get(entry.action.id);\n if (dedupeEntry?.emitted) continue;\n pending.push(entry);\n }\n return pending;\n } finally {\n drainInProgress = false;\n }\n },\n markEmitted: async (digest) => {\n // Find the entry with this digest and update cursor\n const entries = await store.read(lastEmittedSequence, batchSize);\n const entry = entries.find((e) => e.entry_digest === digest);\n if (entry) {\n // Update in-memory cursor\n if (entry.sequence > lastEmittedSequence) {\n lastEmittedSequence = entry.sequence;\n }\n // Mark in persistent dedupe index (restart-safe)\n await dedupe.markEmitted(entry.action.id);\n }\n },\n onError,\n });\n\n return {\n session,\n hookHandler,\n backgroundService,\n\n start() {\n stats.isRunning = true;\n backgroundService.start();\n },\n\n async stop() {\n backgroundService.stop();\n await backgroundService.drain();\n await hookHandler.close();\n stats.isRunning = false;\n },\n\n getStats() {\n return { ...stats };\n },\n };\n}\n","/**\n * @peac/adapter-openclaw - Plugin Tools\n *\n * Tools exposed by the PEAC receipts plugin for OpenClaw.\n *\n * @experimental This module is experimental and may change.\n */\n\nimport type { PluginTool, PluginLogger } from './plugin.js';\n\n// =============================================================================\n// Constants\n// =============================================================================\n\n/** Maximum files to scan for status (DoS protection) */\nconst MAX_STATUS_FILE_SCAN = 1000;\n\n/** Maximum files to parse for query (DoS protection) */\nconst MAX_QUERY_FILE_PARSE = 10000;\n\n/** Maximum file size in bytes to read (DoS protection) - 10MB */\nconst MAX_FILE_SIZE_BYTES = 10 * 1024 * 1024;\n\n/** Allowed JWS algorithms (security) */\nconst ALLOWED_ALGORITHMS = ['EdDSA', 'ES256', 'ES384', 'ES512', 'RS256', 'RS384', 'RS512'] as const;\n\n/**\n * Decode a receipt file's auth + evidence from the _jws payload.\n * _jws is the source of truth -- top-level auth/evidence are convenience duplicates.\n * Returns null if _jws is missing or cannot be decoded.\n */\nfunction decodeReceiptPayload(receipt: Record<string, unknown>): {\n auth: Record<string, unknown>;\n evidence: Record<string, unknown>;\n} | null {\n const jws = receipt._jws;\n if (typeof jws !== 'string') return null;\n\n const parts = jws.split('.');\n if (parts.length !== 3) return null;\n\n try {\n const payloadJson = Buffer.from(parts[1], 'base64url').toString('utf-8');\n const payload = JSON.parse(payloadJson);\n const { evidence, ...auth } = payload;\n return { auth: auth ?? {}, evidence: evidence ?? {} };\n } catch {\n return null;\n }\n}\n\n/**\n * Strip redundant top-level auth/evidence when _jws is present.\n * The JWS payload contains the canonical claims; keeping top-level\n * copies risks divergence between signed and unsigned data.\n */\nfunction stripRedundantFields(content: Record<string, unknown>): Record<string, unknown> {\n const { auth, evidence, ...rest } = content;\n return rest;\n}\n\n/** Algorithm to key type compatibility map */\nconst ALG_KEY_TYPE_MAP: Record<string, { kty: string; crv?: string[] }> = {\n EdDSA: { kty: 'OKP', crv: ['Ed25519', 'Ed448'] },\n ES256: { kty: 'EC', crv: ['P-256'] },\n ES384: { kty: 'EC', crv: ['P-384'] },\n ES512: { kty: 'EC', crv: ['P-521'] },\n RS256: { kty: 'RSA' },\n RS384: { kty: 'RSA' },\n RS512: { kty: 'RSA' },\n};\n\n// =============================================================================\n// Status Tool Types\n// =============================================================================\n\n/**\n * Plugin stats interface matching plugin.ts PluginStats.\n */\ninterface PluginStats {\n totalCaptured: number;\n duplicatesSkipped: number;\n pendingCount: number;\n totalEmitted: number;\n totalErrors: number;\n keyId: string;\n isRunning: boolean;\n}\n\n// =============================================================================\n// Status Tool\n// =============================================================================\n\n/**\n * Create the peac_receipts.status tool.\n * Shows spool size, last receipt time, and config summary.\n *\n * @param getStats - Getter function that returns live stats on each invocation.\n * Accepts either a getter or a static PluginStats for backwards compat.\n * @param outputDir - Directory where receipt files are stored.\n */\nexport function createStatusTool(\n getStats: (() => PluginStats) | PluginStats,\n outputDir: string\n): PluginTool {\n return {\n name: 'peac_receipts.status',\n description: 'Show PEAC receipts status: spool size, last receipt time, config summary',\n parameters: {},\n\n async execute(): Promise<StatusResult> {\n const stats = typeof getStats === 'function' ? getStats() : getStats;\n const fs = await import('fs');\n const pathModule = await import('path');\n\n // Use path.resolve for portability\n const resolvedOutputDir = pathModule.resolve(outputDir);\n\n // Count receipts in output directory (capped for performance)\n let receiptCount = 0;\n let lastReceiptTime: string | null = null;\n let oldestReceiptTime: string | null = null;\n let countApproximate = false;\n\n try {\n const files = await fs.promises.readdir(resolvedOutputDir);\n const receiptFiles = files.filter((f) => f.endsWith('.peac.json'));\n receiptCount = receiptFiles.length;\n\n // Cap the scan for performance\n const filesToScan = receiptFiles.slice(0, MAX_STATUS_FILE_SCAN);\n countApproximate = receiptFiles.length > MAX_STATUS_FILE_SCAN;\n\n if (filesToScan.length > 0) {\n // Get timestamps from file stats (capped)\n const fileStats = await Promise.all(\n filesToScan.map(async (f) => {\n const stat = await fs.promises.stat(pathModule.join(resolvedOutputDir, f));\n return { file: f, mtime: stat.mtime };\n })\n );\n\n fileStats.sort((a, b) => b.mtime.getTime() - a.mtime.getTime());\n lastReceiptTime = fileStats[0].mtime.toISOString();\n oldestReceiptTime = fileStats[fileStats.length - 1].mtime.toISOString();\n }\n } catch {\n // Directory might not exist yet\n }\n\n return {\n status: 'ok',\n spool: {\n pending_entries: stats.pendingCount,\n total_captured: stats.totalCaptured,\n duplicates_skipped: stats.duplicatesSkipped,\n },\n receipts: {\n count: receiptCount,\n count_approximate: countApproximate,\n output_dir: resolvedOutputDir,\n last_receipt_time: lastReceiptTime,\n oldest_receipt_time: oldestReceiptTime,\n },\n emitter: {\n total_emitted: stats.totalEmitted,\n total_errors: stats.totalErrors,\n is_running: stats.isRunning,\n key_id: stats.keyId,\n },\n };\n },\n };\n}\n\ninterface StatusResult {\n status: 'ok' | 'error';\n spool: {\n pending_entries: number;\n total_captured: number;\n duplicates_skipped: number;\n };\n receipts: {\n count: number;\n count_approximate: boolean;\n output_dir: string;\n last_receipt_time: string | null;\n oldest_receipt_time: string | null;\n };\n emitter: {\n total_emitted: number;\n total_errors: number;\n is_running: boolean;\n key_id: string;\n };\n}\n\n// =============================================================================\n// Export Bundle Tool\n// =============================================================================\n\n/**\n * Create the peac_receipts.export_bundle tool.\n * Exports receipts as a bundle directory for audit.\n *\n * Note: Creates a directory structure, not a ZIP archive.\n * Use @peac/audit createDisputeBundle for production ZIP bundles.\n */\nexport function createExportBundleTool(outputDir: string, logger: PluginLogger): PluginTool {\n return {\n name: 'peac_receipts.export_bundle',\n description: 'Export receipts as a bundle directory for audit (manifest.json + receipts/)',\n parameters: {\n type: 'object',\n properties: {\n workflow_id: {\n type: 'string',\n description: 'Filter by workflow ID',\n },\n since: {\n type: 'string',\n description: 'Include receipts since this RFC 3339 timestamp',\n },\n until: {\n type: 'string',\n description: 'Include receipts until this RFC 3339 timestamp',\n },\n output_path: {\n type: 'string',\n description: 'Output path for bundle directory (default: peac-bundle-{timestamp})',\n },\n },\n },\n\n async execute(params: ExportBundleParams): Promise<ExportBundleResult> {\n const fs = await import('fs');\n const pathModule = await import('path');\n\n // Use path.resolve for portability\n const resolvedOutputDir = pathModule.resolve(outputDir);\n\n try {\n // List receipts\n const files = await fs.promises.readdir(resolvedOutputDir);\n const receiptFiles = files.filter((f) => f.endsWith('.peac.json'));\n\n if (receiptFiles.length === 0) {\n return {\n status: 'ok',\n message: 'No receipts to export',\n receipt_count: 0,\n };\n }\n\n // Filter receipts with structured skip tracking\n const receipts: Array<{ file: string; content: unknown; mtime: Date }> = [];\n const skippedReasons = { stat_error: 0, invalid_json: 0, malformed_jws: 0, filtered: 0 };\n const skippedFiles: string[] = [];\n\n for (const file of receiptFiles) {\n const filePath = pathModule.join(resolvedOutputDir, file);\n let stat;\n try {\n stat = await fs.promises.stat(filePath);\n } catch {\n skippedReasons.stat_error++;\n skippedFiles.push(file);\n continue;\n }\n\n // Apply time filters\n if (params.since && stat.mtime < new Date(params.since)) {\n skippedReasons.filtered++;\n continue;\n }\n if (params.until && stat.mtime > new Date(params.until)) {\n skippedReasons.filtered++;\n continue;\n }\n\n // Read and parse receipt (tolerate invalid JSON)\n let content;\n try {\n content = JSON.parse(await fs.promises.readFile(filePath, 'utf-8'));\n } catch {\n logger.warn(`Skipping invalid JSON in ${file}`);\n skippedReasons.invalid_json++;\n skippedFiles.push(file);\n continue;\n }\n\n // Apply workflow filter (derive from _jws when present)\n if (params.workflow_id) {\n const decoded = content._jws ? decodeReceiptPayload(content) : null;\n // If _jws exists but is malformed, skip this receipt (untrusted)\n if (content._jws && !decoded) {\n logger.warn(`Skipping ${file}: _jws present but malformed`);\n skippedReasons.malformed_jws++;\n skippedFiles.push(file);\n continue;\n }\n const authBlock = (decoded?.auth ?? content?.auth) as\n | Record<string, unknown>\n | undefined;\n const extensions = authBlock?.extensions as Record<string, unknown> | undefined;\n const workflowExt = extensions?.['org.peacprotocol/workflow'] as\n | Record<string, unknown>\n | undefined;\n if (workflowExt?.workflow_id !== params.workflow_id) {\n skippedReasons.filtered++;\n continue;\n }\n }\n\n receipts.push({ file, content, mtime: stat.mtime });\n }\n\n if (receipts.length === 0) {\n return {\n status: 'ok',\n message: 'No receipts match the filter criteria',\n receipt_count: 0,\n scanned_count: receiptFiles.length,\n exported_count: 0,\n skipped_count:\n skippedReasons.stat_error +\n skippedReasons.invalid_json +\n skippedReasons.malformed_jws +\n skippedReasons.filtered,\n skipped_reasons: skippedReasons,\n skipped_files: skippedFiles.length > 0 ? skippedFiles.slice(0, 100) : undefined,\n };\n }\n\n // Create bundle manifest\n const manifest = {\n version: '1.0',\n format: 'peac-bundle-directory',\n created_at: new Date().toISOString(),\n receipt_count: receipts.length,\n filters: {\n workflow_id: params.workflow_id || null,\n since: params.since || null,\n until: params.until || null,\n },\n receipts: receipts.map((r) => ({\n file: r.file,\n mtime: r.mtime.toISOString(),\n })),\n };\n\n // Determine output path (directory, not ZIP)\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n const bundleDir = params.output_path\n ? pathModule.resolve(params.output_path)\n : pathModule.join(resolvedOutputDir, `peac-bundle-${timestamp}`);\n\n await fs.promises.mkdir(bundleDir, { recursive: true });\n\n // Write manifest\n await fs.promises.writeFile(\n pathModule.join(bundleDir, 'manifest.json'),\n JSON.stringify(manifest, null, 2)\n );\n\n // Copy receipts\n const receiptsDir = pathModule.join(bundleDir, 'receipts');\n await fs.promises.mkdir(receiptsDir, { recursive: true });\n\n for (const receipt of receipts) {\n const content = receipt.content as Record<string, unknown>;\n // When _jws is present, omit redundant top-level auth/evidence.\n // The JWS payload is the canonical source; redundant fields can diverge.\n const written =\n typeof content._jws === 'string' ? stripRedundantFields(content) : content;\n await fs.promises.writeFile(\n pathModule.join(receiptsDir, receipt.file),\n JSON.stringify(written, null, 2)\n );\n }\n\n logger.info(`Exported ${receipts.length} receipts to ${bundleDir}`);\n\n return {\n status: 'ok',\n message: `Exported ${receipts.length} receipts to directory`,\n receipt_count: receipts.length,\n bundle_path: bundleDir,\n scanned_count: receiptFiles.length,\n exported_count: receipts.length,\n skipped_count:\n skippedReasons.stat_error +\n skippedReasons.invalid_json +\n skippedReasons.malformed_jws +\n skippedReasons.filtered,\n skipped_reasons: skippedReasons,\n skipped_files: skippedFiles.length > 0 ? skippedFiles.slice(0, 100) : undefined,\n };\n } catch (error) {\n logger.error('Export bundle failed:', error);\n return {\n status: 'error',\n message: error instanceof Error ? error.message : 'Unknown error',\n receipt_count: 0,\n };\n }\n },\n };\n}\n\ninterface ExportBundleParams {\n workflow_id?: string;\n since?: string;\n until?: string;\n output_path?: string;\n}\n\ninterface ExportBundleResult {\n status: 'ok' | 'error';\n message: string;\n receipt_count: number;\n bundle_path?: string;\n scanned_count?: number;\n exported_count?: number;\n skipped_count?: number;\n skipped_reasons?: {\n stat_error: number;\n invalid_json: number;\n malformed_jws: number;\n filtered: number;\n };\n skipped_files?: string[];\n}\n\n// =============================================================================\n// Verify Tool\n// =============================================================================\n\n/**\n * Create the peac_receipts.verify tool.\n * Verifies a receipt or bundle offline.\n */\nexport function createVerifyTool(logger: PluginLogger): PluginTool {\n return {\n name: 'peac_receipts.verify',\n description: 'Verify a receipt or bundle offline',\n parameters: {\n type: 'object',\n properties: {\n path: {\n type: 'string',\n description: 'Path to receipt file or bundle directory',\n },\n jwks_path: {\n type: 'string',\n description: 'Path to JWKS file for key verification (optional)',\n },\n },\n required: ['path'],\n },\n\n async execute(params: Record<string, unknown>): Promise<VerifyResult> {\n const verifyParams = params as unknown as VerifyParams;\n const fs = await import('fs');\n const pathModule = await import('path');\n\n try {\n const stat = await fs.promises.stat(verifyParams.path);\n\n if (stat.isDirectory()) {\n // Verify bundle\n return await verifyBundle(\n verifyParams.path,\n verifyParams.jwks_path,\n fs,\n pathModule,\n logger\n );\n } else {\n // Verify single receipt\n return await verifySingleReceipt(verifyParams.path, verifyParams.jwks_path, fs, logger);\n }\n } catch (error) {\n logger.error('Verification failed:', error);\n return {\n status: 'error',\n valid: false,\n message: error instanceof Error ? error.message : 'Unknown error',\n errors: [error instanceof Error ? error.message : 'Unknown error'],\n };\n }\n },\n };\n}\n\nasync function verifySingleReceipt(\n receiptPath: string,\n jwksPath: string | undefined,\n fs: typeof import('fs'),\n logger: PluginLogger\n): Promise<VerifyResult> {\n // Check file size before reading (DoS protection)\n const stat = await fs.promises.stat(receiptPath);\n if (stat.size > MAX_FILE_SIZE_BYTES) {\n return {\n status: 'error',\n valid: false,\n message: `File too large: ${stat.size} bytes exceeds limit of ${MAX_FILE_SIZE_BYTES} bytes`,\n errors: [`File size ${stat.size} bytes exceeds ${MAX_FILE_SIZE_BYTES} byte limit`],\n };\n }\n\n const content = await fs.promises.readFile(receiptPath, 'utf-8');\n const receipt = JSON.parse(content);\n\n const errors: string[] = [];\n const warnings: string[] = [];\n\n // Trust boundary: _jws is the source of truth for signed data.\n // If _jws is present but malformed, the receipt is invalid (possible tampering).\n // Only allow unsigned top-level fields when _jws is genuinely absent.\n let auth: unknown;\n let evidence: unknown;\n\n if (!receipt._jws) {\n // No JWS -- use top-level fields (unsigned, best-effort)\n auth = receipt.auth;\n evidence = receipt.evidence;\n warnings.push('Missing _jws field -- using unsigned top-level fields');\n } else {\n const decoded = decodeReceiptPayload(receipt);\n if (!decoded) {\n // _jws exists but is malformed -- receipt is invalid, do not fall back\n errors.push('_jws field present but payload could not be decoded (malformed JWS)');\n auth = undefined;\n evidence = undefined;\n } else {\n auth = decoded.auth;\n evidence = decoded.evidence;\n\n // Dual-representation mismatch check: if top-level auth/evidence also exist,\n // they MUST match the signed payload. A mismatch means the unsigned fields\n // have been tampered with (or carelessly copied), creating ambiguity.\n if (receipt.auth !== undefined || receipt.evidence !== undefined) {\n const topAuth = receipt.auth as Record<string, unknown> | undefined;\n const topEvidence = receipt.evidence as Record<string, unknown> | undefined;\n const authMatch =\n topAuth === undefined || JSON.stringify(topAuth) === JSON.stringify(decoded.auth);\n const evidenceMatch =\n topEvidence === undefined ||\n JSON.stringify(topEvidence) === JSON.stringify(decoded.evidence);\n if (!authMatch || !evidenceMatch) {\n errors.push(\n 'Dual-representation mismatch: top-level auth/evidence differs from _jws payload'\n );\n }\n }\n }\n }\n\n if (!auth) {\n errors.push('Missing auth block');\n }\n if (!evidence) {\n errors.push('Missing evidence block');\n }\n\n // Check for interaction evidence\n const evidenceObj = evidence as Record<string, unknown> | undefined;\n const extensions = evidenceObj?.extensions as Record<string, unknown> | undefined;\n const interaction = extensions?.['org.peacprotocol/interaction@0.1'] as\n | Record<string, unknown>\n | undefined;\n if (interaction) {\n // Validate interaction fields\n if (!interaction.interaction_id) {\n errors.push('Missing interaction_id');\n }\n if (!interaction.kind) {\n errors.push('Missing kind');\n }\n const executor = interaction.executor as Record<string, unknown> | undefined;\n if (!executor?.platform) {\n errors.push('Missing executor.platform');\n }\n if (!interaction.started_at) {\n errors.push('Missing started_at');\n }\n\n // Check timing invariant\n if (interaction.completed_at && interaction.started_at) {\n if (\n new Date(interaction.completed_at as string) < new Date(interaction.started_at as string)\n ) {\n errors.push('completed_at is before started_at');\n }\n }\n\n // Check output requires result\n const result = interaction.result as Record<string, unknown> | undefined;\n if (interaction.output && !result?.status) {\n errors.push('output present but result.status missing');\n }\n } else {\n warnings.push('No interaction evidence found');\n }\n\n // Signature verification (if JWKS provided)\n if (jwksPath && receipt._jws) {\n try {\n const { verify, base64urlDecode, base64urlDecodeString } = await import('@peac/crypto');\n const jwks = JSON.parse(await fs.promises.readFile(jwksPath, 'utf-8'));\n\n // Parse JWS header to get kid and alg\n const jwsParts = receipt._jws.split('.');\n if (jwsParts.length !== 3) {\n errors.push('Invalid JWS format (expected 3 parts)');\n } else {\n const headerJson = base64urlDecodeString(jwsParts[0]);\n const header = JSON.parse(headerJson) as { kid?: string; alg?: string; crit?: string[] };\n\n // Reject 'none' algorithm (security)\n if (header.alg === 'none') {\n errors.push('Algorithm \"none\" is not allowed');\n }\n\n // Reject algorithms not in allowlist\n if (\n header.alg &&\n !ALLOWED_ALGORITHMS.includes(header.alg as (typeof ALLOWED_ALGORITHMS)[number])\n ) {\n errors.push(\n `Algorithm \"${header.alg}\" is not in allowed list: ${ALLOWED_ALGORITHMS.join(', ')}`\n );\n }\n\n // Reject unknown critical headers (JOSE compliance)\n // Per RFC 7515: crit lists headers that MUST be understood, we don't support any\n if (header.crit && header.crit.length > 0) {\n // Check if crit references headers that are missing (per JOSE spec)\n const headerObj = header as Record<string, unknown>;\n const missingCrit = header.crit.filter((h) => !(h in headerObj));\n if (missingCrit.length > 0) {\n errors.push(`Critical headers declared but missing: ${missingCrit.join(', ')}`);\n }\n // Reject all crit headers since we don't understand any extensions\n errors.push(`Unsupported critical headers: ${header.crit.join(', ')}`);\n }\n\n const targetKid = header.kid;\n\n // Strict key selection by kid\n let keyJwk:\n | {\n kid?: string;\n kty?: string;\n crv?: string;\n x?: string;\n n?: string;\n use?: string;\n key_ops?: string[];\n }\n | undefined;\n if (!Array.isArray(jwks.keys) || jwks.keys.length === 0) {\n errors.push('JWKS has no keys');\n } else if (targetKid) {\n // JWS has kid: require exact match\n keyJwk = jwks.keys.find((k: { kid?: string }) => k.kid === targetKid);\n if (!keyJwk) {\n errors.push(`Key with kid \"${targetKid}\" not found in JWKS`);\n }\n } else if (jwks.keys.length === 1) {\n // JWS has no kid but JWKS has exactly 1 key: accept it\n keyJwk = jwks.keys[0];\n warnings.push('JWS has no kid - using only key from JWKS');\n } else {\n // JWS has no kid and JWKS has multiple keys: fail\n errors.push(`JWS missing kid but JWKS has ${jwks.keys.length} keys - cannot select`);\n }\n\n // Verify algorithm matches key type\n if (keyJwk && header.alg && errors.length === 0) {\n const expectedKeyType = ALG_KEY_TYPE_MAP[header.alg];\n if (expectedKeyType) {\n if (keyJwk.kty !== expectedKeyType.kty) {\n errors.push(\n `Algorithm \"${header.alg}\" requires key type \"${expectedKeyType.kty}\" but key has \"${keyJwk.kty}\"`\n );\n } else if (\n expectedKeyType.crv &&\n keyJwk.crv &&\n !expectedKeyType.crv.includes(keyJwk.crv)\n ) {\n errors.push(\n `Algorithm \"${header.alg}\" requires curve ${expectedKeyType.crv.join(' or ')} but key has \"${keyJwk.crv}\"`\n );\n }\n }\n\n // Validate key use if present (must be \"sig\" for signature verification)\n if (keyJwk.use && keyJwk.use !== 'sig') {\n errors.push(\n `Key use \"${keyJwk.use}\" is not valid for signature verification (expected \"sig\")`\n );\n }\n\n // Validate key_ops if present (must include \"verify\")\n if (keyJwk.key_ops && !keyJwk.key_ops.includes('verify')) {\n errors.push(`Key operations ${JSON.stringify(keyJwk.key_ops)} do not include \"verify\"`);\n }\n }\n\n if (keyJwk && errors.length === 0) {\n // Get the public key bytes (x for OKP/EC, n for RSA)\n const publicKeyParam = keyJwk.x || keyJwk.n;\n if (!publicKeyParam) {\n errors.push('Selected key missing public key (x or n parameter)');\n } else {\n // Decode base64url public key bytes\n const publicKeyBytes = base64urlDecode(publicKeyParam);\n await verify(receipt._jws, publicKeyBytes);\n logger.info(`Signature verified with key ${keyJwk.kid || 'anonymous'}`);\n }\n }\n }\n } catch (error) {\n errors.push(\n `Signature verification failed: ${error instanceof Error ? error.message : 'Unknown'}`\n );\n }\n } else if (!jwksPath) {\n warnings.push('No JWKS provided - signature not verified');\n }\n\n return {\n status: errors.length === 0 ? 'ok' : 'error',\n valid: errors.length === 0,\n message: errors.length === 0 ? 'Receipt is valid' : 'Receipt has validation errors',\n errors: errors.length > 0 ? errors : undefined,\n warnings: warnings.length > 0 ? warnings : undefined,\n receipt_id: (auth as Record<string, unknown>)?.rid as string | undefined,\n interaction_id: (interaction as Record<string, unknown>)?.interaction_id as string | undefined,\n };\n}\n\nasync function verifyBundle(\n bundlePath: string,\n jwksPath: string | undefined,\n fs: typeof import('fs'),\n pathModule: typeof import('path'),\n logger: PluginLogger\n): Promise<VerifyResult> {\n // Read manifest\n const manifestPath = pathModule.join(bundlePath, 'manifest.json');\n const manifest = JSON.parse(await fs.promises.readFile(manifestPath, 'utf-8'));\n\n const receiptsDir = pathModule.join(bundlePath, 'receipts');\n const files = await fs.promises.readdir(receiptsDir);\n\n let validCount = 0;\n let invalidCount = 0;\n const allErrors: string[] = [];\n const allWarnings: string[] = [];\n\n for (const file of files) {\n if (!file.endsWith('.peac.json')) continue;\n\n const result = await verifySingleReceipt(\n pathModule.join(receiptsDir, file),\n jwksPath,\n fs,\n logger\n );\n\n if (result.valid) {\n validCount++;\n } else {\n invalidCount++;\n if (result.errors) {\n allErrors.push(...result.errors.map((e) => `${file}: ${e}`));\n }\n }\n if (result.warnings) {\n allWarnings.push(...result.warnings.map((w) => `${file}: ${w}`));\n }\n }\n\n return {\n status: invalidCount === 0 ? 'ok' : 'error',\n valid: invalidCount === 0,\n message: `Bundle verification: ${validCount} valid, ${invalidCount} invalid`,\n errors: allErrors.length > 0 ? allErrors : undefined,\n warnings: allWarnings.length > 0 ? allWarnings : undefined,\n bundle_stats: {\n total: validCount + invalidCount,\n valid: validCount,\n invalid: invalidCount,\n manifest_receipt_count: manifest.receipt_count,\n },\n };\n}\n\ninterface VerifyParams {\n path: string;\n jwks_path?: string;\n}\n\ninterface VerifyResult {\n status: 'ok' | 'error';\n valid: boolean;\n message: string;\n errors?: string[];\n warnings?: string[];\n receipt_id?: string;\n interaction_id?: string;\n bundle_stats?: {\n total: number;\n valid: number;\n invalid: number;\n manifest_receipt_count: number;\n };\n}\n\n// =============================================================================\n// Query Tool\n// =============================================================================\n\n/**\n * Create the peac_receipts.query tool.\n * Query receipts by workflow_id, tool name, or time range.\n */\nexport function createQueryTool(outputDir: string, logger: PluginLogger): PluginTool {\n return {\n name: 'peac_receipts.query',\n description: 'Query receipts by workflow_id, tool name, or time range',\n parameters: {\n type: 'object',\n properties: {\n workflow_id: {\n type: 'string',\n description: 'Filter by workflow ID',\n },\n tool_name: {\n type: 'string',\n description: 'Filter by tool name',\n },\n since: {\n type: 'string',\n description: 'Include receipts since this RFC 3339 timestamp',\n },\n until: {\n type: 'string',\n description: 'Include receipts until this RFC 3339 timestamp',\n },\n status: {\n type: 'string',\n enum: ['ok', 'error', 'timeout', 'canceled'],\n description: 'Filter by result status',\n },\n limit: {\n type: 'integer',\n description: 'Maximum number of results (default: 100)',\n },\n offset: {\n type: 'integer',\n description: 'Skip this many results (for pagination)',\n },\n },\n },\n\n async execute(params: QueryParams): Promise<QueryResult> {\n const fs = await import('fs');\n const pathModule = await import('path');\n\n // Use path.resolve for portability\n const resolvedOutputDir = pathModule.resolve(outputDir);\n\n try {\n const files = await fs.promises.readdir(resolvedOutputDir);\n const receiptFiles = files.filter((f) => f.endsWith('.peac.json'));\n\n const limit = Math.min(params.limit || 100, MAX_QUERY_FILE_PARSE);\n const offset = params.offset || 0;\n\n // If we have time filters, we can sort by mtime first (cheap) to reduce parsing\n // Get file stats first for time-based pre-filtering\n const fileInfos: Array<{ file: string; mtime: Date }> = [];\n for (const file of receiptFiles.slice(0, MAX_QUERY_FILE_PARSE)) {\n try {\n const filePath = pathModule.join(resolvedOutputDir, file);\n const stat = await fs.promises.stat(filePath);\n\n // Apply time filters early (before parsing JSON)\n if (params.since && stat.mtime < new Date(params.since)) {\n continue;\n }\n if (params.until && stat.mtime > new Date(params.until)) {\n continue;\n }\n\n fileInfos.push({ file, mtime: stat.mtime });\n } catch {\n // Skip files that can't be stat'd\n continue;\n }\n }\n\n // Sort by mtime descending (newest first) before parsing\n fileInfos.sort((a, b) => b.mtime.getTime() - a.mtime.getTime());\n\n // Now parse files until we have enough matches\n const matches: QueryMatch[] = [];\n let skippedForFilters = 0;\n\n let filesSkippedForSize = 0;\n let filesSkippedForInvalidJson = 0;\n let filesSkippedForMalformedJws = 0;\n for (const { file } of fileInfos) {\n const filePath = pathModule.join(resolvedOutputDir, file);\n\n // Check file size before reading (DoS protection)\n try {\n const fileStat = await fs.promises.stat(filePath);\n if (fileStat.size > MAX_FILE_SIZE_BYTES) {\n filesSkippedForSize++;\n continue;\n }\n } catch {\n continue;\n }\n\n // Read and parse receipt (tolerate invalid JSON)\n let content;\n try {\n content = JSON.parse(await fs.promises.readFile(filePath, 'utf-8'));\n } catch {\n // Skip invalid JSON files\n filesSkippedForInvalidJson++;\n continue;\n }\n\n // Derive filter data from _jws (source of truth when present).\n // If _jws exists but is malformed, skip this receipt (untrusted).\n const decoded = content._jws ? decodeReceiptPayload(content) : null;\n if (content._jws && !decoded) {\n filesSkippedForMalformedJws++;\n continue;\n }\n const authBlock = (decoded?.auth ?? content?.auth) as Record<string, unknown> | undefined;\n const evidenceBlock = (decoded?.evidence ?? content?.evidence) as\n | Record<string, unknown>\n | undefined;\n const evidenceExtensions = evidenceBlock?.extensions as\n | Record<string, unknown>\n | undefined;\n const interaction = evidenceExtensions?.['org.peacprotocol/interaction@0.1'] as\n | Record<string, unknown>\n | undefined;\n const authExtensions = authBlock?.extensions as Record<string, unknown> | undefined;\n const workflow = authExtensions?.['org.peacprotocol/workflow'] as\n | Record<string, unknown>\n | undefined;\n\n // Apply workflow filter\n if (params.workflow_id && workflow?.workflow_id !== params.workflow_id) {\n skippedForFilters++;\n continue;\n }\n\n // Apply tool filter\n const tool = interaction?.tool as Record<string, unknown> | undefined;\n if (params.tool_name && tool?.name !== params.tool_name) {\n skippedForFilters++;\n continue;\n }\n\n // Apply status filter\n const result = interaction?.result as Record<string, unknown> | undefined;\n if (params.status && result?.status !== params.status) {\n skippedForFilters++;\n continue;\n }\n\n matches.push({\n file,\n receipt_id: authBlock?.rid as string | undefined,\n interaction_id: interaction?.interaction_id as string | undefined,\n workflow_id: workflow?.workflow_id as string | undefined,\n tool_name: tool?.name as string | undefined,\n status: result?.status as string | undefined,\n started_at: interaction?.started_at as string | undefined,\n completed_at: interaction?.completed_at as string | undefined,\n });\n\n // Early exit if we have enough matches (limit + offset)\n // This avoids parsing all files when we only need a few\n if (matches.length >= offset + limit + 100) {\n // Buffer of 100 for sorting stability\n break;\n }\n }\n\n // Final sort by started_at (more accurate than mtime), then by filename for determinism\n matches.sort((a, b) => {\n const aTime = a.started_at ? new Date(a.started_at).getTime() : 0;\n const bTime = b.started_at ? new Date(b.started_at).getTime() : 0;\n if (bTime !== aTime) return bTime - aTime;\n // Secondary sort by filename for deterministic ordering\n return a.file.localeCompare(b.file);\n });\n\n // Apply pagination\n const paginated = matches.slice(offset, offset + limit);\n\n // Build warnings for truncation\n const warnings: string[] = [];\n if (receiptFiles.length > MAX_QUERY_FILE_PARSE) {\n warnings.push(`Results capped at ${MAX_QUERY_FILE_PARSE} files`);\n }\n if (filesSkippedForSize > 0) {\n warnings.push(\n `${filesSkippedForSize} files skipped (exceeded ${MAX_FILE_SIZE_BYTES} byte limit)`\n );\n }\n if (filesSkippedForInvalidJson > 0) {\n warnings.push(`${filesSkippedForInvalidJson} files skipped (invalid JSON)`);\n }\n if (filesSkippedForMalformedJws > 0) {\n warnings.push(`${filesSkippedForMalformedJws} files skipped (malformed JWS)`);\n }\n\n const totalSkipped =\n filesSkippedForSize + filesSkippedForInvalidJson + filesSkippedForMalformedJws;\n const hasTruncation = receiptFiles.length > MAX_QUERY_FILE_PARSE || totalSkipped > 0;\n\n return {\n status: 'ok',\n total: matches.length,\n offset,\n limit,\n results: paginated,\n scanned_count: fileInfos.length,\n matched_count: matches.length,\n truncated: hasTruncation,\n skipped:\n hasTruncation || skippedForFilters > 0\n ? {\n too_large: filesSkippedForSize,\n invalid_json: filesSkippedForInvalidJson,\n malformed_jws: filesSkippedForMalformedJws,\n filtered: skippedForFilters,\n capped:\n receiptFiles.length > MAX_QUERY_FILE_PARSE\n ? receiptFiles.length - MAX_QUERY_FILE_PARSE\n : 0,\n }\n : undefined,\n ...(warnings.length > 0 && { warning: warnings.join('; ') }),\n };\n } catch (error) {\n logger.error('Query failed:', error);\n return {\n status: 'error',\n total: 0,\n offset: 0,\n limit: params.limit || 100,\n results: [],\n error: error instanceof Error ? error.message : 'Unknown error',\n };\n }\n },\n };\n}\n\ninterface QueryParams {\n workflow_id?: string;\n tool_name?: string;\n since?: string;\n until?: string;\n status?: 'ok' | 'error' | 'timeout' | 'canceled';\n limit?: number;\n offset?: number;\n}\n\ninterface QueryMatch {\n file: string;\n receipt_id?: string;\n interaction_id?: string;\n workflow_id?: string;\n tool_name?: string;\n status?: string;\n started_at?: string;\n completed_at?: string;\n}\n\ninterface QueryResult {\n status: 'ok' | 'error';\n total: number;\n offset: number;\n limit: number;\n results: QueryMatch[];\n scanned_count?: number;\n matched_count?: number;\n truncated?: boolean;\n skipped?: {\n too_large: number;\n invalid_json: number;\n malformed_jws: number;\n filtered: number;\n capped: number;\n };\n error?: string;\n warning?: string;\n}\n","/**\n * @peac/adapter-openclaw - Plugin Activation\n *\n * High-level entry point that wires together all adapter components\n * from config. Calls existing functions (resolveSigner, createPluginInstance,\n * createFileReceiptWriter, etc.) -- no logic duplication.\n *\n * Usage:\n * const result = await activate({ config, logger });\n * result.instance.start();\n *\n * When OpenClaw's plugin loader gains a stable activation shape,\n * add a thin validated wrapper at that time.\n */\n\nimport * as path from 'node:path';\nimport * as fs from 'node:fs/promises';\nimport type { OpenClawAdapterConfig } from './types.js';\nimport type { PluginLogger, PluginInstance, PluginTool } from './plugin.js';\nimport type { OpenClawHookHandler } from './hooks.js';\nimport type { FsSpoolStoreOptions } from '@peac/capture-node';\nimport { createFsSpoolStore, createFsDedupeIndex, getFsSpoolDiagnostics } from '@peac/capture-node';\nimport { resolveSigner, createFileReceiptWriter, createPluginInstance } from './plugin.js';\nimport {\n createStatusTool,\n createExportBundleTool,\n createVerifyTool,\n createQueryTool,\n} from './tools.js';\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Options for activating the plugin.\n */\nexport interface ActivateOptions {\n /** Adapter configuration (signing, capture, correlation, background). */\n config: ActivateConfig;\n /** Logger instance. */\n logger?: PluginLogger;\n /** Data directory for spool, dedupe, and signing key. Default: ~/.openclaw/peac/ */\n dataDir?: string;\n /** Spool store options override. */\n spoolOptions?: Partial<\n Pick<\n FsSpoolStoreOptions,\n 'maxEntries' | 'maxFileBytes' | 'autoCommitIntervalMs' | 'lockOptions'\n >\n >;\n}\n\n/**\n * Configuration for activate(). Extends OpenClawAdapterConfig with\n * required signing fields.\n */\nexport interface ActivateConfig extends OpenClawAdapterConfig {\n /** Signing configuration (required for activation). */\n signing: {\n /** Key reference: env:VAR_NAME or file:/path */\n key_ref: string;\n /** Issuer URI for receipts */\n issuer: string;\n /** Optional audience URI */\n audience?: string;\n };\n /** Output directory for receipt files. Default: {dataDir}/receipts/ */\n output_dir?: string;\n /** Background emitter settings. */\n background?: {\n drain_interval_ms?: number;\n batch_size?: number;\n };\n}\n\n/**\n * Result of activating the plugin.\n */\nexport interface ActivateResult {\n /** The running plugin instance. */\n instance: PluginInstance;\n /** The 4 plugin tools (status, export, verify, query). */\n tools: PluginTool[];\n /** Hook handler for tool call events. */\n hookHandler: OpenClawHookHandler;\n /** Data directory used. */\n dataDir: string;\n /** Flush pending spool entries into signed receipts. */\n flush: () => Promise<void>;\n /** Shut down the plugin cleanly. */\n shutdown: () => Promise<void>;\n}\n\n// =============================================================================\n// Defaults\n// =============================================================================\n\nconst DEFAULT_DATA_DIR_NAME = '.openclaw/peac';\nconst SPOOL_FILENAME = 'spool.jsonl';\nconst DEDUPE_FILENAME = 'dedupe.idx';\n\n// =============================================================================\n// Helpers\n// =============================================================================\n\nfunction defaultDataDir(): string {\n const home = process.env.HOME || process.env.USERPROFILE || '.';\n return path.join(home, DEFAULT_DATA_DIR_NAME);\n}\n\nfunction noopLogger(): PluginLogger {\n const noop = () => {};\n return { debug: noop, info: noop, warn: noop, error: noop };\n}\n\n// =============================================================================\n// Activation\n// =============================================================================\n\n/**\n * Activate the PEAC evidence export plugin.\n *\n * This is the single canonical entry point. It:\n * 1. Resolves the signing key from config (env: or file:)\n * 2. Creates durable stores (FsSpoolStore + FsDedupeIndex)\n * 3. Creates the receipt writer\n * 4. Creates the plugin instance (session + hooks + emitter)\n * 5. Creates the 4 plugin tools\n * 6. Logs startup diagnostics\n *\n * @throws If signing key cannot be resolved\n * @throws If data directory is not writable\n * @throws If spool lockfile cannot be acquired\n */\nexport async function activate(options: ActivateOptions): Promise<ActivateResult> {\n const { config, spoolOptions } = options;\n const logger = options.logger ?? noopLogger();\n const dataDir = options.dataDir ?? defaultDataDir();\n\n // 1. Ensure data directory exists\n await fs.mkdir(dataDir, { recursive: true });\n\n // Verify writable\n try {\n await fs.access(dataDir, (await import('node:constants')).W_OK);\n } catch {\n throw new Error(`Data directory is not writable: ${dataDir}`);\n }\n\n // 2. Resolve signing key\n logger.info(`Resolving signing key from: ${config.signing.key_ref.split(':')[0]}:***`);\n const signer = await resolveSigner(\n config.signing.key_ref,\n config.signing.issuer,\n config.signing.audience\n );\n logger.info(`Signing key resolved. kid: ${signer.getKeyId()}`);\n\n // 3. Create durable stores\n const spoolPath = path.join(dataDir, SPOOL_FILENAME);\n const dedupePath = path.join(dataDir, DEDUPE_FILENAME);\n\n const store = await createFsSpoolStore({\n filePath: spoolPath,\n maxEntries: spoolOptions?.maxEntries,\n maxFileBytes: spoolOptions?.maxFileBytes,\n autoCommitIntervalMs: spoolOptions?.autoCommitIntervalMs,\n lockOptions: spoolOptions?.lockOptions,\n onWarning: (msg: string) => logger.warn(`spool: ${msg}`),\n });\n\n const dedupe = await createFsDedupeIndex({\n filePath: dedupePath,\n });\n\n // 4. Create receipt writer\n const outputDir = config.output_dir ?? path.join(dataDir, 'receipts');\n const writer = await createFileReceiptWriter(outputDir);\n\n // 5. Create plugin instance\n const instance = await createPluginInstance({\n signer,\n writer,\n adapterConfig: config,\n store,\n dedupe,\n drainIntervalMs: config.background?.drain_interval_ms,\n batchSize: config.background?.batch_size,\n onError: (err) => logger.error(`plugin error: ${err.message}`),\n });\n\n // 6. Create tools\n const tools: PluginTool[] = [\n createStatusTool(() => instance.getStats(), outputDir),\n createExportBundleTool(outputDir, logger),\n createVerifyTool(logger),\n createQueryTool(outputDir, logger),\n ];\n\n // 7. Log startup diagnostics\n const diag = getFsSpoolDiagnostics(store);\n if (diag) {\n logger.info(\n `PEAC evidence export active. ` +\n `Spool: ${diag.entryCount} entries, ${diag.fileBytes} bytes. ` +\n `Receipts: ${outputDir}`\n );\n } else {\n logger.info(`PEAC evidence export active. Receipts: ${outputDir}`);\n }\n\n // 8. Shutdown handler\n async function shutdown(): Promise<void> {\n logger.info('Shutting down PEAC evidence export...');\n await instance.stop();\n await store.close();\n await dedupe.close();\n logger.info('PEAC evidence export stopped.');\n }\n\n return {\n instance,\n tools,\n hookHandler: instance.hookHandler,\n dataDir,\n flush: () => instance.backgroundService.drain(),\n shutdown,\n };\n}\n","/**\n * @peac/adapter-openclaw - Signing Key Generation\n *\n * Generates an Ed25519 keypair for PEAC receipt signing.\n * Reuses generateKeyId() from plugin.ts for kid derivation.\n *\n * Usage (programmatic):\n * const result = await generateSigningKey({ outputDir: '~/.openclaw/peac' });\n * console.log(result.kid);\n *\n * Usage (CLI):\n * npx @peac/adapter-openclaw keygen\n * npx @peac/adapter-openclaw keygen --output-dir /path/to/dir\n */\n\nimport * as path from 'node:path';\nimport * as fs from 'node:fs/promises';\nimport { generateKeypair, base64urlEncode } from '@peac/crypto';\nimport { generateKeyId, type JWK } from './plugin.js';\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Options for key generation.\n */\nexport interface KeygenOptions {\n /** Directory to write the key file to. Default: current directory. */\n outputDir?: string;\n /** Filename for the private key. Default: signing-key.jwk */\n filename?: string;\n}\n\n/**\n * Result of key generation.\n */\nexport interface KeygenResult {\n /** Key ID (derived from public key). */\n kid: string;\n /** Path where the private key was written. */\n keyPath: string;\n /** The public JWK (safe to share). */\n publicJwk: JWK;\n /** The private JWK (keep secret). */\n privateJwk: JWK;\n}\n\n// =============================================================================\n// Defaults\n// =============================================================================\n\nconst DEFAULT_KEY_FILENAME = 'signing-key.jwk';\n\n// =============================================================================\n// Key Generation\n// =============================================================================\n\n/**\n * Generate an Ed25519 signing keypair and write the private key to disk.\n *\n * - Private key file has 0o600 permissions (owner read/write only).\n * On platforms where chmod fails (Windows), a warning is logged to stderr.\n * - The key ID (kid) is derived from the public key via generateKeyId().\n *\n * @returns KeygenResult with paths and key material\n */\nexport async function generateSigningKey(options?: KeygenOptions): Promise<KeygenResult> {\n const outputDir = options?.outputDir ?? '.';\n const filename = options?.filename ?? DEFAULT_KEY_FILENAME;\n\n // Generate Ed25519 keypair via @peac/crypto\n const { privateKey: privateKeyBytes, publicKey: publicKeyBytes } = await generateKeypair();\n\n // Encode as base64url\n const d = base64urlEncode(privateKeyBytes);\n const x = base64urlEncode(publicKeyBytes);\n\n // Build JWK\n const privateJwk: JWK = {\n kty: 'OKP',\n crv: 'Ed25519',\n x,\n d,\n alg: 'EdDSA',\n use: 'sig',\n };\n\n // Derive key ID from public component\n const kid = generateKeyId(privateJwk);\n privateJwk.kid = kid;\n\n // Public JWK (no private component)\n const publicJwk: JWK = {\n kty: 'OKP',\n crv: 'Ed25519',\n x,\n kid,\n alg: 'EdDSA',\n use: 'sig',\n };\n\n // Write to disk\n await fs.mkdir(outputDir, { recursive: true });\n const keyPath = path.join(outputDir, filename);\n await fs.writeFile(keyPath, JSON.stringify(privateJwk, null, 2) + '\\n', 'utf-8');\n\n // Set restrictive permissions (0o600 = owner read/write only)\n try {\n await fs.chmod(keyPath, 0o600);\n } catch {\n // chmod may fail on Windows -- log warning but don't fail\n process.stderr.write(\n `Warning: Could not set file permissions on ${keyPath}. ` +\n `Ensure the file is not readable by other users.\\n`\n );\n }\n\n return { kid, keyPath, publicJwk, privateJwk };\n}\n\n// =============================================================================\n// CLI Entry Point\n// =============================================================================\n\n/**\n * CLI handler for `peac-keygen` command.\n * Parses args, generates key, prints results.\n */\nexport async function keygenCli(args: string[]): Promise<void> {\n let outputDir: string | undefined;\n\n for (let i = 0; i < args.length; i++) {\n if (args[i] === '--output-dir' && i + 1 < args.length) {\n outputDir = args[i + 1];\n i++;\n } else if (args[i] === '--help' || args[i] === '-h') {\n process.stdout.write(\n 'Usage: peac-keygen [--output-dir <dir>]\\n\\n' +\n 'Generate an Ed25519 signing key for PEAC receipt signing.\\n\\n' +\n 'Options:\\n' +\n ' --output-dir <dir> Directory for key file (default: current directory)\\n' +\n ' --help, -h Show this help message\\n'\n );\n return;\n }\n }\n\n const result = await generateSigningKey({ outputDir });\n\n process.stdout.write(`Key generated successfully.\\n`);\n process.stdout.write(` kid: ${result.kid}\\n`);\n process.stdout.write(` key file: ${result.keyPath}\\n`);\n process.stdout.write(` public x: ${result.publicJwk.x}\\n`);\n process.stdout.write(`\\nTo use with the OpenClaw adapter:\\n`);\n process.stdout.write(` signing.key_ref: \"file:${path.resolve(result.keyPath)}\"\\n`);\n}\n"]}