callman-mcp 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (204) hide show
  1. package/CHANGELOG.md +82 -0
  2. package/README.md +45 -16
  3. package/dist/client/api.d.ts +64 -3
  4. package/dist/client/api.d.ts.map +1 -1
  5. package/dist/client/api.js +67 -2
  6. package/dist/client/api.js.map +1 -1
  7. package/dist/client/errors.d.ts.map +1 -1
  8. package/dist/client/errors.js +33 -7
  9. package/dist/client/errors.js.map +1 -1
  10. package/dist/client/types.d.ts +91 -2
  11. package/dist/client/types.d.ts.map +1 -1
  12. package/dist/context.d.ts +2 -0
  13. package/dist/context.d.ts.map +1 -1
  14. package/dist/context.js +7 -2
  15. package/dist/context.js.map +1 -1
  16. package/dist/domain/contracts.d.ts +893 -0
  17. package/dist/domain/contracts.d.ts.map +1 -0
  18. package/dist/domain/contracts.js +90 -0
  19. package/dist/domain/contracts.js.map +1 -0
  20. package/dist/domain/diagram/build.d.ts +520 -18
  21. package/dist/domain/diagram/build.d.ts.map +1 -1
  22. package/dist/domain/diagram/build.js +65 -19
  23. package/dist/domain/diagram/build.js.map +1 -1
  24. package/dist/domain/diagram/patch.d.ts +624 -51
  25. package/dist/domain/diagram/patch.d.ts.map +1 -1
  26. package/dist/domain/diagram/patch.js +180 -40
  27. package/dist/domain/diagram/patch.js.map +1 -1
  28. package/dist/domain/diagram/style.d.ts +315 -0
  29. package/dist/domain/diagram/style.d.ts.map +1 -0
  30. package/dist/domain/diagram/style.js +124 -0
  31. package/dist/domain/diagram/style.js.map +1 -0
  32. package/dist/domain/diagram/summarize.d.ts +8 -0
  33. package/dist/domain/diagram/summarize.d.ts.map +1 -1
  34. package/dist/domain/diagram/summarize.js +28 -13
  35. package/dist/domain/diagram/summarize.js.map +1 -1
  36. package/dist/domain/requestIntegrations.d.ts +719 -0
  37. package/dist/domain/requestIntegrations.d.ts.map +1 -0
  38. package/dist/domain/requestIntegrations.js +222 -0
  39. package/dist/domain/requestIntegrations.js.map +1 -0
  40. package/dist/domain/requestShape.d.ts +1350 -152
  41. package/dist/domain/requestShape.d.ts.map +1 -1
  42. package/dist/domain/requestShape.js +336 -121
  43. package/dist/domain/requestShape.js.map +1 -1
  44. package/dist/domain/resolve.d.ts +2 -1
  45. package/dist/domain/resolve.d.ts.map +1 -1
  46. package/dist/domain/resolve.js +5 -1
  47. package/dist/domain/resolve.js.map +1 -1
  48. package/dist/domain/scenario/build.d.ts +82 -26
  49. package/dist/domain/scenario/build.d.ts.map +1 -1
  50. package/dist/domain/scenario/build.js +196 -65
  51. package/dist/domain/scenario/build.js.map +1 -1
  52. package/dist/domain/scenario/nodeConfig.d.ts +11 -0
  53. package/dist/domain/scenario/nodeConfig.d.ts.map +1 -0
  54. package/dist/domain/scenario/nodeConfig.js +251 -0
  55. package/dist/domain/scenario/nodeConfig.js.map +1 -0
  56. package/dist/domain/scenario/summarize.d.ts +145 -25
  57. package/dist/domain/scenario/summarize.d.ts.map +1 -1
  58. package/dist/domain/scenario/summarize.js +84 -29
  59. package/dist/domain/scenario/summarize.js.map +1 -1
  60. package/dist/lib/mask.d.ts +0 -18
  61. package/dist/lib/mask.d.ts.map +1 -1
  62. package/dist/lib/mask.js +2 -44
  63. package/dist/lib/mask.js.map +1 -1
  64. package/dist/lib/pagination.d.ts +3 -2
  65. package/dist/lib/pagination.d.ts.map +1 -1
  66. package/dist/lib/pagination.js +13 -8
  67. package/dist/lib/pagination.js.map +1 -1
  68. package/dist/lib/redact.d.ts +12 -0
  69. package/dist/lib/redact.d.ts.map +1 -0
  70. package/dist/lib/redact.js +50 -0
  71. package/dist/lib/redact.js.map +1 -0
  72. package/dist/lib/strict.d.ts +4 -0
  73. package/dist/lib/strict.d.ts.map +1 -0
  74. package/dist/lib/strict.js +14 -0
  75. package/dist/lib/strict.js.map +1 -0
  76. package/dist/prompts/index.js +7 -7
  77. package/dist/prompts/index.js.map +1 -1
  78. package/dist/resources/docs/contracts.d.ts +2 -0
  79. package/dist/resources/docs/contracts.d.ts.map +1 -0
  80. package/dist/resources/docs/contracts.js +74 -0
  81. package/dist/resources/docs/contracts.js.map +1 -0
  82. package/dist/resources/docs/diagramSchema.d.ts +1 -1
  83. package/dist/resources/docs/diagramSchema.d.ts.map +1 -1
  84. package/dist/resources/docs/diagramSchema.js +95 -28
  85. package/dist/resources/docs/diagramSchema.js.map +1 -1
  86. package/dist/resources/docs/overview.d.ts +1 -1
  87. package/dist/resources/docs/overview.d.ts.map +1 -1
  88. package/dist/resources/docs/overview.js +29 -7
  89. package/dist/resources/docs/overview.js.map +1 -1
  90. package/dist/resources/docs/requestSchema.d.ts +1 -1
  91. package/dist/resources/docs/requestSchema.d.ts.map +1 -1
  92. package/dist/resources/docs/requestSchema.js +85 -16
  93. package/dist/resources/docs/requestSchema.js.map +1 -1
  94. package/dist/resources/generated/aiPacks.d.ts +1 -1
  95. package/dist/resources/generated/aiPacks.d.ts.map +1 -1
  96. package/dist/resources/generated/aiPacks.js +3 -2
  97. package/dist/resources/generated/aiPacks.js.map +1 -1
  98. package/dist/resources/index.d.ts.map +1 -1
  99. package/dist/resources/index.js +19 -19
  100. package/dist/resources/index.js.map +1 -1
  101. package/dist/run/executeCollection.d.ts +3 -1
  102. package/dist/run/executeCollection.d.ts.map +1 -1
  103. package/dist/run/executeCollection.js +16 -4
  104. package/dist/run/executeCollection.js.map +1 -1
  105. package/dist/run/summarize.d.ts +17 -6
  106. package/dist/run/summarize.d.ts.map +1 -1
  107. package/dist/run/summarize.js +48 -41
  108. package/dist/run/summarize.js.map +1 -1
  109. package/dist/run/types.d.ts +1 -0
  110. package/dist/run/types.d.ts.map +1 -1
  111. package/dist/server.d.ts +1 -1
  112. package/dist/server.d.ts.map +1 -1
  113. package/dist/server.js +1 -1
  114. package/dist/server.js.map +1 -1
  115. package/dist/tools/catalog.d.ts +1 -1
  116. package/dist/tools/catalog.d.ts.map +1 -1
  117. package/dist/tools/catalog.js +18 -0
  118. package/dist/tools/catalog.js.map +1 -1
  119. package/dist/tools/collections.d.ts.map +1 -1
  120. package/dist/tools/collections.js +53 -41
  121. package/dist/tools/collections.js.map +1 -1
  122. package/dist/tools/contracts.d.ts +4 -0
  123. package/dist/tools/contracts.d.ts.map +1 -0
  124. package/dist/tools/contracts.js +201 -0
  125. package/dist/tools/contracts.js.map +1 -0
  126. package/dist/tools/diagrams.d.ts.map +1 -1
  127. package/dist/tools/diagrams.js +19 -10
  128. package/dist/tools/diagrams.js.map +1 -1
  129. package/dist/tools/environments.d.ts.map +1 -1
  130. package/dist/tools/environments.js +184 -64
  131. package/dist/tools/environments.js.map +1 -1
  132. package/dist/tools/import.d.ts.map +1 -1
  133. package/dist/tools/import.js +111 -20
  134. package/dist/tools/import.js.map +1 -1
  135. package/dist/tools/index.d.ts +2 -1
  136. package/dist/tools/index.d.ts.map +1 -1
  137. package/dist/tools/index.js +19 -1
  138. package/dist/tools/index.js.map +1 -1
  139. package/dist/tools/lookups.d.ts +38 -7
  140. package/dist/tools/lookups.d.ts.map +1 -1
  141. package/dist/tools/lookups.js +113 -10
  142. package/dist/tools/lookups.js.map +1 -1
  143. package/dist/tools/meta.d.ts.map +1 -1
  144. package/dist/tools/meta.js +9 -4
  145. package/dist/tools/meta.js.map +1 -1
  146. package/dist/tools/requests.d.ts.map +1 -1
  147. package/dist/tools/requests.js +138 -50
  148. package/dist/tools/requests.js.map +1 -1
  149. package/dist/tools/run.d.ts.map +1 -1
  150. package/dist/tools/run.js +84 -28
  151. package/dist/tools/run.js.map +1 -1
  152. package/dist/tools/scenarios.d.ts.map +1 -1
  153. package/dist/tools/scenarios.js +238 -75
  154. package/dist/tools/scenarios.js.map +1 -1
  155. package/dist/tools/shared.d.ts +1 -0
  156. package/dist/tools/shared.d.ts.map +1 -1
  157. package/dist/tools/shared.js +9 -1
  158. package/dist/tools/shared.js.map +1 -1
  159. package/dist/tools/workspaces.d.ts.map +1 -1
  160. package/dist/tools/workspaces.js +44 -7
  161. package/dist/tools/workspaces.js.map +1 -1
  162. package/dist-cjs/client/api.js +67 -2
  163. package/dist-cjs/client/errors.js +33 -7
  164. package/dist-cjs/context.js +7 -2
  165. package/dist-cjs/domain/contracts.js +93 -0
  166. package/dist-cjs/domain/diagram/build.js +71 -20
  167. package/dist-cjs/domain/diagram/patch.js +179 -39
  168. package/dist-cjs/domain/diagram/style.js +130 -0
  169. package/dist-cjs/domain/diagram/summarize.js +28 -13
  170. package/dist-cjs/domain/requestIntegrations.js +228 -0
  171. package/dist-cjs/domain/requestShape.js +342 -121
  172. package/dist-cjs/domain/resolve.js +5 -1
  173. package/dist-cjs/domain/scenario/build.js +197 -65
  174. package/dist-cjs/domain/scenario/nodeConfig.js +260 -0
  175. package/dist-cjs/domain/scenario/summarize.js +86 -29
  176. package/dist-cjs/lib/mask.js +3 -48
  177. package/dist-cjs/lib/pagination.js +13 -8
  178. package/dist-cjs/lib/redact.js +53 -0
  179. package/dist-cjs/lib/strict.js +18 -0
  180. package/dist-cjs/prompts/index.js +7 -7
  181. package/dist-cjs/resources/docs/contracts.js +76 -0
  182. package/dist-cjs/resources/docs/diagramSchema.js +95 -28
  183. package/dist-cjs/resources/docs/overview.js +29 -7
  184. package/dist-cjs/resources/docs/requestSchema.js +85 -16
  185. package/dist-cjs/resources/generated/aiPacks.js +3 -2
  186. package/dist-cjs/resources/index.js +17 -17
  187. package/dist-cjs/run/executeCollection.js +16 -4
  188. package/dist-cjs/run/summarize.js +48 -41
  189. package/dist-cjs/server.js +1 -1
  190. package/dist-cjs/tools/catalog.js +18 -0
  191. package/dist-cjs/tools/collections.js +52 -40
  192. package/dist-cjs/tools/contracts.js +204 -0
  193. package/dist-cjs/tools/diagrams.js +19 -10
  194. package/dist-cjs/tools/environments.js +182 -62
  195. package/dist-cjs/tools/import.js +107 -16
  196. package/dist-cjs/tools/index.js +21 -2
  197. package/dist-cjs/tools/lookups.js +123 -11
  198. package/dist-cjs/tools/meta.js +9 -4
  199. package/dist-cjs/tools/requests.js +134 -46
  200. package/dist-cjs/tools/run.js +82 -26
  201. package/dist-cjs/tools/scenarios.js +235 -72
  202. package/dist-cjs/tools/shared.js +11 -2
  203. package/dist-cjs/tools/workspaces.js +43 -6
  204. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/tools/shared.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACpG,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAE3D,kCAAkC;AAClC,6EAA6E;AAC7E,+EAA+E;AAC/E,+DAA+D;AAC/D,oFAAoF;AACpF,sEAAsE;AACtE,4CAA4C;AAC5C,8EAA8E;AAE9E,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,UAAmC,EAAE,IAAa,EAAkB,EAAE,CAAC,CAAC;IACzF,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,IAAI,aAAa,CAAC,UAAU,CAAC,EAAE,CAAC;IACpE,iBAAiB,EAAE,UAAU;CAC9B,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,KAAc,EAAkB,EAAE;IAC5D,IAAI,OAAgC,CAAC;IACrC,IAAI,KAAK,YAAY,eAAe,EAAE,CAAC;QACrC,OAAO,GAAG;YACR,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC;YACpB,GAAG,CAAC,KAAK,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAClE,OAAO,EAAE,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,IAAI,EAAE;SACzC,CAAC;IACJ,CAAC;SAAM,IAAI,KAAK,YAAY,cAAc,EAAE,CAAC;QAC3C,OAAO,GAAG,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,CAAC;IAChF,CAAC;SAAM,IAAI,KAAK,YAAY,mBAAmB,EAAE,CAAC;QAChD,OAAO,GAAG,EAAE,IAAI,EAAE,qBAAqB,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC;IAC1F,CAAC;SAAM,CAAC;QACN,OAAO,GAAG,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;IACxG,CAAC;IACD,MAAM,UAAU,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;IACtC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,iBAAiB,EAAE,UAAU,EAAE,CAAC;AACxH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAClB,CAAI,EAAwC,EAAE,EAAE,CAChD,KAAK,EAAE,IAAO,EAA2B,EAAE;IACzC,IAAI,CAAC;QACH,OAAO,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC;AACH,CAAC,CAAC;AAEJ,0EAA0E;AAE1E,MAAM,CAAC,MAAM,IAAI,GAAoB,EAAE,YAAY,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC;AAChI,MAAM,CAAC,MAAM,KAAK,GAAoB,EAAE,YAAY,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC;AACnI,MAAM,CAAC,MAAM,gBAAgB,GAAoB,EAAE,YAAY,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC;AAC7I,MAAM,CAAC,MAAM,WAAW,GAAoB,EAAE,YAAY,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC;AACvI,MAAM,CAAC,MAAM,GAAG,GAAoB,EAAE,YAAY,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;AAEhI,0EAA0E;AAE1E,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC;KAC1B,MAAM,EAAE;KACR,GAAG,CAAC,GAAG,CAAC;KACR,QAAQ,EAAE;KACV,QAAQ,CAAC,2HAA2H,CAAC,CAAC;AAEzI,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,KAAK,GAAG,EAAE,EAAE,EAAE,CACjD,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,GAAG,IAAI,cAAc,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAEvF,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,4DAA4D,CAAC;IAC7G,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sBAAsB,MAAM,CAAC,YAAY,GAAG,CAAC;CACtH,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC;KACxB,OAAO,CAAC,IAAI,CAAC;KACb,QAAQ,CAAC,uHAAuH,CAAC,CAAC;AAErI,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sDAAsD,CAAC,CAAC;AAEjH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,OAAgB,EAAE,IAAY,EAAQ,EAAE;IACrE,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACrB,MAAM,IAAI,cAAc,CAAC,kBAAkB,EAAE,YAAY,IAAI,qEAAqE,CAAC,CAAC;IACtI,CAAC;AACH,CAAC,CAAC"}
