@0xmaxma/claude-gateway 1.4.8 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/README.md +25 -2
  2. package/config.template.json +1 -0
  3. package/dist/agent/runner.d.ts +14 -0
  4. package/dist/agent/runner.d.ts.map +1 -1
  5. package/dist/agent/runner.js +59 -0
  6. package/dist/agent/runner.js.map +1 -1
  7. package/dist/api/gateway-router.d.ts +20 -0
  8. package/dist/api/gateway-router.d.ts.map +1 -1
  9. package/dist/api/gateway-router.js +214 -0
  10. package/dist/api/gateway-router.js.map +1 -1
  11. package/dist/api/line-webhook-router.d.ts +5 -0
  12. package/dist/api/line-webhook-router.d.ts.map +1 -1
  13. package/dist/api/line-webhook-router.js +63 -0
  14. package/dist/api/line-webhook-router.js.map +1 -1
  15. package/dist/apps/agent-manager.d.ts.map +1 -1
  16. package/dist/apps/agent-manager.js +14 -0
  17. package/dist/apps/agent-manager.js.map +1 -1
  18. package/dist/cli-viewer/pairing-store.d.ts +117 -0
  19. package/dist/cli-viewer/pairing-store.d.ts.map +1 -0
  20. package/dist/cli-viewer/pairing-store.js +196 -0
  21. package/dist/cli-viewer/pairing-store.js.map +1 -0
  22. package/dist/cli-viewer/telegram-initdata.d.ts +21 -0
  23. package/dist/cli-viewer/telegram-initdata.d.ts.map +1 -0
  24. package/dist/cli-viewer/telegram-initdata.js +74 -0
  25. package/dist/cli-viewer/telegram-initdata.js.map +1 -0
  26. package/dist/cli-viewer/url.d.ts +13 -0
  27. package/dist/cli-viewer/url.d.ts.map +1 -0
  28. package/dist/cli-viewer/url.js +27 -0
  29. package/dist/cli-viewer/url.js.map +1 -0
  30. package/dist/session/process.d.ts.map +1 -1
  31. package/dist/session/process.js +7 -0
  32. package/dist/session/process.js.map +1 -1
  33. package/dist/types.d.ts +10 -0
  34. package/dist/types.d.ts.map +1 -1
  35. package/dist/ui/cli-viewer-ui.d.ts +37 -0
  36. package/dist/ui/cli-viewer-ui.d.ts.map +1 -0
  37. package/dist/ui/cli-viewer-ui.js +274 -0
  38. package/dist/ui/cli-viewer-ui.js.map +1 -0
  39. package/mcp/tools/discord/module.ts +99 -1
  40. package/mcp/tools/telegram/receiver-server.ts +41 -1
  41. package/package.json +1 -1
@@ -102,6 +102,19 @@ class AgentManager {
102
102
  uid = os.userInfo().uid;
103
103
  }
104
104
  catch { /* use 1000 */ }
105
+ // Mount the agent's media directory into the container at the SAME absolute
106
+ // path as the host. The gateway hands the agent uploaded-image paths (and the
107
+ // browser-screenshot dir) as raw host paths under <agentsDir>/<agentName>/media
108
+ // — a sibling of workspace, so outside the /workspace mount and never
109
+ // translated. Mounting it at the identical path lets those raw paths resolve
110
+ // inside the container with zero translation. Pre-create it (like ~/.claude
111
+ // above) so Docker bind-mounts an existing uid-owned dir instead of a
112
+ // root-owned one; :rw because browser screenshots write here. realpathSync
113
+ // gives the Docker daemon the real source while the destination stays the
114
+ // host-identical path the agent is handed.
115
+ const agentMediaDir = path.join(this.agentsDir, agentName, 'media');
116
+ fs.mkdirSync(agentMediaDir, { recursive: true });
117
+ const agentMediaSource = fs.realpathSync(agentMediaDir);
105
118
  // Write Dockerfile.agent: install curl + pre-create ~/.claude owned by host uid so
106
119
  // Docker bind-mounts land inside a uid-1000-owned dir and Claude Code can freely
107
120
  // create subdirs (session-env, todos, etc.) at runtime without cap_drop: ALL blocking chown.
@@ -129,6 +142,7 @@ class AgentManager {
129
142
  `${homeDir}/.claude.json:${homeDir}/.claude.json:ro`,
130
143
  `${homeDir}/.claude/settings.json:${homeDir}/.claude/settings.json:ro`,
131
144
  `${workspaceDir}:/workspace`,
145
+ `${agentMediaSource}:${agentMediaDir}:rw`,
132
146
  ],
133
147
  };
134
148
  const services = (compose.services ?? {});
