@obov/mext 0.6.0 → 0.7.1

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 (75) hide show
  1. package/dist/build.js +16 -2
  2. package/dist/build.js.map +1 -1
  3. package/dist/cli/args.js +1 -2
  4. package/dist/cli/args.js.map +1 -1
  5. package/dist/cli/build.js +22 -2
  6. package/dist/cli/build.js.map +1 -1
  7. package/dist/cli/dev-server.js +3 -2
  8. package/dist/cli/dev-server.js.map +1 -1
  9. package/dist/cli/dev.d.ts +6 -0
  10. package/dist/cli/dev.js +4 -4
  11. package/dist/cli/dev.js.map +1 -1
  12. package/dist/cli/main.js +2 -0
  13. package/dist/cli/main.js.map +1 -1
  14. package/dist/cli/media.d.ts +19 -0
  15. package/dist/cli/media.js +77 -0
  16. package/dist/cli/media.js.map +1 -0
  17. package/dist/cli/run.js +5 -0
  18. package/dist/cli/run.js.map +1 -1
  19. package/dist/cli/serve.d.ts +10 -0
  20. package/dist/cli/serve.js +114 -0
  21. package/dist/cli/serve.js.map +1 -0
  22. package/dist/client/index.d.ts +2 -1
  23. package/dist/client/index.js.map +1 -1
  24. package/dist/client/runner.js +3 -0
  25. package/dist/client/runner.js.map +1 -1
  26. package/dist/client/typed.d.ts +3 -1
  27. package/dist/client/typed.js +39 -3
  28. package/dist/client/typed.js.map +1 -1
  29. package/dist/client/types.d.ts +31 -2
  30. package/dist/client/types.js.map +1 -1
  31. package/dist/config.d.ts +17 -0
  32. package/dist/config.js +36 -1
  33. package/dist/config.js.map +1 -1
  34. package/dist/content.d.ts +65 -0
  35. package/dist/content.js +99 -0
  36. package/dist/content.js.map +1 -0
  37. package/dist/index.d.ts +3 -1
  38. package/dist/index.js +1 -0
  39. package/dist/index.js.map +1 -1
  40. package/dist/invoke.d.ts +4 -0
  41. package/dist/invoke.js +12 -5
  42. package/dist/invoke.js.map +1 -1
  43. package/dist/manifest.d.ts +6 -1
  44. package/dist/manifest.js.map +1 -1
  45. package/dist/mcp/constants.d.ts +2 -0
  46. package/dist/mcp/constants.js +2 -0
  47. package/dist/mcp/constants.js.map +1 -1
  48. package/dist/mcp/dispatch.d.ts +9 -3
  49. package/dist/mcp/dispatch.js +10 -4
  50. package/dist/mcp/dispatch.js.map +1 -1
  51. package/dist/mcp/host.d.ts +14 -0
  52. package/dist/mcp/host.js +48 -0
  53. package/dist/mcp/host.js.map +1 -0
  54. package/dist/mcp/http.d.ts +22 -5
  55. package/dist/mcp/http.js +125 -18
  56. package/dist/mcp/http.js.map +1 -1
  57. package/dist/mcp/index.d.ts +1 -0
  58. package/dist/mcp/index.js +1 -0
  59. package/dist/mcp/index.js.map +1 -1
  60. package/dist/mcp/tasks.js +1 -1
  61. package/dist/mcp/tasks.js.map +1 -1
  62. package/dist/remote/client.d.ts +24 -1
  63. package/dist/remote/client.js +177 -53
  64. package/dist/remote/client.js.map +1 -1
  65. package/dist/remote/index.d.ts +1 -1
  66. package/dist/remote/index.js.map +1 -1
  67. package/dist/route.d.ts +40 -2
  68. package/dist/route.js +128 -8
  69. package/dist/route.js.map +1 -1
  70. package/dist/start.js +3 -2
  71. package/dist/start.js.map +1 -1
  72. package/dist/version-constant.d.ts +1 -1
  73. package/dist/version-constant.js +1 -1
  74. package/dist/version-constant.js.map +1 -1
  75. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../src/mcp/tasks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAkB,MAAM,8BAA8B,CAAA;AAC/F,OAAO,KAAK,CAAC,MAAM,KAAK,CAAA;AAKxB,OAAO,EAAE,gBAAgB,EAAkB,MAAM,aAAa,CAAA;AAC9D,OAAO,EAAE,WAAW,EAAE,WAAW,EAAuB,MAAM,eAAe,CAAA;AAC7E,OAAO,EACL,cAAc,EACd,SAAS,EACT,WAAW,EACX,YAAY,EACZ,eAAe,GAIhB,MAAM,WAAW,CAAA;AAElB;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,CAAC,MAAM,eAAe,GAAG,+BAA+B,CAAA;AAe9D,MAAM,CAAC,MAAM,WAAW,GAAyB,MAAM,CAAC,MAAM,CAAC;IAC7D,cAAc,EAAE,KAAK;IACrB,WAAW,EAAE,MAAM;IACnB,WAAW,EAAE,MAAM;IACnB,WAAW,EAAE,KAAK;IAClB,UAAU,EAAE,KAAK;CAClB,CAAC,CAAA;AAEF,sDAAsD;AACtD,MAAM,CAAC,MAAM,SAAS,GAAG,WAAW,CAAA;AAiGpC,uCAAuC;AACvC,MAAM,UAAU,eAAe,CAAC,QAAkB;IAChD,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE;QAAE,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI;YAAE,OAAO,IAAI,CAAA;IACnF,OAAO,KAAK,CAAA;AACd,CAAC;AAED,kDAAkD;AAClD,MAAM,UAAU,aAAa,CAAC,kBAA2B;IACvD,MAAM,UAAU,GAAI,kBAA2D,EAAE,UAAU,CAAA;IAC3F,OAAO,aAAa,CAAC,UAAU,CAAC,IAAI,UAAU,CAAC,eAAe,CAAC,KAAK,SAAS,CAAA;AAC/E,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,QAAkB,EAAE,IAAa;IAC5D,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,YAAY,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAA;IACrG,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;IAC1B,MAAM,IAAI,GAAG,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAA;IACnE,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC,4CAA4C,CAAC,CAAC;QAAE,OAAO,KAAK,CAAA;IACtF,MAAM,IAAI,GAAG,aAAa,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAA;IAC3E,MAAM,MAAM,GAAG,OAAO,IAAI,EAAE,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAA;IAC7E,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAA;IAC5C,MAAM,EAAE,GAAG,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IAChF,OAAO,EAAE,KAAK,SAAS,IAAI,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,IAAI,KAAK,SAAS,CAAA;AAClF,CAAC;AAED,MAAM,SAAS,GAAG,CAAC,MAAc,EAAU,EAAE,CAAC,GAAG,gBAAgB,QAAQ,MAAM,EAAE,CAAA;AACjF,MAAM,QAAQ,GAAG,CAAC,MAAc,EAAE,GAAW,EAAU,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,CAAC,UAAU,GAAG,EAAE,CAAA;AAC7F,MAAM,SAAS,GAAG,CAAC,MAAc,EAAU,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,CAAC,SAAS,CAAA;AAC3E,MAAM,WAAW,GAAG,CAAC,MAAc,EAAU,EAAE,CAAC,GAAG,gBAAgB,QAAQ,MAAM,EAAE,CAAA;AAEnF,MAAM,QAAQ,GAA4B,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAA;AAavF,MAAM,UAAU,iBAAiB,CAAC,OAA2B;IAC3D,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,KAAK,CAAA;IACpC,MAAM,MAAM,GAAe,EAAE,GAAG,WAAW,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAA;IAChE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,EAAE,CAAA;IAC/B,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,IAAI,cAAc,CAAA;IAChD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAuB,CAAA;IAC9C,IAAI,MAAM,GAAG,KAAK,CAAA;IAElB,uCAAuC;IACvC,MAAM,SAAS,GAAG,KAAK,EAAK,EAAoB,EAAc,EAAE;QAC9D,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,EAAE,CAAA;QACnB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,UAAU,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;YACzB,MAAM,IAAI,aAAa,CAAC,iBAAiB,CAAC,aAAa,EAAE,mBAAmB,CAAC,CAAA;QAC/E,CAAC;IACH,CAAC,CAAA;IAED,MAAM,UAAU,GAAG,KAAK,EAAE,MAAc,EAAE,SAAoB,EAAuB,EAAE;QACrF,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;QAC/D,MAAM,MAAM,GAAG,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAA;QAC/D,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM,IAAI,MAAM,CAAC,SAAS,KAAK,SAAS,CAAC,SAAS,CAAC;YAAE,MAAM,WAAW,CAAC,MAAM,CAAC,CAAA;QAC/G,OAAO,MAAM,CAAA;IACf,CAAC,CAAA;IAED,MAAM,IAAI,GAAG,CAAC,MAAkB,EAAW,EAAE,CAC3C,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAA;IAEtF,8DAA8D;IAC9D,MAAM,MAAM,GAAG,KAAK,EAAE,MAAc,EAAE,IAAwB,EAAiB,EAAE;QAC/E,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QACjC,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,KAAK,CAAC,IAAI,EAAE,CAAA;YAClB,OAAM;QACR,CAAC;QACD,IAAI,GAAG;YAAE,MAAM,SAAS,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;IAC5F,CAAC,CAAA;IAED,MAAM,KAAK,GAAG,KAAK,EAAE,KAAwB,EAAE,OAA2B,EAA8B,EAAE;QACxG,MAAM,MAAM,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAA;QACpD,MAAM,OAAO,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;QACxC,MAAM,MAAM,GAAe;YACzB,CAAC,EAAE,CAAC;YACJ,MAAM;YACN,SAAS,EAAE,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC;YACvC,OAAO,EAAE,KAAK,CAAC,EAAE;YACjB,MAAM,EAAE,SAAS;YACjB,SAAS,EAAE,OAAO;YAClB,aAAa,EAAE,OAAO;YACtB,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,IAAK,CAAC,KAAK;YAChC,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE;SACxB,CAAA;QACD,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAA;QACxC,MAAM,OAAO,GAAG,IAAI,GAAG,EAA+C,CAAA;QACtE,IAAI,SAAS,GAAG,KAAK,CAAA;QACrB,IAAI,WAAwB,CAAA;QAC5B,MAAM,IAAI,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,WAAW,GAAG,OAAO,CAAC,CAAC,CAAA;QACpE,MAAM,KAAK,GAAG,GAAS,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAA;QAEhF,2CAA2C;QAC3C,IAAI,OAAkC,CAAA;QACtC,IAAI,KAAK,GAAG,KAAK,CAAA;QACjB,MAAM,OAAO,GAAG,GAAkB,EAAE;YAClC,KAAK,GAAG,IAAI,CAAA;YACZ,OAAO,KAAK,CAAC,KAAK,IAAI,EAAE;gBACtB,IAAI,CAAC;oBACH,OAAO,KAAK,EAAE,CAAC;wBACb,KAAK,GAAG,KAAK,CAAA;wBACb,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,WAAW,CAAA;wBAC5F,MAAM,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,CAAA;oBACvE,CAAC;gBACH,CAAC;wBAAS,CAAC;oBACT,OAAO,GAAG,SAAS,CAAA;gBACrB,CAAC;YACH,CAAC,CAAC,EAAE,CAAA;YACJ,OAAO,OAAO,CAAA;QAChB,CAAC,CAAA;QACD,MAAM,YAAY,GAAG,GAAS,EAAE,CAAC,KAAK,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAA;QAEpG,MAAM,IAAI,GAAG,KAAK,IAAmB,EAAE;YACrC,IAAI,CAAC;gBACH,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,MAAM,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;oBACrF,UAAU,CAAC,KAAK,CAAC,IAAI,YAAY,CAAC,gBAAgB,EAAE,YAAY,CAAC,CAAC,CAAA;gBACpE,CAAC;gBACD,KAAK,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC;oBAC1C,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAA;oBAClD,MAAM,MAAM,GAAG,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAA;oBAC3E,IAAI,MAAM;wBAAE,OAAO,CAAC,MAAM,CAAC,CAAA;gBAC7B,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,UAAU,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;YAC3B,CAAC;QACH,CAAC,CAAA;QAED,IAAI,SAAqD,CAAA;QACzD,IAAI,IAAgD,CAAA;QACpD,IAAI,WAA8C,CAAA;QAClD,MAAM,UAAU,GAAG,GAAS,EAAE;YAC5B,IAAI,SAAS,KAAK,SAAS;gBAAE,aAAa,CAAC,SAAS,CAAC,CAAA;YACrD,IAAI,IAAI,KAAK,SAAS;gBAAE,aAAa,CAAC,IAAI,CAAC,CAAA;QAC7C,CAAC,CAAA;QAED,MAAM,MAAM,GAAG,KAAK,IAAmB,EAAE;YACvC,IAAI,SAAS;gBAAE,OAAM;YACrB,SAAS,GAAG,IAAI,CAAA;YAChB,UAAU,EAAE,CAAA;YACZ,OAAO,MAAM,CAAC,aAAa,CAAA;YAC3B,KAAK,EAAE,CAAA;YACP,OAAO,CAAC,KAAK,EAAE,CAAA;YACf,IAAI,CAAC;gBACH,MAAM,OAAO,EAAE,CAAA;YACjB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,UAAU,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;YAC3B,CAAC;YACD,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;YACtB,IAAI,CAAC;gBACH,MAAM,WAAW,EAAE,EAAE,CAAA;YACvB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,UAAU,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;YAC3B,CAAC;YACD,WAAW,EAAE,CAAA;QACf,CAAC,CAAA;QAED,IAAI,KAAK,GAAG,CAAC,CAAA;QACb,MAAM,GAAG,GAAe,KAAK,EAAE,UAAU,EAAE,EAAE;YAC3C,MAAM,GAAG,GAAG,GAAG,cAAc,GAAG,KAAK,EAAE,EAAE,CAAA;YACzC,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC;gBAAE,MAAM,eAAe,CAAC,UAAU,CAAC,CAAA;YAC5G,UAAU,CAAC,MAAM,CAAC,cAAc,EAAE,CAAA;YAClC,IAAI,OAAoB,CAAA;YACxB,MAAM,QAAQ,GAAG,IAAI,OAAO,CAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAClE,OAAO,GAAG,GAAG,EAAE;oBACb,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;oBACnB,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;gBAClC,CAAC,CAAA;gBACD,UAAU,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;gBACpE,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,EAAE;oBAC1B,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;oBACnB,UAAU,CAAC,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;oBACvD,OAAO,CAAC,MAAM,CAAC,CAAA;gBACjB,CAAC,CAAC,CAAA;YACJ,CAAC,CAAC,CAAA;YACF,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;YACxB,MAAM,CAAC,aAAa,GAAG,EAAE,GAAG,MAAM,CAAC,aAAa,EAAE,CAAC,GAAG,CAAC,EAAE,WAAW,CAAC,UAAU,CAAC,EAAE,CAAA;YAClF,MAAM,CAAC,MAAM,GAAG,gBAAgB,CAAA;YAChC,KAAK,EAAE,CAAA;YACP,IAAI,CAAC;gBACH,MAAM,OAAO,EAAE,CAAA;YACjB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;gBACnB,UAAU,CAAC,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;gBACvD,MAAM,KAAK,CAAA;YACb,CAAC;YACD,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAA;YAC/B,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;gBACzB,OAAO,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,CAAA;gBAChC,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,MAAM,KAAK,CAAC;oBAAE,OAAO,MAAM,CAAC,aAAa,CAAA;YACjF,CAAC;YACD,IAAI,CAAC,MAAM,CAAC,aAAa,IAAI,CAAC,SAAS;gBAAE,MAAM,CAAC,MAAM,GAAG,SAAS,CAAA;YAClE,KAAK,EAAE,CAAA;YACP,IAAI,CAAC,SAAS;gBAAE,YAAY,EAAE,CAAA;YAC9B,OAAO,SAAS,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAA;QACxC,CAAC,CAAA;QAED,MAAM,QAAQ,GAAG,CAAC,MAAsB,EAAQ,EAAE;YAChD,IAAI,SAAS;gBAAE,OAAM;YACrB,MAAM,CAAC,aAAa;gBAClB,MAAM,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAA;YACjH,KAAK,EAAE,CAAA;YACP,YAAY,EAAE,CAAA;QAChB,CAAC,CAAA;QAED,MAAM,IAAI,GAAgB;YACxB,IAAI;YACJ,KAAK,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC;YAC3C,IAAI;YACJ,KAAK,CAAC,WAAW;gBACf,IAAI,SAAS;oBAAE,OAAM;gBACrB,MAAM,CAAC,MAAM,GAAG,WAAW,CAAA;gBAC3B,MAAM,MAAM,EAAE,CAAA;YAChB,CAAC;SACF,CAAA;QACD,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;QACzB,IAAI,CAAC;YACH,IAAI,GAAG;gBAAE,WAAW,GAAG,MAAM,GAAG,CAAC,SAAS,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,CAAA;YAClF,yCAAyC;YACzC,MAAM,OAAO,EAAE,CAAA;QACjB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;YACtB,MAAM,WAAW,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;YACrC,MAAM,KAAK,CAAA;QACb,CAAC;QACD,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE;YAC3B,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;YAC/B,YAAY,EAAE,CAAA;QAChB,CAAC,EAAE,MAAM,CAAC,WAAW,CAAC,CAAA;QACtB,SAAS,CAAC,KAAK,EAAE,EAAE,CAAA;QACnB,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,IAAI,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,EAAE,EAAE,MAAM,CAAC,WAAW,CAAC,CAAA;YACzD,IAAI,CAAC,KAAK,EAAE,EAAE,CAAA;QAChB,CAAC;QACD,OAAO,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,CAAA;QAEzB,MAAM,MAAM,GAAqB;YAC/B,UAAU,EAAE,MAAM;YAClB,MAAM;YACN,MAAM,EAAE,SAAS;YACjB,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,aAAa,EAAE,MAAM,CAAC,aAAa;YACnC,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,cAAc,EAAE,MAAM,CAAC,cAAc;SACtC,CAAA;QACD,OAAO;YACL,MAAM;YACN,MAAM;YACN,MAAM,EAAE,UAAU,CAAC,MAAM;YACzB,GAAG;YACH,QAAQ;YACR,KAAK,CAAC,MAAM,CAAC,OAAO;gBAClB,IAAI,SAAS;oBAAE,OAAM;gBACrB,IAAI,OAAO,IAAI,OAAO,IAAI,UAAU,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;oBACpD,+CAA+C;oBAC/C,MAAM,CAAC,MAAM,GAAG,WAAW,CAAA;gBAC7B,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,MAAM,GAAG,WAAW,CAAA;oBAC3B,MAAM,MAAM,GAAG,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;oBAC3F,MAAM,CAAC,MAAM,GAAG,EAAE,GAAG,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,EAAE,EAAE,CAAA;gBAC7F,CAAC;gBACD,MAAM,MAAM,EAAE,CAAA;YAChB,CAAC;SACF,CAAA;IACH,CAAC,CAAA;IAED,OAAO;QACL,MAAM;QACN,OAAO,CAAC,cAAc;YACpB,MAAM,GAAG,GAAwD;gBAC/D,OAAO,EAAE,SAAS;gBAClB,KAAK,CAAC,MAAM,CAAC,KAAK;oBAChB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,IAAI,MAAM;wBAAE,OAAO,SAAS,CAAA;oBACnD,IAAI,CAAC;wBACH,OAAO,MAAM,KAAK,CAAC,KAAK,EAAE,cAAc,CAAC,CAAA;oBAC3C,CAAC;oBAAC,OAAO,KAAK,EAAE,CAAC;wBACf,UAAU,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;wBACzB,GAAG,CAAC,OAAO,GAAG,KAAK,CAAA;wBACnB,MAAM,KAAK,CAAA;oBACb,CAAC;gBACH,CAAC;aACF,CAAA;YACD,OAAO,GAAG,CAAA;QACZ,CAAC;QAED,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS;YACzB,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;YAClD,MAAM,IAAI,GAAa;gBACrB,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,GAAG,CAAC,MAAM,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACtF,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,aAAa,EAAE,MAAM,CAAC,aAAa;gBACnC,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,cAAc,EAAE,MAAM,CAAC,cAAc;aACtC,CAAA;YACD,IAAI,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;gBACjB,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAA;gBACtB,IAAI,CAAC,KAAK,GAAG;oBACX,IAAI,EAAE,iBAAiB,CAAC,aAAa;oBACrC,OAAO,EAAE,8DAA8D,MAAM,CAAC,WAAW,MAAM;oBAC/F,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;iBAC1B,CAAA;YACH,CAAC;iBAAM,IAAI,MAAM,CAAC,MAAM,KAAK,gBAAgB,IAAI,MAAM,CAAC,aAAa;gBAAE,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC,aAAa,CAAA;iBAC3G,IAAI,MAAM,CAAC,MAAM,KAAK,WAAW,IAAI,MAAM,CAAC,MAAM;gBAAE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAA;YACpF,OAAO,IAAI,CAAA;QACb,CAAC;QAED,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,cAAc;YAC5C,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;YAClD,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC;gBAAE,OAAM;YACvD,IAAI,KAAK,GAAG,KAAK,CAAA;YACjB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;gBAC1D,kCAAkC;gBAClC,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC,GAAG,CAAC,KAAK,SAAS,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC;oBAAE,SAAQ;gBAC/E,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAA;gBACtE,IAAI,MAAM,KAAK,SAAS;oBAAE,SAAQ;gBAClC,MAAM,SAAS,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAA;gBAC5H,KAAK,GAAG,IAAI,CAAA;YACd,CAAC;YACD,IAAI,KAAK;gBAAE,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QAC1C,CAAC;QAED,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS;YAC5B,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;YAClD,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC;gBAAE,OAAM;YACvD,MAAM,SAAS,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAA;YACvG,MAAM,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;QAChC,CAAC;QAED,KAAK,CAAC,KAAK;YACT,MAAM,GAAG,IAAI,CAAA;YACb,MAAM,KAAK,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;YACnC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAM;YAC9B,KAAK,MAAM,IAAI,IAAI,KAAK;gBAAE,IAAI,CAAC,KAAK,CAAC,IAAI,YAAY,CAAC,sBAAsB,EAAE,YAAY,CAAC,CAAC,CAAA;YAC5F,IAAI,KAAgD,CAAA;YACpD,MAAM,OAAO,CAAC,IAAI,CAAC;gBACjB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC3C,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,KAAK,GAAG,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;aACjF,CAAC,CAAA;YACF,YAAY,CAAC,KAAK,CAAC,CAAA;YACnB,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAA;QAC5D,CAAC;KACF,CAAA;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAiB,EAAE,OAAoB,EAAE,SAAoB,EAAE,OAAgB;IACjH,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAA;IAC3B,IAAI,OAAO;QAAE,KAAK,CAAC,oBAAoB,CAAC,EAAE,UAAU,EAAE,EAAE,CAAC,eAAe,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAA;IAClF,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;IAC7C,KAAK,CAAC,iBAAiB,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IAC7H,yFAAyF;IACzF,KAAK,CAAC,iBAAiB,CAAC,cAAc,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,EAAE;QAClF,MAAM,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,cAAc,IAAI,EAAE,CAAC,CAAA;QACxE,OAAO,EAAE,CAAA;IACX,CAAC,CAAC,CAAA;IACF,KAAK,CAAC,iBAAiB,CAAC,cAAc,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;QAC7E,MAAM,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;QACvC,OAAO,EAAE,CAAA;IACX,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,MAAc;IACjC,OAAO,IAAI,aAAa,CAAC,iBAAiB,CAAC,aAAa,EAAE,iBAAiB,MAAM,EAAE,CAAC,CAAA;AACtF,CAAC;AAED,SAAS,SAAS,CAAC,SAAoB;IACrC,OAAO,GAAG,SAAS,CAAC,IAAI,IAAI,SAAS,CAAC,EAAE,EAAE,CAAA;AAC5C,CAAC;AAED,SAAS,WAAW,CAAC,GAAW;IAC9B,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,CAAA;IAC5B,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ,IAAI,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAA;IACpI,OAAO,KAA8B,CAAA;AACvC,CAAC;AAED,SAAS,SAAS,CAAC,GAAW;IAC5B,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,MAAgC,EAAE,KAAc;IAClE,IAAI,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,CAAA;IACf,CAAC;IAAC,MAAM,CAAC;QACP,kBAAkB;IACpB,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,KAAc;IACpC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,4BAA4B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;AAC9G,CAAC;AAED,SAAS,aAAa,CAAC,KAAc;IACnC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;AAC7E,CAAC","sourcesContent":["import { randomBytes } from \"node:crypto\"\nimport { ProtocolError, ProtocolErrorCode, type McpServer } from \"@modelcontextprotocol/server\"\nimport * as z from \"zod\"\nimport type { ProgressUpdate } from \"../command.ts\"\nimport type { AskHandler, DetachedExecution } from \"../invoke.ts\"\nimport type { Principal } from \"../principal.ts\"\nimport type { RegisteredCommand, Registry } from \"../registry.ts\"\nimport { STATE_KEY_PREFIX, type MextState } from \"../state.ts\"\nimport { errorResult, valueResult, type ToolCallResult } from \"./dispatch.ts\"\nimport {\n ASK_KEY_PREFIX,\n askAnswer,\n elicitation,\n elicitResult,\n modeUnavailable,\n type ElicitationModes,\n type ElicitationRequest,\n type ElicitResultValue,\n} from \"./mrtr.ts\"\n\n/**\n * MCP tasks 확장 (io.modelcontextprotocol/tasks, §12.6). 서버 측: task 생성 (invoke detach) · tasks/get · update · cancel.\n *\n * D5: SDK 2.4.0 은 tasks 런타임이 없다 (task 메서드 = 2025-11-25 어휘, typed API 미제공). 단 3-arg setRequestHandler\n * (custom params schema) 로 tasks/get · update · cancel 을 등록할 수 있고 (era gate 통과), Mcp-Name = params.taskId 헤더 검증은\n * SDK 가 한다. tools/call 결과 resultType \"task\" 는 SDK 가 그대로 통과시킨다. 그래서 mext 가 이 파일에서 직접 구현한다.\n *\n * D2: store 키 (값 = JSON, 접두 \"mext:\", 키마다 writer 하나)\n * mext:task:<taskId> TaskRecord. writer = 실행 프로세스 (생성 · 상태 · heartbeat · 결과)\n * mext:task:<taskId>:input:<ask-N> 답 (ElicitResult). writer = tasks/update 를 받은 프로세스. 이미 있으면 무시\n * mext:task:<taskId>:cancel 취소 기록 ({}). writer = tasks/cancel 을 받은 프로세스\n * bus 채널 mext:task:<taskId> = 답 · 취소 도착 알림 ({\"type\":\"input\"|\"cancel\"}). 내용은 store 가 원본, 메시지는 깨우기만.\n * bus 없음 = 실행 프로세스가 storePollMs (1초) 마다 store 폴링. 같은 프로세스의 task = 직접 깨움.\n * store ttl: 실행 중 = ttlMs + lostAfterMs (heartbeat 마다 연장, 유실 후 failed 를 ttlMs 동안 조회), 종료 = ttlMs.\n *\n * R4: ctx.ask 의미 차이. MRTR (동기) = 라운드마다 핸들러 재실행 (ask 이전 코드 반복), task = 재실행 없이 대기\n * (ask 이전 코드 1회). 키 (ask-0 · ask-1 …) · elicitation 형식 · 답 해석 (askAnswer) · 미선언 mode = INPUT_UNAVAILABLE 은 같다.\n * 두 경로 모두에서 맞게 동작하려면 MRTR 규칙 (부작용은 ask 뒤) 을 따른다.\n */\n\nexport const TASKS_EXTENSION = \"io.modelcontextprotocol/tasks\"\n\nexport interface TaskTiming {\n /** CreateTaskResult · tasks/get 의 pollIntervalMs (클라이언트 폴링 권장 간격) */\n pollIntervalMs: number\n /** 실행 프로세스의 heartbeat (레코드 갱신) 간격 */\n heartbeatMs: number\n /** heartbeat 이 이보다 오래 없으면 tasks/get = failed (TASK_LOST) */\n lostAfterMs: number\n /** bus 없음: 실행 프로세스의 답 · 취소 store 폴링 간격 */\n storePollMs: number\n /** close (SIGTERM · SIGINT) 시 실행 중 task 정리 상한 */\n shutdownMs: number\n}\n\nexport const TASK_TIMING: Readonly<TaskTiming> = Object.freeze({\n pollIntervalMs: 2_000,\n heartbeatMs: 10_000,\n lostAfterMs: 30_000,\n storePollMs: 1_000,\n shutdownMs: 5_000,\n})\n\n/** tasks/get failed 의 error.data.code (실행 프로세스 유실) */\nexport const TASK_LOST = \"TASK_LOST\"\n\nexport type TaskStatus = \"working\" | \"input_required\" | \"completed\" | \"failed\" | \"cancelled\"\n\n/** tools/call 의 task 응답 (resultType \"task\") */\nexport interface CreateTaskResult {\n resultType: \"task\"\n taskId: string\n status: TaskStatus\n statusMessage?: string\n createdAt: string\n lastUpdatedAt: string\n ttlMs: number\n pollIntervalMs: number\n _meta?: Record<string, unknown>\n}\n\n/** tasks/get 결과 (resultType 은 SDK 가 \"complete\" 로 채운다) */\nexport interface TaskView {\n taskId: string\n status: TaskStatus\n statusMessage?: string\n createdAt: string\n lastUpdatedAt: string\n ttlMs: number\n pollIntervalMs: number\n /** input_required */\n inputRequests?: Record<string, ElicitationRequest>\n /** completed = 같은 요청의 동기 tools/call 결과 */\n result?: TaskResult\n /** failed (TASK_LOST) */\n error?: TaskError\n}\n\ntype TaskResult = ToolCallResult & { resultType: \"complete\"; _meta?: Record<string, unknown> }\n\ninterface TaskError {\n code: number\n message: string\n data?: Record<string, unknown>\n}\n\n/** D2: mext:task:<taskId> 의 값 */\ninterface TaskRecord {\n v: 1\n taskId: string\n /** 바인딩 \"<kind>:<id>\". 다른 주체 = 없는 task */\n principal: string\n command: string\n status: TaskStatus\n statusMessage?: string\n createdAt: string\n lastUpdatedAt: string\n ttlMs: number\n /** epoch ms. heartbeatMs 마다 갱신 */\n heartbeatAt: number\n inputRequests?: Record<string, ElicitationRequest>\n result?: TaskResult\n}\n\nexport interface TaskRuntimeOptions {\n state: MextState\n timing?: Partial<TaskTiming>\n /** 완료 결과 _meta (동기 결과와 같은 manifestHash) */\n meta?: Record<string, unknown>\n /** store · bus 예외 보고. 기본 stderr 1줄 */\n onerror?: (error: unknown) => void\n}\n\n/** 요청 하나의 task 조건 */\nexport interface TaskRequestOptions {\n principal: Principal\n /** 생성 요청이 선언한 elicitation mode (ctx.ask 가능 여부, MRTR 과 같은 규칙) */\n modes: ElicitationModes\n /** handler.js: 응답 후 실행 유지 (플랫폼 waitUntil) */\n waitUntil?: (promise: Promise<unknown>) => void\n /** 완료 결과 _meta. 기본 = TaskRuntimeOptions.meta (호출자별 manifestHash 를 쓸 때 지정, §4 expose) */\n meta?: Record<string, unknown>\n}\n\nexport interface TaskRequest {\n /** invoke 의 detach. task 명령어가 아니면 undefined (동기) */\n detach: (entry: RegisteredCommand) => Promise<DetachedExecution | undefined>\n /** 생성 중 store · bus 예외 (있으면 요청 = -32603) */\n readonly failure: unknown\n}\n\nexport interface TaskRuntime {\n readonly timing: TaskTiming\n request(options: TaskRequestOptions): TaskRequest\n get(taskId: string, principal: Principal): Promise<TaskView>\n update(taskId: string, principal: Principal, inputResponses: Record<string, unknown>): Promise<void>\n cancel(taskId: string, principal: Principal): Promise<void>\n /** 실행 중 task 취소 → cancelled 기록 (상한 shutdownMs). 이후 새 task 없음 (동기 실행) */\n close(): Promise<void>\n}\n\n/** registry 에 task 명령어가 있는지 (선언 조건) */\nexport function hasTaskCommands(registry: Registry): boolean {\n for (const entry of registry.commands.values()) if (entry.command.task) return true\n return false\n}\n\n/** 요청 _meta 의 clientCapabilities 에 tasks 확장 선언 */\nexport function declaresTasks(clientCapabilities: unknown): boolean {\n const extensions = (clientCapabilities as { extensions?: unknown } | undefined)?.extensions\n return isPlainObject(extensions) && extensions[TASKS_EXTENSION] !== undefined\n}\n\n/**\n * HTTP: task 가 될 수 있는 tools/call 인지 (응답 = application/json, §12.6). 확장 선언 + 대상 명령어가 task 명령어.\n * 대상 = dispatcher 의 arguments.command (별칭 포함), 그 외 = 도구 이름 (command 노출)\n */\nexport function requestsTask(registry: Registry, body: unknown): boolean {\n if (!isPlainObject(body) || body.method !== \"tools/call\" || !isPlainObject(body.params)) return false\n const params = body.params\n const meta = isPlainObject(params._meta) ? params._meta : undefined\n if (!declaresTasks(meta?.[\"io.modelcontextprotocol/clientCapabilities\"])) return false\n const args = isPlainObject(params.arguments) ? params.arguments : undefined\n const target = typeof args?.command === \"string\" ? args.command : params.name\n if (typeof target !== \"string\") return false\n const id = registry.commands.has(target) ? target : registry.aliases.get(target)\n return id !== undefined && registry.commands.get(id)?.command.task !== undefined\n}\n\nconst recordKey = (taskId: string): string => `${STATE_KEY_PREFIX}task:${taskId}`\nconst inputKey = (taskId: string, key: string): string => `${recordKey(taskId)}:input:${key}`\nconst cancelKey = (taskId: string): string => `${recordKey(taskId)}:cancel`\nconst taskChannel = (taskId: string): string => `${STATE_KEY_PREFIX}task:${taskId}`\n\nconst TERMINAL: ReadonlySet<TaskStatus> = new Set([\"completed\", \"failed\", \"cancelled\"])\n\n/** 같은 프로세스에서 실행 중인 task */\ninterface RunningTask {\n /** 답 · 취소를 store 에서 다시 읽는다 */\n wake(): Promise<void>\n abort(reason: unknown): void\n /** 종료 기록 완료 */\n done: Promise<void>\n /** 아직 끝나지 않았으면 cancelled 기록 (종료 상한) */\n forceCancel(): Promise<void>\n}\n\nexport function createTaskRuntime(options: TaskRuntimeOptions): TaskRuntime {\n const { store, bus } = options.state\n const timing: TaskTiming = { ...TASK_TIMING, ...options.timing }\n const meta = options.meta ?? {}\n const report = options.onerror ?? defaultOnError\n const running = new Map<string, RunningTask>()\n let closed = false\n\n /** store · bus 호출. 예외 = 보고 + -32603 */\n const storeCall = async <T>(fn: () => Promise<T>): Promise<T> => {\n try {\n return await fn()\n } catch (error) {\n safeReport(report, error)\n throw new ProtocolError(ProtocolErrorCode.InternalError, \"State store error\")\n }\n }\n\n const readRecord = async (taskId: string, principal: Principal): Promise<TaskRecord> => {\n const raw = await storeCall(() => store.get(recordKey(taskId)))\n const record = raw === undefined ? undefined : parseRecord(raw)\n if (!record || record.taskId !== taskId || record.principal !== bindingOf(principal)) throw unknownTask(taskId)\n return record\n }\n\n const lost = (record: TaskRecord): boolean =>\n !TERMINAL.has(record.status) && Date.now() - record.heartbeatAt > timing.lostAfterMs\n\n /** 답 · 취소 도착 알림: 같은 프로세스 = 직접, 그 외 = bus (없으면 실행 프로세스가 폴링) */\n const notify = async (taskId: string, type: \"input\" | \"cancel\"): Promise<void> => {\n const local = running.get(taskId)\n if (local) {\n await local.wake()\n return\n }\n if (bus) await storeCall(() => bus.publish(taskChannel(taskId), JSON.stringify({ type })))\n }\n\n const start = async (entry: RegisteredCommand, request: TaskRequestOptions): Promise<DetachedExecution> => {\n const taskId = randomBytes(16).toString(\"base64url\")\n const created = new Date().toISOString()\n const record: TaskRecord = {\n v: 1,\n taskId,\n principal: bindingOf(request.principal),\n command: entry.id,\n status: \"working\",\n createdAt: created,\n lastUpdatedAt: created,\n ttlMs: entry.command.task!.ttlMs,\n heartbeatAt: Date.now(),\n }\n const controller = new AbortController()\n const waiters = new Map<string, (answer: ElicitResultValue) => void>()\n let finalized = false\n let resolveDone!: () => void\n const done = new Promise<void>((resolve) => (resolveDone = resolve))\n const touch = (): void => void (record.lastUpdatedAt = new Date().toISOString())\n\n // 순서 보장 · 합치기: 쓰는 중 변경 = 끝난 뒤 최신 상태로 한 번 더\n let writing: Promise<void> | undefined\n let dirty = false\n const persist = (): Promise<void> => {\n dirty = true\n writing ??= (async () => {\n try {\n while (dirty) {\n dirty = false\n const ttlMs = TERMINAL.has(record.status) ? record.ttlMs : record.ttlMs + timing.lostAfterMs\n await store.set(recordKey(taskId), JSON.stringify(record), { ttlMs })\n }\n } finally {\n writing = undefined\n }\n })()\n return writing\n }\n const persistLater = (): void => void persist().catch((error: unknown) => safeReport(report, error))\n\n const wake = async (): Promise<void> => {\n try {\n if (!controller.signal.aborted && (await store.get(cancelKey(taskId))) !== undefined) {\n controller.abort(new DOMException(\"Task cancelled\", \"AbortError\"))\n }\n for (const [key, resolve] of [...waiters]) {\n const raw = await store.get(inputKey(taskId, key))\n const answer = raw === undefined ? undefined : elicitResult(parseJson(raw))\n if (answer) resolve(answer)\n }\n } catch (error) {\n safeReport(report, error)\n }\n }\n\n let heartbeat: ReturnType<typeof setInterval> | undefined\n let poll: ReturnType<typeof setInterval> | undefined\n let unsubscribe: (() => Promise<void>) | undefined\n const stopTimers = (): void => {\n if (heartbeat !== undefined) clearInterval(heartbeat)\n if (poll !== undefined) clearInterval(poll)\n }\n\n const finish = async (): Promise<void> => {\n if (finalized) return\n finalized = true\n stopTimers()\n delete record.inputRequests\n touch()\n waiters.clear()\n try {\n await persist()\n } catch (error) {\n safeReport(report, error)\n }\n running.delete(taskId)\n try {\n await unsubscribe?.()\n } catch (error) {\n safeReport(report, error)\n }\n resolveDone()\n }\n\n let index = 0\n const ask: AskHandler = async (askRequest) => {\n const key = `${ASK_KEY_PREFIX}${index++}`\n if (!(askRequest.kind === \"url\" ? request.modes.url : request.modes.form)) throw modeUnavailable(askRequest)\n controller.signal.throwIfAborted()\n let onAbort!: () => void\n const answered = new Promise<ElicitResultValue>((resolve, reject) => {\n onAbort = () => {\n waiters.delete(key)\n reject(controller.signal.reason)\n }\n controller.signal.addEventListener(\"abort\", onAbort, { once: true })\n waiters.set(key, (answer) => {\n waiters.delete(key)\n controller.signal.removeEventListener(\"abort\", onAbort)\n resolve(answer)\n })\n })\n answered.catch(() => {})\n record.inputRequests = { ...record.inputRequests, [key]: elicitation(askRequest) }\n record.status = \"input_required\"\n touch()\n try {\n await persist()\n } catch (error) {\n waiters.delete(key)\n controller.signal.removeEventListener(\"abort\", onAbort)\n throw error\n }\n const response = await answered\n if (record.inputRequests) {\n delete record.inputRequests[key]\n if (Object.keys(record.inputRequests).length === 0) delete record.inputRequests\n }\n if (!record.inputRequests && !finalized) record.status = \"working\"\n touch()\n if (!finalized) persistLater()\n return askAnswer(askRequest, response)\n }\n\n const progress = (update: ProgressUpdate): void => {\n if (finalized) return\n record.statusMessage =\n update.message ?? (update.total !== undefined ? `${update.progress}/${update.total}` : String(update.progress))\n touch()\n persistLater()\n }\n\n const task: RunningTask = {\n wake,\n abort: (reason) => controller.abort(reason),\n done,\n async forceCancel() {\n if (finalized) return\n record.status = \"cancelled\"\n await finish()\n },\n }\n running.set(taskId, task)\n try {\n if (bus) unsubscribe = await bus.subscribe(taskChannel(taskId), () => void wake())\n // store 기록 후 응답 (tasks/get 이 바로 성공해야 한다)\n await persist()\n } catch (error) {\n running.delete(taskId)\n await unsubscribe?.().catch(() => {})\n throw error\n }\n heartbeat = setInterval(() => {\n record.heartbeatAt = Date.now()\n persistLater()\n }, timing.heartbeatMs)\n heartbeat.unref?.()\n if (!bus) {\n poll = setInterval(() => void wake(), timing.storePollMs)\n poll.unref?.()\n }\n request.waitUntil?.(done)\n\n const handle: CreateTaskResult = {\n resultType: \"task\",\n taskId,\n status: \"working\",\n createdAt: record.createdAt,\n lastUpdatedAt: record.lastUpdatedAt,\n ttlMs: record.ttlMs,\n pollIntervalMs: timing.pollIntervalMs,\n }\n return {\n handle,\n taskId,\n signal: controller.signal,\n ask,\n progress,\n async settle(outcome) {\n if (finalized) return\n if (\"error\" in outcome && controller.signal.aborted) {\n // 취소 후 예외 = cancelled. 핸들러가 끝까지 가면 (값 반환) 그 결과\n record.status = \"cancelled\"\n } else {\n record.status = \"completed\"\n const result = \"error\" in outcome ? errorResult(outcome.error) : valueResult(outcome.value)\n record.result = { ...result, resultType: \"complete\", _meta: { ...(request.meta ?? meta) } }\n }\n await finish()\n },\n }\n }\n\n return {\n timing,\n request(requestOptions) {\n const out: { failure: unknown; detach: TaskRequest[\"detach\"] } = {\n failure: undefined,\n async detach(entry) {\n if (!entry.command.task || closed) return undefined\n try {\n return await start(entry, requestOptions)\n } catch (error) {\n safeReport(report, error)\n out.failure = error\n throw error\n }\n },\n }\n return out\n },\n\n async get(taskId, principal) {\n const record = await readRecord(taskId, principal)\n const view: TaskView = {\n taskId: record.taskId,\n status: record.status,\n ...(record.statusMessage !== undefined ? { statusMessage: record.statusMessage } : {}),\n createdAt: record.createdAt,\n lastUpdatedAt: record.lastUpdatedAt,\n ttlMs: record.ttlMs,\n pollIntervalMs: timing.pollIntervalMs,\n }\n if (lost(record)) {\n view.status = \"failed\"\n view.error = {\n code: ProtocolErrorCode.InternalError,\n message: `Task lost: the executing process stopped (no heartbeat for ${timing.lostAfterMs}ms).`,\n data: { code: TASK_LOST },\n }\n } else if (record.status === \"input_required\" && record.inputRequests) view.inputRequests = record.inputRequests\n else if (record.status === \"completed\" && record.result) view.result = record.result\n return view\n },\n\n async update(taskId, principal, inputResponses) {\n const record = await readRecord(taskId, principal)\n if (TERMINAL.has(record.status) || lost(record)) return\n let wrote = false\n for (const [key, value] of Object.entries(inputResponses)) {\n // 모르는 키 · 형식이 아닌 답 · 이미 답한 키 = 무시\n if (record.inputRequests?.[key] === undefined || !elicitResult(value)) continue\n const stored = await storeCall(() => store.get(inputKey(taskId, key)))\n if (stored !== undefined) continue\n await storeCall(() => store.set(inputKey(taskId, key), JSON.stringify(value), { ttlMs: record.ttlMs + timing.lostAfterMs }))\n wrote = true\n }\n if (wrote) await notify(taskId, \"input\")\n },\n\n async cancel(taskId, principal) {\n const record = await readRecord(taskId, principal)\n if (TERMINAL.has(record.status) || lost(record)) return\n await storeCall(() => store.set(cancelKey(taskId), \"{}\", { ttlMs: record.ttlMs + timing.lostAfterMs }))\n await notify(taskId, \"cancel\")\n },\n\n async close() {\n closed = true\n const tasks = [...running.values()]\n if (tasks.length === 0) return\n for (const task of tasks) task.abort(new DOMException(\"Server shutting down\", \"AbortError\"))\n let timer: ReturnType<typeof setTimeout> | undefined\n await Promise.race([\n Promise.all(tasks.map((task) => task.done)),\n new Promise<void>((resolve) => (timer = setTimeout(resolve, timing.shutdownMs))),\n ])\n clearTimeout(timer)\n await Promise.all(tasks.map((task) => task.forceCancel()))\n },\n }\n}\n\n/**\n * McpServer 에 tasks/get · tasks/update · tasks/cancel 등록 (D5: 3-arg setRequestHandler, custom params schema).\n * declare = server/discover capabilities.extensions 에 확장 선언 (생성 가능할 때만). transport 연결 전에 호출\n */\nexport function installTaskHandlers(server: McpServer, runtime: TaskRuntime, principal: Principal, declare: boolean): void {\n const inner = server.server\n if (declare) inner.registerCapabilities({ extensions: { [TASKS_EXTENSION]: {} } })\n const byId = z.object({ taskId: z.string() })\n inner.setRequestHandler(\"tasks/get\", { params: byId }, async ({ taskId }) => ({ ...(await runtime.get(taskId, principal)) }))\n // inputResponses 는 SDK 가 params 에서 분리 (MRTR 예약 키) → ctx.mcpReq.inputResponses (bare 결과만)\n inner.setRequestHandler(\"tasks/update\", { params: byId }, async ({ taskId }, ctx) => {\n await runtime.update(taskId, principal, ctx.mcpReq.inputResponses ?? {})\n return {}\n })\n inner.setRequestHandler(\"tasks/cancel\", { params: byId }, async ({ taskId }) => {\n await runtime.cancel(taskId, principal)\n return {}\n })\n}\n\nfunction unknownTask(taskId: string): ProtocolError {\n return new ProtocolError(ProtocolErrorCode.InvalidParams, `Unknown task: ${taskId}`)\n}\n\nfunction bindingOf(principal: Principal): string {\n return `${principal.kind}:${principal.id}`\n}\n\nfunction parseRecord(raw: string): TaskRecord | undefined {\n const value = parseJson(raw)\n if (!isPlainObject(value) || value.v !== 1 || typeof value.taskId !== \"string\" || typeof value.status !== \"string\") return undefined\n return value as unknown as TaskRecord\n}\n\nfunction parseJson(raw: string): unknown {\n try {\n return JSON.parse(raw)\n } catch {\n return undefined\n }\n}\n\nfunction safeReport(report: (error: unknown) => void, error: unknown): void {\n try {\n report(error)\n } catch {\n // 보고는 동작을 바꾸지 않는다\n }\n}\n\nfunction defaultOnError(error: unknown): void {\n process.stderr.write(`mext: state store error: ${error instanceof Error ? error.message : String(error)}\\n`)\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n}\n"]}