1
+ {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/tools/shared.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"workspaces.d.ts","sourceRoot":"","sources":["../../src/tools/workspaces.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIzE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAKjD,eAAO,MAAM,sBAAsB,GAAI,QAAQ,SAAS,EAAE,KAAK,WAAW,KAAG,IA6F5E,CAAC"}
1
+ {"version":3,"file":"workspaces.d.ts","sourceRoot":"","sources":["../../src/tools/workspaces.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIzE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAKjD,eAAO,MAAM,sBAAsB,GAAI,QAAQ,SAAS,EAAE,KAAK,WAAW,KAAG,IA8I5E,CAAC"}
@@ -2,11 +2,11 @@ import { z } from "zod";
2
2
  import { ToolInputError } from "../client/errors.js";
3
3
  import { resolveRef } from "../domain/resolve.js";
4
4
  import { normalizeName } from "../lib/ids.js";
5
- import { confirmArg, DESTRUCTIVE, guarded, ok, READ, requireConfirm, workspaceArg, WRITE } from "./shared.js";
5
+ import { confirmArg, DESTRUCTIVE, guarded, IDEMPOTENT_WRITE, ok, READ, requireConfirm, workspaceArg, WRITE } from "./shared.js";
6
6
  export const registerWorkspaceTools = (server, ctx) => {
7
7
  server.registerTool("list_workspaces", {
8
8
  title: "List workspaces",
9
- description: "List the workspaces you belong to, with your role in each (owner / editor / viewer). A token keeps your role: writes are refused where you are a viewer.",
9
+ description: "List the workspaces you belong to, with your role in each (owner / editor / viewer) and which one is the session default. The token works in all of them; a token keeps your role: writes are refused where you are a viewer.",
10
10
  inputSchema: {},
11
11
  annotations: READ,
12
12
  }, guarded(async () => {
@@ -17,10 +17,26 @@ export const registerWorkspaceTools = (server, ctx) => {
17
17
  name: workspace.name,
18
18
  role: workspace.role,
19
19
  memberCount: workspace.memberCount ?? null,
20
- isDefault: workspace.id === ctx.config.defaultWorkspaceId,
20
+ isDefault: workspace.id === ctx.getDefaultWorkspaceId(),
21
21
  })),
22
22
  });
23
23
  }));