@@ -1 +1 @@
1
- {"version":3,"file":"agent-manager.js","sourceRoot":"","sources":["../../src/apps/agent-manager.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,4CAA8B;AAC9B,gDAAkC;AAClC,4CAA8B;AAC9B,2DAA8C;AAC9C,sDAA2B;AAiB3B,iFAAiF;AAEjF,MAAM,mBAAmB,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,iBAAiB,EAAE,aAAa,CAAC,CAAC;AACtF,MAAM,kBAAkB,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,iBAAiB,EAAE,QAAQ,CAAC,CAAC;AAEhF,gFAAgF;AAEhF,MAAa,YAAY;IAIvB,YACmB,aAAqB,mBAAmB,EACxC,YAAoB,kBAAkB;QADtC,eAAU,GAAV,UAAU,CAA8B;QACxC,cAAS,GAAT,SAAS,CAA6B;QALzD,qEAAqE;QAC7D,eAAU,GAAkB,OAAO,CAAC,OAAO,EAAE,CAAC;IAKnD,CAAC;IAEI,KAAK,CAAC,cAAc,CAAI,EAAW;QACzC,IAAI,OAAoB,CAAC;QACzB,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC;QAC7B,IAAI,CAAC,UAAU,GAAG,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,EAAE,GAAG,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7D,MAAM,IAAI,CAAC;QACX,IAAI,CAAC;YACH,OAAO,EAAE,EAAE,CAAC;QACd,CAAC;gBAAS,CAAC;YACT,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAED,8EAA8E;IAE9E;;;OAGG;IACH,gBAAgB;QACd,MAAM,GAAG,GAAG,CAAC,GAAW,EAAU,EAAE,CAClC,IAAA,6BAAQ,EAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;QAEzD,MAAM,SAAS,GAAG,GAAG,CAAC,cAAc,CAAC,CAAC;QACtC,MAAM,aAAa,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;QACjD,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC;QACnD,MAAM,OAAO,GAAG,GAAG,CAAC,aAAa,CAAC,CAAC;QAEnC,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;IACxD,CAAC;IAED;;;;;;OAMG;IACH,kBAAkB,CAAC,KAAe;QAChC,IAAI,CAAC,KAAK,CAAC,gBAAgB,IAAI,CAAC,KAAK,CAAC,UAAU;YAAE,OAAO;QAEzD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,oBAAoB,CAAC,CAAC;QACvE,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAClD,MAAM,OAAO,GAAG,iBAAI,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,iBAAI,CAAC,cAAc,EAAE,CAA4B,CAAC;QAE3F,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,KAAK,CAAC,gBAAgB,CAAC;QACvE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC,UAAU,CAAC;QACzD,MAAM,OAAO,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC;QAC7B,gFAAgF;QAChF,0EAA0E;QAC1E,MAAM,YAAY,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC;QAEjF,IAAI,GAAG,GAAG,IAAI,CAAC;QACf,IAAI,CAAC;YAAC,GAAG,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,cAAc,CAAC,CAAC;QAEzD,mFAAmF;QACnF,iFAAiF;QACjF,6FAA6F;QAC7F,MAAM,mBAAmB,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,kBAAkB,CAAC,CAAC;QAC7E,EAAE,CAAC,aAAa,CAAC,mBAAmB,EAAE;YACpC,yBAAyB;YACzB,0EAA0E;YAC1E,uCAAuC;YACvC,mBAAmB,OAAO,aAAa;YACvC,mBAAmB,GAAG,IAAI,GAAG,IAAI,OAAO,EAAE;SAC3C,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;QAErB,MAAM,YAAY,GAAG;YACnB,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,WAAW,EAAE,UAAU,EAAE,kBAAkB,EAAE;YACrE,IAAI,EAAE,GAAG,GAAG,IAAI,GAAG,EAAE;YACrB,OAAO,EAAE,gBAAgB;YACzB,cAAc,EAAE,GAAG,KAAK,CAAC,IAAI,QAAQ;YACrC,OAAO,EAAE,gBAAgB;YACzB,QAAQ,EAAE,CAAC,KAAK,CAAC;YACjB,YAAY,EAAE,CAAC,mBAAmB,CAAC;YACnC,QAAQ,EAAE,MAAM;YAChB,OAAO,EAAE;gBACP,GAAG,SAAS,IAAI,SAAS,KAAK;gBAC9B,GAAG,OAAO,mBAAmB;gBAC7B,GAAG,OAAO,IAAI,OAAO,KAAK;gBAC1B,GAAG,OAAO,iBAAiB,OAAO,kBAAkB;gBACpD,GAAG,OAAO,0BAA0B,OAAO,2BAA2B;gBACtE,GAAG,YAAY,aAAa;aAC7B;SACF,CAAC;QAEF,MAAM,QAAQ,GAAG,CAAC,OAAO,CAAC,QAAQ,IAAI,EAAE,CAA4B,CAAC;QACrE,QAAQ,CAAC,OAAO,CAAC,GAAG,YAAY,CAAC;QACjC,OAAO,CAAC,UAAU,CAAC,GAAG,QAAQ,CAAC;QAE/B,EAAE,CAAC,aAAa,CAAC,WAAW,EAAE,iBAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;IAChF,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,WAAW,CAAC,KAAe;QAC/B,IAAI,CAAC,KAAK,CAAC,gBAAgB,IAAI,CAAC,KAAK,CAAC,UAAU;YAAE,OAAO;QAEzD,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,KAAK,CAAC,gBAAgB,CAAC;QACvE,uFAAuF;QACvF,gGAAgG;QAChG,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QACtD,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;QACvD,MAAM,SAAS,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC;QAE9E,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE5C,IAAI,CAAC;YAAC,EAAE,CAAC,MAAM,CAAC,aAAa,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;QAC1F,EAAE,CAAC,WAAW,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;QAEzC,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,iBAAiB,CAAC,SAAS,EAAE;gBACtC,EAAE,EAAE,SAAS;gBACb,IAAI,EAAE,WAAW;gBACjB,WAAW,EAAE,iBAAiB,KAAK,CAAC,IAAI,EAAE;gBAC1C,SAAS,EAAE,GAAG,KAAK,CAAC,IAAI,QAAQ;gBAChC,SAAS,EAAE,KAAK,CAAC,UAAU,CAAC,SAAS;gBACrC,SAAS,EAAE,aAAa;gBACxB,GAAG,EAAE,EAAE;gBACP,WAAW,EAAE,IAAI;gBACjB,MAAM,EAAE;oBACN,KAAK,EAAE,mBAAmB;oBAC1B,UAAU,EAAE,EAAE;iBACf;aACF,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,6EAA6E;YAC7E,IAAI,CAAC;gBAAC,EAAE,CAAC,MAAM,CAAC,aAAa,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC;YAC9E,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,WAAW,CAAC,KAAe;QAC/B,IAAI,CAAC,KAAK,CAAC,gBAAgB;YAAE,OAAO;QACpC,MAAM,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAC5D,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,iBAAiB,CAAC,SAAiB;QACvC,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;QACxE,IAAI,CAAC;YAAC,EAAE,CAAC,MAAM,CAAC,aAAa,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC;QAC/E,MAAM,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;IAC1C,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,eAAe,CAAC,QAAsB;QAC1C,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,MAAM,MAAM,GAA0C,EAAE,CAAC;QACzD,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,IAAI,GAAG,CAAC,gBAAgB,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBACrD,IAAI,CAAC;oBACH,MAAM,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;gBAC9B,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE,KAAK,EAAG,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;gBAChE,CAAC;YACH,CAAC;QACH,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;OAGG;IACH,YAAY,CAAC,SAAiB;QAC5B,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;QACnD,IAAI,CAAC,SAAS;YAAE,OAAO,IAAI,CAAC;QAC5B,IAAI,CAAC;YACH,OAAO,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,EAAE,OAAO,CAAC,CAAC;QACrE,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED;;OAEG;IACH,aAAa,CAAC,SAAiB,EAAE,OAAe;QAC9C,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;QACnD,IAAI,CAAC,SAAS;YAAE,OAAO;QACvB,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACxE,CAAC;IAEO,gBAAgB,CAAC,SAAiB;QACxC,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,WAAW,CAAC,CAAC;QAC5F,OAAO,KAAK,CAAC,CAAC,CAAE,KAAK,CAAC,WAAW,CAAY,CAAC,CAAC,CAAC,IAAI,CAAC;IACvD,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,eAAe,CAAC,SAAiB;QACrC,OAAO,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE;YAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;YACjC,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAC9B,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,WAAW,CAC1D,CAAC;YACF,OAAO,KAAK,CAAC,CAAC,CAAE,KAAK,CAAC,IAAI,CAAY,CAAC,CAAC,CAAC,IAAI,CAAC;QAChD,CAAC,CAAC,CAAC;IACL,CAAC;IAED,8EAA8E;IAEtE,UAAU;QAChB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;YACtD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAc,CAAC;YAC5C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC;gBAAE,MAAM,CAAC,MAAM,GAAG,EAAE,CAAC;YACtD,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;QACtE,CAAC;IACH,CAAC;IAEO,WAAW,CAAC,MAAiB;QACnC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACjE,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,UAAU,QAAQ,OAAO,CAAC,GAAG,EAAE,CAAC;QACpD,EAAE,CAAC,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QAChE,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IACtC,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAAC,OAAe,EAAE,KAA8B;QAC7E,OAAO,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE;YAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;YACjC,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,CAAC;YAChE,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC;gBACb,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YAC7B,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC5B,CAAC;YACD,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAC3B,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAAC,OAAe;QAC7C,OAAO,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE;YAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;YACjC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,CAAC;YACjE,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAC3B,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AA7QD,oCA6QC"}
1
+ {"version":3,"file":"agent-manager.js","sourceRoot":"","sources":["../../src/apps/agent-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,117 @@
1
+ /**
2
+ * Chat channel a `/cli` pairing originated from. The channel already
3
+ * authenticated the requesting user (allowlist / pairing gate) before a pairing
4
+ * is ever created, so the channel + user id recorded here is a trusted binding.
5
+ */
6
+ export type CliChannel = 'telegram' | 'discord' | 'line';
7
+ /** Runtime guard for the trusted channel set (payloads cross a process boundary). */
8
+ export declare function isCliChannel(value: unknown): value is CliChannel;
9
+ /**
10
+ * Pairing lifecycle:
11
+ * pending — created by `/cli`, waiting for proof (chat-approve or initData).
12
+ * approved — the authenticated chat user approved (or initData verified).
13
+ * consumed — a browser exchanged the approval for an access session cookie.
14
+ * denied — the user explicitly rejected.
15
+ */
16
+ export type CliPairingStatus = 'pending' | 'approved' | 'consumed' | 'denied';
17
+ export interface CliPairing {
18
+ /** Random, URL-safe id in the `/cli/<id>` link. NOT a secret on its own —
19
+ * approval on an authenticated channel is still required to unlock. */
20
+ pairingId: string;
21
+ agentId: string;
22
+ channel: CliChannel;
23
+ /** Channel user id the pairing was minted for. Approval must come from this
24
+ * same user, and (Telegram) initData's user id must match it. */
25
+ userId: string;
26
+ /** Short human-readable code shown both in chat and in the browser so the
27
+ * operator can visually confirm the browser they opened is the right one. */
28
+ code: string;
29
+ status: CliPairingStatus;
30
+ /** Bound to the first browser that opens the link (first-writer-wins). The
31
+ * access session is only ever issued to the browser holding this token, so a
32
+ * later opener (e.g. a leaked link) cannot ride someone else's approval. */
33
+ browserToken?: string;
34
+ /** Issued once, at consume time; carried by the `cli_session` cookie and
35
+ * resolved back to this (agent-scoped) pairing on every viewer request. */
36
+ accessToken?: string;
37
+ createdAt: number;
38
+ /** Approval window — a pending pairing past this is dead. */
39
+ expiresAt: number;
40
+ /** Access session lifetime — set at consume; the viewer is locked out after. */
41
+ accessExpiresAt?: number;
42
+ }
43
+ export interface CreatedPairing {
44
+ pairingId: string;
45
+ code: string;
46
+ }
47
+ /**
48
+ * In-memory store of `/cli` webview pairings (device-authorization flow).
49
+ *
50
+ * A single process-wide instance is shared by the runner's callback handler
51
+ * (which creates and approves pairings on behalf of the authenticated chat) and
52
+ * the gateway HTTP routes (which serve the browser side). Mirrors the singleton
53
+ * shape of `pty-stream-registry` so both sides reference one source of truth
54
+ * without threading a dependency through constructors.
55
+ *
56
+ * Security model: the pairing id in the URL is not a credential. Unlocking a
57
+ * viewer requires EITHER a chat approval from the pairing's own user (Discord /
58
+ * LINE) OR a verified Telegram initData whose user id matches — both gated by
59
+ * the channel's existing allowlist. The resulting access session is scoped to a
60
+ * single agent; it never carries admin/dashboard authority.
61
+ */
62
+ export declare class CliPairingStore {
63
+ private readonly pairings;
64
+ /** Create a pending pairing for an authenticated chat user. */
65
+ create(agentId: string, channel: CliChannel, userId: string): CreatedPairing;
66
+ /** Raw lookup (no expiry filtering) — callers decide how to treat state. */
67
+ get(pairingId: string): CliPairing | undefined;
68
+ /** True when a pairing is still within its pre-consume approval window. */
69
+ private isLive;
70
+ /**
71
+ * Bind (or re-check) the browser that opened the link. First-writer-wins: the
72
+ * first browser to GET the link owns the pairing. A different browser (no or
73
+ * mismatched token) gets `'already'` — a leaked/forwarded link opened
74
+ * elsewhere is visibly rejected rather than silently sharing the session.
75
+ */
76
+ bindBrowser(pairingId: string, browserToken: string): 'bound' | 'already' | 'gone';
77
+ /**
78
+ * Approve via an authenticated chat action (Discord / LINE) or a verified
79
+ * Telegram initData. The approving user and channel must match the pairing.
80
+ */
81
+ approve(pairingId: string, channel: CliChannel, userId: string): 'ok' | 'mismatch' | 'gone';
82
+ /** Explicit rejection from the authenticated chat user. */
83
+ deny(pairingId: string, channel: CliChannel, userId: string): 'ok' | 'mismatch' | 'gone';
84
+ /**
85
+ * Exchange an approval for an access session. Returns the access token exactly
86
+ * once per pairing. `requireBrowserToken` enforces that only the bound browser
87
+ * (Discord / LINE device flow) may consume; the Telegram initData path proves
88
+ * identity cryptographically in the same request and passes it through here
89
+ * with the freshly-bound token.
90
+ */
91
+ consume(pairingId: string, browserToken: string): {
92
+ accessToken: string;
93
+ } | null;
94
+ /**
95
+ * Issue an access session for the Telegram initData fast-path. Identity is
96
+ * already proven cryptographically (the caller verified the signed initData and
97
+ * that its user matches the pairing), so — unlike the Discord/LINE device flow —
98
+ * this does NOT depend on the first-writer browser binding: a Telegram Mini App
99
+ * webview may not replay the `cli_pair` cookie set on the initial page load, so
100
+ * we (re)bind this browser and issue. Idempotent for the same browser.
101
+ */
102
+ issueAccessForVerifiedUser(pairingId: string, browserToken: string): {
103
+ accessToken: string;
104
+ } | null;
105
+ /**
106
+ * Resolve an access-session token to its (agent-scoped) pairing. Used by every
107
+ * viewer request to authorize and to learn which single agent it may touch.
108
+ */
109
+ resolveAccess(accessToken: string): CliPairing | null;
110
+ /** Drop dead pairings: expired-and-unconsumed, or access sessions past TTL. */
111
+ prune(): void;
112
+ /** Test/introspection helper. */
113
+ size(): number;
114
+ }
115
+ /** Process-wide singleton shared by the runner callback and the gateway routes. */
116
+ export declare const cliPairingStore: CliPairingStore;
117
+ //# sourceMappingURL=pairing-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pairing-store.d.ts","sourceRoot":"","sources":["../../src/cli-viewer/pairing-store.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,SAAS,GAAG,MAAM,CAAC;AAEzD,qFAAqF;AACrF,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,UAAU,CAEhE;AAED;;;;;;GAMG;AACH,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,UAAU,GAAG,UAAU,GAAG,QAAQ,CAAC;AAE9E,MAAM,WAAW,UAAU;IACzB;4EACwE;IACxE,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,UAAU,CAAC;IACpB;sEACkE;IAClE,MAAM,EAAE,MAAM,CAAC;IACf;kFAC8E;IAC9E,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,gBAAgB,CAAC;IACzB;;iFAE6E;IAC7E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;gFAC4E;IAC5E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,6DAA6D;IAC7D,SAAS,EAAE,MAAM,CAAC;IAClB,gFAAgF;IAChF,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAOD,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiC;IAE1D,+DAA+D;IAC/D,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,cAAc;IAmB5E,4EAA4E;IAC5E,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAI9C,2EAA2E;IAC3E,OAAO,CAAC,MAAM;IAId;;;;;OAKG;IACH,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM;IAclF;;;OAGG;IACH,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,UAAU,GAAG,MAAM;IAQ3F,2DAA2D;IAC3D,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,UAAU,GAAG,MAAM;IAQxF;;;;;;OAMG;IACH,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAoBhF;;;;;;;OAOG;IACH,0BAA0B,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAkBnG;;;OAGG;IACH,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI;IAcrD,+EAA+E;IAC/E,KAAK,IAAI,IAAI;IASb,iCAAiC;IACjC,IAAI,IAAI,MAAM;CAGf;AAED,mFAAmF;AACnF,eAAO,MAAM,eAAe,iBAAwB,CAAC"}
@@ -0,0 +1,196 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.cliPairingStore = exports.CliPairingStore = void 0;
7
+ exports.isCliChannel = isCliChannel;
8
+ const crypto_1 = __importDefault(require("crypto"));
9
+ /** Runtime guard for the trusted channel set (payloads cross a process boundary). */
10
+ function isCliChannel(value) {
11
+ return value === 'telegram' || value === 'discord' || value === 'line';
12
+ }
13
+ /** Approval window: how long the operator has to approve after `/cli`. */
14
+ const PAIRING_TTL_MS = 3 * 60 * 1000;
15
+ /** Viewer session lifetime once unlocked. Short — re-run `/cli` to renew. */
16
+ const ACCESS_TTL_MS = 30 * 60 * 1000;
17
+ /**
18
+ * In-memory store of `/cli` webview pairings (device-authorization flow).
19
+ *
20
+ * A single process-wide instance is shared by the runner's callback handler
21
+ * (which creates and approves pairings on behalf of the authenticated chat) and
22
+ * the gateway HTTP routes (which serve the browser side). Mirrors the singleton
23
+ * shape of `pty-stream-registry` so both sides reference one source of truth
24
+ * without threading a dependency through constructors.
25
+ *
26
+ * Security model: the pairing id in the URL is not a credential. Unlocking a
27
+ * viewer requires EITHER a chat approval from the pairing's own user (Discord /
28
+ * LINE) OR a verified Telegram initData whose user id matches — both gated by
29
+ * the channel's existing allowlist. The resulting access session is scoped to a
30
+ * single agent; it never carries admin/dashboard authority.
31
+ */
32
+ class CliPairingStore {
33
+ constructor() {
34
+ this.pairings = new Map();
35
+ }
36
+ /** Create a pending pairing for an authenticated chat user. */
37
+ create(agentId, channel, userId) {
38
+ const pairingId = crypto_1.default.randomBytes(18).toString('hex');
39
+ // 4-digit visual-confirm code (0000–9999). Not a secret — it only helps the
40
+ // operator confirm the browser matches; security rests on channel approval.
41
+ const code = String(crypto_1.default.randomInt(0, 10000)).padStart(4, '0');
42
+ const now = Date.now();
43
+ this.pairings.set(pairingId, {
44
+ pairingId,
45
+ agentId,
46
+ channel,
47
+ userId,
48
+ code,
49
+ status: 'pending',
50
+ createdAt: now,
51
+ expiresAt: now + PAIRING_TTL_MS,
52
+ });
53
+ return { pairingId, code };
54
+ }
55
+ /** Raw lookup (no expiry filtering) — callers decide how to treat state. */
56
+ get(pairingId) {
57
+ return this.pairings.get(pairingId);
58
+ }
59
+ /** True when a pairing is still within its pre-consume approval window. */
60
+ isLive(p) {
61
+ return !!p && p.status !== 'consumed' && p.status !== 'denied' && p.expiresAt > Date.now();
62
+ }
63
+ /**
64
+ * Bind (or re-check) the browser that opened the link. First-writer-wins: the
65
+ * first browser to GET the link owns the pairing. A different browser (no or
66
+ * mismatched token) gets `'already'` — a leaked/forwarded link opened
67
+ * elsewhere is visibly rejected rather than silently sharing the session.
68
+ */
69
+ bindBrowser(pairingId, browserToken) {
70
+ const p = this.pairings.get(pairingId);
71
+ // A consumed pairing is still reachable by its own bound browser (the viewer
72
+ // keeps loading), so allow the matching token through even post-consume.
73
+ if (!p || p.status === 'denied' || (p.status !== 'consumed' && p.expiresAt <= Date.now())) {
74
+ return 'gone';
75
+ }
76
+ if (!p.browserToken) {
77
+ p.browserToken = browserToken;
78
+ return 'bound';
79
+ }
80
+ return p.browserToken === browserToken ? 'bound' : 'already';
81
+ }
82
+ /**
83
+ * Approve via an authenticated chat action (Discord / LINE) or a verified
84
+ * Telegram initData. The approving user and channel must match the pairing.
85
+ */
86
+ approve(pairingId, channel, userId) {
87
+ const p = this.pairings.get(pairingId);
88
+ if (!this.isLive(p))
89
+ return 'gone';
90
+ if (p.channel !== channel || p.userId !== userId)
91
+ return 'mismatch';
92
+ if (p.status === 'pending')
93
+ p.status = 'approved';
94
+ return 'ok';
95
+ }
96
+ /** Explicit rejection from the authenticated chat user. */
97
+ deny(pairingId, channel, userId) {
98
+ const p = this.pairings.get(pairingId);
99
+ if (!this.isLive(p))
100
+ return 'gone';
101
+ if (p.channel !== channel || p.userId !== userId)
102
+ return 'mismatch';
103
+ p.status = 'denied';
104
+ return 'ok';
105
+ }
106
+ /**
107
+ * Exchange an approval for an access session. Returns the access token exactly
108
+ * once per pairing. `requireBrowserToken` enforces that only the bound browser
109
+ * (Discord / LINE device flow) may consume; the Telegram initData path proves
110
+ * identity cryptographically in the same request and passes it through here
111
+ * with the freshly-bound token.
112
+ */
113
+ consume(pairingId, browserToken) {
114
+ const p = this.pairings.get(pairingId);
115
+ if (!p)
116
+ return null;
117
+ // Idempotent for the owning browser: a repeat call returns the same token so
118
+ // a re-poll after unlock still works.
119
+ if (p.status === 'consumed') {
120
+ if (p.accessToken && p.browserToken === browserToken && (p.accessExpiresAt ?? 0) > Date.now()) {
121
+ return { accessToken: p.accessToken };
122
+ }
123
+ return null;
124
+ }
125
+ if (p.status !== 'approved' || p.expiresAt <= Date.now())
126
+ return null;
127
+ if (!p.browserToken || p.browserToken !== browserToken)
128
+ return null;
129
+ const accessToken = crypto_1.default.randomBytes(32).toString('hex');
130
+ p.accessToken = accessToken;
131
+ p.status = 'consumed';
132
+ p.accessExpiresAt = Date.now() + ACCESS_TTL_MS;
133
+ return { accessToken };
134
+ }
135
+ /**
136
+ * Issue an access session for the Telegram initData fast-path. Identity is
137
+ * already proven cryptographically (the caller verified the signed initData and
138
+ * that its user matches the pairing), so — unlike the Discord/LINE device flow —
139
+ * this does NOT depend on the first-writer browser binding: a Telegram Mini App
140
+ * webview may not replay the `cli_pair` cookie set on the initial page load, so
141
+ * we (re)bind this browser and issue. Idempotent for the same browser.
142
+ */
143
+ issueAccessForVerifiedUser(pairingId, browserToken) {
144
+ const p = this.pairings.get(pairingId);
145
+ if (!p || p.status === 'denied')
146
+ return null;
147
+ if (p.status === 'consumed') {
148
+ if (p.accessToken && p.browserToken === browserToken && (p.accessExpiresAt ?? 0) > Date.now()) {
149
+ return { accessToken: p.accessToken };
150
+ }
151
+ return null;
152
+ }
153
+ if (p.expiresAt <= Date.now())
154
+ return null;
155
+ p.browserToken = browserToken;
156
+ const accessToken = crypto_1.default.randomBytes(32).toString('hex');
157
+ p.accessToken = accessToken;
158
+ p.status = 'consumed';
159
+ p.accessExpiresAt = Date.now() + ACCESS_TTL_MS;
160
+ return { accessToken };
161
+ }
162
+ /**
163
+ * Resolve an access-session token to its (agent-scoped) pairing. Used by every
164
+ * viewer request to authorize and to learn which single agent it may touch.
165
+ */
166
+ resolveAccess(accessToken) {
167
+ if (!accessToken)
168
+ return null;
169
+ for (const p of this.pairings.values()) {
170
+ if (p.status === 'consumed' &&
171
+ p.accessToken === accessToken &&
172
+ (p.accessExpiresAt ?? 0) > Date.now()) {
173
+ return p;
174
+ }
175
+ }
176
+ return null;
177
+ }
178
+ /** Drop dead pairings: expired-and-unconsumed, or access sessions past TTL. */
179
+ prune() {
180
+ const now = Date.now();
181
+ for (const [id, p] of this.pairings) {
182
+ const deadPending = p.status !== 'consumed' && p.expiresAt <= now;
183
+ const deadAccess = p.status === 'consumed' && (p.accessExpiresAt ?? 0) <= now;
184
+ if (deadPending || deadAccess)
185
+ this.pairings.delete(id);
186
+ }
187
+ }
188
+ /** Test/introspection helper. */
189
+ size() {
190
+ return this.pairings.size;
191
+ }
192
+ }
193
+ exports.CliPairingStore = CliPairingStore;
194
+ /** Process-wide singleton shared by the runner callback and the gateway routes. */
195
+ exports.cliPairingStore = new CliPairingStore();
196
+ //# sourceMappingURL=pairing-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pairing-store.js","sourceRoot":"","sources":["../../src/cli-viewer/pairing-store.ts"],"names":[],"mappings":";;;;;;AAUA,oCAEC;AAZD,oDAA4B;AAS5B,qFAAqF;AACrF,SAAgB,YAAY,CAAC,KAAc;IACzC,OAAO,KAAK,KAAK,UAAU,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,MAAM,CAAC;AACzE,CAAC;AAsCD,0EAA0E;AAC1E,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AACrC,6EAA6E;AAC7E,MAAM,aAAa,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAOrC;;;;;;;;;;;;;;GAcG;AACH,MAAa,eAAe;IAA5B;QACmB,aAAQ,GAAG,IAAI,GAAG,EAAsB,CAAC;IA8J5D,CAAC;IA5JC,+DAA+D;IAC/D,MAAM,CAAC,OAAe,EAAE,OAAmB,EAAE,MAAc;QACzD,MAAM,SAAS,GAAG,gBAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACzD,4EAA4E;QAC5E,4EAA4E;QAC5E,MAAM,IAAI,GAAG,MAAM,CAAC,gBAAM,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QACjE,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE;YAC3B,SAAS;YACT,OAAO;YACP,OAAO;YACP,MAAM;YACN,IAAI;YACJ,MAAM,EAAE,SAAS;YACjB,SAAS,EAAE,GAAG;YACd,SAAS,EAAE,GAAG,GAAG,cAAc;SAChC,CAAC,CAAC;QACH,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IAC7B,CAAC;IAED,4EAA4E;IAC5E,GAAG,CAAC,SAAiB;QACnB,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACtC,CAAC;IAED,2EAA2E;IACnE,MAAM,CAAC,CAAyB;QACtC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,UAAU,IAAI,CAAC,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7F,CAAC;IAED;;;;;OAKG;IACH,WAAW,CAAC,SAAiB,EAAE,YAAoB;QACjD,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACvC,6EAA6E;QAC7E,yEAAyE;QACzE,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,MAAM,KAAK,UAAU,IAAI,CAAC,CAAC,SAAS,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC;YAC1F,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,IAAI,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC;YACpB,CAAC,CAAC,YAAY,GAAG,YAAY,CAAC;YAC9B,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,OAAO,CAAC,CAAC,YAAY,KAAK,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/D,CAAC;IAED;;;OAGG;IACH,OAAO,CAAC,SAAiB,EAAE,OAAmB,EAAE,MAAc;QAC5D,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACvC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;YAAE,OAAO,MAAM,CAAC;QACnC,IAAI,CAAC,CAAC,OAAO,KAAK,OAAO,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM;YAAE,OAAO,UAAU,CAAC;QACpE,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS;YAAE,CAAC,CAAC,MAAM,GAAG,UAAU,CAAC;QAClD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,2DAA2D;IAC3D,IAAI,CAAC,SAAiB,EAAE,OAAmB,EAAE,MAAc;QACzD,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACvC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;YAAE,OAAO,MAAM,CAAC;QACnC,IAAI,CAAC,CAAC,OAAO,KAAK,OAAO,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM;YAAE,OAAO,UAAU,CAAC;QACpE,CAAC,CAAC,MAAM,GAAG,QAAQ,CAAC;QACpB,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;OAMG;IACH,OAAO,CAAC,SAAiB,EAAE,YAAoB;QAC7C,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACvC,IAAI,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QACpB,6EAA6E;QAC7E,sCAAsC;QACtC,IAAI,CAAC,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;YAC5B,IAAI,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,YAAY,KAAK,YAAY,IAAI,CAAC,CAAC,CAAC,eAAe,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;gBAC9F,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;YACxC,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,CAAC,CAAC,MAAM,KAAK,UAAU,IAAI,CAAC,CAAC,SAAS,IAAI,IAAI,CAAC,GAAG,EAAE;YAAE,OAAO,IAAI,CAAC;QACtE,IAAI,CAAC,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC,YAAY,KAAK,YAAY;YAAE,OAAO,IAAI,CAAC;QACpE,MAAM,WAAW,GAAG,gBAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC3D,CAAC,CAAC,WAAW,GAAG,WAAW,CAAC;QAC5B,CAAC,CAAC,MAAM,GAAG,UAAU,CAAC;QACtB,CAAC,CAAC,eAAe,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,aAAa,CAAC;QAC/C,OAAO,EAAE,WAAW,EAAE,CAAC;IACzB,CAAC;IAED;;;;;;;OAOG;IACH,0BAA0B,CAAC,SAAiB,EAAE,YAAoB;QAChE,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACvC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QAC7C,IAAI,CAAC,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;YAC5B,IAAI,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,YAAY,KAAK,YAAY,IAAI,CAAC,CAAC,CAAC,eAAe,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;gBAC9F,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;YACxC,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,CAAC,CAAC,SAAS,IAAI,IAAI,CAAC,GAAG,EAAE;YAAE,OAAO,IAAI,CAAC;QAC3C,CAAC,CAAC,YAAY,GAAG,YAAY,CAAC;QAC9B,MAAM,WAAW,GAAG,gBAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC3D,CAAC,CAAC,WAAW,GAAG,WAAW,CAAC;QAC5B,CAAC,CAAC,MAAM,GAAG,UAAU,CAAC;QACtB,CAAC,CAAC,eAAe,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,aAAa,CAAC;QAC/C,OAAO,EAAE,WAAW,EAAE,CAAC;IACzB,CAAC;IAED;;;OAGG;IACH,aAAa,CAAC,WAAmB;QAC/B,IAAI,CAAC,WAAW;YAAE,OAAO,IAAI,CAAC;QAC9B,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;YACvC,IACE,CAAC,CAAC,MAAM,KAAK,UAAU;gBACvB,CAAC,CAAC,WAAW,KAAK,WAAW;gBAC7B,CAAC,CAAC,CAAC,eAAe,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,EACrC,CAAC;gBACD,OAAO,CAAC,CAAC;YACX,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,+EAA+E;IAC/E,KAAK;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,KAAK,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACpC,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,KAAK,UAAU,IAAI,CAAC,CAAC,SAAS,IAAI,GAAG,CAAC;YAClE,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,KAAK,UAAU,IAAI,CAAC,CAAC,CAAC,eAAe,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC;YAC9E,IAAI,WAAW,IAAI,UAAU;gBAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IAED,iCAAiC;IACjC,IAAI;QACF,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;IAC5B,CAAC;CACF;AA/JD,0CA+JC;AAED,mFAAmF;AACtE,QAAA,eAAe,GAAG,IAAI,eAAe,EAAE,CAAC"}
@@ -0,0 +1,21 @@
1
+ export interface VerifiedInitData {
2
+ /** Telegram user id (stringified) proven by the signature. */
3
+ userId: string;
4
+ }
5
+ /**
6
+ * Verify a Telegram Mini App `initData` string against a bot token.
7
+ *
8
+ * Telegram signs the launch parameters so a Mini App can prove which user opened
9
+ * it without any secret in the URL. The check (per Telegram's spec):
10
+ * secret_key = HMAC_SHA256(key = "WebAppData", data = <bot token>)
11
+ * data_check_str = every "key=value" except `hash`, sorted, joined by "\n"
12
+ * expected_hash = HMAC_SHA256(key = secret_key, data = data_check_str)
13
+ * and `expected_hash` must equal the payload's `hash` (timing-safe).
14
+ *
15
+ * Returns the verified user id, or null if the payload is missing fields,
16
+ * tampered, stale, or the signature does not match. The caller is still
17
+ * responsible for authorizing that user for the target agent — a valid
18
+ * signature only proves *who* opened the Mini App, not *what* they may see.
19
+ */
20
+ export declare function verifyTelegramInitData(initData: string, botToken: string): VerifiedInitData | null;
21
+ //# sourceMappingURL=telegram-initdata.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telegram-initdata.d.ts","sourceRoot":"","sources":["../../src/cli-viewer/telegram-initdata.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,gBAAgB;IAC/B,8DAA8D;IAC9D,MAAM,EAAE,MAAM,CAAC;CAChB;AAKD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,gBAAgB,GAAG,IAAI,CA8CzB"}
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.verifyTelegramInitData = verifyTelegramInitData;
7
+ const crypto_1 = __importDefault(require("crypto"));
8
+ /** Max age of a Telegram initData payload we still trust (replay bound). */
9
+ const INITDATA_MAX_AGE_SEC = 60 * 60;
10
+ /**
11
+ * Verify a Telegram Mini App `initData` string against a bot token.
12
+ *
13
+ * Telegram signs the launch parameters so a Mini App can prove which user opened
14
+ * it without any secret in the URL. The check (per Telegram's spec):
15
+ * secret_key = HMAC_SHA256(key = "WebAppData", data = <bot token>)
16
+ * data_check_str = every "key=value" except `hash`, sorted, joined by "\n"
17
+ * expected_hash = HMAC_SHA256(key = secret_key, data = data_check_str)
18
+ * and `expected_hash` must equal the payload's `hash` (timing-safe).
19
+ *
20
+ * Returns the verified user id, or null if the payload is missing fields,
21
+ * tampered, stale, or the signature does not match. The caller is still
22
+ * responsible for authorizing that user for the target agent — a valid
23
+ * signature only proves *who* opened the Mini App, not *what* they may see.
24
+ */
25
+ function verifyTelegramInitData(initData, botToken) {
26
+ if (!initData || !botToken)
27
+ return null;
28
+ let params;
29
+ try {
30
+ params = new URLSearchParams(initData);
31
+ }
32
+ catch {
33
+ return null;
34
+ }
35
+ const hash = params.get('hash');
36
+ if (!hash || !/^[0-9a-f]+$/i.test(hash))
37
+ return null;
38
+ params.delete('hash');
39
+ const dataCheckString = [...params.entries()]
40
+ .map(([k, v]) => `${k}=${v}`)
41
+ .sort()
42
+ .join('\n');
43
+ const secretKey = crypto_1.default.createHmac('sha256', 'WebAppData').update(botToken).digest();
44
+ const expected = crypto_1.default.createHmac('sha256', secretKey).update(dataCheckString).digest();
45
+ let provided;
46
+ try {
47
+ provided = Buffer.from(hash, 'hex');
48
+ }
49
+ catch {
50
+ return null;
51
+ }
52
+ if (provided.length !== expected.length || !crypto_1.default.timingSafeEqual(provided, expected)) {
53
+ return null;
54
+ }
55
+ // Reject stale payloads (replay bound). auth_date is unix seconds.
56
+ const authDate = Number(params.get('auth_date') ?? '');
57
+ if (!Number.isFinite(authDate) || authDate <= 0)
58
+ return null;
59
+ if (Date.now() / 1000 - authDate > INITDATA_MAX_AGE_SEC)
60
+ return null;
61
+ const userRaw = params.get('user');
62
+ if (!userRaw)
63
+ return null;
64
+ try {
65
+ const user = JSON.parse(userRaw);
66
+ if (user.id === undefined || user.id === null || user.id === '')
67
+ return null;
68
+ return { userId: String(user.id) };
69
+ }
70
+ catch {
71
+ return null;
72
+ }
73
+ }
74
+ //# sourceMappingURL=telegram-initdata.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telegram-initdata.js","sourceRoot":"","sources":["../../src/cli-viewer/telegram-initdata.ts"],"names":[],"mappings":";;;;;AAyBA,wDAiDC;AA1ED,oDAA4B;AAO5B,4EAA4E;AAC5E,MAAM,oBAAoB,GAAG,EAAE,GAAG,EAAE,CAAC;AAErC;;;;;;;;;;;;;;GAcG;AACH,SAAgB,sBAAsB,CACpC,QAAgB,EAChB,QAAgB;IAEhB,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAExC,IAAI,MAAuB,CAAC;IAC5B,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,eAAe,CAAC,QAAQ,CAAC,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC,IAAI,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACrD,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAEtB,MAAM,eAAe,GAAG,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;SAC1C,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;SAC5B,IAAI,EAAE;SACN,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,MAAM,SAAS,GAAG,gBAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,CAAC;IACtF,MAAM,QAAQ,GAAG,gBAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,MAAM,EAAE,CAAC;IAEzF,IAAI,QAAgB,CAAC;IACrB,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,IAAI,CAAC,gBAAM,CAAC,eAAe,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,CAAC;QACvF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,mEAAmE;IACnE,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;IACvD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,QAAQ,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7D,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,QAAQ,GAAG,oBAAoB;QAAE,OAAO,IAAI,CAAC;IAErE,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACnC,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAA6B,CAAC;QAC7D,IAAI,IAAI,CAAC,EAAE,KAAK,SAAS,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,IAAI,IAAI,CAAC,EAAE,KAAK,EAAE;YAAE,OAAO,IAAI,CAAC;QAC7E,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Build the absolute, phone-openable URL for a `/cli` webview from the operator-
3
+ * configured `gateway.publicUrl`. Kept tiny and dependency-free so both the
4
+ * runner callback (which mints pairings) and the gateway routes can share one
5
+ * definition of "how a /cli link is formed".
6
+ */
7
+ /** Trim and validate the configured public origin. Returns null when unusable
8
+ * (unset, blank, or not http(s)) so callers can report "not configured" rather
9
+ * than emit a broken link. Trailing slashes are stripped. */
10
+ export declare function normalizePublicUrl(publicUrl: string | undefined): string | null;
11
+ /** Full viewer link for a pairing, or null when no public URL is configured. */
12
+ export declare function buildCliUrl(publicUrl: string | undefined, pairingId: string): string | null;
13
+ //# sourceMappingURL=url.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"url.d.ts","sourceRoot":"","sources":["../../src/cli-viewer/url.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;8DAE8D;AAC9D,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAK/E;AAED,gFAAgF;AAChF,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAG3F"}
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ /**
3
+ * Build the absolute, phone-openable URL for a `/cli` webview from the operator-
4
+ * configured `gateway.publicUrl`. Kept tiny and dependency-free so both the
5
+ * runner callback (which mints pairings) and the gateway routes can share one
6
+ * definition of "how a /cli link is formed".
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.normalizePublicUrl = normalizePublicUrl;
10
+ exports.buildCliUrl = buildCliUrl;
11
+ /** Trim and validate the configured public origin. Returns null when unusable
12
+ * (unset, blank, or not http(s)) so callers can report "not configured" rather
13
+ * than emit a broken link. Trailing slashes are stripped. */
14
+ function normalizePublicUrl(publicUrl) {
15
+ const u = (publicUrl ?? '').trim().replace(/\/+$/, '');
16
+ if (!u)
17
+ return null;
18
+ if (!/^https?:\/\//i.test(u))
19
+ return null;
20
+ return u;
21
+ }
22
+ /** Full viewer link for a pairing, or null when no public URL is configured. */
23
+ function buildCliUrl(publicUrl, pairingId) {
24
+ const base = normalizePublicUrl(publicUrl);
25
+ return base ? `${base}/cli/${pairingId}` : null;
26
+ }
27
+ //# sourceMappingURL=url.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"url.js","sourceRoot":"","sources":["../../src/cli-viewer/url.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;AAKH,gDAKC;AAGD,kCAGC;AAdD;;8DAE8D;AAC9D,SAAgB,kBAAkB,CAAC,SAA6B;IAC9D,MAAM,CAAC,GAAG,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACvD,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACpB,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1C,OAAO,CAAC,CAAC;AACX,CAAC;AAED,gFAAgF;AAChF,SAAgB,WAAW,CAAC,SAA6B,EAAE,SAAiB;IAC1E,MAAM,IAAI,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAC3C,OAAO,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,QAAQ,SAAS,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAClD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../../src/session/process.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../../src/session/process.ts"],"names":[],"mappings":"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"}
@@ -625,6 +625,13 @@ class SessionProcess extends events_1.EventEmitter {
625
625
  // result.usage is cumulative across all sub-calls; message_start.usage reflects a single API call's context.
626
626
  let lastMessageStartContext = 0;
627
627
  proc.stdout?.on('data', (data) => {
628
+ // Child produced output => the session is doing real work right now. Count
629
+ // this as activity so the idle reaper measures "time since the session last
630
+ // did anything", not just "time since the parent last injected a message".
631
+ // Without this, a self-paced loop (a /loop in dynamic mode using
632
+ // ScheduleWakeup) that wakes itself and works entirely inside this child
633
+ // process stays invisible to the idle timer and gets reaped mid-flight.
634
+ this.touch();
628
635
  // Update heartbeat so the receiver's stalled detector knows Claude is active
629
636
  if (heartbeatPath) {
630
637
  try {