1
+ {"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../src/mcp/tasks.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomBytes } from \"node:crypto\"\nimport { ProtocolError, ProtocolErrorCode, type McpServer } from \"@modelcontextprotocol/server\"\nimport * as z from \"zod\"\nimport type { ProgressUpdate } from \"../command.ts\"\nimport type { AskHandler, DetachedExecution } from \"../invoke.ts\"\nimport type { Principal } from \"../principal.ts\"\nimport type { RegisteredCommand, Registry } from \"../registry.ts\"\nimport { STATE_KEY_PREFIX, type MextState } from \"../state.ts\"\nimport { errorResult, valueResult, type ToolCallResult } from \"./dispatch.ts\"\nimport {\n ASK_KEY_PREFIX,\n askAnswer,\n elicitation,\n elicitResult,\n modeUnavailable,\n type ElicitationModes,\n type ElicitationRequest,\n type ElicitResultValue,\n} from \"./mrtr.ts\"\n\n/**\n * MCP tasks 확장 (io.modelcontextprotocol/tasks, §12.6). 서버 측: task 생성 (invoke detach) · tasks/get · update · cancel.\n *\n * D5: SDK 2.4.0 은 tasks 런타임이 없다 (task 메서드 = 2025-11-25 어휘, typed API 미제공). 단 3-arg setRequestHandler\n * (custom params schema) 로 tasks/get · update · cancel 을 등록할 수 있고 (era gate 통과), Mcp-Name = params.taskId 헤더 검증은\n * SDK 가 한다. tools/call 결과 resultType \"task\" 는 SDK 가 그대로 통과시킨다. 그래서 mext 가 이 파일에서 직접 구현한다.\n *\n * D2: store 키 (값 = JSON, 접두 \"mext:\", 키마다 writer 하나)\n * mext:task:<taskId> TaskRecord. writer = 실행 프로세스 (생성 · 상태 · heartbeat · 결과)\n * mext:task:<taskId>:input:<ask-N> 답 (ElicitResult). writer = tasks/update 를 받은 프로세스. 이미 있으면 무시\n * mext:task:<taskId>:cancel 취소 기록 ({}). writer = tasks/cancel 을 받은 프로세스\n * bus 채널 mext:task:<taskId> = 답 · 취소 도착 알림 ({\"type\":\"input\"|\"cancel\"}). 내용은 store 가 원본, 메시지는 깨우기만.\n * bus 없음 = 실행 프로세스가 storePollMs (1초) 마다 store 폴링. 같은 프로세스의 task = 직접 깨움.\n * store ttl: 실행 중 = ttlMs + lostAfterMs (heartbeat 마다 연장, 유실 후 failed 를 ttlMs 동안 조회), 종료 = ttlMs.\n *\n * R4: ctx.ask 의미 차이. MRTR (동기) = 라운드마다 핸들러 재실행 (ask 이전 코드 반복), task = 재실행 없이 대기\n * (ask 이전 코드 1회). 키 (ask-0 · ask-1 …) · elicitation 형식 · 답 해석 (askAnswer) · 미선언 mode = INPUT_UNAVAILABLE 은 같다.\n * 두 경로 모두에서 맞게 동작하려면 MRTR 규칙 (부작용은 ask 뒤) 을 따른다.\n */\n\nexport const TASKS_EXTENSION = \"io.modelcontextprotocol/tasks\"\n\nexport interface TaskTiming {\n /** CreateTaskResult · tasks/get 의 pollIntervalMs (클라이언트 폴링 권장 간격) */\n pollIntervalMs: number\n /** 실행 프로세스의 heartbeat (레코드 갱신) 간격 */\n heartbeatMs: number\n /** heartbeat 이 이보다 오래 없으면 tasks/get = failed (TASK_LOST) */\n lostAfterMs: number\n /** bus 없음: 실행 프로세스의 답 · 취소 store 폴링 간격 */\n storePollMs: number\n /** close (SIGTERM · SIGINT) 시 실행 중 task 정리 상한 */\n shutdownMs: number\n}\n\nexport const TASK_TIMING: Readonly<TaskTiming> = Object.freeze({\n pollIntervalMs: 2_000,\n heartbeatMs: 10_000,\n lostAfterMs: 30_000,\n storePollMs: 1_000,\n shutdownMs: 5_000,\n})\n\n/** tasks/get failed 의 error.data.code (실행 프로세스 유실) */\nexport const TASK_LOST = \"TASK_LOST\"\n\nexport type TaskStatus = \"working\" | \"input_required\" | \"completed\" | \"failed\" | \"cancelled\"\n\n/** tools/call 의 task 응답 (resultType \"task\") */\nexport interface CreateTaskResult {\n resultType: \"task\"\n taskId: string\n status: TaskStatus\n statusMessage?: string\n createdAt: string\n lastUpdatedAt: string\n ttlMs: number\n pollIntervalMs: number\n _meta?: Record<string, unknown>\n}\n\n/** tasks/get 결과 (resultType 은 SDK 가 \"complete\" 로 채운다) */\nexport interface TaskView {\n taskId: string\n status: TaskStatus\n statusMessage?: string\n createdAt: string\n lastUpdatedAt: string\n ttlMs: number\n pollIntervalMs: number\n /** input_required */\n inputRequests?: Record<string, ElicitationRequest>\n /** completed = 같은 요청의 동기 tools/call 결과 */\n result?: TaskResult\n /** failed (TASK_LOST) */\n error?: TaskError\n}\n\ntype TaskResult = ToolCallResult & { resultType: \"complete\"; _meta?: Record<string, unknown> }\n\ninterface TaskError {\n code: number\n message: string\n data?: Record<string, unknown>\n}\n\n/** D2: mext:task:<taskId> 의 값 */\ninterface TaskRecord {\n v: 1\n taskId: string\n /** 바인딩 \"<kind>:<id>\". 다른 주체 = 없는 task */\n principal: string\n command: string\n status: TaskStatus\n statusMessage?: string\n createdAt: string\n lastUpdatedAt: string\n ttlMs: number\n /** epoch ms. heartbeatMs 마다 갱신 */\n heartbeatAt: number\n inputRequests?: Record<string, ElicitationRequest>\n result?: TaskResult\n}\n\nexport interface TaskRuntimeOptions {\n state: MextState\n timing?: Partial<TaskTiming>\n /** 완료 결과 _meta (동기 결과와 같은 manifestHash) */\n meta?: Record<string, unknown>\n /** store · bus 예외 보고. 기본 stderr 1줄 */\n onerror?: (error: unknown) => void\n}\n\n/** 요청 하나의 task 조건 */\nexport interface TaskRequestOptions {\n principal: Principal\n /** 생성 요청이 선언한 elicitation mode (ctx.ask 가능 여부, MRTR 과 같은 규칙) */\n modes: ElicitationModes\n /** handler.js: 응답 후 실행 유지 (플랫폼 waitUntil) */\n waitUntil?: (promise: Promise<unknown>) => void\n /** 완료 결과 _meta. 기본 = TaskRuntimeOptions.meta (호출자별 manifestHash 를 쓸 때 지정, §4 expose) */\n meta?: Record<string, unknown>\n}\n\nexport interface TaskRequest {\n /** invoke 의 detach. task 명령어가 아니면 undefined (동기) */\n detach: (entry: RegisteredCommand) => Promise<DetachedExecution | undefined>\n /** 생성 중 store · bus 예외 (있으면 요청 = -32603) */\n readonly failure: unknown\n}\n\nexport interface TaskRuntime {\n readonly timing: TaskTiming\n request(options: TaskRequestOptions): TaskRequest\n get(taskId: string, principal: Principal): Promise<TaskView>\n update(taskId: string, principal: Principal, inputResponses: Record<string, unknown>): Promise<void>\n cancel(taskId: string, principal: Principal): Promise<void>\n /** 실행 중 task 취소 → cancelled 기록 (상한 shutdownMs). 이후 새 task 없음 (동기 실행) */\n close(): Promise<void>\n}\n\n/** registry 에 task 명령어가 있는지 (선언 조건) */\nexport function hasTaskCommands(registry: Registry): boolean {\n for (const entry of registry.commands.values()) if (entry.command.task) return true\n return false\n}\n\n/** 요청 _meta 의 clientCapabilities 에 tasks 확장 선언 */\nexport function declaresTasks(clientCapabilities: unknown): boolean {\n const extensions = (clientCapabilities as { extensions?: unknown } | undefined)?.extensions\n return isPlainObject(extensions) && extensions[TASKS_EXTENSION] !== undefined\n}\n\n/**\n * HTTP: task 가 될 수 있는 tools/call 인지 (응답 = application/json, §12.6). 확장 선언 + 대상 명령어가 task 명령어.\n * 대상 = dispatcher 의 arguments.command (별칭 포함), 그 외 = 도구 이름 (command 노출)\n */\nexport function requestsTask(registry: Registry, body: unknown): boolean {\n if (!isPlainObject(body) || body.method !== \"tools/call\" || !isPlainObject(body.params)) return false\n const params = body.params\n const meta = isPlainObject(params._meta) ? params._meta : undefined\n if (!declaresTasks(meta?.[\"io.modelcontextprotocol/clientCapabilities\"])) return false\n const args = isPlainObject(params.arguments) ? params.arguments : undefined\n const target = typeof args?.command === \"string\" ? args.command : params.name\n if (typeof target !== \"string\") return false\n const id = registry.commands.has(target) ? target : registry.aliases.get(target)\n return id !== undefined && registry.commands.get(id)?.command.task !== undefined\n}\n\nconst recordKey = (taskId: string): string => `${STATE_KEY_PREFIX}task:${taskId}`\nconst inputKey = (taskId: string, key: string): string => `${recordKey(taskId)}:input:${key}`\nconst cancelKey = (taskId: string): string => `${recordKey(taskId)}:cancel`\nconst taskChannel = (taskId: string): string => `${STATE_KEY_PREFIX}task:${taskId}`\n\nconst TERMINAL: ReadonlySet<TaskStatus> = new Set([\"completed\", \"failed\", \"cancelled\"])\n\n/** 같은 프로세스에서 실행 중인 task */\ninterface RunningTask {\n /** 답 · 취소를 store 에서 다시 읽는다 */\n wake(): Promise<void>\n abort(reason: unknown): void\n /** 종료 기록 완료 */\n done: Promise<void>\n /** 아직 끝나지 않았으면 cancelled 기록 (종료 상한) */\n forceCancel(): Promise<void>\n}\n\nexport function createTaskRuntime(options: TaskRuntimeOptions): TaskRuntime {\n const { store, bus } = options.state\n const timing: TaskTiming = { ...TASK_TIMING, ...options.timing }\n const meta = options.meta ?? {}\n const report = options.onerror ?? defaultOnError\n const running = new Map<string, RunningTask>()\n let closed = false\n\n /** store · bus 호출. 예외 = 보고 + -32603 */\n const storeCall = async <T>(fn: () => Promise<T>): Promise<T> => {\n try {\n return await fn()\n } catch (error) {\n safeReport(report, error)\n throw new ProtocolError(ProtocolErrorCode.InternalError, \"State store error\")\n }\n }\n\n const readRecord = async (taskId: string, principal: Principal): Promise<TaskRecord> => {\n const raw = await storeCall(() => store.get(recordKey(taskId)))\n const record = raw === undefined ? undefined : parseRecord(raw)\n if (!record || record.taskId !== taskId || record.principal !== bindingOf(principal)) throw unknownTask(taskId)\n return record\n }\n\n const lost = (record: TaskRecord): boolean =>\n !TERMINAL.has(record.status) && Date.now() - record.heartbeatAt > timing.lostAfterMs\n\n /** 답 · 취소 도착 알림: 같은 프로세스 = 직접, 그 외 = bus (없으면 실행 프로세스가 폴링) */\n const notify = async (taskId: string, type: \"input\" | \"cancel\"): Promise<void> => {\n const local = running.get(taskId)\n if (local) {\n await local.wake()\n return\n }\n if (bus) await storeCall(() => bus.publish(taskChannel(taskId), JSON.stringify({ type })))\n }\n\n const start = async (entry: RegisteredCommand, request: TaskRequestOptions): Promise<DetachedExecution> => {\n const taskId = randomBytes(16).toString(\"base64url\")\n const created = new Date().toISOString()\n const record: TaskRecord = {\n v: 1,\n taskId,\n principal: bindingOf(request.principal),\n command: entry.id,\n status: \"working\",\n createdAt: created,\n lastUpdatedAt: created,\n ttlMs: entry.command.task!.ttlMs,\n heartbeatAt: Date.now(),\n }\n const controller = new AbortController()\n const waiters = new Map<string, (answer: ElicitResultValue) => void>()\n let finalized = false\n let resolveDone!: () => void\n const done = new Promise<void>((resolve) => (resolveDone = resolve))\n const touch = (): void => void (record.lastUpdatedAt = new Date().toISOString())\n\n // 순서 보장 · 합치기: 쓰는 중 변경 = 끝난 뒤 최신 상태로 한 번 더\n let writing: Promise<void> | undefined\n let dirty = false\n const persist = (): Promise<void> => {\n dirty = true\n writing ??= (async () => {\n try {\n while (dirty) {\n dirty = false\n const ttlMs = TERMINAL.has(record.status) ? record.ttlMs : record.ttlMs + timing.lostAfterMs\n await store.set(recordKey(taskId), JSON.stringify(record), { ttlMs })\n }\n } finally {\n writing = undefined\n }\n })()\n return writing\n }\n const persistLater = (): void => void persist().catch((error: unknown) => safeReport(report, error))\n\n const wake = async (): Promise<void> => {\n try {\n if (!controller.signal.aborted && (await store.get(cancelKey(taskId))) !== undefined) {\n controller.abort(new DOMException(\"Task cancelled\", \"AbortError\"))\n }\n for (const [key, resolve] of [...waiters]) {\n const raw = await store.get(inputKey(taskId, key))\n const answer = raw === undefined ? undefined : elicitResult(parseJson(raw))\n if (answer) resolve(answer)\n }\n } catch (error) {\n safeReport(report, error)\n }\n }\n\n let heartbeat: ReturnType<typeof setInterval> | undefined\n let poll: ReturnType<typeof setInterval> | undefined\n let unsubscribe: (() => Promise<void>) | undefined\n const stopTimers = (): void => {\n if (heartbeat !== undefined) clearInterval(heartbeat)\n if (poll !== undefined) clearInterval(poll)\n }\n\n const finish = async (): Promise<void> => {\n if (finalized) return\n finalized = true\n stopTimers()\n delete record.inputRequests\n touch()\n waiters.clear()\n try {\n await persist()\n } catch (error) {\n safeReport(report, error)\n }\n running.delete(taskId)\n try {\n await unsubscribe?.()\n } catch (error) {\n safeReport(report, error)\n }\n resolveDone()\n }\n\n let index = 0\n const ask: AskHandler = async (askRequest) => {\n const key = `${ASK_KEY_PREFIX}${index++}`\n if (!(askRequest.kind === \"url\" ? request.modes.url : request.modes.form)) throw modeUnavailable(askRequest)\n controller.signal.throwIfAborted()\n let onAbort!: () => void\n const answered = new Promise<ElicitResultValue>((resolve, reject) => {\n onAbort = () => {\n waiters.delete(key)\n reject(controller.signal.reason)\n }\n controller.signal.addEventListener(\"abort\", onAbort, { once: true })\n waiters.set(key, (answer) => {\n waiters.delete(key)\n controller.signal.removeEventListener(\"abort\", onAbort)\n resolve(answer)\n })\n })\n answered.catch(() => {})\n record.inputRequests = { ...record.inputRequests, [key]: elicitation(askRequest) }\n record.status = \"input_required\"\n touch()\n try {\n await persist()\n } catch (error) {\n waiters.delete(key)\n controller.signal.removeEventListener(\"abort\", onAbort)\n throw error\n }\n const response = await answered\n if (record.inputRequests) {\n delete record.inputRequests[key]\n if (Object.keys(record.inputRequests).length === 0) delete record.inputRequests\n }\n if (!record.inputRequests && !finalized) record.status = \"working\"\n touch()\n if (!finalized) persistLater()\n return askAnswer(askRequest, response)\n }\n\n const progress = (update: ProgressUpdate): void => {\n if (finalized) return\n record.statusMessage =\n update.message ?? (update.total !== undefined ? `${update.progress}/${update.total}` : String(update.progress))\n touch()\n persistLater()\n }\n\n const task: RunningTask = {\n wake,\n abort: (reason) => controller.abort(reason),\n done,\n async forceCancel() {\n if (finalized) return\n record.status = \"cancelled\"\n await finish()\n },\n }\n running.set(taskId, task)\n try {\n if (bus) unsubscribe = await bus.subscribe(taskChannel(taskId), () => void wake())\n // store 기록 후 응답 (tasks/get 이 바로 성공해야 한다)\n await persist()\n } catch (error) {\n running.delete(taskId)\n await unsubscribe?.().catch(() => {})\n throw error\n }\n heartbeat = setInterval(() => {\n record.heartbeatAt = Date.now()\n persistLater()\n }, timing.heartbeatMs)\n heartbeat.unref?.()\n if (!bus) {\n poll = setInterval(() => void wake(), timing.storePollMs)\n poll.unref?.()\n }\n request.waitUntil?.(done)\n\n const handle: CreateTaskResult = {\n resultType: \"task\",\n taskId,\n status: \"working\",\n createdAt: record.createdAt,\n lastUpdatedAt: record.lastUpdatedAt,\n ttlMs: record.ttlMs,\n pollIntervalMs: timing.pollIntervalMs,\n }\n return {\n handle,\n taskId,\n signal: controller.signal,\n ask,\n progress,\n async settle(outcome) {\n if (finalized) return\n if (\"error\" in outcome && controller.signal.aborted) {\n // 취소 후 예외 = cancelled. 핸들러가 끝까지 가면 (값 반환) 그 결과\n record.status = \"cancelled\"\n } else {\n record.status = \"completed\"\n const result = \"error\" in outcome ? errorResult(outcome.error) : valueResult(outcome.value, outcome.content)\n record.result = { ...result, resultType: \"complete\", _meta: { ...(request.meta ?? meta) } }\n }\n await finish()\n },\n }\n }\n\n return {\n timing,\n request(requestOptions) {\n const out: { failure: unknown; detach: TaskRequest[\"detach\"] } = {\n failure: undefined,\n async detach(entry) {\n if (!entry.command.task || closed) return undefined\n try {\n return await start(entry, requestOptions)\n } catch (error) {\n safeReport(report, error)\n out.failure = error\n throw error\n }\n },\n }\n return out\n },\n\n async get(taskId, principal) {\n const record = await readRecord(taskId, principal)\n const view: TaskView = {\n taskId: record.taskId,\n status: record.status,\n ...(record.statusMessage !== undefined ? { statusMessage: record.statusMessage } : {}),\n createdAt: record.createdAt,\n lastUpdatedAt: record.lastUpdatedAt,\n ttlMs: record.ttlMs,\n pollIntervalMs: timing.pollIntervalMs,\n }\n if (lost(record)) {\n view.status = \"failed\"\n view.error = {\n code: ProtocolErrorCode.InternalError,\n message: `Task lost: the executing process stopped (no heartbeat for ${timing.lostAfterMs}ms).`,\n data: { code: TASK_LOST },\n }\n } else if (record.status === \"input_required\" && record.inputRequests) view.inputRequests = record.inputRequests\n else if (record.status === \"completed\" && record.result) view.result = record.result\n return view\n },\n\n async update(taskId, principal, inputResponses) {\n const record = await readRecord(taskId, principal)\n if (TERMINAL.has(record.status) || lost(record)) return\n let wrote = false\n for (const [key, value] of Object.entries(inputResponses)) {\n // 모르는 키 · 형식이 아닌 답 · 이미 답한 키 = 무시\n if (record.inputRequests?.[key] === undefined || !elicitResult(value)) continue\n const stored = await storeCall(() => store.get(inputKey(taskId, key)))\n if (stored !== undefined) continue\n await storeCall(() => store.set(inputKey(taskId, key), JSON.stringify(value), { ttlMs: record.ttlMs + timing.lostAfterMs }))\n wrote = true\n }\n if (wrote) await notify(taskId, \"input\")\n },\n\n async cancel(taskId, principal) {\n const record = await readRecord(taskId, principal)\n if (TERMINAL.has(record.status) || lost(record)) return\n await storeCall(() => store.set(cancelKey(taskId), \"{}\", { ttlMs: record.ttlMs + timing.lostAfterMs }))\n await notify(taskId, \"cancel\")\n },\n\n async close() {\n closed = true\n const tasks = [...running.values()]\n if (tasks.length === 0) return\n for (const task of tasks) task.abort(new DOMException(\"Server shutting down\", \"AbortError\"))\n let timer: ReturnType<typeof setTimeout> | undefined\n await Promise.race([\n Promise.all(tasks.map((task) => task.done)),\n new Promise<void>((resolve) => (timer = setTimeout(resolve, timing.shutdownMs))),\n ])\n clearTimeout(timer)\n await Promise.all(tasks.map((task) => task.forceCancel()))\n },\n }\n}\n\n/**\n * McpServer 에 tasks/get · tasks/update · tasks/cancel 등록 (D5: 3-arg setRequestHandler, custom params schema).\n * declare = server/discover capabilities.extensions 에 확장 선언 (생성 가능할 때만). transport 연결 전에 호출\n */\nexport function installTaskHandlers(server: McpServer, runtime: TaskRuntime, principal: Principal, declare: boolean): void {\n const inner = server.server\n if (declare) inner.registerCapabilities({ extensions: { [TASKS_EXTENSION]: {} } })\n const byId = z.object({ taskId: z.string() })\n inner.setRequestHandler(\"tasks/get\", { params: byId }, async ({ taskId }) => ({ ...(await runtime.get(taskId, principal)) }))\n // inputResponses 는 SDK 가 params 에서 분리 (MRTR 예약 키) → ctx.mcpReq.inputResponses (bare 결과만)\n inner.setRequestHandler(\"tasks/update\", { params: byId }, async ({ taskId }, ctx) => {\n await runtime.update(taskId, principal, ctx.mcpReq.inputResponses ?? {})\n return {}\n })\n inner.setRequestHandler(\"tasks/cancel\", { params: byId }, async ({ taskId }) => {\n await runtime.cancel(taskId, principal)\n return {}\n })\n}\n\nfunction unknownTask(taskId: string): ProtocolError {\n return new ProtocolError(ProtocolErrorCode.InvalidParams, `Unknown task: ${taskId}`)\n}\n\nfunction bindingOf(principal: Principal): string {\n return `${principal.kind}:${principal.id}`\n}\n\nfunction parseRecord(raw: string): TaskRecord | undefined {\n const value = parseJson(raw)\n if (!isPlainObject(value) || value.v !== 1 || typeof value.taskId !== \"string\" || typeof value.status !== \"string\") return undefined\n return value as unknown as TaskRecord\n}\n\nfunction parseJson(raw: string): unknown {\n try {\n return JSON.parse(raw)\n } catch {\n return undefined\n }\n}\n\nfunction safeReport(report: (error: unknown) => void, error: unknown): void {\n try {\n report(error)\n } catch {\n // 보고는 동작을 바꾸지 않는다\n }\n}\n\nfunction defaultOnError(error: unknown): void {\n process.stderr.write(`mext: state store error: ${error instanceof Error ? error.message : String(error)}\\n`)\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n}\n"]}
@@ -4,7 +4,8 @@
4
4
  * Mcp-Name · Mcp-Param-* 헤더. 응답 = application/json 또는 text/event-stream (progress 알림 → onNotification).