24
+ server.registerTool("use_workspace", {
25
+ title: "Set the default workspace for this session",
26
+ description: "Pick the workspace new things go to for the rest of this session (collections, environments, scenarios, imports — anything created without `workspace`), and the one that wins when a name exists in several workspaces. It never hides the others: lists and searches still cover every workspace. `workspace: null` clears the default. Lasts until the MCP server restarts; CALLMAN_WORKSPACE_ID sets it at start.",
27
+ inputSchema: { workspace: z.string().max(200).nullable().describe("Workspace name or id; null = no default") },
28
+ annotations: IDEMPOTENT_WRITE,
29
+ }, guarded(async ({ workspace }) => {
30
+ const previous = ctx.getDefaultWorkspaceId();
31
+ if (workspace === null || !workspace.trim()) {
32
+ ctx.setDefaultWorkspaceId(null);
33
+ return ok({ defaultWorkspace: null, previousDefaultId: previous, note: "No default workspace: creating something now needs `workspace`; reads still cover all workspaces." });
34
+ }
35
+ const target = await ctx.resolveWorkspace(workspace);
36
+ ctx.setDefaultWorkspaceId(target.id);
37
+ ctx.invalidate();
38
+ return ok({ defaultWorkspace: { id: target.id, name: target.name, role: target.role }, previousDefaultId: previous });
39
+ }));
24
40
  server.registerTool("list_workspace_members", {
25
41
  title: "List workspace members",
26
42
  description: "List the members of a workspace with their role and status (active / invited).",
@@ -36,7 +52,7 @@ export const registerWorkspaceTools = (server, ctx) => {
36
52
  }));
