@bolloon/bolloon-agent 0.4.29 → 0.4.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/contacts/chain.js +579 -0
- package/dist/agents/contacts/cli.js +158 -0
- package/dist/agents/contacts/consent.js +124 -0
- package/dist/agents/contacts/grant-payload.js +45 -0
- package/dist/agents/contacts/grants.js +451 -0
- package/dist/agents/contacts/policy.js +264 -0
- package/dist/agents/contacts/preview-types.js +6 -0
- package/dist/agents/contacts/providers.js +341 -0
- package/dist/agents/contacts/store.js +326 -0
- package/dist/agents/contacts/tools.js +154 -0
- package/dist/agents/contacts/types.js +148 -0
- package/dist/agents/pi-sdk.js +10 -0
- package/dist/electron-build/agents/contacts/chain.js +619 -0
- package/dist/electron-build/agents/contacts/chain.js.map +1 -0
- package/dist/electron-build/agents/contacts/consent.js +163 -0
- package/dist/electron-build/agents/contacts/consent.js.map +1 -0
- package/dist/electron-build/agents/contacts/grant-payload.js +52 -0
- package/dist/electron-build/agents/contacts/grant-payload.js.map +1 -0
- package/dist/electron-build/agents/contacts/grants.js +500 -0
- package/dist/electron-build/agents/contacts/grants.js.map +1 -0
- package/dist/electron-build/agents/contacts/policy.js +271 -0
- package/dist/electron-build/agents/contacts/policy.js.map +1 -0
- package/dist/electron-build/agents/contacts/preview-types.js +8 -0
- package/dist/electron-build/agents/contacts/preview-types.js.map +1 -0
- package/dist/electron-build/agents/contacts/providers.js +384 -0
- package/dist/electron-build/agents/contacts/providers.js.map +1 -0
- package/dist/electron-build/agents/contacts/store.js +370 -0
- package/dist/electron-build/agents/contacts/store.js.map +1 -0
- package/dist/electron-build/agents/contacts/tools.js +159 -0
- package/dist/electron-build/agents/contacts/tools.js.map +1 -0
- package/dist/electron-build/agents/contacts/types.js +166 -0
- package/dist/electron-build/agents/contacts/types.js.map +1 -0
- package/dist/electron-build/agents/external-events.js.map +1 -1
- package/dist/electron-build/agents/goal-store.js.map +1 -1
- package/dist/electron-build/agents/pi-sdk.js +10 -0
- package/dist/electron-build/agents/pi-sdk.js.map +1 -1
- package/dist/electron-build/security/tool-gate.js +4 -0
- package/dist/electron-build/security/tool-gate.js.map +1 -1
- package/dist/index.js +30 -0
- package/dist/security/tool-gate.js +4 -0
- package/dist/web/mobile-contacts.js +329 -0
- package/dist/web/mobile-core.js +481 -15
- package/dist/web/mobile.html +32 -0
- package/dist/web/mobile.js +139 -0
- package/dist/web/routes-contacts.js +420 -0
- package/dist/web/server.js +5 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-gate.js","sourceRoot":"","sources":["../../../src/security/tool-gate.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;;;;;;;;;;;AAIH,2DAA2G;AAsB3G,+DAA+D;AAC/D,cAAc;AACd,+DAA+D;AAE/D,MAAM,cAAc,GAAG,IAAI,GAAG,CAAS;IACrC,sCAAsC;IACtC,eAAe,EAAE,oBAAoB,EAAE,kBAAkB;IACzD,YAAY,EAAE,cAAc,EAAE,mBAAmB;IACjD,cAAc,EAAE,aAAa,EAAE,iBAAiB;IAChD,YAAY,EAAE,OAAO;IACrB,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,YAAY;IAC1C,eAAe,EAAE,mBAAmB,EAAE,eAAe;IACrD,iBAAiB,EAAE,gBAAgB;IACnC,mEAAmE;IACnE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY;IAChE,aAAa,EAAE,aAAa,EAAE,UAAU,EAAE,YAAY;IACtD,WAAW,EAAE,cAAc;IAC3B,mDAAmD;IACnD,WAAW,EAAE,aAAa,EAAE,OAAO,EAAE,WAAW;IAChD,YAAY,EAAE,YAAY;IAC1B,SAAS,EAAE,UAAU,EAAE,WAAW;IAClC,YAAY,EAAE,WAAW;IACzB,6DAA6D;IAC7D,aAAa,EAAE,cAAc,EAAE,eAAe,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,YAAY;IACxG,kFAAkF;IAClF,eAAe,EAAE,eAAe,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,gBAAgB;IAC1I,yBAAyB,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,yBAAyB,EAAE,yBAAyB;IACjI,aAAa;IACb,YAAY;IACZ,UAAU;IACV,yCAAyC;IACzC,gBAAgB,EAAE,kBAAkB,EAAE,oBAAoB;IAC1D,aAAa,EAAE,oBAAoB,EAAE,WAAW;IAChD,eAAe,EAAE,qBAAqB;IACtC,2CAA2C;IAC3C,cAAc,EAAE,cAAc,EAAE,uBAAuB,EAAE,eAAe;IACxE,kDAAkD;IAClD,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,YAAY;IACzD,4DAA4D;IAC5D,iBAAiB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,gBAAgB;IAC3E,4DAA4D;IAC5D,qBAAqB,EAAE,qBAAqB,EAAE,qBAAqB;IACnE,2DAA2D;IAC3D,gBAAgB,EAAE,UAAU;IAC5B,4CAA4C;IAC5C,aAAa;IACb,oDAAoD;IACpD,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,cAAc,EAAE,cAAc;IACjE,yCAAyC;IACzC,WAAW,EAAE,YAAY;IACzB,2CAA2C;IAC3C,sBAAsB,EAAE,wBAAwB;IAChD,6DAA6D;IAC7D,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,WAAW;IAC5E,uBAAuB,EAAE,iBAAiB;IAC1C,mBAAmB,EAAE,mBAAmB;IACxC,oFAAoF;IACpF,eAAe,EAAE,aAAa,EAAE,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,eAAe;IAChG,oEAAoE;IACpE,oBAAoB,EAAE,oBAAoB;IAC1C,8DAA8D;IAC9D,SAAS,EAAE,OAAO,EAAE,cAAc;IAClC,YAAY,EAAE,SAAS,EAAE,aAAa;IACtC,cAAc,EAAE,SAAS;IACzB,cAAc,EAAE,cAAc,EAAE,aAAa;IAC7C,uCAAuC;IACvC,mBAAmB,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,eAAe,EAAE,kBAAkB;CAClG,CAAC,CAAC;AAEU,QAAA,aAAa,GAAe,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAE9E;;;GAGG;AACH,wBAA+B,GAAgB;IAC7C,IAAI,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QACjC,OAAO,QAAA,aAAa,CAAC;IACvB,CAAC;IACD,OAAO;QACL,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,KAAK;QACd,MAAM,EAAE,OAAO,GAAG,CAAC,IAAI,SAAS;QAChC,QAAQ,EAAE,QAAQ,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK;KACzE,CAAC;AACJ,CAAC;AAED,+DAA+D;AAC/D,kCAAkC;AAClC,+DAA+D;AAE/D,MAAM,cAAc,GAAG,CAAC,WAAW,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC;AAEjE,qBAA4B,GAAgB;IAC1C,qDAAqD;IACrD,SAAS,QAAQ,CAAC,GAAY,EAAE,IAAI,GAAa,EAAE;QACjD,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QACzD,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACjC,IAAK,cAAoC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;gBACtD,OAAO,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAChC,CAAC;YACD,MAAM,KAAK,GAAG,QAAQ,CAAE,GAA+B,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAC1E,IAAI,KAAK;gBAAE,OAAO,KAAK,CAAC;QAC1B,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,YAAY,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACxC,IAAI,YAAY,EAAE,CAAC;QACjB,OAAO;YACL,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,sCAAsC,YAAY,EAAE;YAC5D,QAAQ,EAAE,YAAY;SACvB,CAAC;IACJ,CAAC;IACD,wDAAwD;IACxD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,IAAI,CAAC,MAAM,GAAG,KAAK,EAAE,CAAC;QACxB,OAAO;YACL,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,YAAY,IAAI,CAAC,MAAM,4BAA4B;YAC3D,QAAQ,EAAE,aAAa,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE;SAChD,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC3C,CAAC;AAED,+DAA+D;AAC/D,8CAA8C;AAC9C,+DAA+D;AAE/D,0CAA0C;AAC1C,MAAM,qBAAqB,GAA2C;AACpE,mEAAmE;CACpE,CAAC;AAEF,sBAA6B,GAAgB;IAC3C,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;QACnB,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC5C,CAAC;IACD,MAAM,YAAY,GAAG,qBAAqB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACrD,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC5C,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,YAAY,EAAE,CAAC;QAC7B,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,GAAG,CAAC,SAAS,EAAE,CAAC;YACjD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,GAAG,CAAC,SAAS,WAAW,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC;QACtG,CAAC;QACD,IAAI,CAAC,YAAY,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YACjD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,GAAG,CAAC,SAAS,WAAW,CAAC,EAAE,EAAE,CAAC;QAC9F,CAAC;IACH,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC5C,CAAC;AAED,+DAA+D;AAC/D,qCAAqC;AACrC,+DAA+D;AAE/D,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAE7B,mBAA0B,GAAgB;IACxC,MAAM,MAAM,GAAG,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC;IACrC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,MAAM,GAAG,MAAM,CAAC;IACtB,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,IAAI,GAAG,GAAG,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,CAAC;IAClF,IAAI,QAAQ,CAAC,MAAM,IAAI,kBAAkB,EAAE,CAAC;QAC1C,OAAO;YACL,IAAI,EAAE,MAAM;YACZ,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,OAAO,GAAG,CAAC,IAAI,gBAAgB,QAAQ,CAAC,MAAM,UAAU,kBAAkB,GAAG;YACrF,QAAQ,EAAE,MAAM,QAAQ,CAAC,MAAM,WAAW,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;SACzG,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AACzC,CAAC;AAED,+DAA+D;AAC/D,8BAA8B;AAC9B,+DAA+D;AAE/D,MAAM,kBAAkB,GAAyC;IAC/D,EAAE,EAAE,EAAE,2DAA2D,EAAE,KAAK,EAAE,iBAAiB,EAAE;IAC7F,EAAE,EAAE,EAAE,wDAAwD,EAAE,KAAK,EAAE,WAAW,EAAE;IACpF,EAAE,EAAE,EAAE,kBAAkB,EAAE,KAAK,EAAE,eAAe,EAAE;IAClD,EAAE,EAAE,EAAE,4BAA4B,EAAE,KAAK,EAAE,wBAAwB,EAAE;IACrE,EAAE,EAAE,EAAE,gBAAgB,EAAE,KAAK,EAAE,YAAY,EAAE;IAC7C,EAAE,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,EAAE;IAC3C,EAAE,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,EAAE;CAC5C,CAAC;AAEF,qBAA4B,GAAgB;IAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACxC,KAAK,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,kBAAkB,EAAE,CAAC;QAC/C,IAAI,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YACpB,OAAO;gBACL,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,KAAK;gBACd,MAAM,EAAE,+BAA+B,KAAK,EAAE;gBAC9C,QAAQ,EAAE,OAAO,KAAK,EAAE;aACzB,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC3C,CAAC;AAED,+DAA+D;AAC/D,yCAAyC;AACzC,qCAAqC;AACrC,+DAA+D;AAE/D,qBAA4B,MAAc;IACxC,MAAM,GAAG,GAAG,IAAA,mCAAe,EAAC,MAAM,CAAC,CAAC;IACpC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3C,CAAC;IACD,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,GAAG,CAAC,QAAQ,KAAK,UAAU;QACpC,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,QAAQ,EAAE,GAAG,CAAC,QAAQ;KACvB,CAAC;AACJ,CAAC;AAED,+DAA+D;AAC/D,oDAAoD;AACpD,+DAA+D;AAE/D,MAAM,sBAAsB,GAA0C;IACpE,EAAE,EAAE,EAAE,gDAAgD,EAAE,MAAM,EAAE,WAAW,EAAE;IAC7E,EAAE,EAAE,EAAE,4BAA4B,EAAE,MAAM,EAAE,eAAe,EAAE;IAC7D,EAAE,EAAE,EAAE,kBAAkB,EAAE,MAAM,EAAE,aAAa,EAAE;IACjD,EAAE,EAAE,EAAE,2BAA2B,EAAE,MAAM,EAAE,aAAa,EAAE;IAC1D,EAAE,EAAE,EAAE,2BAA2B,EAAE,MAAM,EAAE,gBAAgB,EAAE;IAC7D,EAAE,EAAE,EAAE,oBAAoB,EAAE,MAAM,EAAE,QAAQ,EAAE;CAC/C,CAAC;AAEF,wBAA+B,GAAgB;IAC7C,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC7E,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC9C,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC;IAC3D,KAAK,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,sBAAsB,EAAE,CAAC;QACpD,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACjB,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;QACxF,CAAC;IACH,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC9C,CAAC;AAcD,MAAM,UAAU,GAA4C;IAC1D,WAAW;IACX,YAAY;IACZ,SAAS;IACT,WAAW;IACX,4EAA4E;IAC5E,cAAc;IACd,gCAAgC;CACjC,CAAC;AAEF,sBAA6B,GAAgB;IAC3C,MAAM,OAAO,GAAiB,EAAE,CAAC;IACjC,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;QAC/B,IAAI,CAAC;YACH,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;YACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAChB,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;gBACf,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;YAC3E,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,sCAAsC;YACtC,OAAO,CAAC,IAAI,CAAC,eAAe,KAAK,CAAC,IAAI,gCAAgC,EAAE,GAAG,CAAC,CAAC;QAC/E,CAAC;IACH,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AACpC,CAAC;AAED,mCAAmC;AACnC,uBAA8B,MAAc;IAC1C,MAAM,CAAC,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IAC9B,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AACpF,CAAC"}
|
|
1
|
+
{"version":3,"file":"tool-gate.js","sourceRoot":"","sources":["../../../src/security/tool-gate.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -2278,6 +2278,36 @@ async function processInputInner(input, comm) {
|
|
|
2278
2278
|
catch { /* 静默 */ }
|
|
2279
2279
|
return;
|
|
2280
2280
|
}
|
|
2281
|
+
// /contacts — 联系方式与持久授权统一入口 (2026-09-19, Phase 10)
|
|
2282
|
+
// /contacts · /contacts authorize [once|long|full] · /contacts revoke all|<id> · pause|resume · bind|verify
|
|
2283
|
+
if (cmd === '/contacts' || cmd.startsWith('/contacts ')) {
|
|
2284
|
+
try {
|
|
2285
|
+
const { ContactChain } = await import('./agents/contacts/chain.js');
|
|
2286
|
+
const { contactsCli } = await import('./agents/contacts/cli.js');
|
|
2287
|
+
let ownerDid = globalThis.__bolloonUserDid || 'did:bolln:local';
|
|
2288
|
+
try {
|
|
2289
|
+
const fsmod = await import('fs');
|
|
2290
|
+
const osmod = await import('os');
|
|
2291
|
+
const pmod = await import('path');
|
|
2292
|
+
const uf = pmod.join(process.env.HOME || osmod.homedir(), '.bolloon', 'identity', 'user.json');
|
|
2293
|
+
const j = JSON.parse(fsmod.readFileSync(uf, 'utf8'));
|
|
2294
|
+
if (j?.did)
|
|
2295
|
+
ownerDid = String(j.did);
|
|
2296
|
+
}
|
|
2297
|
+
catch { /* 还没有用户身份 → 本地占位 */ }
|
|
2298
|
+
const chain = new ContactChain({ ownerDid, displayName: '本机用户' });
|
|
2299
|
+
const rest = cmd.startsWith('/contacts ') ? cmd.slice('/contacts '.length).trim() : '';
|
|
2300
|
+
const r = await contactsCli(chain, rest);
|
|
2301
|
+
for (const line of r.lines)
|
|
2302
|
+
appendLine(line);
|
|
2303
|
+
if (!r.ok)
|
|
2304
|
+
appendLine(`${C_WARN}命令没成功, 上面是原因${RESET}`);
|
|
2305
|
+
}
|
|
2306
|
+
catch (e) {
|
|
2307
|
+
appendLine(`${C_ERROR}/contacts 失败: ${String(e?.message || e).slice(0, 160)}${RESET}`);
|
|
2308
|
+
}
|
|
2309
|
+
return;
|
|
2310
|
+
}
|
|
2281
2311
|
// /skills [名] — 查看正式技能 (2026-08-12 Task5): 无参列全部, 带名看详情. 运行时开始前的技能 view.
|
|
2282
2312
|
if (cmd === '/skills' || cmd.startsWith('/skills ')) {
|
|
2283
2313
|
try {
|
|
@@ -21,6 +21,10 @@ const TOOL_WHITELIST = new Set([
|
|
|
21
21
|
'read', 'write', 'edit_file', 'list_files',
|
|
22
22
|
'list_sessions', 'get_session_state', 'list_messages',
|
|
23
23
|
'send_to_channel', 'create_channel',
|
|
24
|
+
// 2026-09-19: 联系方式 (手机/邮箱) —— 高风险工具, 白名单放行后**仍要过 contact policy**
|
|
25
|
+
// (unverified_contact / consent_revoked / batch_forbidden / rate_limited / not_bound_to_task ...)
|
|
26
|
+
'contact.list_authorized', 'contact.preview', 'contact.request_consent',
|
|
27
|
+
'contact.send', 'contact.await_reply', 'contact.revoke',
|
|
24
28
|
// M2.1 (2026-06-17): 新增的 10 个 agent 工具 (跟 pi-sdk registerTools 同步)
|
|
25
29
|
'write_file', 'git_diff', 'git_commit', 'git_push', 'git_branch',
|
|
26
30
|
'create_task', 'update_task', 'get_task', 'list_tasks',
|
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mobile-contacts.ts — 手机端「联系方式与授权」能力 (2026-09-19, Phase 5/10)
|
|
3
|
+
*
|
|
4
|
+
* 手机端负责 (leo 冻结的分工): 输入手机号/邮箱 · OTP 确认 · 生物识别/系统授权 · 展示待发内容 ·
|
|
5
|
+
* 批准高风险联系 · **用设备私钥签名长期授权** · 保存本地能力副本 (只 capability, 不含明文)。
|
|
6
|
+
* 桌面端负责: 长期 Goal/Run · Supervisor · 执行与恢复 · 持久化 · 证据。
|
|
7
|
+
*
|
|
8
|
+
* 实现要点 (为什么这样写):
|
|
9
|
+
* - **浏览器安全**: 本文件不 import 任何 node: 模块, 只用 WebCrypto / fetch / storage。
|
|
10
|
+
* - **签名规范共用**: 载荷用 `contacts/grant-payload.ts` 的规范函数 (与桌面 Node 侧同一份 → 签名一定对得上)。
|
|
11
|
+
* - **不支持 Ed25519 就明说**: 老 WebView 没 Ed25519 时返回 device_signing_unavailable,
|
|
12
|
+
* **绝不用"不签名"糊过去** (桌面本来就拒收未签名授权)。
|
|
13
|
+
* - **桌面离线不假装成功**: 授权存本地队列, capability 副本落手机, 明确告知"待桌面在线时同步"。
|
|
14
|
+
*/
|
|
15
|
+
import { canonicalGrantPayload, canonicalRevocationPayload, presetForChoice, } from '../agents/contacts/grant-payload.js';
|
|
16
|
+
const K_DEVICE = 'bolloon.contacts.device.v1';
|
|
17
|
+
const K_QUEUE = 'bolloon.contacts.queue.v1';
|
|
18
|
+
const K_CAPS = 'bolloon.contacts.capabilities.v1';
|
|
19
|
+
const cryptoOf = (c) => (c || globalThis.crypto || null);
|
|
20
|
+
/** WebCrypto Ed25519 是否可用 (老 WebView 可能没有 —— 要如实告知, 不能糊过去) */
|
|
21
|
+
export function ed25519Available(c) {
|
|
22
|
+
const cobj = cryptoOf(c);
|
|
23
|
+
if (!cobj?.subtle)
|
|
24
|
+
return false;
|
|
25
|
+
try {
|
|
26
|
+
const alg = { name: 'Ed25519' };
|
|
27
|
+
return typeof cobj.subtle.importKey === 'function' && !!alg;
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* UTF-8 字节 —— 显式拷进 ArrayBuffer: 新版 lib.dom 的 BufferSource 不接受 ArrayBufferLike,
|
|
35
|
+
* 而 WebCrypto (sign/digest) 在浏览器与 Node 都要求真正的 ArrayBuffer。
|
|
36
|
+
*/
|
|
37
|
+
function bytesOf(s) {
|
|
38
|
+
const src = new TextEncoder().encode(s);
|
|
39
|
+
const out = new Uint8Array(new ArrayBuffer(src.byteLength));
|
|
40
|
+
out.set(src);
|
|
41
|
+
return out;
|
|
42
|
+
}
|
|
43
|
+
function b64(buf) {
|
|
44
|
+
const arr = new Uint8Array(buf);
|
|
45
|
+
let out = '';
|
|
46
|
+
for (let i = 0; i < arr.length; i++)
|
|
47
|
+
out += String.fromCharCode(arr[i]);
|
|
48
|
+
return btoa(out);
|
|
49
|
+
}
|
|
50
|
+
function pemFromSpki(spki) {
|
|
51
|
+
const b = b64(spki).replace(/(.{64})/g, '$1\n').trim();
|
|
52
|
+
return `-----BEGIN PUBLIC KEY-----\n${b}\n-----END PUBLIC KEY-----\n`;
|
|
53
|
+
}
|
|
54
|
+
async function sha256Hex(c, text) {
|
|
55
|
+
const d = await c.subtle.digest('SHA-256', bytesOf(text));
|
|
56
|
+
return [...new Uint8Array(d)].map((x) => x.toString(16).padStart(2, '0')).join('');
|
|
57
|
+
}
|
|
58
|
+
/** 取/建设备密钥 (私钥只以 JWK 存在本机 storage; 永不上传) */
|
|
59
|
+
export async function loadOrCreateDeviceKey(storage, c) {
|
|
60
|
+
const cobj = cryptoOf(c);
|
|
61
|
+
if (!cobj?.subtle)
|
|
62
|
+
throw new Error('device_signing_unavailable: 本机没有 WebCrypto');
|
|
63
|
+
const raw = storage.getItem(K_DEVICE);
|
|
64
|
+
if (raw) {
|
|
65
|
+
try {
|
|
66
|
+
const parsed = JSON.parse(raw);
|
|
67
|
+
if (parsed?.privateKeyJwk && parsed?.publicKeyPem && parsed?.deviceId)
|
|
68
|
+
return parsed;
|
|
69
|
+
}
|
|
70
|
+
catch { /* 坏了就重建 (旧私钥丢失 → 之前签的授权在桌面仍有效, 只是不能再签新的) */ }
|
|
71
|
+
}
|
|
72
|
+
let pair;
|
|
73
|
+
try {
|
|
74
|
+
pair = (await cobj.subtle.generateKey({ name: 'Ed25519' }, true, ['sign', 'verify']));
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
throw new Error(`device_signing_unavailable: ${String(err?.message || err)}`);
|
|
78
|
+
}
|
|
79
|
+
const publicKeyPem = pemFromSpki(await cobj.subtle.exportKey('spki', pair.publicKey));
|
|
80
|
+
const privateKeyJwk = (await cobj.subtle.exportKey('jwk', pair.privateKey));
|
|
81
|
+
const deviceId = `dev-${(await sha256Hex(cobj, publicKeyPem)).slice(0, 12)}`;
|
|
82
|
+
const material = { deviceId, publicKeyPem, privateKeyJwk };
|
|
83
|
+
storage.setItem(K_DEVICE, JSON.stringify(material));
|
|
84
|
+
return material;
|
|
85
|
+
}
|
|
86
|
+
async function importPrivate(storage, c) {
|
|
87
|
+
const k = await loadOrCreateDeviceKey(storage, c);
|
|
88
|
+
return c.subtle.importKey('jwk', k.privateKeyJwk, { name: 'Ed25519' }, false, ['sign']);
|
|
89
|
+
}
|
|
90
|
+
/** 用设备私钥签一条 Grant (核心: 手机确认 → 桌面才认) */
|
|
91
|
+
export async function signGrantOnDevice(grant, storage, c) {
|
|
92
|
+
const cobj = cryptoOf(c);
|
|
93
|
+
const key = await importPrivate(storage, cobj);
|
|
94
|
+
const payload = canonicalGrantPayload(grant);
|
|
95
|
+
const sig = await cobj.subtle.sign({ name: 'Ed25519' }, key, bytesOf(payload));
|
|
96
|
+
const dev = await loadOrCreateDeviceKey(storage, cobj);
|
|
97
|
+
return { deviceId: dev.deviceId, alg: 'ed25519', payloadHash: await sha256Hex(cobj, payload), sig: b64(sig) };
|
|
98
|
+
}
|
|
99
|
+
/** 撤销也要签名 (桌面拒收未登记设备的撤销) */
|
|
100
|
+
export async function signRevocationOnDevice(rev, storage, c) {
|
|
101
|
+
const cobj = cryptoOf(c);
|
|
102
|
+
const key = await importPrivate(storage, cobj);
|
|
103
|
+
const payload = canonicalRevocationPayload(rev);
|
|
104
|
+
const sig = await cobj.subtle.sign({ name: 'Ed25519' }, key, bytesOf(payload));
|
|
105
|
+
const dev = await loadOrCreateDeviceKey(storage, cobj);
|
|
106
|
+
return { deviceId: dev.deviceId, alg: 'ed25519', payloadHash: await sha256Hex(cobj, payload), sig: b64(sig) };
|
|
107
|
+
}
|
|
108
|
+
async function post(base, path, body, f) {
|
|
109
|
+
const res = await f(`${String(base).replace(/\/+$/, '')}${path}`, {
|
|
110
|
+
method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body ?? {}),
|
|
111
|
+
});
|
|
112
|
+
let json = null;
|
|
113
|
+
try {
|
|
114
|
+
json = await res.json();
|
|
115
|
+
}
|
|
116
|
+
catch { /* 空响应 */ }
|
|
117
|
+
return { status: res.status, json };
|
|
118
|
+
}
|
|
119
|
+
async function get(base, path, f) {
|
|
120
|
+
const res = await f(`${String(base).replace(/\/+$/, '')}${path}`);
|
|
121
|
+
let json = null;
|
|
122
|
+
try {
|
|
123
|
+
json = await res.json();
|
|
124
|
+
}
|
|
125
|
+
catch { /* 空响应 */ }
|
|
126
|
+
return { status: res.status, json };
|
|
127
|
+
}
|
|
128
|
+
/** 桌面登记手机公钥 (配对阶段; 之后桌面只接受这台设备签的授权) */
|
|
129
|
+
export async function registerDeviceOnDesktop(base, storage, opts = {}) {
|
|
130
|
+
const f = opts.fetchImpl || fetch;
|
|
131
|
+
const dev = await loadOrCreateDeviceKey(storage, opts.cryptoObj);
|
|
132
|
+
const r = await post(base, '/api/contacts/devices', { deviceId: dev.deviceId, publicKeyPem: dev.publicKeyPem, label: opts.label || '手机' }, f);
|
|
133
|
+
if (r.status !== 200 || !r.json?.ok)
|
|
134
|
+
return { ok: false, error: `桌面未接受设备登记: ${r.json?.error || r.status}`, data: dev };
|
|
135
|
+
return { ok: true, data: dev };
|
|
136
|
+
}
|
|
137
|
+
export function saveCapabilityCopy(storage, items) {
|
|
138
|
+
const clean = (items || []).map((c) => ({
|
|
139
|
+
contactId: String(c.contactId || ''), kind: c.kind, displayValue: String(c.displayValue || ''),
|
|
140
|
+
verificationStatus: String(c.verificationStatus || ''), capabilities: [...(c.capabilities || [])],
|
|
141
|
+
provider: c.provider ? String(c.provider) : undefined, state: c.state ? String(c.state) : undefined,
|
|
142
|
+
}));
|
|
143
|
+
storage.setItem(K_CAPS, JSON.stringify(clean));
|
|
144
|
+
}
|
|
145
|
+
export function loadCapabilityCopy(storage) {
|
|
146
|
+
try {
|
|
147
|
+
const v = JSON.parse(storage.getItem(K_CAPS) || '[]');
|
|
148
|
+
return Array.isArray(v) ? v : [];
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
return [];
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
export function pendingQueue(storage) {
|
|
155
|
+
try {
|
|
156
|
+
const v = JSON.parse(storage.getItem(K_QUEUE) || '[]');
|
|
157
|
+
return Array.isArray(v) ? v : [];
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
return [];
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
function setQueue(storage, q) { storage.setItem(K_QUEUE, JSON.stringify(q.slice(-20))); }
|
|
164
|
+
/** 桌面在线时把排队中的授权补同步上去 */
|
|
165
|
+
export async function flushQueuedGrants(base, storage, opts = {}) {
|
|
166
|
+
const f = opts.fetchImpl || fetch;
|
|
167
|
+
const q = pendingQueue(storage);
|
|
168
|
+
const keep = [];
|
|
169
|
+
const results = [];
|
|
170
|
+
let sent = 0, failed = 0;
|
|
171
|
+
for (const item of q) {
|
|
172
|
+
try {
|
|
173
|
+
const r = await post(base, '/api/contacts/grants/sync', { grant: { ...item.grant, signature: item.signature } }, f);
|
|
174
|
+
if (r.status === 200 && r.json?.ok) {
|
|
175
|
+
sent++;
|
|
176
|
+
results.push({ grantId: item.grant.grantId, ok: true });
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
failed++;
|
|
180
|
+
keep.push(item);
|
|
181
|
+
results.push({ grantId: item.grant.grantId, ok: false, error: r.json?.code || r.status });
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
failed++;
|
|
185
|
+
keep.push(item);
|
|
186
|
+
results.push({ grantId: item.grant.grantId, ok: false, error: 'network' });
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
setQueue(storage, keep);
|
|
190
|
+
return { sent, failed, results };
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* 手机确认授权 → 设备签名 → 送桌面验签。
|
|
194
|
+
* 桌面离线时: 授权进本地队列 + 返回 queued=true (明确告诉用户"等桌面在线时同步", 不假装已生效)。
|
|
195
|
+
*/
|
|
196
|
+
export async function authorizeFromPhone(input) {
|
|
197
|
+
const c = cryptoOf(input.cryptoObj);
|
|
198
|
+
if (!ed25519Available(c || undefined)) {
|
|
199
|
+
return { ok: false, error: 'device_signing_unavailable: 本机 WebView 不支持 Ed25519 设备签名 —— 请在桌面端授权 (或升级系统 WebView)' };
|
|
200
|
+
}
|
|
201
|
+
const dev = await loadOrCreateDeviceKey(input.storage, c);
|
|
202
|
+
const preset = presetForChoice(input.choice);
|
|
203
|
+
const grant = {
|
|
204
|
+
grantId: `gr-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`,
|
|
205
|
+
identityId: input.identityId || `sid-phone-${dev.deviceId.slice(-6)}`,
|
|
206
|
+
ownerDid: input.ownerDid,
|
|
207
|
+
...preset,
|
|
208
|
+
grantedAt: new Date().toISOString(),
|
|
209
|
+
grantedBy: input.grantedBy || 'leo',
|
|
210
|
+
grantedVia: 'mobile',
|
|
211
|
+
deviceIds: [dev.deviceId],
|
|
212
|
+
status: 'active',
|
|
213
|
+
grantVersion: 1,
|
|
214
|
+
};
|
|
215
|
+
const signature = await signGrantOnDevice(grant, input.storage, c);
|
|
216
|
+
const f = input.fetchImpl || fetch;
|
|
217
|
+
// 先登记设备 (幂等), 再送授权
|
|
218
|
+
const reg = await registerDeviceOnDesktop(input.base, input.storage, { fetchImpl: f, cryptoObj: c }).catch(() => ({ ok: false }));
|
|
219
|
+
if (!reg.ok) {
|
|
220
|
+
const q = pendingQueue(input.storage);
|
|
221
|
+
q.push({ grant, signature, queuedAt: new Date().toISOString() });
|
|
222
|
+
setQueue(input.storage, q);
|
|
223
|
+
return { ok: false, queued: true, error: `桌面暂不可达 → 授权已存在手机, 待桌面在线时自动同步 (${reg.error || 'offline'})`,
|
|
224
|
+
data: { grantId: grant.grantId, level: grant.level, signature },
|
|
225
|
+
note: '桌面不在线时不假装已生效: 授权在本地队列里, 桌面一上线就补同步' };
|
|
226
|
+
}
|
|
227
|
+
const r = await post(input.base, '/api/contacts/grants/sync', { grant: { ...grant, signature } }, f);
|
|
228
|
+
if (r.status === 200 && r.json?.ok) {
|
|
229
|
+
return { ok: true, data: { grantId: grant.grantId, level: grant.level, signature }, note: '桌面已验签接受' };
|
|
230
|
+
}
|
|
231
|
+
const q = pendingQueue(input.storage);
|
|
232
|
+
q.push({ grant, signature, queuedAt: new Date().toISOString() });
|
|
233
|
+
setQueue(input.storage, q);
|
|
234
|
+
return { ok: false, queued: true, error: `桌面拒绝/未接受: ${r.json?.code || r.json?.reason || r.status}`,
|
|
235
|
+
data: { grantId: grant.grantId, level: grant.level, signature },
|
|
236
|
+
note: '已保存在手机本地队列 (不会因为失败就当成已授权)' };
|
|
237
|
+
}
|
|
238
|
+
export async function revokeFromPhone(opts) {
|
|
239
|
+
const c = cryptoOf(opts.cryptoObj);
|
|
240
|
+
if (!ed25519Available(c || undefined))
|
|
241
|
+
return { ok: false, error: 'device_signing_unavailable: 本机不支持设备签名, 撤销需在桌面端进行' };
|
|
242
|
+
const revokedAt = new Date().toISOString();
|
|
243
|
+
const payload = { grantId: opts.grantId, grantVersion: opts.version || 1, revokedAt, by: 'mobile' };
|
|
244
|
+
const signature = await signRevocationOnDevice(payload, opts.storage, c);
|
|
245
|
+
const f = opts.fetchImpl || fetch;
|
|
246
|
+
const r = await post(opts.base, '/api/contacts/grants/revoke-sync', { grantId: opts.grantId, by: 'mobile', reason: opts.reason, version: payload.grantVersion, revokedAt, signature }, f);
|
|
247
|
+
if (r.status === 200 && r.json?.ok)
|
|
248
|
+
return { ok: true, data: { grantId: opts.grantId }, note: '桌面已验签并立即失效' };
|
|
249
|
+
return { ok: false, error: `撤销未送达: ${r.json?.code || r.json?.error || r.status}`, note: '桌面不在线时撤销**不会**被当作已完成 —— 请在桌面在线后重试 (或桌面端撤销)' };
|
|
250
|
+
}
|
|
251
|
+
/** 从桌面读联系方式/授权/待批准 (桌面离线 → 退回手机本地 capability 副本, 明确标注) */
|
|
252
|
+
export async function loadFromDesktop(base, storage, opts = {}) {
|
|
253
|
+
const f = opts.fetchImpl || fetch;
|
|
254
|
+
if (!base) {
|
|
255
|
+
const caps = loadCapabilityCopy(storage);
|
|
256
|
+
return { ok: false, error: 'desktop_offline', data: { contacts: caps, grants: [], effective: '桌面不在线 (显示手机本地副本)', approvals: [], waiting: [] },
|
|
257
|
+
note: '以下是你手机上保存的能力副本 (不是桌面实时状态)' };
|
|
258
|
+
}
|
|
259
|
+
try {
|
|
260
|
+
const a = await get(base, '/api/contacts', f);
|
|
261
|
+
const b = await get(base, '/api/contacts/grants', f);
|
|
262
|
+
if (a.status !== 200 && b.status !== 200)
|
|
263
|
+
return { ok: false, error: `desktop_http_${a.status || b.status}` };
|
|
264
|
+
const view = {
|
|
265
|
+
contacts: a.json?.contacts || [], grants: b.json?.grants || [], effective: b.json?.effective || '',
|
|
266
|
+
approvals: a.json?.approvals || [], waiting: a.json?.waiting || [],
|
|
267
|
+
};
|
|
268
|
+
saveCapabilityCopy(storage, (view.contacts || []).filter((c) => c.capabilities?.includes('send')).map((c) => ({
|
|
269
|
+
contactId: c.contactId, kind: c.kind, displayValue: c.displayValue, verificationStatus: c.status,
|
|
270
|
+
capabilities: c.capabilities, provider: c.provider, state: c.status,
|
|
271
|
+
})));
|
|
272
|
+
return { ok: true, data: view };
|
|
273
|
+
}
|
|
274
|
+
catch (err) {
|
|
275
|
+
const caps = loadCapabilityCopy(storage);
|
|
276
|
+
return { ok: false, error: 'desktop_offline', data: { contacts: caps, grants: [], effective: '桌面不在线 (显示手机本地副本)', approvals: [], waiting: [] },
|
|
277
|
+
note: `连不上桌面 (${String(err?.message || err).slice(0, 60)}) —— 显示本地副本` };
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
/** 绑定/验证 (手机上输入, 桌面执行 —— 明文只走这一条 HTTPS/局域网请求, 不落手机存储) */
|
|
281
|
+
export async function bindFromPhone(base, opts, storage, f) {
|
|
282
|
+
const impl = f || fetch;
|
|
283
|
+
if (!base)
|
|
284
|
+
return { ok: false, error: 'desktop_offline: 绑定需要桌面端在线 (桌面负责落盘与验证码通道)' };
|
|
285
|
+
const r = await post(base, '/api/contacts/bind', { kind: opts.kind, value: opts.value, region: opts.region }, impl);
|
|
286
|
+
if (r.status === 200 && r.json?.ok)
|
|
287
|
+
return { ok: true, data: r.json };
|
|
288
|
+
return { ok: false, error: r.json?.error || `HTTP ${r.status}` };
|
|
289
|
+
}
|
|
290
|
+
export async function verifyFromPhone(base, opts, storage, f) {
|
|
291
|
+
const impl = f || fetch;
|
|
292
|
+
if (!base)
|
|
293
|
+
return { ok: false, error: 'desktop_offline: 验证需要桌面端在线' };
|
|
294
|
+
const r = await post(base, '/api/contacts/verify', { contactId: opts.contactId, challengeId: opts.challengeId, code: opts.code }, impl);
|
|
295
|
+
if (r.status === 200 && r.json?.ok)
|
|
296
|
+
return { ok: true, data: r.json };
|
|
297
|
+
return { ok: false, error: r.json?.error || `HTTP ${r.status}` };
|
|
298
|
+
}
|
|
299
|
+
/** 手机上批准高风险联系 (展示待发内容 → 批准/拒绝) */
|
|
300
|
+
export async function decideApprovalFromPhone(base, opts, f) {
|
|
301
|
+
const impl = f || fetch;
|
|
302
|
+
if (!base)
|
|
303
|
+
return { ok: false, error: 'desktop_offline: 批准需要桌面端在线 (手机不在线时不会假装已批准)' };
|
|
304
|
+
const r = await post(base, `/api/contacts/approvals/${encodeURIComponent(opts.consentId)}/${opts.action}`, { by: 'leo', via: 'mobile', body: opts.body, reason: opts.reason }, impl);
|
|
305
|
+
if (r.status === 200 && r.json?.ok)
|
|
306
|
+
return { ok: true, data: r.json };
|
|
307
|
+
return { ok: false, error: r.json?.error || `HTTP ${r.status}` };
|
|
308
|
+
}
|
|
309
|
+
export function buildPhoneCard(view, opts) {
|
|
310
|
+
return {
|
|
311
|
+
title: '让 Bolloon 代表你联系外部的人',
|
|
312
|
+
effective: view?.effective || opts.offline || '未知',
|
|
313
|
+
contacts: (view?.contacts || []).map((c) => ({
|
|
314
|
+
displayValue: c.displayValue || '', kind: c.kind || '', state: c.status || c.verificationStatus || '',
|
|
315
|
+
label: c.capabilities?.includes('send') ? '可联系' : '不可联系',
|
|
316
|
+
})),
|
|
317
|
+
approvals: (view?.approvals || []).map((a) => ({
|
|
318
|
+
consentId: a.consentId, contactName: a.contactName, channel: a.channel, subject: a.subject,
|
|
319
|
+
bodyPreview: a.bodyPreview || '', reason: a.reason, reallySent: !!a.reallySent,
|
|
320
|
+
})),
|
|
321
|
+
choices: [
|
|
322
|
+
{ id: 'task_once', label: '仅本次任务' },
|
|
323
|
+
{ id: 'persistent', label: '长期使用 (推荐)' },
|
|
324
|
+
{ id: 'full_contact_access', label: '完全授权联系方式能力' },
|
|
325
|
+
],
|
|
326
|
+
willNotGet: ['读取全部邮箱', '读取通讯录', '群发消息', '自动支付/转账', '代表你签署合同', '拿到手机号/邮箱明文'],
|
|
327
|
+
deviceSigning: opts.deviceSigning,
|
|
328
|
+
};
|
|
329
|
+
}
|