5
5
  * MRTR (InputRequiredResult) 재시도 루프는 callTool 의 onInputRequired 가 담당.
6
6
  * tasks 확장 (§12.6) 선언: tools/call 이 CreateTaskResult (resultType "task") 를 그대로 돌려주고, 폴링 · 답 · 취소 =
7
- * getTask · updateTask · cancelTask (Mcp-Name = taskId). 폴링 루프는 client/task.ts
7
+ * getTask · updateTask · cancelTask (Mcp-Name = taskId). 폴링 루프는 client/task.ts.
8
+ * subscriptions/listen (mext.md §12.5) = listen: 응답 SSE 를 ack 뒤에도 계속 읽는다 (타입 client subscribe)
8
9
  */
9
10
  export declare const PROTOCOL_VERSION = "2026-07-28";
10
11
  export declare const META_KEYS: {
@@ -105,9 +106,31 @@ export interface ToolsListResult {
105
106
  ttlMs?: number;
106
107
  cacheScope?: string;
107
108
  }
109
+ /** subscriptions/listen 스트림 종료. client = close · signal, server = 완료 result · 스트림 끝, error = 연결 오류 · JSON-RPC 오류 */
110
+ export type ListenEnd = {
111
+ reason: "client";
112
+ } | {
113
+ reason: "server";
114
+ } | {
115
+ reason: "error";
116
+ error: unknown;
117
+ };
118
+ /** ack 를 받은 subscriptions/listen 스트림 */
119
+ export interface RemoteListen {
120
+ /** ack (notifications/subscriptions/acknowledged) 의 notifications. ack 없이 완료 = {} */
121
+ readonly acknowledged: Record<string, unknown>;
122
+ /** 스트림 종료 (reject 하지 않는다) */
123
+ readonly done: Promise<ListenEnd>;
124
+ close(): void;
125
+ }
108
126
  export interface RemoteClient {
109
127
  readonly url: string;
110
128
  request(method: string, params?: Record<string, unknown>, options?: RequestOptions): Promise<Record<string, unknown>>;
129
+ /**
130
+ * subscriptions/listen. ack 까지 기다린 뒤 스트림을 계속 읽는다 (알림 = onNotification).
131
+ * ack 전 실패 = reject (401 · JSON-RPC 오류 · 연결 실패 · ack 전 abort = signal.reason)
132
+ */
133
+ listen(notifications: Record<string, unknown>, options?: RequestOptions): Promise<RemoteListen>;
111
134
  listTools(options?: RequestOptions): Promise<RemoteTool[]>;
112
135
  listToolsResult(options?: RequestOptions): Promise<ToolsListResult>;
113
136
  callTool(tool: RemoteTool, args: Record<string, unknown>, options?: CallToolOptions): Promise<CallToolResult>;
@@ -5,7 +5,8 @@ import { VERSION } from "../version-constant.js";
5
5
  * Mcp-Name · Mcp-Param-* 헤더. 응답 = application/json 또는 text/event-stream (progress 알림 → onNotification).
6
6
  * MRTR (InputRequiredResult) 재시도 루프는 callTool 의 onInputRequired 가 담당.
7
7
  * tasks 확장 (§12.6) 선언: tools/call 이 CreateTaskResult (resultType "task") 를 그대로 돌려주고, 폴링 · 답 · 취소 =
8
- * getTask · updateTask · cancelTask (Mcp-Name = taskId). 폴링 루프는 client/task.ts
8
+ * getTask · updateTask · cancelTask (Mcp-Name = taskId). 폴링 루프는 client/task.ts.
9
+ * subscriptions/listen (mext.md §12.5) = listen: 응답 SSE 를 ack 뒤에도 계속 읽는다 (타입 client subscribe)
9
10
  */
10
11
  export const PROTOCOL_VERSION = "2026-07-28";
11
12
  export const META_KEYS = {
@@ -66,7 +67,8 @@ export function createRemoteClient(options) {
66
67
  const doFetch = options.fetch ?? fetch;
67
68
  const clientInfo = options.clientInfo ?? { name: "mext", version: VERSION };
68
69
  let nextId = 1;
69
- const request = async (method, params = {}, opts = {}, extraHeaders = {}) => {
70
+ /** POST 1회. 401 = RemoteUnauthorizedError. 응답 본문은 호출자가 읽는다 */
71
+ const send = async (method, params, opts, extraHeaders) => {
70
72
  const id = nextId++;
71
73
  const meta = {
72
74
  ...(isRecord(params._meta) ? params._meta : {}),
@@ -101,20 +103,114 @@ export function createRemoteClient(options) {
101
103
  throw error;
102
104
  throw new RemoteTransportError(`Cannot reach ${options.url}: ${errorMessage(error)}`, { cause: error });
103
105
  }
104
- const type = res.headers.get("content-type") ?? "";
105
106
  if (res.status === 401) {
106
107
  const payload = await readJson(res);
107
108
  const err = isRecord(payload) && isRecord(payload.error) ? payload.error : {};
108
109
  throw new RemoteUnauthorizedError(typeof err.message === "string" ? err.message : "Authentication required.", parseBearerChallenge(res.headers.get("www-authenticate")), err.data);
109
110
  }
110
- if (type.includes("text/event-stream")) {
111
+ return { res, id };
112
+ };
113
+ const request = async (method, params = {}, opts = {}, extraHeaders = {}) => {
114
+ const { res, id } = await send(method, params, opts, extraHeaders);
115
+ if (isEventStream(res)) {
111
116
  return handleMessage(await readSse(res, id, opts), id, res.status);
112
117
  }
118
+ return handleMessage(await jsonMessage(res), id, res.status);
119
+ };
120
+ const jsonMessage = async (res) => {
113
121
  const payload = await readJson(res);
114
122
  if (payload === undefined) {
115
123
  throw new RemoteTransportError(`${options.url} returned HTTP ${res.status} without a JSON-RPC response.`);
116
124
  }
117
- return handleMessage(payload, id, res.status);
125
+ return payload;
126
+ };
127
+ const listen = async (notifications, opts = {}) => {
128
+ const { signal } = opts;
129
+ signal?.throwIfAborted();
130
+ const { res, id } = await send("subscriptions/listen", { notifications }, opts, {});
131
+ if (!isEventStream(res)) {
132
+ // JSON 응답 = 오류 (handleMessage 가 던진다) 또는 ack 없는 완료
133
+ handleMessage(await jsonMessage(res), id, res.status);
134
+ return { acknowledged: {}, done: Promise.resolve({ reason: "server" }), close() { } };
135
+ }
136
+ const stream = sseStream(res);
137
+ let closed = false;
138
+ const close = () => {
139
+ if (closed)
140
+ return;
141
+ closed = true;
142
+ void stream.cancel();
143
+ };
144
+ signal?.addEventListener("abort", close, { once: true });
145
+ const notify = (message) => {
146
+ try {
147
+ opts.onNotification?.(message.method, isRecord(message.params) ? message.params : {});
148
+ }
149
+ catch {
150
+ // 수신자 예외는 스트림에 영향 없음
151
+ }
152
+ };
153
+ // ack 까지. 그 전의 완료 result = ack 없는 완료, 오류 = reject
154
+ let acknowledged;
155
+ try {
156
+ while (acknowledged === undefined) {
157
+ const message = await stream.next();
158
+ if (message === undefined)
159
+ throw new RemoteTransportError("Event stream ended before subscriptions/listen was acknowledged.");
160
+ if (message.method === "notifications/subscriptions/acknowledged") {
161
+ const params = isRecord(message.params) ? message.params : {};
162
+ acknowledged = isRecord(params.notifications) ? params.notifications : {};
163
+ }
164
+ else if (isNotification(message))
165
+ notify(message);
166
+ else if (message.id === id) {
167
+ handleMessage(message, id, res.status);
168
+ signal?.removeEventListener("abort", close);
169
+ await stream.cancel();
170
+ return { acknowledged: {}, done: Promise.resolve({ reason: "server" }), close() { } };
171
+ }
172
+ }
173
+ }
174
+ catch (error) {
175
+ signal?.removeEventListener("abort", close);
176
+ await stream.cancel();
177
+ if (signal?.aborted)
178
+ throw signal.reason;
179
+ throw error;
180
+ }
181
+ const done = (async () => {
182
+ try {
183
+ for (;;) {
184
+ let message;
185
+ try {
186
+ message = await stream.next();
187
+ }
188
+ catch (error) {
189
+ return closed ? { reason: "client" } : { reason: "error", error };
190
+ }
191
+ if (closed)
192
+ return { reason: "client" };
193
+ if (message === undefined)
194
+ return { reason: "server" };
195
+ if (isNotification(message))
196
+ notify(message);
197
+ else if (message.id === id) {
198
+ try {
199
+ handleMessage(message, id, res.status);
200
+ return { reason: "server" };
201
+ }
202
+ catch (error) {
203
+ return { reason: "error", error };
204
+ }
205
+ }
206
+ }
207
+ }
208
+ finally {
209
+ signal?.removeEventListener("abort", close);
210
+ await stream.cancel();
211
+ }
212
+ })();
213
+ return { acknowledged, done, close };
118
214
  };
119
215
  const handleMessage = (message, id, status) => {
120
216
  if (!isRecord(message))
@@ -183,6 +279,7 @@ export function createRemoteClient(options) {
183
279
  return {
184
280
  url: options.url,
185
281
  request: (method, params, opts) => request(method, params, opts),
282
+ listen,
186
283
  listTools: async (opts) => (await listToolsResult(opts)).tools,
187
284
  listToolsResult,
188
285
  callTool,
@@ -212,77 +309,104 @@ function paramHeaders(tool, args) {
212
309
  return out;
213
310
  }
214
311
  /* SSE */
312
+ function isEventStream(res) {
313
+ return (res.headers.get("content-type") ?? "").includes("text/event-stream");
314
+ }
315
+ function isNotification(message) {
316
+ return typeof message.method === "string" && message.id === undefined;
317
+ }
215
318
  /** 응답 스트림에서 id 의 응답 메시지가 올 때까지 읽는다. 알림은 콜백, 응답 후 스트림을 닫는다 */
216
319
  async function readSse(res, id, opts) {
320
+ const stream = sseStream(res);
321
+ try {
322
+ for (let message = await stream.next(); message !== undefined; message = await stream.next()) {
323
+ if (isNotification(message)) {
324
+ try {
325
+ opts.onNotification?.(message.method, isRecord(message.params) ? message.params : {});
326
+ }
327
+ catch {
328
+ // 표시 오류는 응답에 영향 없음
329
+ }
330
+ continue;
331
+ }
332
+ if (message.id === id && ("result" in message || "error" in message))
333
+ return message;
334
+ }
335
+ }
336
+ finally {
337
+ await stream.cancel();
338
+ }
339
+ if (opts.signal?.aborted)
340
+ throw opts.signal.reason;
341
+ throw new RemoteTransportError("Event stream ended without a response.");
342
+ }
343
+ function sseStream(res) {
217
344
  if (!res.body)
218
345
  throw new RemoteTransportError("Empty event stream.");
219
346
  const reader = res.body.pipeThrough(new TextDecoderStream()).getReader();
220
347
  let buffer = "";
221
348
  let data = [];
349
+ let ended = false;
222
350
  const dispatch = () => {
223
351
  if (data.length === 0)
224
352
  return undefined;
225
353
  const text = data.join("\n");
226
354
  data = [];
227
- let message;
228
355
  try {
229
- message = JSON.parse(text);
356
+ const message = JSON.parse(text);
357
+ return isRecord(message) ? message : undefined;
230
358
  }
231
359
  catch {
232
360
  return undefined;
233
361
  }
234
- if (!isRecord(message))
235
- return undefined;
236
- if (typeof message.method === "string" && message.id === undefined) {
237
- try {
238
- opts.onNotification?.(message.method, isRecord(message.params) ? message.params : {});
239
- }
240
- catch {
241
- // 표시 오류는 응답에 영향 없음
362
+ };
363
+ /** buffer 의 완성된 줄을 처리. 이벤트 경계에서 메시지가 나오면 그 메시지 */
364
+ const drain = () => {
365
+ let nl;
366
+ while ((nl = buffer.search(/\r\n|\r|\n/)) >= 0) {
367
+ const line = buffer.slice(0, nl);
368
+ buffer = buffer.slice(nl + (buffer.startsWith("\r\n", nl) ? 2 : 1));
369
+ if (line === "") {
370
+ const found = dispatch();
371
+ if (found !== undefined)
372
+ return found;
373
+ continue;
242
374
  }
243
- return undefined;
375
+ if (line.startsWith(":"))
376
+ continue;
377
+ const colon = line.indexOf(":");
378
+ const field = colon < 0 ? line : line.slice(0, colon);
379
+ let value = colon < 0 ? "" : line.slice(colon + 1);
380
+ if (value.startsWith(" "))
381
+ value = value.slice(1);
382
+ if (field === "data")
383
+ data.push(value);
244
384
  }
245
- if (message.id === id && ("result" in message || "error" in message))
246
- return message;
247
385
  return undefined;
248
386
  };
249
- try {
250
- for (;;) {
251
- const { done, value } = await reader.read();
252
- if (done)
253
- break;
254
- buffer += value;
255
- let nl;
256
- while ((nl = buffer.search(/\r\n|\r|\n/)) >= 0) {
257
- const line = buffer.slice(0, nl);
258
- buffer = buffer.slice(nl + (buffer.startsWith("\r\n", nl) ? 2 : 1));
259
- if (line === "") {
260
- const found = dispatch();
261
- if (found !== undefined)
262
- return found;
263
- continue;
387
+ return {
388
+ async next() {
389
+ for (;;) {
390
+ const found = drain();
391
+ if (found !== undefined)
392
+ return found;
393
+ if (ended)
394
+ return undefined;
395
+ const { done, value } = await reader.read();
396
+ if (done) {
397
+ ended = true;
398
+ return dispatch();
264
399
  }
265
- if (line.startsWith(":"))
266
- continue;
267
- const colon = line.indexOf(":");
268
- const field = colon < 0 ? line : line.slice(0, colon);
269
- let value = colon < 0 ? "" : line.slice(colon + 1);
270
- if (value.startsWith(" "))
271
- value = value.slice(1);
272
- if (field === "data")
273
- data.push(value);
400
+ buffer += value;
274
401
  }
275
- }
276
- const found = dispatch();
277
- if (found !== undefined)
278
- return found;
279
- }
280
- finally {
281
- await reader.cancel().catch(() => { });
282
- }
283
- if (opts.signal?.aborted)
284
- throw opts.signal.reason;
285
- throw new RemoteTransportError("Event stream ended without a response.");
402
+ },
403
+ async cancel() {
404
+ ended = true;
405
+ buffer = "";
406
+ data = [];
407
+ await reader.cancel().catch(() => { });
408
+ },
409
+ };
286
410
  }
287
411
  async function readJson(res) {
288
412
  const text = await res.text().catch(() => "");