37
53
  server.registerTool("add_workspace_member", {
38
54
  title: "Add a workspace member",
39
- description: "Add a person to a workspace by email with a role (editor can write collections/requests/scenarios; viewer is read-only; owner manages the workspace). Requires the owner role in that workspace. The person must already have a Callman account — the server does not send invitations to unknown emails.",
55
+ description: "Add a person to a workspace by email with a role (editor can write collections/requests/scenarios; viewer is read-only; owner manages the workspace). Requires the owner role in that workspace. The person must already have a Callman account — the server does not send invitations to unknown emails. Change a role later with update_workspace_member.",
40
56
  inputSchema: {
41
57
  workspace: workspaceArg,
42
58
  email: z.string().email().max(255),
@@ -50,12 +66,33 @@ export const registerWorkspaceTools = (server, ctx) => {
50
66
  return ok({
51
67
  workspace: { id: target.id, name: target.name },
52
68
  member: { id: member.id, email: member.email, role: member.role, status: member.status },
53
- note: member.status === "invited" ? "Pending — the person gets access when they sign in." : "Added.",
69
+ note: "Added — the person has access now.",
54
70
  });
55
71
  }));
72
+ server.registerTool("update_workspace_member", {
73
+ title: "Change a member's role",
74
+ description: "Change a workspace member's role (owner / editor / viewer) by exact email or membership id. Requires the owner role; the last owner cannot be demoted.",
75
+ inputSchema: {
76
+ workspace: workspaceArg,
77
+ member: z.string().min(1).max(255).describe("Member email or membership id"),
78
+ role: z.enum(["owner", "editor", "viewer"]),
79
+ },
80
+ annotations: IDEMPOTENT_WRITE,
81
+ }, guarded(async ({ workspace, member, role }) => {
82
+ const target = await ctx.resolveWorkspace(workspace);
83
+ const { items } = await ctx.api.listMembers(target.id);
84
+ const needle = normalizeName(member);
85
+ const byEmail = items.filter((entry) => normalizeName(entry.email) === needle);
86
+ const resolved = byEmail.length === 1 ? byEmail[0] : resolveRef("member", member, items.map((entry) => ({ ...entry, name: entry.email })), { exact: true }).item;
87
+ if (resolved.role === role)
88
+ return ok({ workspace: { id: target.id, name: target.name }, member: { id: resolved.id, email: resolved.email, role }, note: "Already that role — nothing changed." });
89
+ const updated = await ctx.api.updateMemberRole(target.id, resolved.id, role);
90
+ ctx.invalidate(`members:${target.id}`);
91
+ return ok({ workspace: { id: target.id, name: target.name }, member: { id: updated.id ?? resolved.id, email: updated.email ?? resolved.email, role: updated.role ?? role, previousRole: resolved.role } });
92
+ }));
56
93
  server.registerTool("remove_workspace_member", {
57
94
  title: "Remove a workspace member",
58
- description: "Remove a member from a workspace (by email or membership id). Requires the owner role. Permanent — confirm with the user first.",
95
+ description: "Remove a member from a workspace (by exact email or membership id). Owners can remove anyone; any member can remove themselves (leave). The last owner cannot be removed. Permanent — confirm with the user first.",
59
96
  inputSchema: {
60
97
  workspace: workspaceArg,
61
98
  member: z.string().min(1).max(255).describe("Member email or membership id"),
@@ -70,7 +107,7 @@ export const registerWorkspaceTools = (server, ctx) => {
70
107
  const byEmail = items.filter((entry) => normalizeName(entry.email) === needle);
71
108
  const resolved = byEmail.length === 1
72
109
  ? byEmail[0]
73
- : resolveRef("member", member, items.map((entry) => ({ ...entry, name: entry.email }))).item;
110
+ : resolveRef("member", member, items.map((entry) => ({ ...entry, name: entry.email })), { exact: true }).item;
74
111
  if (!resolved)
75
112
  throw new ToolInputError("REF_NOT_FOUND", `No member matches "${member}".`);
76
113
  await ctx.api.removeMember(target.id, resolved.id);
@@ -1 +1 @@
1
- {"version":3,"file":"workspaces.js","sourceRoot":"","sources":["../../src/tools/workspaces.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"workspaces.js","sourceRoot":"","sources":["../../src/tools/workspaces.ts"],"names":[],"mappings":"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"}
@@ -26,6 +26,9 @@ class CallmanApi {
26
26
  addMember(workspaceId, body) {
27
27
  return this.http.request("POST", `/workspaces/${workspaceId}/members`, { body });
28
28
  }
29
+ updateMemberRole(workspaceId, memberId, role) {
30
+ return this.http.request("PATCH", `/workspaces/${workspaceId}/members/${memberId}/role`, { body: { role } });
31
+ }
29
32
  removeMember(workspaceId, memberId) {
30
33
  return this.http.request("DELETE", `/workspaces/${workspaceId}/members/${memberId}`);
31
34
  }
@@ -87,9 +90,42 @@ class CallmanApi {
87
90
  updateRequest(ws, id, body) {
88
91
  return this.http.request("PATCH", `/requests/${id}`, { workspaceId: ws, body });
89
92
  }
93
+ // isEnabledInRunner has its own route — PATCH /requests/:id strips it.
94
+ setRequestRunState(ws, id, isEnabledInRunner) {
95
+ return this.http.request("PATCH", `/requests/${id}/run-toggle`, { workspaceId: ws, body: { isEnabledInRunner } });
96
+ }
90
97
  deleteRequest(ws, id) {
91
98
  return this.http.request("DELETE", `/requests/${id}`, { workspaceId: ws });
92
99
  }
100
+ // ── contract checks (per request) ───────────────────────────────────
101
+ listContractRules(ws, requestId) {
102
+ return this.http.request("GET", "/contract-rules", { workspaceId: ws, query: { requestId } });
103
+ }
104
+ createContractRules(ws, body) {
105
+ return this.http.request("POST", "/contract-rules/batch", { workspaceId: ws, body });
106
+ }
107
+ updateContractRule(ws, id, body) {
108
+ return this.http.request("PATCH", `/contract-rules/${id}`, { workspaceId: ws, body });
109
+ }
110
+ deleteContractRule(ws, id) {
111
+ return this.http.request("DELETE", `/contract-rules/${id}`, { workspaceId: ws });
112
+ }
113
+ validateContractRules(ws, body) {
114
+ return this.http.request("POST", "/contract-rules/validate", { workspaceId: ws, body });
115
+ }
116
+ getDataContract(ws, requestId) {
117
+ return this.http.request("GET", "/data-contracts", { workspaceId: ws, query: { requestId } });
118
+ }
119
+ putDataContract(ws, body) {
120
+ return this.http.request("PUT", "/data-contracts", { workspaceId: ws, body });
121
+ }
122
+ deleteDataContract(ws, requestId) {
123
+ return this.http.request("DELETE", "/data-contracts", { workspaceId: ws, query: { requestId } });
124
+ }
125
+ // ── connections (safe records) ──────────────────────────────────────
126
+ listConnections(ws, type) {
127
+ return this.http.request("GET", "/connections", { workspaceId: ws, query: type ? { type } : {} });
128
+ }
93
129
  // ── import ──────────────────────────────────────────────────────────
94
130
  importJson(ws, body) {
95
131
  return this.http.request("POST", "/import/json", { workspaceId: ws, body, timeoutMs: 120_000 });
@@ -98,12 +134,25 @@ class CallmanApi {
98
134
  return this.http.request("POST", "/import/scenario", { workspaceId: ws, body, timeoutMs: 120_000 });
99
135
  }
100
136
  // ── environments / globals ──────────────────────────────────────────
101
- listEnvironments(ws, reveal = false) {
137
+ listEnvironments(ws, reveal = false, page = 1) {
102
138
  return this.http.request("GET", "/environments", {
103
139
  workspaceId: ws,
104
- query: { page: 1, limit: 100, ...(reveal ? { reveal: "true" } : {}) },
140
+ query: { page, limit: 100, ...(reveal ? { reveal: "true" } : {}) },
105
141
  });
106
142
  }
143
+ async listAllEnvironments(ws) {
144
+ const out = [];
145
+ for (let page = 1; page <= 50; page += 1) {
146
+ const result = await this.listEnvironments(ws, false, page);
147
+ out.push(...result.items);
148
+ if (page >= result.pagination.totalPages || result.items.length === 0)
149
+ break;
150
+ }
151
+ return out;
152
+ }
153
+ updateEnvironment(ws, id, body) {
154
+ return this.http.request("PATCH", `/environments/${id}`, { workspaceId: ws, body });
155
+ }
107
156
  getEnvironment(ws, id, reveal = false) {
108
157
  return this.http.request("GET", `/environments/${id}`, { workspaceId: ws, query: reveal ? { reveal: "true" } : {} });
109
158
  }
@@ -125,6 +174,12 @@ class CallmanApi {
125
174
  listGlobalVariables(ws, reveal = false) {
126
175
  return this.http.request("GET", "/variables/global", { workspaceId: ws, query: reveal ? { reveal: "true" } : {} });
127
176
  }
177
+ setGlobalVariable(ws, body) {
178
+ return this.http.request("POST", "/variables/global", { workspaceId: ws, body });
179
+ }
180
+ deleteGlobalVariable(ws, key) {
181
+ return this.http.request("DELETE", `/variables/global/${encodeURIComponent(key)}`, { workspaceId: ws });
182
+ }
128
183
  // ── scenarios ───────────────────────────────────────────────────────
129
184
  listScenarios(ws) {
130
185
  return this.http.request("GET", "/scenarios", { workspaceId: ws });
@@ -144,6 +199,16 @@ class CallmanApi {
144
199
  deleteScenario(ws, id) {
145
200
  return this.http.request("DELETE", `/scenarios/${id}`, { workspaceId: ws });
146
201
  }
202
+ // On-prem scenario groups the caller can bind a scenario to ([] on cloud).
203
+ listMyScenarioGroups(ws) {
204
+ return this.http.request("GET", "/scenarios/my-groups", { workspaceId: ws });
205
+ }
206
+ listApproverCandidates(ws, id) {
207
+ return this.http.request("GET", `/scenarios/${id}/approver-candidates`, { workspaceId: ws });
208
+ }
209
+ submitScenario(ws, id, body) {
210
+ return this.http.request("POST", `/scenarios/${id}/submit`, { workspaceId: ws, body });
211
+ }
147
212
  runScenario(ws, id, body) {
148
213
  return this.http.request("POST", `/scenarios/${id}/run-server`, { workspaceId: ws, body });
149
214
  }
@@ -46,6 +46,19 @@ class ToolInputError extends Error {
46
46
  }
47
47
  exports.ToolInputError = ToolInputError;
48
48
  const SCOPE_HINT = "Create a token with that permission in the Callman desktop app (Settings → AI tools → New token) and update the CALLMAN_TOKEN in your MCP config.";
49
+ // Point a validation error at the reference for the area it came from.
50
+ const validationHint = (path) => {
51
+ const doc = /\/(scenarios|scenario-folders)/.test(path)
52
+ ? "callman://docs/scenario-nodes"
53
+ : /\/diagrams/.test(path)
54
+ ? "callman://docs/diagram-schema"
55
+ : /\/(contract-rules|data-contracts)/.test(path)
56
+ ? "callman://docs/contracts"
57
+ : /\/(environments|variables)/.test(path)
58
+ ? null
59
+ : "callman://docs/request-schema";
60
+ return `The server rejected the input — check the fields listed in details${doc ? ` against ${doc}` : " (keys 1–100 chars, values ≤ 5000)"}.`;
61
+ };
49
62
  const hintFor = (error) => {
50
63
  switch (error.code) {
51
64
  case "PAT_SCOPE_MISSING": {
@@ -55,11 +68,24 @@ const hintFor = (error) => {
55
68
  return `The token lacks the permission ${required}. ${SCOPE_HINT}`;
56
69
  }
57
70
  case "PAT_ROUTE_FORBIDDEN":
58
- return "This area of Callman is not available to AI tools yet (mocks, connections, history, UI tests, admin). Use the desktop app for it.";
59
- case "FEATURE_DISABLED":
60
- return "AI tools are switched off for this account by an administrator (feature flag mcp). Ask them to enable it in the admin panel.";
71
+ return "This area of Callman is not available to AI tools (mocks, history, UI tests, schedules, connection editing, admin). Use the desktop app for it.";
72
+ case "FEATURE_DISABLED": {
73
+ const feature = error.details?.feature;
74
+ return typeof feature === "string"
75
+ ? `The "${feature}" feature is switched off for this account or edition. An administrator can enable it in the admin panel; whoami lists the enabled features.`
76
+ : "A feature this call needs is switched off for this account. whoami lists the enabled features; an administrator can enable it in the admin panel.";
77
+ }
61
78
  case "SECRET_MASKED_VALUE_REJECTED":
62
- return "A masked value (••••) was sent back as if it were real. Read the value with get_environment reveal:true (needs environments:reveal) or set a new real value.";
79
+ return "A masked value (••••) was sent back as if it were real. Read the value with reveal: true (needs environments:reveal) or send the real value.";
80
+ case "SCENARIO_NOT_APPROVED":
81
+ return "Personal tokens run the APPROVED version of a scenario, and this one has none yet. Submit it for review (submit_scenario) and have an approver approve it in the desktop app, then run it again.";
82
+ case "SCENARIO_GROUP_REQUIRED":
83
+ return "You belong to several scenario groups — pass `group` (name or id) to say which one owns the scenario.";
84
+ case "SCENARIO_ENV_NOT_FOUND":
85
+ return "The scenario has no environment with that id or name — get_scenario lists its environments.";
86
+ case "WORKSPACE_LAST_OWNER_REQUIRED":
87
+ case "WORKSPACE_LAST_OWNER_ROLE_CHANGE_FORBIDDEN":
88
+ return "A workspace must keep at least one owner. Make someone else owner first (update_workspace_member), then change or remove this member.";
63
89
  case "SCENARIO_VERSION_CONFLICT":
64
90
  return "Someone changed the scenario since it was read. Re-read it with get_scenario, reapply your change on the current version, then call update_scenario with the new expectedVersion (or force:true to overwrite).";
65
91
  case "DIAGRAM_DOCUMENT_INVALID":
@@ -71,9 +97,9 @@ const hintFor = (error) => {
71
97
  case "WORKSPACE_MEMBER_EXISTS":
72
98
  return "That person is already a member of the workspace. Use list_workspace_members to see their role.";
73
99
  case "WORKSPACE_MEMBER_REMOVE_FORBIDDEN":
74
- return "That member cannot be removed (the last owner of a workspace must stay).";
100
+ return "Only a workspace owner can remove other members (anyone can remove themselves).";
75
101
  case "VALIDATION_ERROR":
76
- return "The request body did not pass validation — check the listed fields against callman://docs/request-schema.";
102
+ return validationHint(error.path);
77
103
  case "WORKSPACE_ACCESS_DENIED":
78
104
  case "WORKSPACE_NOT_FOUND":
79
105
  case "WORKSPACE_ID_REQUIRED":
@@ -90,7 +116,7 @@ const hintFor = (error) => {
90
116
  case 404:
91
117
  return "Nothing matched that id. Use the list_* / search_* tools to find the right item — names work as references too.";
92
118
  case 409:
93
- return "That name already exists. Pick another name or reuse the existing item (list it first).";
119
+ return "The server refused the change because of the item's current state (a name that already exists, a newer version, an approval rule). Read the item again and see the error message.";
94
120
  case 413:
95
121
  return "The payload is too large for the server. Split the import or reduce the document.";
96
122
  case 429:
@@ -20,10 +20,11 @@ const createToolContext = (options) => {
20
20
  const api = new api_js_1.CallmanApi(http);
21
21
  const cache = new cache_js_1.TtlCache(options.cacheTtlMs ?? 15_000);
22
22
  let runLock = Promise.resolve();
23
+ let defaultWorkspaceId = options.config.defaultWorkspaceId ?? null;
23
24
  const listWorkspaces = () => cache.getOrSet("workspaces", () => api.listWorkspaces());
24
25
  const pickWorkspace = async (explicit, required) => {
25
26
  const workspaces = await listWorkspaces();
26
- const wanted = (explicit ?? "").trim() || options.config.defaultWorkspaceId || "";
27
+ const wanted = (explicit ?? "").trim() || defaultWorkspaceId || "";
27
28
  if (wanted) {
28
29
  const byId = workspaces.find((workspace) => workspace.id === wanted);
29
30
  if (byId)
@@ -52,7 +53,7 @@ const createToolContext = (options) => {
52
53
  return null;
53
54
  throw new errors_js_1.ToolInputError(workspaces.length === 0 ? "WORKSPACE_NONE" : "WORKSPACE_REQUIRED", workspaces.length === 0
54
55
  ? "You are not a member of any workspace."
55
- : "Several workspaces are available — pass `workspace` (name or id) or set CALLMAN_WORKSPACE_ID.", { candidates: summarize(workspaces) });
56
+ : "This needs one target workspace and you have several — pass `workspace` (name or id), or pick a default for the session with use_workspace.", { candidates: summarize(workspaces) });
56
57
  };
57
58
  return {
58
59
  config: options.config,
@@ -61,6 +62,10 @@ const createToolContext = (options) => {
61
62
  cache,
62
63
  version: options.version,
63
64
  listWorkspaces,
65
+ getDefaultWorkspaceId: () => defaultWorkspaceId,
66
+ setDefaultWorkspaceId: (id) => {
67
+ defaultWorkspaceId = id;
68
+ },
64
69
  getTokenScopes: () => cache.getOrSet("token-scopes", async () => {
65
70
  try {
66
71
  return (await api.me()).token.scopes ?? [];
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.undeclaredDataColumns = exports.dataContractRowSchema = exports.DATA_CONTRACT_LIMITS = exports.contractRuleInputSchema = exports.contractRulesSchema = exports.contractPathSchema = void 0;
4
+ const callman_core_1 = require("callman-core");
5
+ const zod_1 = require("zod");
6
+ const strict_js_1 = require("../lib/strict.js");
7
+ // Contract checks on a saved request — the same two documents the desktop's
8
+ // Contracts tab edits and every runner (desktop, CLI, run_request /
9
+ // run_collection) evaluates after the response:
10
+ // * contract RULES — "the field at `path` must satisfy `rules`"
11
+ // * a DATA CONTRACT — rows of inputs ({{data.<column>}}), each with its own
12
+ // expected status and field assertions; the request runs once per row.
13
+ // The rule vocabulary mirrors the backend's contractRuleRulesSchema exactly
14
+ // (strict here, so a misspelled rule is an error instead of a no-op).
15
+ // `users[].id`, `data.items[0].price`, `[].name`, `response.status`,
16
+ // `response.headers.content-type` — same grammar the backend enforces.
17
+ const CONTRACT_PATH = /^(\[\d*\]|[A-Za-z0-9_$-]+(\[\d*\])?)(\.(\[\d*\]|[A-Za-z0-9_$-]+(\[\d*\])?))*$/;
18
+ exports.contractPathSchema = zod_1.z
19
+ .string()
20
+ .trim()
21
+ .min(1)
22
+ .max(500)
23
+ .regex(CONTRACT_PATH, "Invalid contract path — use dots and [] like users[].id, items[0].price or response.status")
24
+ .describe("Field path. Body paths: user.id, users[].id (every element), items[0].price (one element), [].name (top-level array). `response.status`, `response.headers.<name>` and `response.duration` check the HTTP envelope instead of the body.");
25
+ const nonNegativeInt = zod_1.z.number().int().min(0);
26
+ exports.contractRulesSchema = (0, strict_js_1.strictObject)({
27
+ required: zod_1.z.boolean().optional().describe("The field must exist"),
28
+ type: zod_1.z.enum(["string", "number", "boolean", "object", "array", "null"]).optional(),
29
+ equals: zod_1.z.union([zod_1.z.string().max(2000), zod_1.z.number(), zod_1.z.boolean()]).optional().describe("Exact value (honours caseSensitive for strings)"),
30
+ notEmpty: zod_1.z.boolean().optional().describe("Not \"\", [], {} or null"),
31
+ // numbers
32
+ min: zod_1.z.number().optional(),
33
+ max: zod_1.z.number().optional(),
34
+ greaterThan: zod_1.z.number().optional(),
35
+ lessThan: zod_1.z.number().optional(),
36
+ integer: zod_1.z.boolean().optional(),
37
+ positive: zod_1.z.boolean().optional(),
38
+ negative: zod_1.z.boolean().optional(),
39
+ nonZero: zod_1.z.boolean().optional(),
40
+ // strings
41
+ minLength: nonNegativeInt.optional(),
42
+ maxLength: nonNegativeInt.optional(),
43
+ pattern: zod_1.z.string().max(1000).optional().describe("JavaScript regular expression the string must match"),
44
+ contains: zod_1.z.string().max(1000).optional(),
45
+ notContains: zod_1.z.string().max(1000).optional(),
46
+ startsWith: zod_1.z.string().max(1000).optional(),
47
+ endsWith: zod_1.z.string().max(1000).optional(),
48
+ caseSensitive: zod_1.z.boolean().optional().describe("For equals/contains/startsWith/endsWith (default true)"),
49
+ enumValues: zod_1.z.array(zod_1.z.union([zod_1.z.string().max(500), zod_1.z.number()])).min(1).max(100).optional().describe("The value must be one of these"),
50
+ format: zod_1.z.enum(callman_core_1.SCENARIO_CONTRACT_FORMATS).optional().describe(`String format: ${callman_core_1.SCENARIO_CONTRACT_FORMATS.join(", ")}`),
51
+ // arrays
52
+ minItems: nonNegativeInt.optional(),
53
+ maxItems: nonNegativeInt.optional(),
54
+ sorted: (0, strict_js_1.strictObject)({ order: zod_1.z.enum(["asc", "desc"]), field: zod_1.z.string().max(200).optional().describe("Sort key for arrays of objects") }, "sorted field").optional(),
55
+ unique: (0, strict_js_1.strictObject)({ mode: zod_1.z.enum(["whole", "byField"]), fields: zod_1.z.array(zod_1.z.string().max(200)).max(50).optional().describe("Required with mode byField") }, "unique field").optional(),
56
+ // objects
57
+ requiredKeys: zod_1.z.array(zod_1.z.string().max(200)).max(100).optional(),
58
+ forbiddenKeys: zod_1.z.array(zod_1.z.string().max(200)).max(100).optional(),
59
+ minProperties: nonNegativeInt.optional(),
60
+ maxProperties: nonNegativeInt.optional(),
61
+ strictSchema: zod_1.z.boolean().optional().describe("Objects: no keys beyond requiredKeys"),
62
+ }, "contract rule").refine((rules) => Object.values(rules).some((value) => value !== undefined), { message: "Give at least one rule (e.g. { required: true, type: \"string\" })" });
63
+ exports.contractRuleInputSchema = (0, strict_js_1.strictObject)({
64
+ path: exports.contractPathSchema,
65
+ rules: exports.contractRulesSchema,
66
+ enabled: zod_1.z.boolean().optional().describe("Default true"),
67
+ }, "contract rule field");
68
+ // Data-driven contract — backend caps (DATA_CONTRACT_*).
69
+ exports.DATA_CONTRACT_LIMITS = { rows: 20, columns: 8, assertions: 12, cell: 4096 };
70
+ exports.dataContractRowSchema = (0, strict_js_1.strictObject)({
71
+ data: zod_1.z
72
+ .record(zod_1.z.string().max(exports.DATA_CONTRACT_LIMITS.cell))
73
+ .default({})
74
+ .describe("Column → value for this row; the request reads them as {{data.<column>}}"),
75
+ expectedStatus: zod_1.z.number().int().min(100).max(599).optional().describe("HTTP status this row must return"),
76
+ assertions: zod_1.z
77
+ .array((0, strict_js_1.strictObject)({ path: exports.contractPathSchema, rules: exports.contractRulesSchema, enabled: zod_1.z.boolean().optional() }, "row assertion field"))
78
+ .max(exports.DATA_CONTRACT_LIMITS.assertions)
79
+ .default([])
80
+ .describe(`Field checks for this row (≤ ${exports.DATA_CONTRACT_LIMITS.assertions})`),
81
+ }, "data contract row field");
82
+ // Every {{data.x}} a row set needs must be a declared column — catch the
83
+ // typo before the run reports an empty value.
84
+ const undeclaredDataColumns = (columns, rows) => {
85
+ const declared = new Set(columns);
86
+ const used = new Set();
87
+ for (const row of rows)
88
+ for (const key of Object.keys(row.data))
89
+ if (!declared.has(key))
90
+ used.add(key);
91
+ return [...used];
92
+ };
93
+ exports.undeclaredDataColumns = undeclaredDataColumns;
@@ -1,10 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.buildDiagramDocument = exports.suggestComponentTypes = exports.diagramInputSchema = exports.diagramEdgeInputSchema = exports.diagramNodeInputSchema = exports.EDGE_SEMANTICS_INPUT = void 0;
3
+ exports.buildDiagramDocument = exports.edgeStyleFor = exports.assertNotConnector = exports.parentWarning = exports.containerTypes = exports.isContainerType = exports.suggestComponentTypes = exports.diagramInputSchema = exports.diagramEdgeInputSchema = exports.diagramNodeInputSchema = exports.EDGE_SEMANTICS_INPUT = void 0;
4
4
  const callman_core_1 = require("callman-core");
5
5
  const zod_1 = require("zod");
6
6
  const errors_js_1 = require("../../client/errors.js");
7
7
  const ids_js_1 = require("../../lib/ids.js");
8
+ const strict_js_1 = require("../../lib/strict.js");
9
+ const style_js_1 = require("./style.js");
8
10
  // From the COMPACT diagram a model writes (typed nodes with labels, edges
9
11
  // with a meaning) to the DiagramDocument the Diagram Studio renders. Ids are
10
12
  // short and stable (n1…, e1…), component types are checked against the
@@ -12,30 +14,40 @@ const ids_js_1 = require("../../lib/ids.js");
12
14
  // meaning becomes the studio's notation (sync / async / fallback / bus), and
13
15
  // the result is validated with the same parser the backend and desktop use.
14
16
  exports.EDGE_SEMANTICS_INPUT = ["sync", "async", "fallback", "bus"];
15
- exports.diagramNodeInputSchema = zod_1.z.object({
17
+ const ARROWS = ["none", "classic", "classicThin", "open", "block", "diamond", "oval"];
18
+ exports.diagramNodeInputSchema = (0, strict_js_1.strictObject)({
16
19
  id: zod_1.z.string().min(1).max(64).optional().describe("Stable id (n1, api, db…); generated when omitted"),
17
- type: zod_1.z.string().min(1).max(80).describe("Component type from callman://diagram/components, e.g. net.service, db.postgres, aws.lambda, flow.process"),
20
+ type: zod_1.z.string().min(1).max(80).describe("Component type from callman://diagram/components, e.g. net.service, net.api-gateway, db.postgres, mq.kafka, aws.lambda, flow.process"),
18
21
  label: zod_1.z.string().max(200).optional(),
19
- parent: zod_1.z.string().max(64).optional().describe("Id of a container node (net.zone, flow.frame…) this node sits inside"),
20
- position: zod_1.z.object({ x: zod_1.z.number(), y: zod_1.z.number() }).optional(),
21
- size: zod_1.z.object({ width: zod_1.z.number().positive(), height: zod_1.z.number().positive() }).optional(),
22
- style: zod_1.z.record(zod_1.z.unknown()).optional(),
23
- data: zod_1.z.record(zod_1.z.unknown()).optional(),
24
- });
25
- exports.diagramEdgeInputSchema = zod_1.z.object({
22
+ parent: zod_1.z.string().max(64).optional().describe("Id of a container node this node sits inside: frame, pool.horizontal or pool.vertical"),
23
+ position: zod_1.z.object({ x: zod_1.z.number(), y: zod_1.z.number() }).strict().optional().describe("Top-left corner; relative to the parent container when `parent` is set. Omit to auto-layout"),
24
+ size: zod_1.z.object({ width: zod_1.z.number().positive(), height: zod_1.z.number().positive() }).strict().optional().describe("Defaults to the component's catalog size"),
25
+ style: style_js_1.nodeStyleInputSchema.optional(),
26
+ rotation: zod_1.z.number().min(-360).max(360).optional().describe("Degrees, clockwise"),
27
+ locked: zod_1.z.boolean().optional().describe("Locked nodes cannot be moved or resized in the studio"),
28
+ hidden: zod_1.z.boolean().optional(),
29
+ data: zod_1.z.record(zod_1.z.unknown()).optional().describe("Free-form metadata kept with the node (not rendered), e.g. { owner: \"team-a\", repo: \"…\" }"),
30
+ }, "node field");
31
+ exports.diagramEdgeInputSchema = (0, strict_js_1.strictObject)({
26
32
  id: zod_1.z.string().min(1).max(64).optional(),
27
- source: zod_1.z.string().min(1).max(64),
28
- target: zod_1.z.string().min(1).max(64),
33
+ source: zod_1.z.string().min(1).max(64).describe("Node id"),
34
+ target: zod_1.z.string().min(1).max(64).describe("Node id. A container (frame/pool) id is allowed — the line ends at its border"),
29
35
  label: zod_1.z.string().max(200).optional(),
30
- semantic: zod_1.z.enum(exports.EDGE_SEMANTICS_INPUT).optional().describe("sync (default) = request/response, async = event, fallback = retry/optional, bus = message bus"),
31
- routing: zod_1.z.enum(["orthogonal", "straight", "curved"]).optional(),
32
- markerEnd: zod_1.z.enum(["none", "classic", "classicThin", "open", "block", "diamond", "oval"]).optional(),
33
- });
36
+ semantic: zod_1.z.enum(exports.EDGE_SEMANTICS_INPUT).optional().describe("sync (default, solid) = request/response, async (dashed) = event, fallback (dotted) = retry/optional, bus (heavy) = message bus; automatic bus when an end is a messaging component"),
37
+ color: style_js_1.colorInputSchema.optional().describe('Line CSS color, e.g. "#8B5CF6". Independent of `semantic`'),
38
+ routing: zod_1.z.enum(["orthogonal", "straight", "curved"]).optional().describe("orthogonal (default, right-angle auto-routing), straight, curved"),
39
+ markerEnd: zod_1.z.enum(ARROWS).optional().describe("Arrow at the target (default classicThin)"),
40
+ markerStart: zod_1.z.enum(ARROWS).optional().describe("Arrow at the source (default none) — set it for a two-way connection"),
41
+ }, "edge field");
34
42
  exports.diagramInputSchema = zod_1.z.object({
35
43
  title: zod_1.z.string().min(1).max(200),
36
44
  nodes: zod_1.z.array(exports.diagramNodeInputSchema).min(1).max(500),
37
45
  edges: zod_1.z.array(exports.diagramEdgeInputSchema).max(2000).default([]),
38
- canvas: zod_1.z.object({ background: zod_1.z.enum(["grid", "dots", "blank"]).optional(), gridSize: zod_1.z.number().int().positive().optional() }).optional(),
46
+ canvas: zod_1.z
47
+ .object({ background: zod_1.z.enum(["grid", "dots", "blank"]).optional(), gridSize: zod_1.z.number().int().positive().optional() })
48
+ .strict()
49
+ .optional()
50
+ .describe("Canvas background (default dots) and grid size (default 16)"),
39
51
  });
40
52
  const suggestComponentTypes = (type, limit = 5) => {
41
53
  const seen = new Set();
@@ -69,6 +81,34 @@ const suggestComponentTypes = (type, limit = 5) => {
69
81
  return out;
70
82
  };
71
83
  exports.suggestComponentTypes = suggestComponentTypes;
84
+ // Containers hold children through `parent`: frames and swimlane pools.
85
+ const isContainerType = (type) => {
86
+ const def = type ? (0, callman_core_1.getDiagramComponent)(type) : undefined;
87
+ return Boolean(def?.container || def?.swimlane);
88
+ };
89
+ exports.isContainerType = isContainerType;
90
+ const containerTypes = () => callman_core_1.DIAGRAM_COMPONENT_CATALOG.filter((entry) => entry.container || entry.swimlane).map((entry) => entry.type);
91
+ exports.containerTypes = containerTypes;
92
+ const parentWarning = (id, parentId, parentType) => (0, exports.isContainerType)(parentType)
93
+ ? null
94
+ : `Node ${id} sits inside "${parentId}" (${parentType ?? "unknown"}), which is not a container — use ${(0, exports.containerTypes)().join(", ")} to group nodes.`;
95
+ exports.parentWarning = parentWarning;
96
+ // Edge input → the stored edge's visual fields: the semantic's line tuple
97
+ // plus an optional color.
98
+ // line / arrow / line.dashed are palette connectors (0-height), not nodes.
99
+ const assertNotConnector = (type, id) => {
100
+ if ((0, callman_core_1.getDiagramComponent)(type)?.variant === "line") {
101
+ throw new errors_js_1.ToolInputError("DIAGRAM_CONNECTOR_NOT_NODE", `"${type}" on ${id} is a connector, not a node — draw it as an edge between two nodes.`);
102
+ }
103
+ };
104
+ exports.assertNotConnector = assertNotConnector;
105
+ const edgeStyleFor = (semantic, color) => {
106
+ const base = semantic ? (0, callman_core_1.semanticStyle)(semantic) : undefined;
107
+ if (!color)
108
+ return base;
109
+ return { ...(base ?? {}), stroke: (0, style_js_1.toTokenRef)(color) };
110
+ };
111
+ exports.edgeStyleFor = edgeStyleFor;
72
112
  const buildDiagramDocument = (input, options = {}) => {
73
113
  const strict = options.strictTypes !== false;
74
114
  const warnings = [];
@@ -96,6 +136,8 @@ const buildDiagramDocument = (input, options = {}) => {
96
136
  type = "rect";
97
137
  }
98
138
  }
139
+ if (known)
140
+ (0, exports.assertNotConnector)(type, id);
99
141
  const def = (0, callman_core_1.getDiagramComponent)(type);
100
142
  typeOf.set(id, type);
101
143
  if (node.parent && !idSet.has(node.parent)) {
@@ -108,10 +150,18 @@ const buildDiagramDocument = (input, options = {}) => {
108
150
  size: node.size ?? def?.defaultSize ?? { width: 140, height: 60 },
109
151
  ...(node.label !== undefined || !known ? { label: node.label ?? node.type } : def?.defaultLabel ? { label: def.defaultLabel } : {}),
110
152
  ...(node.parent ? { parentId: node.parent } : {}),
111
- ...(node.style ? { style: node.style } : {}),
153
+ ...(node.style ? { style: (0, style_js_1.applyStyleInput)(undefined, node.style) } : {}),
154
+ ...(node.rotation ? { rotation: node.rotation } : {}),
155
+ ...(node.locked ? { locked: true } : {}),
156
+ ...(node.hidden ? { hidden: true } : {}),
112
157
  ...(node.data ? { data: node.data } : {}),
113
158
  };
114
159
  });
160
+ for (const node of nodes) {
161
+ const warning = node.parentId ? (0, exports.parentWarning)(node.id, node.parentId, typeOf.get(node.parentId)) : null;
162
+ if (warning)
163
+ warnings.push(warning);
164
+ }
115
165
  if (unknown.length > 0) {
116
166
  throw new errors_js_1.ToolInputError("DIAGRAM_UNKNOWN_COMPONENT_TYPE", `Unknown component type(s): ${unknown.map((entry) => entry.type).join(", ")}. Read callman://diagram/components for the catalog, or pass strictTypes:false to draw them as rectangles.`, { unknownTypes: unknown });
117
167
  }
@@ -131,7 +181,7 @@ const buildDiagramDocument = (input, options = {}) => {
131
181
  if (!semantic && ((0, callman_core_1.isBusComponentType)(typeOf.get(edge.source)) || (0, callman_core_1.isBusComponentType)(typeOf.get(edge.target)))) {
132
182
  semantic = "bus";
133
183
  }
134
- const style = semantic ? (0, callman_core_1.semanticStyle)(semantic) : undefined;
184
+ const style = (0, exports.edgeStyleFor)(semantic, edge.color);
135
185
  return {
136
186
  id,
137
187
  source: edge.source,
@@ -139,7 +189,8 @@ const buildDiagramDocument = (input, options = {}) => {
139
189
  ...(edge.label ? { label: edge.label } : {}),
140
190
  routing: edge.routing ?? "orthogonal",
141
191
  markerEnd: edge.markerEnd ?? "classicThin",
142
- ...(style && !(0, callman_core_1.isDefaultEdgeStyle)(style) ? { style } : semantic === "sync" ? { style } : {}),
192
+ ...(edge.markerStart && edge.markerStart !== "none" ? { markerStart: edge.markerStart } : {}),
193
+ ...(style && (!(0, callman_core_1.isDefaultEdgeStyle)(style) || semantic === "sync" || edge.color) ? { style } : {}),
143
194
  };
144
195
  });
145
196
  const timestamp = options.createdAt ?? (0, callman_core_1.nowIso)();