@agentteams/cli 0.1.75 → 0.1.77

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 (93) hide show
  1. package/.eslintcache +1 -1
  2. package/dist/api/convention.d.ts +11 -0
  3. package/dist/api/convention.d.ts.map +1 -0
  4. package/dist/api/convention.js +26 -0
  5. package/dist/api/convention.js.map +1 -0
  6. package/dist/api/worktree.d.ts +13 -0
  7. package/dist/api/worktree.d.ts.map +1 -0
  8. package/dist/api/worktree.js +8 -0
  9. package/dist/api/worktree.js.map +1 -0
  10. package/dist/commands/convention.d.ts.map +1 -1
  11. package/dist/commands/convention.js +6 -8
  12. package/dist/commands/convention.js.map +1 -1
  13. package/dist/commands/index.d.ts.map +1 -1
  14. package/dist/commands/index.js +4 -19
  15. package/dist/commands/index.js.map +1 -1
  16. package/dist/commands/mcp.d.ts +13 -0
  17. package/dist/commands/mcp.d.ts.map +1 -0
  18. package/dist/commands/mcp.js +13 -0
  19. package/dist/commands/mcp.js.map +1 -0
  20. package/dist/commands/search.d.ts.map +1 -1
  21. package/dist/commands/search.js +8 -35
  22. package/dist/commands/search.js.map +1 -1
  23. package/dist/commands/worktree.d.ts +9 -0
  24. package/dist/commands/worktree.d.ts.map +1 -0
  25. package/dist/commands/worktree.js +119 -0
  26. package/dist/commands/worktree.js.map +1 -0
  27. package/dist/index.js +101 -0
  28. package/dist/index.js.map +1 -1
  29. package/dist/mcp/context.d.ts +15 -0
  30. package/dist/mcp/context.d.ts.map +1 -0
  31. package/dist/mcp/context.js +47 -0
  32. package/dist/mcp/context.js.map +1 -0
  33. package/dist/mcp/resources.d.ts +17 -0
  34. package/dist/mcp/resources.d.ts.map +1 -0
  35. package/dist/mcp/resources.js +50 -0
  36. package/dist/mcp/resources.js.map +1 -0
  37. package/dist/mcp/server.d.ts +20 -0
  38. package/dist/mcp/server.d.ts.map +1 -0
  39. package/dist/mcp/server.js +106 -0
  40. package/dist/mcp/server.js.map +1 -0
  41. package/dist/mcp/tools.d.ts +20 -0
  42. package/dist/mcp/tools.d.ts.map +1 -0
  43. package/dist/mcp/tools.js +172 -0
  44. package/dist/mcp/tools.js.map +1 -0
  45. package/dist/mcp-registration/atomicWrite.d.ts +26 -0
  46. package/dist/mcp-registration/atomicWrite.d.ts.map +1 -0
  47. package/dist/mcp-registration/atomicWrite.js +58 -0
  48. package/dist/mcp-registration/atomicWrite.js.map +1 -0
  49. package/dist/mcp-registration/clients.d.ts +5 -0
  50. package/dist/mcp-registration/clients.d.ts.map +1 -0
  51. package/dist/mcp-registration/clients.js +300 -0
  52. package/dist/mcp-registration/clients.js.map +1 -0
  53. package/dist/mcp-registration/detect.d.ts +23 -0
  54. package/dist/mcp-registration/detect.d.ts.map +1 -0
  55. package/dist/mcp-registration/detect.js +48 -0
  56. package/dist/mcp-registration/detect.js.map +1 -0
  57. package/dist/mcp-registration/index.d.ts +50 -0
  58. package/dist/mcp-registration/index.d.ts.map +1 -0
  59. package/dist/mcp-registration/index.js +205 -0
  60. package/dist/mcp-registration/index.js.map +1 -0
  61. package/dist/mcp-registration/install.d.ts +66 -0
  62. package/dist/mcp-registration/install.d.ts.map +1 -0
  63. package/dist/mcp-registration/install.js +244 -0
  64. package/dist/mcp-registration/install.js.map +1 -0
  65. package/dist/mcp-registration/jsonc.d.ts +44 -0
  66. package/dist/mcp-registration/jsonc.d.ts.map +1 -0
  67. package/dist/mcp-registration/jsonc.js +266 -0
  68. package/dist/mcp-registration/jsonc.js.map +1 -0
  69. package/dist/mcp-registration/render.d.ts +18 -0
  70. package/dist/mcp-registration/render.d.ts.map +1 -0
  71. package/dist/mcp-registration/render.js +91 -0
  72. package/dist/mcp-registration/render.js.map +1 -0
  73. package/dist/mcp-registration/serverSpec.d.ts +31 -0
  74. package/dist/mcp-registration/serverSpec.d.ts.map +1 -0
  75. package/dist/mcp-registration/serverSpec.js +29 -0
  76. package/dist/mcp-registration/serverSpec.js.map +1 -0
  77. package/dist/mcp-registration/types.d.ts +98 -0
  78. package/dist/mcp-registration/types.d.ts.map +1 -0
  79. package/dist/mcp-registration/types.js +12 -0
  80. package/dist/mcp-registration/types.js.map +1 -0
  81. package/dist/mcp-registration/vendorCommand.d.ts +18 -0
  82. package/dist/mcp-registration/vendorCommand.d.ts.map +1 -0
  83. package/dist/mcp-registration/vendorCommand.js +27 -0
  84. package/dist/mcp-registration/vendorCommand.js.map +1 -0
  85. package/dist/utils/apiContext.d.ts +13 -0
  86. package/dist/utils/apiContext.d.ts.map +1 -0
  87. package/dist/utils/apiContext.js +26 -0
  88. package/dist/utils/apiContext.js.map +1 -0
  89. package/dist/utils/searchParams.d.ts +21 -0
  90. package/dist/utils/searchParams.d.ts.map +1 -0
  91. package/dist/utils/searchParams.js +47 -0
  92. package/dist/utils/searchParams.js.map +1 -0
  93. package/package.json +5 -3
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/mcp-registration/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,+BAA+B,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACjF,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,aAAa,EAAe,MAAM,cAAc,CAAC;AAEtE,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,sBAAsB,EAAE,eAAe,EAAkB,MAAM,cAAc,CAAC;AACtH,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,eAAe,EAAuB,MAAM,iBAAiB,CAAC;AAIxF,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,sBAAsB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACtG,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC1F,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAExF,cAAc,YAAY,CAAC;AAE3B,MAAM,kBAAkB,GAAG,aAAa,EAAE,CAAC;AAE3C,OAAO,EAAE,kBAAkB,EAAE,CAAC;AA2B9B,SAAS,kBAAkB,CACzB,OAAsC,EACtC,YAA0C;IAE1C,IAAI,YAAY,EAAE,WAAW;QAAE,OAAO,YAAY,CAAC,WAAW,CAAC;IAE/D,MAAM,MAAM,GAAG,UAAU,CAAC,oBAAoB,CAAC,OAAkC,CAAC,CAAC,CAAC;IACpF,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,EAAE,CAAC,CAAC;IAChE,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,MAAM,EAAE,MAAM,CAAC,MAAM;KACtB,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CAAC,SAAmC;IAC7D,OAAO;QACL,OAAO,EAAE,SAAS,EAAE,OAAO,IAAI,OAAO,EAAE;QACxC,GAAG,EAAE,SAAS,EAAE,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE;QACpC,GAAG,EAAE,SAAS,EAAE,GAAG,IAAI,OAAO,CAAC,GAAG;KACnC,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,KAAc;IAChC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE;QAAE,OAAO,MAAM,CAAC;IACzE,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAC1D,MAAM,IAAI,KAAK,CAAC,sBAAsB,MAAM,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;AACnF,CAAC;AAED,SAAS,aAAa,CAAC,KAAa;IAClC,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;IACjC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,mBAAmB,KAAK,wBAAwB,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACpG,CAAC;IACD,OAAO,MAAM,CAAC,EAAE,CAAC;AACnB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CACjC,OAAsC,EACtC,YAA0C;IAE1C,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAC9D,MAAM,OAAO,GAAG,kBAAkB,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAC1D,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACxC,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC;IAExF,MAAM,IAAI,GAAG,eAAe,CAAC,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAEzG,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE;QAC1C,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;QACpC,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,QAAQ,EAAE,CAAC,CAAC;QAC5D,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACxC,OAAO;YACL,QAAQ;YACR,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,KAAK;YACL,UAAU,EAAE,UAAU,CAAC,UAAU,CAAC,OAAO,CAAC;YAC1C,MAAM,EAAE,UAAU,CAAC,MAAM;YACzB,QAAQ,EAAE,UAAU,CAAC,QAAQ;YAC7B,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,OAAO,EAAE,mBAAmB,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,eAAe,CAAC;YAClE,aAAa,EAAE,uBAAuB,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,eAAe,CAAC;YAC5E,gBAAgB,EAAE,UAAU,CAAC,gBAAgB,IAAI,IAAI;SACtD,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,MAAM,KAAK,GAAa;QACtB,0BAA0B,KAAK,qBAAqB,WAAW,CAAC,SAAS,UAAU,WAAW,CAAC,MAAM,EAAE;QACvG,sIAAsI;KACvI,CAAC;IAEF,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,MAAM,OAAO,CAAC,KAAK,KAAK,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACxD,KAAK,CAAC,IAAI,CAAC,SAAS,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;QAC1C,IAAI,OAAO,CAAC,gBAAgB;YAAE,KAAK,CAAC,IAAI,CAAC,SAAS,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;QAC9E,IAAI,OAAO,CAAC,aAAa;YAAE,KAAK,CAAC,IAAI,CAAC,YAAY,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;QAC3E,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC5B,KAAK,CAAC,IAAI,CAAC,SAAS,OAAO,CAAC,OAAO,cAAc,OAAO,CAAC,UAAU,GAAG,CAAC,CAAC;IAC1E,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;AACrF,CAAC;AAED,SAAS,uBAAuB,CAAC,KAAmC;IAClE,IAAI,KAAK,CAAC,QAAQ,KAAK,MAAM;QAAE,OAAO,cAAc,CAAC;IACrD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,KAAK,CAAC,cAAc;QAAE,KAAK,CAAC,IAAI,CAAC,cAAc,KAAK,CAAC,cAAc,EAAE,CAAC,CAAC;IAC3E,IAAI,KAAK,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,UAAU,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC/E,OAAO,GAAG,KAAK,CAAC,QAAQ,KAAK,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;AACnD,CAAC;AAED,SAAS,gBAAgB,CAAC,MAAqB;IAC7C,OAAO,KAAK,MAAM,CAAC,QAAQ,KAAK,MAAM,CAAC,OAAO,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC;AACrE,CAAC;AAED,SAAS,SAAS,CAAC,OAAwB;IACzC,OAAO;QACL,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,WAAW,IAAI,CAAC,CAAC,OAAO,KAAK,oBAAoB,CAAC,CAAC,MAAM;QACtG,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,qBAAqB,IAAI,CAAC,CAAC,OAAO,KAAK,sBAAsB,CAAC,CAAC,MAAM;QAClH,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,MAAM;KAC7D,CAAC;AACJ,CAAC;AAED,MAAM,0BAA0B,GAC9B,oLAAoL,CAAC;AAEvL;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAClC,OAAsC,EACtC,YAA0C;IAE1C,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAC9D,MAAM,OAAO,GAAG,kBAAkB,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAC1D,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAExC,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,MAAM,MAAM,GAAG,UAAU,CAAC,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;QACzD,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QAElE,MAAM,MAAM,GAAG,aAAa,CAAC;YAC3B,MAAM;YACN,KAAK;YACL,WAAW;YACX,OAAO;YACP,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,YAAY,EAAE,YAAY,EAAE,YAAY;SACzC,CAAC,CAAC;QAEH,MAAM,KAAK,GAAG;YACZ,4BAA4B,MAAM,CAAC,KAAK,KAAK,KAAK,SAAS;YAC3D,WAAW,WAAW,CAAC,SAAS,UAAU,WAAW,CAAC,MAAM,EAAE;SAC/D,CAAC;QACF,IAAI,KAAK,KAAK,MAAM;YAAE,KAAK,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;QAC7D,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC;QACrC,IAAI,MAAM,CAAC,UAAU;YAAE,KAAK,CAAC,IAAI,CAAC,WAAW,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;QAClE,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;YACzB,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;YAC/B,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;QACnC,CAAC;QAED,OAAO;YACL,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;YACtB,IAAI,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE;YAChE,QAAQ,EAAE,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAC;SAC3C,CAAC;IACJ,CAAC;IAED,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CACb,8JAA8J,CAC/J,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;QACjB,MAAM,IAAI,GAAG,cAAc,CAAC;YAC1B,OAAO;YACP,WAAW;YACX,qBAAqB,EAAE,YAAY,EAAE,qBAAqB;SAC3D,CAAC,CAAC;QAEH,MAAM,KAAK,GAAG;YACZ,0DAA0D;YAC1D,mBAAmB,eAAe,+BAA+B,IAAI,CAAC,OAAO,CAAC,SAAS,UAAU,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE;YACtH,0BAA0B;YAC1B,EAAE;SACH,CAAC;QAEF,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjC,KAAK,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,QAAQ,KAAK,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,KAAK,uBAAuB,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAClH,KAAK,CAAC,IAAI,CAAC,eAAe,KAAK,CAAC,UAAU,QAAQ,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;YACpE,IAAI,KAAK,CAAC,MAAM;gBAAE,KAAK,CAAC,IAAI,CAAC,eAAe,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;QAC9D,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,gGAAgG,CAAC,CAAC;QAE7G,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;IAC9F,CAAC;IAED,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,eAAe,CAAC;QACxC,OAAO;QACP,WAAW;QACX,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,YAAY,EAAE,YAAY,EAAE,YAAY;QACxC,qBAAqB,EAAE,YAAY,EAAE,qBAAqB;KAC3D,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;IACnC,MAAM,KAAK,GAAG;QACZ,8DAA8D,IAAI,CAAC,OAAO,CAAC,SAAS,UAAU,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE;QACnH,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;QAChC,EAAE;QACF,YAAY,OAAO,CAAC,OAAO,gBAAgB,OAAO,CAAC,OAAO,aAAa,OAAO,CAAC,MAAM,UAAU;KAChG,CAAC;IAEF,OAAO;QACL,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;QACtB,IAAI,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE;QAC9D,QAAQ,EAAE,sBAAsB,CAAC,OAAO,CAAC;KAC1C,CAAC;AACJ,CAAC"}
@@ -0,0 +1,66 @@
1
+ import { type DetectionDependencies } from './detect.js';
2
+ import { renderConfigSnippet, renderVendorCommandLine } from './render.js';
3
+ import { type McpCredentials } from './serverSpec.js';
4
+ import type { DetectionSignal, InstallResult, McpClientDefinition, McpPathContext, McpScope } from './types.js';
5
+ import { type VendorRunner } from './vendorCommand.js';
6
+ export interface InstallClientOptions {
7
+ client: McpClientDefinition;
8
+ scope: McpScope;
9
+ credentials: McpCredentials;
10
+ context: McpPathContext;
11
+ serverEntry?: string;
12
+ serverName?: string;
13
+ vendorRunner?: VendorRunner;
14
+ }
15
+ /** Apply (or explicitly decline to apply) the AgentTeams entry for one client/scope. */
16
+ export declare function installClient(options: InstallClientOptions): InstallResult;
17
+ export interface BatchPlanEntry {
18
+ clientId: McpClientDefinition['id'];
19
+ label: string;
20
+ evidence: DetectionSignal['evidence'];
21
+ executablePath: string | null;
22
+ configPaths: string[];
23
+ scope: McpScope;
24
+ strategy: McpClientDefinition['scopes'][McpScope]['strategy'];
25
+ targetPath: string;
26
+ applicable: boolean;
27
+ reason?: string;
28
+ }
29
+ export interface BatchPlan {
30
+ scope: McpScope;
31
+ entries: BatchPlanEntry[];
32
+ /** A single user-scope registration binds the client to one AgentTeams project. */
33
+ binding: {
34
+ projectId: string;
35
+ teamId: string;
36
+ };
37
+ }
38
+ export interface BuildBatchPlanOptions {
39
+ context: McpPathContext;
40
+ credentials: McpCredentials;
41
+ detection?: DetectionSignal[];
42
+ detectionDependencies?: Omit<DetectionDependencies, 'context'>;
43
+ }
44
+ /**
45
+ * Detection plan for the no-argument `install`. Nothing here touches the
46
+ * filesystem — the caller prints it and stops unless `--yes` was passed.
47
+ */
48
+ export declare function buildBatchPlan(options: BuildBatchPlanOptions): BatchPlan;
49
+ export interface RunBatchInstallOptions extends BuildBatchPlanOptions {
50
+ serverEntry?: string;
51
+ serverName?: string;
52
+ vendorRunner?: VendorRunner;
53
+ }
54
+ /**
55
+ * Apply the plan client by client. One client's failure must not strand the
56
+ * rest, so every entry is attempted and the caller derives the exit code from
57
+ * the collected outcomes.
58
+ */
59
+ export declare function runBatchInstall(options: RunBatchInstallOptions): {
60
+ plan: BatchPlan;
61
+ results: InstallResult[];
62
+ };
63
+ /** Non-zero exit only for real failures; "config only" and "not detected" are expected states. */
64
+ export declare function resolveInstallExitCode(results: InstallResult[]): number;
65
+ export { renderConfigSnippet, renderVendorCommandLine };
66
+ //# sourceMappingURL=install.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/mcp-registration/install.ts"],"names":[],"mappings":"AAGA,OAAO,EAAiB,KAAK,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAExE,OAAO,EAAkC,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAC3G,OAAO,EAAoC,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACxF,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,mBAAmB,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAChH,OAAO,EAAoB,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEzE,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,mBAAmB,CAAC;IAC5B,KAAK,EAAE,QAAQ,CAAC;IAChB,WAAW,EAAE,cAAc,CAAC;IAC5B,OAAO,EAAE,cAAc,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AA4JD,wFAAwF;AACxF,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CA8B1E;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,mBAAmB,CAAC,IAAI,CAAC,CAAC;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,eAAe,CAAC,UAAU,CAAC,CAAC;IACtC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,KAAK,EAAE,QAAQ,CAAC;IAChB,QAAQ,EAAE,mBAAmB,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,CAAC;IAC9D,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,QAAQ,CAAC;IAChB,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,mFAAmF;IACnF,OAAO,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAChD;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,cAAc,CAAC;IACxB,WAAW,EAAE,cAAc,CAAC;IAC5B,SAAS,CAAC,EAAE,eAAe,EAAE,CAAC;IAC9B,qBAAqB,CAAC,EAAE,IAAI,CAAC,qBAAqB,EAAE,SAAS,CAAC,CAAC;CAChE;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,SAAS,CAiCxE;AAED,MAAM,WAAW,sBAAuB,SAAQ,qBAAqB;IACnE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,aAAa,EAAE,CAAA;CAAE,CAkC9G;AAED,kGAAkG;AAClG,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,MAAM,CAEvE;AAED,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,CAAC"}
@@ -0,0 +1,244 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { PROJECT_SCOPE_FILE_MODE, USER_SCOPE_FILE_MODE, writeConfigFileAtomically } from './atomicWrite.js';
3
+ import { findClient, MCP_CLIENTS } from './clients.js';
4
+ import { detectClients } from './detect.js';
5
+ import { McpConfigParseError, upsertContainerEntry } from './jsonc.js';
6
+ import { buildEntryValue, redactSecrets, renderConfigSnippet, renderVendorCommandLine } from './render.js';
7
+ import { buildServerSpec, MCP_SERVER_NAME } from './serverSpec.js';
8
+ import { runVendorCommand } from './vendorCommand.js';
9
+ function firstLines(text, limit = 4) {
10
+ return text
11
+ .split('\n')
12
+ .map((line) => line.trim())
13
+ .filter((line) => line.length > 0)
14
+ .slice(0, limit)
15
+ .join(' / ');
16
+ }
17
+ function installViaVendorCommand(options, configPath, manualSnippet) {
18
+ const { client, scope, context } = options;
19
+ const serverName = options.serverName ?? MCP_SERVER_NAME;
20
+ const definition = client.scopes[scope];
21
+ const vendor = definition.vendor;
22
+ if (!vendor)
23
+ throw new Error(`No vendor command configured for ${client.id}/${scope}`);
24
+ const spec = buildServerSpec({
25
+ credentials: options.credentials,
26
+ secretMode: scope === 'user' ? 'literal' : 'reference',
27
+ serverEntry: options.serverEntry,
28
+ });
29
+ const executable = client.executables[0];
30
+ const runner = options.vendorRunner ?? runVendorCommand;
31
+ const outcome = runner(executable, vendor.buildArgs(spec, serverName), { cwd: context.cwd, env: context.env });
32
+ const base = { clientId: client.id, scope, strategy: definition.strategy, configPath };
33
+ if (outcome.spawnError) {
34
+ return {
35
+ ...base,
36
+ outcome: 'FAILED',
37
+ detail: `Could not run \`${executable}\`: ${outcome.spawnError}`,
38
+ manualSnippet,
39
+ };
40
+ }
41
+ // Vendor CLIs echo their own argv on failure, and user-scope argv carries the
42
+ // API key, so nothing reaches the caller before passing through redaction.
43
+ const combined = redactSecrets(`${outcome.stdout}\n${outcome.stderr}`, [options.credentials.apiKey]);
44
+ const alreadyRegistered = (vendor.alreadyRegisteredPatterns ?? []).some((pattern) => pattern.test(combined));
45
+ if (alreadyRegistered) {
46
+ return {
47
+ ...base,
48
+ outcome: 'ALREADY_REGISTERED',
49
+ detail: `\`${executable}\` reports "${serverName}" is already registered and refuses to overwrite it. Remove it with the client's own \`mcp remove\` command and re-run, or apply the snippet manually.`,
50
+ manualSnippet,
51
+ };
52
+ }
53
+ if (outcome.status === 0) {
54
+ return {
55
+ ...base,
56
+ outcome: 'INSTALLED',
57
+ detail: vendor.rerunBehavior === 'update'
58
+ ? `Registered "${serverName}" via \`${executable} mcp add\` (re-running updates the entry in place).`
59
+ : `Registered "${serverName}" via \`${executable} mcp add\`.`,
60
+ };
61
+ }
62
+ return {
63
+ ...base,
64
+ outcome: 'FAILED',
65
+ detail: `\`${executable} mcp add\` exited with code ${String(outcome.status)}: ${firstLines(combined) || 'no output'}`,
66
+ manualSnippet,
67
+ };
68
+ }
69
+ function installViaJsonMerge(options, configPath, manualSnippet) {
70
+ const { client, scope } = options;
71
+ const serverName = options.serverName ?? MCP_SERVER_NAME;
72
+ const definition = client.scopes[scope];
73
+ const containerKey = definition.containerKey;
74
+ if (!containerKey)
75
+ throw new Error(`No container key configured for ${client.id}/${scope}`);
76
+ const base = { clientId: client.id, scope, strategy: definition.strategy, configPath };
77
+ const spec = buildServerSpec({
78
+ credentials: options.credentials,
79
+ // Project files are committable, so they never receive a literal key.
80
+ secretMode: scope === 'user' ? 'literal' : 'reference',
81
+ serverEntry: options.serverEntry,
82
+ });
83
+ let source = '';
84
+ if (existsSync(configPath)) {
85
+ try {
86
+ source = readFileSync(configPath, 'utf-8');
87
+ }
88
+ catch (error) {
89
+ return {
90
+ ...base,
91
+ outcome: 'FAILED',
92
+ detail: `Could not read ${configPath}: ${error instanceof Error ? error.message : String(error)}`,
93
+ manualSnippet,
94
+ };
95
+ }
96
+ }
97
+ let edited;
98
+ try {
99
+ edited = upsertContainerEntry(source, {
100
+ containerKey,
101
+ entryKey: serverName,
102
+ entryValue: buildEntryValue(definition.entryShape ?? 'plain', spec, client.secretReference),
103
+ });
104
+ }
105
+ catch (error) {
106
+ const reason = error instanceof McpConfigParseError ? error.message : String(error);
107
+ return {
108
+ ...base,
109
+ outcome: 'FAILED',
110
+ detail: `${configPath} could not be parsed (${reason}). The file was left unchanged — fix it or apply the snippet manually.`,
111
+ manualSnippet,
112
+ };
113
+ }
114
+ if (edited.unchanged) {
115
+ return {
116
+ ...base,
117
+ outcome: 'ALREADY_REGISTERED',
118
+ detail: `"${serverName}" is already present in ${configPath} with identical settings; nothing was written.`,
119
+ };
120
+ }
121
+ try {
122
+ const written = writeConfigFileAtomically(configPath, edited.text, scope === 'user' ? USER_SCOPE_FILE_MODE : PROJECT_SCOPE_FILE_MODE, scope === 'user' ? USER_SCOPE_FILE_MODE : undefined);
123
+ return {
124
+ ...base,
125
+ outcome: 'INSTALLED',
126
+ detail: edited.existed
127
+ ? `Updated the "${serverName}" entry in ${configPath}.`
128
+ : `Added "${serverName}" to ${configPath}.`,
129
+ backupPath: written.backupPath ?? undefined,
130
+ };
131
+ }
132
+ catch (error) {
133
+ return {
134
+ ...base,
135
+ outcome: 'FAILED',
136
+ detail: `Could not write ${configPath}: ${error instanceof Error ? error.message : String(error)}. The original file was left unchanged.`,
137
+ manualSnippet,
138
+ };
139
+ }
140
+ }
141
+ /** Apply (or explicitly decline to apply) the AgentTeams entry for one client/scope. */
142
+ export function installClient(options) {
143
+ const { client, scope } = options;
144
+ const serverName = options.serverName ?? MCP_SERVER_NAME;
145
+ const definition = client.scopes[scope];
146
+ const configPath = definition.configPath(options.context);
147
+ const displaySpec = buildServerSpec({
148
+ credentials: options.credentials,
149
+ secretMode: 'reference',
150
+ serverEntry: options.serverEntry,
151
+ });
152
+ const manualSnippet = renderConfigSnippet(client, scope, displaySpec, serverName);
153
+ if (definition.strategy === 'configOnly') {
154
+ return {
155
+ clientId: client.id,
156
+ scope,
157
+ strategy: 'configOnly',
158
+ configPath,
159
+ outcome: 'SKIPPED_CONFIG_ONLY',
160
+ detail: definition.configOnlyReason ?? 'No safe automated write path for this client/scope.',
161
+ manualSnippet,
162
+ };
163
+ }
164
+ if (definition.strategy === 'vendorCommand') {
165
+ return installViaVendorCommand(options, configPath, manualSnippet);
166
+ }
167
+ return installViaJsonMerge(options, configPath, manualSnippet);
168
+ }
169
+ /**
170
+ * Detection plan for the no-argument `install`. Nothing here touches the
171
+ * filesystem — the caller prints it and stops unless `--yes` was passed.
172
+ */
173
+ export function buildBatchPlan(options) {
174
+ const detection = options.detection ?? detectClients({ context: options.context, ...(options.detectionDependencies ?? {}) });
175
+ const entries = MCP_CLIENTS.map((client) => {
176
+ const signal = detection.find((candidate) => candidate.clientId === client.id);
177
+ const definition = client.scopes.user;
178
+ const detected = signal?.detected ?? false;
179
+ const applicable = detected && definition.strategy !== 'configOnly';
180
+ let reason;
181
+ if (!detected)
182
+ reason = 'Not detected on this machine.';
183
+ else if (definition.strategy === 'configOnly')
184
+ reason = definition.configOnlyReason;
185
+ return {
186
+ clientId: client.id,
187
+ label: client.label,
188
+ evidence: signal?.evidence ?? 'none',
189
+ executablePath: signal?.executablePath ?? null,
190
+ configPaths: signal?.configPaths ?? [],
191
+ scope: 'user',
192
+ strategy: definition.strategy,
193
+ targetPath: definition.configPath(options.context),
194
+ applicable,
195
+ reason,
196
+ };
197
+ });
198
+ return {
199
+ scope: 'user',
200
+ entries,
201
+ binding: { projectId: options.credentials.projectId, teamId: options.credentials.teamId },
202
+ };
203
+ }
204
+ /**
205
+ * Apply the plan client by client. One client's failure must not strand the
206
+ * rest, so every entry is attempted and the caller derives the exit code from
207
+ * the collected outcomes.
208
+ */
209
+ export function runBatchInstall(options) {
210
+ const plan = buildBatchPlan(options);
211
+ const results = [];
212
+ for (const entry of plan.entries) {
213
+ const client = findClient(entry.clientId);
214
+ if (!client)
215
+ continue;
216
+ if (!entry.applicable) {
217
+ results.push({
218
+ clientId: entry.clientId,
219
+ scope: 'user',
220
+ strategy: entry.strategy,
221
+ configPath: entry.targetPath,
222
+ outcome: entry.strategy === 'configOnly' ? 'SKIPPED_CONFIG_ONLY' : 'SKIPPED_NOT_DETECTED',
223
+ detail: entry.reason ?? 'Skipped.',
224
+ });
225
+ continue;
226
+ }
227
+ results.push(installClient({
228
+ client,
229
+ scope: 'user',
230
+ credentials: options.credentials,
231
+ context: options.context,
232
+ serverEntry: options.serverEntry,
233
+ serverName: options.serverName,
234
+ vendorRunner: options.vendorRunner,
235
+ }));
236
+ }
237
+ return { plan, results };
238
+ }
239
+ /** Non-zero exit only for real failures; "config only" and "not detected" are expected states. */
240
+ export function resolveInstallExitCode(results) {
241
+ return results.some((result) => result.outcome === 'FAILED') ? 1 : 0;
242
+ }
243
+ export { renderConfigSnippet, renderVendorCommandLine };
244
+ //# sourceMappingURL=install.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/mcp-registration/install.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAC5G,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,EAAE,aAAa,EAA8B,MAAM,aAAa,CAAC;AACxE,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AACvE,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAC3G,OAAO,EAAE,eAAe,EAAE,eAAe,EAAuB,MAAM,iBAAiB,CAAC;AAExF,OAAO,EAAE,gBAAgB,EAAqB,MAAM,oBAAoB,CAAC;AAYzE,SAAS,UAAU,CAAC,IAAY,EAAE,KAAK,GAAG,CAAC;IACzC,OAAO,IAAI;SACR,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAC1B,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;SACjC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC;SACf,IAAI,CAAC,KAAK,CAAC,CAAC;AACjB,CAAC;AAED,SAAS,uBAAuB,CAC9B,OAA6B,EAC7B,UAAkB,EAClB,aAAqB;IAErB,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IAC3C,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,eAAe,CAAC;IACzD,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC;IACjC,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,oCAAoC,MAAM,CAAC,EAAE,IAAI,KAAK,EAAE,CAAC,CAAC;IAEvF,MAAM,IAAI,GAAG,eAAe,CAAC;QAC3B,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,UAAU,EAAE,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW;QACtD,WAAW,EAAE,OAAO,CAAC,WAAW;KACjC,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,OAAO,CAAC,YAAY,IAAI,gBAAgB,CAAC;IACxD,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAE/G,MAAM,IAAI,GAAG,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,CAAC,QAAQ,EAAE,UAAU,EAAW,CAAC;IAEhG,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;QACvB,OAAO;YACL,GAAG,IAAI;YACP,OAAO,EAAE,QAAQ;YACjB,MAAM,EAAE,mBAAmB,UAAU,OAAO,OAAO,CAAC,UAAU,EAAE;YAChE,aAAa;SACd,CAAC;IACJ,CAAC;IAED,8EAA8E;IAC9E,2EAA2E;IAC3E,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,OAAO,CAAC,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;IAErG,MAAM,iBAAiB,GAAG,CAAC,MAAM,CAAC,yBAAyB,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC7G,IAAI,iBAAiB,EAAE,CAAC;QACtB,OAAO;YACL,GAAG,IAAI;YACP,OAAO,EAAE,oBAAoB;YAC7B,MAAM,EAAE,KAAK,UAAU,eAAe,UAAU,wJAAwJ;YACxM,aAAa;SACd,CAAC;IACJ,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO;YACL,GAAG,IAAI;YACP,OAAO,EAAE,WAAW;YACpB,MAAM,EACJ,MAAM,CAAC,aAAa,KAAK,QAAQ;gBAC/B,CAAC,CAAC,eAAe,UAAU,WAAW,UAAU,qDAAqD;gBACrG,CAAC,CAAC,eAAe,UAAU,WAAW,UAAU,aAAa;SAClE,CAAC;IACJ,CAAC;IAED,OAAO;QACL,GAAG,IAAI;QACP,OAAO,EAAE,QAAQ;QACjB,MAAM,EAAE,KAAK,UAAU,+BAA+B,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,UAAU,CAAC,QAAQ,CAAC,IAAI,WAAW,EAAE;QACtH,aAAa;KACd,CAAC;AACJ,CAAC;AAED,SAAS,mBAAmB,CAAC,OAA6B,EAAE,UAAkB,EAAE,aAAqB;IACnG,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;IAClC,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,eAAe,CAAC;IACzD,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACxC,MAAM,YAAY,GAAG,UAAU,CAAC,YAAY,CAAC;IAC7C,IAAI,CAAC,YAAY;QAAE,MAAM,IAAI,KAAK,CAAC,mCAAmC,MAAM,CAAC,EAAE,IAAI,KAAK,EAAE,CAAC,CAAC;IAE5F,MAAM,IAAI,GAAG,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,CAAC,QAAQ,EAAE,UAAU,EAAW,CAAC;IAEhG,MAAM,IAAI,GAAG,eAAe,CAAC;QAC3B,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,sEAAsE;QACtE,UAAU,EAAE,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW;QACtD,WAAW,EAAE,OAAO,CAAC,WAAW;KACjC,CAAC,CAAC;IAEH,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,MAAM,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAC7C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,GAAG,IAAI;gBACP,OAAO,EAAE,QAAQ;gBACjB,MAAM,EAAE,kBAAkB,UAAU,KAAK,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;gBACjG,aAAa;aACd,CAAC;QACJ,CAAC;IACH,CAAC;IAED,IAAI,MAAM,CAAC;IACX,IAAI,CAAC;QACH,MAAM,GAAG,oBAAoB,CAAC,MAAM,EAAE;YACpC,YAAY;YACZ,QAAQ,EAAE,UAAU;YACpB,UAAU,EAAE,eAAe,CAAC,UAAU,CAAC,UAAU,IAAI,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,eAAe,CAAC;SAC5F,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,MAAM,GAAG,KAAK,YAAY,mBAAmB,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACpF,OAAO;YACL,GAAG,IAAI;YACP,OAAO,EAAE,QAAQ;YACjB,MAAM,EAAE,GAAG,UAAU,yBAAyB,MAAM,wEAAwE;YAC5H,aAAa;SACd,CAAC;IACJ,CAAC;IAED,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;QACrB,OAAO;YACL,GAAG,IAAI;YACP,OAAO,EAAE,oBAAoB;YAC7B,MAAM,EAAE,IAAI,UAAU,2BAA2B,UAAU,gDAAgD;SAC5G,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,yBAAyB,CACvC,UAAU,EACV,MAAM,CAAC,IAAI,EACX,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,uBAAuB,EACjE,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,SAAS,CACpD,CAAC;QACF,OAAO;YACL,GAAG,IAAI;YACP,OAAO,EAAE,WAAW;YACpB,MAAM,EAAE,MAAM,CAAC,OAAO;gBACpB,CAAC,CAAC,gBAAgB,UAAU,cAAc,UAAU,GAAG;gBACvD,CAAC,CAAC,UAAU,UAAU,QAAQ,UAAU,GAAG;YAC7C,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,SAAS;SAC5C,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,GAAG,IAAI;YACP,OAAO,EAAE,QAAQ;YACjB,MAAM,EAAE,mBAAmB,UAAU,KAAK,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,yCAAyC;YACzI,aAAa;SACd,CAAC;IACJ,CAAC;AACH,CAAC;AAED,wFAAwF;AACxF,MAAM,UAAU,aAAa,CAAC,OAA6B;IACzD,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;IAClC,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,eAAe,CAAC;IACzD,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACxC,MAAM,UAAU,GAAG,UAAU,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAE1D,MAAM,WAAW,GAAG,eAAe,CAAC;QAClC,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,UAAU,EAAE,WAAW;QACvB,WAAW,EAAE,OAAO,CAAC,WAAW;KACjC,CAAC,CAAC;IACH,MAAM,aAAa,GAAG,mBAAmB,CAAC,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC;IAElF,IAAI,UAAU,CAAC,QAAQ,KAAK,YAAY,EAAE,CAAC;QACzC,OAAO;YACL,QAAQ,EAAE,MAAM,CAAC,EAAE;YACnB,KAAK;YACL,QAAQ,EAAE,YAAY;YACtB,UAAU;YACV,OAAO,EAAE,qBAAqB;YAC9B,MAAM,EAAE,UAAU,CAAC,gBAAgB,IAAI,qDAAqD;YAC5F,aAAa;SACd,CAAC;IACJ,CAAC;IAED,IAAI,UAAU,CAAC,QAAQ,KAAK,eAAe,EAAE,CAAC;QAC5C,OAAO,uBAAuB,CAAC,OAAO,EAAE,UAAU,EAAE,aAAa,CAAC,CAAC;IACrE,CAAC;IAED,OAAO,mBAAmB,CAAC,OAAO,EAAE,UAAU,EAAE,aAAa,CAAC,CAAC;AACjE,CAAC;AA6BD;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,OAA8B;IAC3D,MAAM,SAAS,GACb,OAAO,CAAC,SAAS,IAAI,aAAa,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,qBAAqB,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;IAE7G,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;QACzC,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,KAAK,MAAM,CAAC,EAAE,CAAC,CAAC;QAC/E,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;QACtC,MAAM,QAAQ,GAAG,MAAM,EAAE,QAAQ,IAAI,KAAK,CAAC;QAC3C,MAAM,UAAU,GAAG,QAAQ,IAAI,UAAU,CAAC,QAAQ,KAAK,YAAY,CAAC;QAEpE,IAAI,MAA0B,CAAC;QAC/B,IAAI,CAAC,QAAQ;YAAE,MAAM,GAAG,+BAA+B,CAAC;aACnD,IAAI,UAAU,CAAC,QAAQ,KAAK,YAAY;YAAE,MAAM,GAAG,UAAU,CAAC,gBAAgB,CAAC;QAEpF,OAAO;YACL,QAAQ,EAAE,MAAM,CAAC,EAAE;YACnB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,QAAQ,EAAE,MAAM,EAAE,QAAQ,IAAI,MAAM;YACpC,cAAc,EAAE,MAAM,EAAE,cAAc,IAAI,IAAI;YAC9C,WAAW,EAAE,MAAM,EAAE,WAAW,IAAI,EAAE;YACtC,KAAK,EAAE,MAAe;YACtB,QAAQ,EAAE,UAAU,CAAC,QAAQ;YAC7B,UAAU,EAAE,UAAU,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC;YAClD,UAAU;YACV,MAAM;SACP,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,KAAK,EAAE,MAAM;QACb,OAAO;QACP,OAAO,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE;KAC1F,CAAC;AACJ,CAAC;AAQD;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,OAA+B;IAC7D,MAAM,IAAI,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IACrC,MAAM,OAAO,GAAoB,EAAE,CAAC;IAEpC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC1C,IAAI,CAAC,MAAM;YAAE,SAAS;QAEtB,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;YACtB,OAAO,CAAC,IAAI,CAAC;gBACX,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,KAAK,EAAE,MAAM;gBACb,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,UAAU,EAAE,KAAK,CAAC,UAAU;gBAC5B,OAAO,EAAE,KAAK,CAAC,QAAQ,KAAK,YAAY,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,sBAAsB;gBACzF,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,UAAU;aACnC,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QAED,OAAO,CAAC,IAAI,CACV,aAAa,CAAC;YACZ,MAAM;YACN,KAAK,EAAE,MAAM;YACb,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,YAAY,EAAE,OAAO,CAAC,YAAY;SACnC,CAAC,CACH,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAC3B,CAAC;AAED,kGAAkG;AAClG,MAAM,UAAU,sBAAsB,CAAC,OAAwB;IAC7D,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACvE,CAAC;AAED,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,CAAC"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Minimal JSONC reader plus a surgical single-entry editor.
3
+ *
4
+ * MCP client config files are user-owned: OpenCode ships `opencode.jsonc`, and
5
+ * Cursor/Antigravity/Kimi users routinely keep comments and a hand-picked key
6
+ * order in their `mcp.json`. A `JSON.parse` → `JSON.stringify` round-trip would
7
+ * silently delete those comments and reorder everything, so writes are done as
8
+ * a text splice that touches only the AgentTeams entry and leaves every other
9
+ * byte of the document exactly where it was.
10
+ */
11
+ export declare class McpConfigParseError extends Error {
12
+ constructor(message: string);
13
+ }
14
+ /**
15
+ * Parse JSON with comments and trailing commas. Returns `undefined` for an
16
+ * empty document — an untouched client config file is frequently zero bytes,
17
+ * and that is a "create it" signal rather than a corruption signal.
18
+ */
19
+ export declare function parseJsonc(text: string): unknown;
20
+ export interface UpsertContainerEntryOptions {
21
+ /** Top-level key holding the server map, e.g. `mcpServers`, `mcp`, `amp.mcpServers`. */
22
+ containerKey: string;
23
+ entryKey: string;
24
+ entryValue: unknown;
25
+ }
26
+ export interface UpsertContainerEntryResult {
27
+ text: string;
28
+ /** The entry was already present before this edit. */
29
+ existed: boolean;
30
+ /** The entry was already present *and* byte-identical, so nothing was rewritten. */
31
+ unchanged: boolean;
32
+ }
33
+ /**
34
+ * Insert or replace `containerKey.entryKey` in a JSON/JSONC document without
35
+ * reformatting anything else.
36
+ *
37
+ * @throws {McpConfigParseError} when the document is not parseable, or when the
38
+ * root / container is not an object. Callers must treat this as "leave the
39
+ * user's file untouched" rather than as permission to overwrite it.
40
+ */
41
+ export declare function upsertContainerEntry(source: string, options: UpsertContainerEntryOptions): UpsertContainerEntryResult;
42
+ /** Read `containerKey.entryKey` from a parsed document, if present. */
43
+ export declare function readContainerEntry(source: string, containerKey: string, entryKey: string): unknown;
44
+ //# sourceMappingURL=jsonc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonc.d.ts","sourceRoot":"","sources":["../../src/mcp-registration/jsonc.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,OAAO,EAAE,MAAM;CAI5B;AAqHD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAmChD;AAuCD,MAAM,WAAW,2BAA2B;IAC1C,wFAAwF;IACxF,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,0BAA0B;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,sDAAsD;IACtD,OAAO,EAAE,OAAO,CAAC;IACjB,oFAAoF;IACpF,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,2BAA2B,GAAG,0BAA0B,CAkErH;AAED,uEAAuE;AACvE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAMlG"}
@@ -0,0 +1,266 @@
1
+ /**
2
+ * Minimal JSONC reader plus a surgical single-entry editor.
3
+ *
4
+ * MCP client config files are user-owned: OpenCode ships `opencode.jsonc`, and
5
+ * Cursor/Antigravity/Kimi users routinely keep comments and a hand-picked key
6
+ * order in their `mcp.json`. A `JSON.parse` → `JSON.stringify` round-trip would
7
+ * silently delete those comments and reorder everything, so writes are done as
8
+ * a text splice that touches only the AgentTeams entry and leaves every other
9
+ * byte of the document exactly where it was.
10
+ */
11
+ export class McpConfigParseError extends Error {
12
+ constructor(message) {
13
+ super(message);
14
+ this.name = 'McpConfigParseError';
15
+ }
16
+ }
17
+ const WHITESPACE = new Set([' ', '\t', '\n', '\r']);
18
+ /** Skip whitespace and `//` / block comments starting at `index`. */
19
+ function skipTrivia(text, index) {
20
+ let i = index;
21
+ while (i < text.length) {
22
+ const char = text[i];
23
+ if (WHITESPACE.has(char)) {
24
+ i += 1;
25
+ continue;
26
+ }
27
+ if (char === '/' && text[i + 1] === '/') {
28
+ i += 2;
29
+ while (i < text.length && text[i] !== '\n')
30
+ i += 1;
31
+ continue;
32
+ }
33
+ if (char === '/' && text[i + 1] === '*') {
34
+ i += 2;
35
+ while (i < text.length && !(text[i] === '*' && text[i + 1] === '/'))
36
+ i += 1;
37
+ i = Math.min(i + 2, text.length);
38
+ continue;
39
+ }
40
+ break;
41
+ }
42
+ return i;
43
+ }
44
+ function scanString(text, index) {
45
+ let i = index + 1;
46
+ while (i < text.length) {
47
+ const char = text[i];
48
+ if (char === '\\') {
49
+ i += 2;
50
+ continue;
51
+ }
52
+ if (char === '"')
53
+ return i + 1;
54
+ i += 1;
55
+ }
56
+ throw new McpConfigParseError('Unterminated string literal');
57
+ }
58
+ /** Return the index just past the value that starts at (or after) `index`. */
59
+ function scanValue(text, index) {
60
+ const start = skipTrivia(text, index);
61
+ const char = text[start];
62
+ if (char === undefined)
63
+ throw new McpConfigParseError('Unexpected end of input');
64
+ if (char === '"')
65
+ return scanString(text, start);
66
+ if (char === '{' || char === '[') {
67
+ const close = char === '{' ? '}' : ']';
68
+ let depth = 0;
69
+ let i = start;
70
+ while (i < text.length) {
71
+ const current = text[i];
72
+ if (current === '"') {
73
+ i = scanString(text, i);
74
+ continue;
75
+ }
76
+ if (current === '/' && (text[i + 1] === '/' || text[i + 1] === '*')) {
77
+ i = skipTrivia(text, i);
78
+ continue;
79
+ }
80
+ if (current === char)
81
+ depth += 1;
82
+ else if (current === close) {
83
+ depth -= 1;
84
+ if (depth === 0)
85
+ return i + 1;
86
+ }
87
+ i += 1;
88
+ }
89
+ throw new McpConfigParseError('Unterminated object or array');
90
+ }
91
+ let i = start;
92
+ while (i < text.length && !WHITESPACE.has(text[i]) && text[i] !== ',' && text[i] !== '}' && text[i] !== ']') {
93
+ i += 1;
94
+ }
95
+ if (i === start)
96
+ throw new McpConfigParseError(`Unexpected token "${char}"`);
97
+ return i;
98
+ }
99
+ /** List the direct members of the object whose `{` sits at `objectStart`. */
100
+ function listMembers(text, objectStart) {
101
+ const members = [];
102
+ let i = skipTrivia(text, objectStart + 1);
103
+ while (i < text.length && text[i] !== '}') {
104
+ if (text[i] === ',') {
105
+ i = skipTrivia(text, i + 1);
106
+ continue;
107
+ }
108
+ if (text[i] !== '"')
109
+ throw new McpConfigParseError('Expected a quoted object key');
110
+ const keyStart = i;
111
+ const keyEnd = scanString(text, i);
112
+ const key = JSON.parse(text.slice(keyStart, keyEnd));
113
+ const colon = skipTrivia(text, keyEnd);
114
+ if (text[colon] !== ':')
115
+ throw new McpConfigParseError(`Expected ":" after object key "${key}"`);
116
+ const valueStart = skipTrivia(text, colon + 1);
117
+ const valueEnd = scanValue(text, valueStart);
118
+ members.push({ key, keyStart, valueStart, valueEnd });
119
+ i = skipTrivia(text, valueEnd);
120
+ }
121
+ return members;
122
+ }
123
+ /**
124
+ * Parse JSON with comments and trailing commas. Returns `undefined` for an
125
+ * empty document — an untouched client config file is frequently zero bytes,
126
+ * and that is a "create it" signal rather than a corruption signal.
127
+ */
128
+ export function parseJsonc(text) {
129
+ if (text.trim().length === 0)
130
+ return undefined;
131
+ let normalized = '';
132
+ let i = 0;
133
+ while (i < text.length) {
134
+ const char = text[i];
135
+ if (char === '"') {
136
+ const end = scanString(text, i);
137
+ normalized += text.slice(i, end);
138
+ i = end;
139
+ continue;
140
+ }
141
+ if (char === '/' && (text[i + 1] === '/' || text[i + 1] === '*')) {
142
+ normalized += ' ';
143
+ i = skipTrivia(text, i);
144
+ continue;
145
+ }
146
+ if (char === ',') {
147
+ const next = skipTrivia(text, i + 1);
148
+ if (text[next] === '}' || text[next] === ']') {
149
+ normalized += ' ';
150
+ i += 1;
151
+ continue;
152
+ }
153
+ }
154
+ normalized += char;
155
+ i += 1;
156
+ }
157
+ try {
158
+ return JSON.parse(normalized);
159
+ }
160
+ catch (error) {
161
+ throw new McpConfigParseError(error instanceof Error ? error.message : String(error));
162
+ }
163
+ }
164
+ function detectIndentUnit(text) {
165
+ const match = /\n([ \t]+)\S/.exec(text);
166
+ return match ? match[1] : ' ';
167
+ }
168
+ function lineIndentOf(text, index) {
169
+ const lineStart = text.lastIndexOf('\n', index) + 1;
170
+ const match = /^[ \t]*/.exec(text.slice(lineStart, index));
171
+ return match ? match[0] : '';
172
+ }
173
+ function serializeValue(value, indentUnit, baseIndent) {
174
+ const json = JSON.stringify(value, null, indentUnit);
175
+ return json
176
+ .split('\n')
177
+ .map((line, lineIndex) => (lineIndex === 0 ? line : `${baseIndent}${line}`))
178
+ .join('\n');
179
+ }
180
+ function appendMember(text, objectStart, memberText, memberIndent) {
181
+ const objectEnd = scanValue(text, objectStart) - 1;
182
+ const members = listMembers(text, objectStart);
183
+ if (members.length === 0) {
184
+ const closingIndent = lineIndentOf(text, objectStart);
185
+ return `${text.slice(0, objectStart + 1)}\n${memberIndent}${memberText}\n${closingIndent}${text.slice(objectEnd)}`;
186
+ }
187
+ const last = members[members.length - 1];
188
+ const afterLast = skipTrivia(text, last.valueEnd);
189
+ const hasTrailingComma = text[afterLast] === ',';
190
+ const insertAt = hasTrailingComma ? afterLast + 1 : last.valueEnd;
191
+ const separator = hasTrailingComma ? '' : ',';
192
+ return `${text.slice(0, insertAt)}${separator}\n${memberIndent}${memberText}${text.slice(insertAt)}`;
193
+ }
194
+ /**
195
+ * Insert or replace `containerKey.entryKey` in a JSON/JSONC document without
196
+ * reformatting anything else.
197
+ *
198
+ * @throws {McpConfigParseError} when the document is not parseable, or when the
199
+ * root / container is not an object. Callers must treat this as "leave the
200
+ * user's file untouched" rather than as permission to overwrite it.
201
+ */
202
+ export function upsertContainerEntry(source, options) {
203
+ const { containerKey, entryKey, entryValue } = options;
204
+ const indentUnit = detectIndentUnit(source);
205
+ if (source.trim().length === 0) {
206
+ const entry = serializeValue(entryValue, indentUnit, indentUnit.repeat(2));
207
+ const text = `{\n${indentUnit}${JSON.stringify(containerKey)}: {\n` +
208
+ `${indentUnit.repeat(2)}${JSON.stringify(entryKey)}: ${entry}\n` +
209
+ `${indentUnit}}\n}\n`;
210
+ return { text, existed: false, unchanged: false };
211
+ }
212
+ // Validate before splicing: a corrupt document must fail loudly here so the
213
+ // caller can preserve the original instead of writing a half-repaired file.
214
+ parseJsonc(source);
215
+ const rootStart = skipTrivia(source, 0);
216
+ if (source[rootStart] !== '{') {
217
+ throw new McpConfigParseError('The top-level value must be an object');
218
+ }
219
+ const container = listMembers(source, rootStart).find((member) => member.key === containerKey);
220
+ if (!container) {
221
+ const memberIndent = lineIndentOf(source, rootStart) + indentUnit;
222
+ const entry = serializeValue(entryValue, indentUnit, `${memberIndent}${indentUnit}`);
223
+ const memberText = `${JSON.stringify(containerKey)}: {\n` +
224
+ `${memberIndent}${indentUnit}${JSON.stringify(entryKey)}: ${entry}\n` +
225
+ `${memberIndent}}`;
226
+ return { text: appendMember(source, rootStart, memberText, memberIndent), existed: false, unchanged: false };
227
+ }
228
+ if (source[container.valueStart] !== '{') {
229
+ throw new McpConfigParseError(`"${containerKey}" exists but is not an object`);
230
+ }
231
+ const entries = listMembers(source, container.valueStart);
232
+ const existing = entries.find((member) => member.key === entryKey);
233
+ if (existing) {
234
+ const baseIndent = lineIndentOf(source, existing.keyStart);
235
+ const entry = serializeValue(entryValue, indentUnit, baseIndent);
236
+ if (source.slice(existing.valueStart, existing.valueEnd) === entry) {
237
+ return { text: source, existed: true, unchanged: true };
238
+ }
239
+ return {
240
+ text: `${source.slice(0, existing.valueStart)}${entry}${source.slice(existing.valueEnd)}`,
241
+ existed: true,
242
+ unchanged: false,
243
+ };
244
+ }
245
+ const memberIndent = entries.length > 0
246
+ ? lineIndentOf(source, entries[0].keyStart)
247
+ : lineIndentOf(source, container.keyStart) + indentUnit;
248
+ const entry = serializeValue(entryValue, indentUnit, memberIndent);
249
+ const memberText = `${JSON.stringify(entryKey)}: ${entry}`;
250
+ return {
251
+ text: appendMember(source, container.valueStart, memberText, memberIndent),
252
+ existed: false,
253
+ unchanged: false,
254
+ };
255
+ }
256
+ /** Read `containerKey.entryKey` from a parsed document, if present. */
257
+ export function readContainerEntry(source, containerKey, entryKey) {
258
+ const parsed = parseJsonc(source);
259
+ if (parsed === undefined || parsed === null || typeof parsed !== 'object')
260
+ return undefined;
261
+ const container = parsed[containerKey];
262
+ if (container === null || typeof container !== 'object')
263
+ return undefined;
264
+ return container[entryKey];
265
+ }
266
+ //# sourceMappingURL=jsonc.js.map