shipscreens 0.1.2 → 0.1.3

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 (320) hide show
  1. package/README.md +37 -0
  2. package/bin/shipscreens.js +15 -1
  3. package/cli/commands/build.js +19 -4
  4. package/cli/mcpServer.js +573 -0
  5. package/dist/app/assets/AgentCli-CJHTv5S4.js +17 -0
  6. package/dist/app/assets/AgentCli-CJHTv5S4.js.map +1 -0
  7. package/dist/app/assets/App-BwQ1zI7a.css +1 -0
  8. package/dist/app/assets/App-DV5XHwn8.js +13 -0
  9. package/dist/app/assets/App-DV5XHwn8.js.map +1 -0
  10. package/dist/app/assets/AppReviewAso-Dvh6A_g-.js +4 -0
  11. package/dist/app/assets/AppReviewAso-Dvh6A_g-.js.map +1 -0
  12. package/dist/app/assets/{Cancelled-66ixTUrm.js → Cancelled-D6i4ywc8.js} +2 -2
  13. package/dist/app/assets/{Cancelled-66ixTUrm.js.map → Cancelled-D6i4ywc8.js.map} +1 -1
  14. package/dist/app/assets/CopyButton-BlPQEoP3.js +2 -0
  15. package/dist/app/assets/CopyButton-BlPQEoP3.js.map +1 -0
  16. package/dist/app/assets/FastlaneScreenshots-DF74cNwo.js +52 -0
  17. package/dist/app/assets/FastlaneScreenshots-DF74cNwo.js.map +1 -0
  18. package/dist/app/assets/FirstExport-BMHdPGDX.js +6 -0
  19. package/dist/app/assets/FirstExport-BMHdPGDX.js.map +1 -0
  20. package/dist/app/assets/FitPanel-Fp4iPZxf.js +2 -0
  21. package/dist/app/assets/FitPanel-Fp4iPZxf.js.map +1 -0
  22. package/dist/app/assets/FivePanelFramework-B967Cblg.js +62 -0
  23. package/dist/app/assets/FivePanelFramework-B967Cblg.js.map +1 -0
  24. package/dist/{assets/ForgotPassword-B9_si1tH.js → app/assets/ForgotPassword-CApAdwy1.js} +2 -2
  25. package/dist/app/assets/{ForgotPassword-B9_si1tH.js.map → ForgotPassword-CApAdwy1.js.map} +1 -1
  26. package/dist/app/assets/Landing-Vxx4PfE4.js +2 -0
  27. package/dist/app/assets/Landing-Vxx4PfE4.js.map +1 -0
  28. package/dist/app/assets/{LanguageSwitcher-BD9N-dla.js → LanguageSwitcher-Cp-6zMXz.js} +2 -2
  29. package/dist/{assets/LanguageSwitcher-BD9N-dla.js.map → app/assets/LanguageSwitcher-Cp-6zMXz.js.map} +1 -1
  30. package/dist/app/assets/{Legal-D3cAXQXw.js → Legal-CGgUYM9f.js} +2 -2
  31. package/dist/app/assets/{Legal-D3cAXQXw.js.map → Legal-CGgUYM9f.js.map} +1 -1
  32. package/dist/app/assets/{NotFound-ClV-6RmP.js → NotFound-DCeMrR7Q.js} +2 -2
  33. package/dist/app/assets/{NotFound-ClV-6RmP.js.map → NotFound-DCeMrR7Q.js.map} +1 -1
  34. package/dist/app/assets/Pricing-CGZnCST5.js +2 -0
  35. package/dist/app/assets/Pricing-CGZnCST5.js.map +1 -0
  36. package/dist/app/assets/{Privacy-DfxgWwC3.js → Privacy-D86um9Ox.js} +2 -2
  37. package/dist/{assets/Privacy-DfxgWwC3.js.map → app/assets/Privacy-D86um9Ox.js.map} +1 -1
  38. package/dist/app/assets/{SignIn-ghQCKcPe.js → SignIn-J1V55TpG.js} +2 -2
  39. package/dist/app/assets/{SignIn-ghQCKcPe.js.map → SignIn-J1V55TpG.js.map} +1 -1
  40. package/dist/app/assets/{SignUp-BKB87hd4.js → SignUp-D6y9FaIp.js} +2 -2
  41. package/dist/{assets/SignUp-BKB87hd4.js.map → app/assets/SignUp-D6y9FaIp.js.map} +1 -1
  42. package/dist/app/assets/SiteHeader-Ch5fAKkA.js +2 -0
  43. package/dist/app/assets/SiteHeader-Ch5fAKkA.js.map +1 -0
  44. package/dist/app/assets/StickyMobileCta-BdjmxjZ4.js +2 -0
  45. package/dist/app/assets/StickyMobileCta-BdjmxjZ4.js.map +1 -0
  46. package/dist/app/assets/StoreAssetsPipeline-Cl-3GPfw.js +6 -0
  47. package/dist/app/assets/StoreAssetsPipeline-Cl-3GPfw.js.map +1 -0
  48. package/dist/app/assets/{Success-819qvzmp.js → Success-BtaUzpPJ.js} +2 -2
  49. package/dist/app/assets/{Success-819qvzmp.js.map → Success-BtaUzpPJ.js.map} +1 -1
  50. package/dist/app/assets/{Terms-7k3nA4SU.js → Terms-D_qNDuwq.js} +2 -2
  51. package/dist/app/assets/{Terms-7k3nA4SU.js.map → Terms-D_qNDuwq.js.map} +1 -1
  52. package/dist/app/assets/ToolGuardrailsPanel-Dqo_LDWu.js +2 -0
  53. package/dist/app/assets/ToolGuardrailsPanel-Dqo_LDWu.js.map +1 -0
  54. package/dist/app/assets/ToolsIndex-D7Z_LkLt.js +6 -0
  55. package/dist/app/assets/ToolsIndex-D7Z_LkLt.js.map +1 -0
  56. package/dist/app/assets/WorkloadCalculator-6PgA8Qfc.js +5 -0
  57. package/dist/app/assets/WorkloadCalculator-6PgA8Qfc.js.map +1 -0
  58. package/dist/app/assets/{calculator-CiqKFdRp.js → calculator-BJHViS7f.js} +2 -2
  59. package/dist/app/assets/{calculator-CiqKFdRp.js.map → calculator-BJHViS7f.js.map} +1 -1
  60. package/dist/app/assets/check-IxdpNvaC.js +2 -0
  61. package/dist/app/assets/check-IxdpNvaC.js.map +1 -0
  62. package/dist/app/assets/chevron-down-DFKVs9n4.js +2 -0
  63. package/dist/app/assets/{chevron-down-_xIkRLaA.js.map → chevron-down-DFKVs9n4.js.map} +1 -1
  64. package/dist/app/assets/circle-check-DA-NWInD.js +2 -0
  65. package/dist/app/assets/circle-check-DA-NWInD.js.map +1 -0
  66. package/dist/app/assets/{clipboard-copy-DCJioqIc.js → clipboard-copy-B2p9wr40.js} +2 -2
  67. package/dist/app/assets/{clipboard-copy-DCJioqIc.js.map → clipboard-copy-B2p9wr40.js.map} +1 -1
  68. package/dist/app/assets/{copy-AQdWJCcs.js → copy-BnUx1vxq.js} +2 -2
  69. package/dist/app/assets/{copy-AQdWJCcs.js.map → copy-BnUx1vxq.js.map} +1 -1
  70. package/dist/app/assets/{crop-DOMVp18h.js → crop-BLAB1KK_.js} +2 -2
  71. package/dist/app/assets/{crop-DOMVp18h.js.map → crop-BLAB1KK_.js.map} +1 -1
  72. package/dist/app/assets/{download-D5RbyXDm.js → download-DNjju5h9.js} +2 -2
  73. package/dist/app/assets/{download-D5RbyXDm.js.map → download-DNjju5h9.js.map} +1 -1
  74. package/dist/app/assets/{eye-CLcZi_uk.js → eye-DkJdJAvt.js} +2 -2
  75. package/dist/app/assets/{eye-CLcZi_uk.js.map → eye-DkJdJAvt.js.map} +1 -1
  76. package/dist/app/assets/folder-tree-zQOd55nP.js +2 -0
  77. package/dist/app/assets/folder-tree-zQOd55nP.js.map +1 -0
  78. package/dist/app/assets/{grid-3x3-AKmIrhzv.js → grid-3x3-BCPiZxWL.js} +2 -2
  79. package/dist/{assets/grid-3x3-AKmIrhzv.js.map → app/assets/grid-3x3-BCPiZxWL.js.map} +1 -1
  80. package/dist/app/assets/hero/cli-build-tree-15s.mp4 +0 -0
  81. package/dist/app/assets/hero/cli-build-tree-15s.webm +0 -0
  82. package/dist/app/assets/hero/cli-build-tree-25s.mp4 +0 -0
  83. package/dist/app/assets/hero/cli-build-tree-25s.webm +0 -0
  84. package/dist/app/assets/hero/cli-build-tree-poster.png +0 -0
  85. package/dist/app/assets/hero/demo-25s-poster.jpg +0 -0
  86. package/dist/app/assets/hero/demo-25s.mp4 +0 -0
  87. package/dist/app/assets/hero/demo-25s.webm +0 -0
  88. package/dist/app/assets/hero/demo-poster.jpg +0 -0
  89. package/dist/app/assets/hero/demo.mp4 +0 -0
  90. package/dist/app/assets/hero/demo.webm +0 -0
  91. package/dist/app/assets/{index-Bqv2NztY.js → index-C4xM6WAU.js} +18 -18
  92. package/dist/app/assets/index-C4xM6WAU.js.map +1 -0
  93. package/dist/app/assets/index-CQecHUcy.css +1 -0
  94. package/dist/app/assets/{layout-grid-CpGXUPMR.js → layout-grid-DvMRLTBT.js} +2 -2
  95. package/dist/app/assets/{layout-grid-CpGXUPMR.js.map → layout-grid-DvMRLTBT.js.map} +1 -1
  96. package/dist/app/assets/noto-sans-arabic-arabic-400-normal-AAMxebZb.woff2 +0 -0
  97. package/dist/app/assets/noto-sans-arabic-arabic-400-normal-hsqIUL9Q.woff +0 -0
  98. package/dist/app/assets/noto-sans-arabic-arabic-500-normal-CoaTbVwZ.woff +0 -0
  99. package/dist/app/assets/noto-sans-arabic-arabic-500-normal-DPISWLls.woff2 +0 -0
  100. package/dist/app/assets/noto-sans-arabic-arabic-700-normal-3CqrwsiZ.woff2 +0 -0
  101. package/dist/app/assets/noto-sans-arabic-arabic-700-normal-DXnsSW3z.woff +0 -0
  102. package/dist/app/assets/noto-sans-thai-thai-400-normal-BEOmKAI1.woff2 +0 -0
  103. package/dist/app/assets/noto-sans-thai-thai-400-normal-Dxb_unuU.woff +0 -0
  104. package/dist/app/assets/noto-sans-thai-thai-500-normal-BOGXO2tw.woff +0 -0
  105. package/dist/app/assets/noto-sans-thai-thai-500-normal-CU_X86GQ.woff2 +0 -0
  106. package/dist/app/assets/noto-sans-thai-thai-700-normal-C9ISMlQq.woff +0 -0
  107. package/dist/app/assets/noto-sans-thai-thai-700-normal-Cm52XUnT.woff2 +0 -0
  108. package/dist/app/assets/{rocket-IzRFv1aW.js → rocket-fjJ-qzsl.js} +2 -2
  109. package/dist/app/assets/{rocket-IzRFv1aW.js.map → rocket-fjJ-qzsl.js.map} +1 -1
  110. package/dist/app/assets/{shield-check-CngdN3zn.js → shield-check-C-qC9fhU.js} +2 -2
  111. package/dist/app/assets/{shield-check-CngdN3zn.js.map → shield-check-C-qC9fhU.js.map} +1 -1
  112. package/dist/app/assets/{signIn-Cn6FaQYi.js → signIn-CYNXaR1Y.js} +2 -2
  113. package/dist/{assets/signIn-Cn6FaQYi.js.map → app/assets/signIn-CYNXaR1Y.js.map} +1 -1
  114. package/dist/app/assets/{smartphone-CpNG_Pfk.js → smartphone-DRYkbHrn.js} +2 -2
  115. package/dist/app/assets/{smartphone-CpNG_Pfk.js.map → smartphone-DRYkbHrn.js.map} +1 -1
  116. package/dist/app/assets/{terminal-BbBESfoU.js → terminal-CY2dKmaU.js} +2 -2
  117. package/dist/{assets/terminal-BbBESfoU.js.map → app/assets/terminal-CY2dKmaU.js.map} +1 -1
  118. package/dist/{assets/useAuth-3WWZ3GCD.js → app/assets/useAuth-D_UWt-CP.js} +2 -2
  119. package/dist/app/assets/{useAuth-3WWZ3GCD.js.map → useAuth-D_UWt-CP.js.map} +1 -1
  120. package/dist/app/index.html +2 -2
  121. package/dist/assets/AgentCli-CJHTv5S4.js +17 -0
  122. package/dist/assets/AgentCli-CJHTv5S4.js.map +1 -0
  123. package/dist/assets/App-BwQ1zI7a.css +1 -0
  124. package/dist/assets/App-DV5XHwn8.js +13 -0
  125. package/dist/assets/App-DV5XHwn8.js.map +1 -0
  126. package/dist/assets/AppReviewAso-Dvh6A_g-.js +4 -0
  127. package/dist/assets/AppReviewAso-Dvh6A_g-.js.map +1 -0
  128. package/dist/assets/{Cancelled-66ixTUrm.js → Cancelled-D6i4ywc8.js} +2 -2
  129. package/dist/assets/{Cancelled-66ixTUrm.js.map → Cancelled-D6i4ywc8.js.map} +1 -1
  130. package/dist/assets/CopyButton-BlPQEoP3.js +2 -0
  131. package/dist/assets/CopyButton-BlPQEoP3.js.map +1 -0
  132. package/dist/assets/FastlaneScreenshots-DF74cNwo.js +52 -0
  133. package/dist/assets/FastlaneScreenshots-DF74cNwo.js.map +1 -0
  134. package/dist/assets/FirstExport-BMHdPGDX.js +6 -0
  135. package/dist/assets/FirstExport-BMHdPGDX.js.map +1 -0
  136. package/dist/assets/FitPanel-Fp4iPZxf.js +2 -0
  137. package/dist/assets/FitPanel-Fp4iPZxf.js.map +1 -0
  138. package/dist/assets/FivePanelFramework-B967Cblg.js +62 -0
  139. package/dist/assets/FivePanelFramework-B967Cblg.js.map +1 -0
  140. package/dist/{app/assets/ForgotPassword-B9_si1tH.js → assets/ForgotPassword-CApAdwy1.js} +2 -2
  141. package/dist/assets/{ForgotPassword-B9_si1tH.js.map → ForgotPassword-CApAdwy1.js.map} +1 -1
  142. package/dist/assets/Landing-Vxx4PfE4.js +2 -0
  143. package/dist/assets/Landing-Vxx4PfE4.js.map +1 -0
  144. package/dist/assets/{LanguageSwitcher-BD9N-dla.js → LanguageSwitcher-Cp-6zMXz.js} +2 -2
  145. package/dist/{app/assets/LanguageSwitcher-BD9N-dla.js.map → assets/LanguageSwitcher-Cp-6zMXz.js.map} +1 -1
  146. package/dist/assets/{Legal-D3cAXQXw.js → Legal-CGgUYM9f.js} +2 -2
  147. package/dist/assets/{Legal-D3cAXQXw.js.map → Legal-CGgUYM9f.js.map} +1 -1
  148. package/dist/assets/{NotFound-ClV-6RmP.js → NotFound-DCeMrR7Q.js} +2 -2
  149. package/dist/assets/{NotFound-ClV-6RmP.js.map → NotFound-DCeMrR7Q.js.map} +1 -1
  150. package/dist/assets/Pricing-CGZnCST5.js +2 -0
  151. package/dist/assets/Pricing-CGZnCST5.js.map +1 -0
  152. package/dist/assets/{Privacy-DfxgWwC3.js → Privacy-D86um9Ox.js} +2 -2
  153. package/dist/{app/assets/Privacy-DfxgWwC3.js.map → assets/Privacy-D86um9Ox.js.map} +1 -1
  154. package/dist/assets/{SignIn-ghQCKcPe.js → SignIn-J1V55TpG.js} +2 -2
  155. package/dist/assets/{SignIn-ghQCKcPe.js.map → SignIn-J1V55TpG.js.map} +1 -1
  156. package/dist/assets/{SignUp-BKB87hd4.js → SignUp-D6y9FaIp.js} +2 -2
  157. package/dist/{app/assets/SignUp-BKB87hd4.js.map → assets/SignUp-D6y9FaIp.js.map} +1 -1
  158. package/dist/assets/SiteHeader-Ch5fAKkA.js +2 -0
  159. package/dist/assets/SiteHeader-Ch5fAKkA.js.map +1 -0
  160. package/dist/assets/StickyMobileCta-BdjmxjZ4.js +2 -0
  161. package/dist/assets/StickyMobileCta-BdjmxjZ4.js.map +1 -0
  162. package/dist/assets/StoreAssetsPipeline-Cl-3GPfw.js +6 -0
  163. package/dist/assets/StoreAssetsPipeline-Cl-3GPfw.js.map +1 -0
  164. package/dist/assets/{Success-819qvzmp.js → Success-BtaUzpPJ.js} +2 -2
  165. package/dist/assets/{Success-819qvzmp.js.map → Success-BtaUzpPJ.js.map} +1 -1
  166. package/dist/assets/{Terms-7k3nA4SU.js → Terms-D_qNDuwq.js} +2 -2
  167. package/dist/assets/{Terms-7k3nA4SU.js.map → Terms-D_qNDuwq.js.map} +1 -1
  168. package/dist/assets/ToolGuardrailsPanel-Dqo_LDWu.js +2 -0
  169. package/dist/assets/ToolGuardrailsPanel-Dqo_LDWu.js.map +1 -0
  170. package/dist/assets/ToolsIndex-D7Z_LkLt.js +6 -0
  171. package/dist/assets/ToolsIndex-D7Z_LkLt.js.map +1 -0
  172. package/dist/assets/WorkloadCalculator-6PgA8Qfc.js +5 -0
  173. package/dist/assets/WorkloadCalculator-6PgA8Qfc.js.map +1 -0
  174. package/dist/assets/{calculator-CiqKFdRp.js → calculator-BJHViS7f.js} +2 -2
  175. package/dist/assets/{calculator-CiqKFdRp.js.map → calculator-BJHViS7f.js.map} +1 -1
  176. package/dist/assets/check-IxdpNvaC.js +2 -0
  177. package/dist/assets/check-IxdpNvaC.js.map +1 -0
  178. package/dist/assets/chevron-down-DFKVs9n4.js +2 -0
  179. package/dist/assets/{chevron-down-_xIkRLaA.js.map → chevron-down-DFKVs9n4.js.map} +1 -1
  180. package/dist/assets/circle-check-DA-NWInD.js +2 -0
  181. package/dist/assets/circle-check-DA-NWInD.js.map +1 -0
  182. package/dist/assets/{clipboard-copy-DCJioqIc.js → clipboard-copy-B2p9wr40.js} +2 -2
  183. package/dist/assets/{clipboard-copy-DCJioqIc.js.map → clipboard-copy-B2p9wr40.js.map} +1 -1
  184. package/dist/assets/{copy-AQdWJCcs.js → copy-BnUx1vxq.js} +2 -2
  185. package/dist/assets/{copy-AQdWJCcs.js.map → copy-BnUx1vxq.js.map} +1 -1
  186. package/dist/assets/{crop-DOMVp18h.js → crop-BLAB1KK_.js} +2 -2
  187. package/dist/assets/{crop-DOMVp18h.js.map → crop-BLAB1KK_.js.map} +1 -1
  188. package/dist/assets/{download-D5RbyXDm.js → download-DNjju5h9.js} +2 -2
  189. package/dist/assets/{download-D5RbyXDm.js.map → download-DNjju5h9.js.map} +1 -1
  190. package/dist/assets/{eye-CLcZi_uk.js → eye-DkJdJAvt.js} +2 -2
  191. package/dist/assets/{eye-CLcZi_uk.js.map → eye-DkJdJAvt.js.map} +1 -1
  192. package/dist/assets/folder-tree-zQOd55nP.js +2 -0
  193. package/dist/assets/folder-tree-zQOd55nP.js.map +1 -0
  194. package/dist/assets/{grid-3x3-AKmIrhzv.js → grid-3x3-BCPiZxWL.js} +2 -2
  195. package/dist/{app/assets/grid-3x3-AKmIrhzv.js.map → assets/grid-3x3-BCPiZxWL.js.map} +1 -1
  196. package/dist/assets/hero/cli-build-tree-15s.mp4 +0 -0
  197. package/dist/assets/hero/cli-build-tree-15s.webm +0 -0
  198. package/dist/assets/hero/cli-build-tree-25s.mp4 +0 -0
  199. package/dist/assets/hero/cli-build-tree-25s.webm +0 -0
  200. package/dist/assets/hero/cli-build-tree-poster.png +0 -0
  201. package/dist/assets/hero/demo-25s-poster.jpg +0 -0
  202. package/dist/assets/hero/demo-25s.mp4 +0 -0
  203. package/dist/assets/hero/demo-25s.webm +0 -0
  204. package/dist/assets/hero/demo-poster.jpg +0 -0
  205. package/dist/assets/hero/demo.mp4 +0 -0
  206. package/dist/assets/hero/demo.webm +0 -0
  207. package/dist/assets/{index-Bqv2NztY.js → index-C4xM6WAU.js} +18 -18
  208. package/dist/assets/index-C4xM6WAU.js.map +1 -0
  209. package/dist/assets/index-CQecHUcy.css +1 -0
  210. package/dist/assets/{layout-grid-CpGXUPMR.js → layout-grid-DvMRLTBT.js} +2 -2
  211. package/dist/assets/{layout-grid-CpGXUPMR.js.map → layout-grid-DvMRLTBT.js.map} +1 -1
  212. package/dist/assets/noto-sans-arabic-arabic-400-normal-AAMxebZb.woff2 +0 -0
  213. package/dist/assets/noto-sans-arabic-arabic-400-normal-hsqIUL9Q.woff +0 -0
  214. package/dist/assets/noto-sans-arabic-arabic-500-normal-CoaTbVwZ.woff +0 -0
  215. package/dist/assets/noto-sans-arabic-arabic-500-normal-DPISWLls.woff2 +0 -0
  216. package/dist/assets/noto-sans-arabic-arabic-700-normal-3CqrwsiZ.woff2 +0 -0
  217. package/dist/assets/noto-sans-arabic-arabic-700-normal-DXnsSW3z.woff +0 -0
  218. package/dist/assets/noto-sans-thai-thai-400-normal-BEOmKAI1.woff2 +0 -0
  219. package/dist/assets/noto-sans-thai-thai-400-normal-Dxb_unuU.woff +0 -0
  220. package/dist/assets/noto-sans-thai-thai-500-normal-BOGXO2tw.woff +0 -0
  221. package/dist/assets/noto-sans-thai-thai-500-normal-CU_X86GQ.woff2 +0 -0
  222. package/dist/assets/noto-sans-thai-thai-700-normal-C9ISMlQq.woff +0 -0
  223. package/dist/assets/noto-sans-thai-thai-700-normal-Cm52XUnT.woff2 +0 -0
  224. package/dist/assets/{rocket-IzRFv1aW.js → rocket-fjJ-qzsl.js} +2 -2
  225. package/dist/assets/{rocket-IzRFv1aW.js.map → rocket-fjJ-qzsl.js.map} +1 -1
  226. package/dist/assets/{shield-check-CngdN3zn.js → shield-check-C-qC9fhU.js} +2 -2
  227. package/dist/assets/{shield-check-CngdN3zn.js.map → shield-check-C-qC9fhU.js.map} +1 -1
  228. package/dist/assets/{signIn-Cn6FaQYi.js → signIn-CYNXaR1Y.js} +2 -2
  229. package/dist/{app/assets/signIn-Cn6FaQYi.js.map → assets/signIn-CYNXaR1Y.js.map} +1 -1
  230. package/dist/assets/{smartphone-CpNG_Pfk.js → smartphone-DRYkbHrn.js} +2 -2
  231. package/dist/assets/{smartphone-CpNG_Pfk.js.map → smartphone-DRYkbHrn.js.map} +1 -1
  232. package/dist/assets/{terminal-BbBESfoU.js → terminal-CY2dKmaU.js} +2 -2
  233. package/dist/{app/assets/terminal-BbBESfoU.js.map → assets/terminal-CY2dKmaU.js.map} +1 -1
  234. package/dist/{app/assets/useAuth-3WWZ3GCD.js → assets/useAuth-D_UWt-CP.js} +2 -2
  235. package/dist/assets/{useAuth-3WWZ3GCD.js.map → useAuth-D_UWt-CP.js.map} +1 -1
  236. package/dist/cancelled/index.html +2 -2
  237. package/dist/forgot-password/index.html +2 -2
  238. package/dist/index.html +2 -2
  239. package/dist/legal/index.html +2 -2
  240. package/dist/llms-full.txt +106 -0
  241. package/dist/llms.txt +35 -0
  242. package/dist/pricing/index.html +33 -0
  243. package/dist/privacy/index.html +2 -2
  244. package/dist/robots.txt +2 -0
  245. package/dist/signin/index.html +2 -2
  246. package/dist/signup/index.html +2 -2
  247. package/dist/sitemap.xml +12 -0
  248. package/dist/success/index.html +2 -2
  249. package/dist/terms/index.html +2 -2
  250. package/dist/tools/5-panel-screenshot-framework/index.html +2 -2
  251. package/dist/tools/agent-cli/index.html +2 -2
  252. package/dist/tools/app-review-aso/index.html +2 -2
  253. package/dist/tools/fastlane-screenshots/index.html +2 -2
  254. package/dist/tools/first-export/index.html +2 -2
  255. package/dist/tools/index.html +2 -2
  256. package/dist/tools/screenshot-workload-calculator/index.html +2 -2
  257. package/dist/tools/store-assets-pipeline/index.html +2 -2
  258. package/package.json +22 -2
  259. package/dist/app/assets/AgentCli-FWNCO1pb.js +0 -17
  260. package/dist/app/assets/AgentCli-FWNCO1pb.js.map +0 -1
  261. package/dist/app/assets/App-yU7CFXCv.js +0 -13
  262. package/dist/app/assets/App-yU7CFXCv.js.map +0 -1
  263. package/dist/app/assets/AppReviewAso-BYfaP1Lu.js +0 -4
  264. package/dist/app/assets/AppReviewAso-BYfaP1Lu.js.map +0 -1
  265. package/dist/app/assets/CliPreflightCard-D7utpFux.js +0 -2
  266. package/dist/app/assets/CliPreflightCard-D7utpFux.js.map +0 -1
  267. package/dist/app/assets/CopyButton-CmVmSaYn.js +0 -2
  268. package/dist/app/assets/CopyButton-CmVmSaYn.js.map +0 -1
  269. package/dist/app/assets/FastlaneScreenshots-CRMcetq-.js +0 -52
  270. package/dist/app/assets/FastlaneScreenshots-CRMcetq-.js.map +0 -1
  271. package/dist/app/assets/FirstExport-C0WgL4Hl.js +0 -6
  272. package/dist/app/assets/FirstExport-C0WgL4Hl.js.map +0 -1
  273. package/dist/app/assets/FivePanelFramework-BwCRmXIK.js +0 -60
  274. package/dist/app/assets/FivePanelFramework-BwCRmXIK.js.map +0 -1
  275. package/dist/app/assets/Landing-s1ni1n-7.js +0 -2
  276. package/dist/app/assets/Landing-s1ni1n-7.js.map +0 -1
  277. package/dist/app/assets/SiteHeader-DxsqNPnt.js +0 -2
  278. package/dist/app/assets/SiteHeader-DxsqNPnt.js.map +0 -1
  279. package/dist/app/assets/StickyMobileCta-C_x2pUIF.js +0 -2
  280. package/dist/app/assets/StickyMobileCta-C_x2pUIF.js.map +0 -1
  281. package/dist/app/assets/StoreAssetsPipeline-4hXRONUd.js +0 -4
  282. package/dist/app/assets/StoreAssetsPipeline-4hXRONUd.js.map +0 -1
  283. package/dist/app/assets/ToolsIndex-CzrxymnM.js +0 -6
  284. package/dist/app/assets/ToolsIndex-CzrxymnM.js.map +0 -1
  285. package/dist/app/assets/WorkloadCalculator-D2TuKS4B.js +0 -5
  286. package/dist/app/assets/WorkloadCalculator-D2TuKS4B.js.map +0 -1
  287. package/dist/app/assets/chevron-down-_xIkRLaA.js +0 -2
  288. package/dist/app/assets/index-Bqv2NztY.js.map +0 -1
  289. package/dist/app/assets/index-DGVMa-P7.css +0 -1
  290. package/dist/assets/AgentCli-FWNCO1pb.js +0 -17
  291. package/dist/assets/AgentCli-FWNCO1pb.js.map +0 -1
  292. package/dist/assets/App-yU7CFXCv.js +0 -13
  293. package/dist/assets/App-yU7CFXCv.js.map +0 -1
  294. package/dist/assets/AppReviewAso-BYfaP1Lu.js +0 -4
  295. package/dist/assets/AppReviewAso-BYfaP1Lu.js.map +0 -1
  296. package/dist/assets/CliPreflightCard-D7utpFux.js +0 -2
  297. package/dist/assets/CliPreflightCard-D7utpFux.js.map +0 -1
  298. package/dist/assets/CopyButton-CmVmSaYn.js +0 -2
  299. package/dist/assets/CopyButton-CmVmSaYn.js.map +0 -1
  300. package/dist/assets/FastlaneScreenshots-CRMcetq-.js +0 -52
  301. package/dist/assets/FastlaneScreenshots-CRMcetq-.js.map +0 -1
  302. package/dist/assets/FirstExport-C0WgL4Hl.js +0 -6
  303. package/dist/assets/FirstExport-C0WgL4Hl.js.map +0 -1
  304. package/dist/assets/FivePanelFramework-BwCRmXIK.js +0 -60
  305. package/dist/assets/FivePanelFramework-BwCRmXIK.js.map +0 -1
  306. package/dist/assets/Landing-s1ni1n-7.js +0 -2
  307. package/dist/assets/Landing-s1ni1n-7.js.map +0 -1
  308. package/dist/assets/SiteHeader-DxsqNPnt.js +0 -2
  309. package/dist/assets/SiteHeader-DxsqNPnt.js.map +0 -1
  310. package/dist/assets/StickyMobileCta-C_x2pUIF.js +0 -2
  311. package/dist/assets/StickyMobileCta-C_x2pUIF.js.map +0 -1
  312. package/dist/assets/StoreAssetsPipeline-4hXRONUd.js +0 -4
  313. package/dist/assets/StoreAssetsPipeline-4hXRONUd.js.map +0 -1
  314. package/dist/assets/ToolsIndex-CzrxymnM.js +0 -6
  315. package/dist/assets/ToolsIndex-CzrxymnM.js.map +0 -1
  316. package/dist/assets/WorkloadCalculator-D2TuKS4B.js +0 -5
  317. package/dist/assets/WorkloadCalculator-D2TuKS4B.js.map +0 -1
  318. package/dist/assets/chevron-down-_xIkRLaA.js +0 -2
  319. package/dist/assets/index-Bqv2NztY.js.map +0 -1
  320. package/dist/assets/index-DGVMa-P7.css +0 -1
@@ -0,0 +1,573 @@
1
+ import { spawn } from 'node:child_process';
2
+ import fs from 'node:fs/promises';
3
+ import path from 'node:path';
4
+ import { getPackageRoot } from './packageRoot.js';
5
+
6
+ const SUPPORTED_PROTOCOL_VERSIONS = ['2025-06-18', '2025-03-26', '2024-11-05'];
7
+ const DEFAULT_PROTOCOL_VERSION = '2024-11-05';
8
+
9
+ const TOOL_DEFINITIONS = [
10
+ {
11
+ name: 'shipscreens_devices',
12
+ title: 'List supported devices',
13
+ description: 'Returns canonical device IDs and metadata for shipscreens.config.yml.',
14
+ inputSchema: {
15
+ type: 'object',
16
+ additionalProperties: false,
17
+ properties: {
18
+ workingDirectory: { type: 'string' },
19
+ timeoutMs: { type: 'integer', minimum: 1000, maximum: 1800000 },
20
+ },
21
+ },
22
+ buildArgs: () => ['devices'],
23
+ },
24
+ {
25
+ name: 'shipscreens_templates',
26
+ title: 'List shipped templates',
27
+ description: 'Returns available template IDs for init/wizard/agent-run.',
28
+ inputSchema: {
29
+ type: 'object',
30
+ additionalProperties: false,
31
+ properties: {
32
+ workingDirectory: { type: 'string' },
33
+ timeoutMs: { type: 'integer', minimum: 1000, maximum: 1800000 },
34
+ },
35
+ },
36
+ buildArgs: () => ['templates'],
37
+ },
38
+ {
39
+ name: 'shipscreens_validate',
40
+ title: 'Validate config',
41
+ description: 'Validates shipscreens.config.yml (schema + asset paths).',
42
+ inputSchema: {
43
+ type: 'object',
44
+ additionalProperties: false,
45
+ properties: {
46
+ workingDirectory: { type: 'string' },
47
+ configPath: { type: 'string' },
48
+ timeoutMs: { type: 'integer', minimum: 1000, maximum: 1800000 },
49
+ },
50
+ },
51
+ buildArgs: (args) => withConfigArg(['validate'], args),
52
+ },
53
+ {
54
+ name: 'shipscreens_build',
55
+ title: 'Build outputs',
56
+ description: 'Builds Fastlane-ready outputs (dir/zip) from shipscreens.config.yml.',
57
+ inputSchema: {
58
+ type: 'object',
59
+ additionalProperties: false,
60
+ properties: {
61
+ workingDirectory: { type: 'string' },
62
+ configPath: { type: 'string' },
63
+ outDir: { type: 'string' },
64
+ mode: { type: 'string', enum: ['shipscreens', 'rendered', 'raw', 'frameit'] },
65
+ format: { type: 'string', enum: ['dir', 'zip'] },
66
+ zip: { type: 'boolean' },
67
+ zipOut: { type: 'string' },
68
+ clean: { type: 'boolean' },
69
+ requirePro: { type: 'boolean' },
70
+ timeoutMs: { type: 'integer', minimum: 1000, maximum: 1800000 },
71
+ },
72
+ },
73
+ buildArgs: (args) => {
74
+ const commandArgs = withConfigArg(['build'], args);
75
+ pushOption(commandArgs, '--out', args.outDir);
76
+ pushOption(commandArgs, '--mode', args.mode);
77
+ pushOption(commandArgs, '--format', args.format);
78
+ pushOption(commandArgs, '--zip-out', args.zipOut);
79
+ pushFlag(commandArgs, '--zip', args.zip);
80
+ pushFlag(commandArgs, '--clean', args.clean);
81
+ pushFlag(commandArgs, '--require-pro', args.requirePro);
82
+ return commandArgs;
83
+ },
84
+ },
85
+ {
86
+ name: 'shipscreens_verify',
87
+ title: 'Verify outputs',
88
+ description: 'Verifies generated outputs for appstore/playstore/any profile rules.',
89
+ inputSchema: {
90
+ type: 'object',
91
+ additionalProperties: false,
92
+ properties: {
93
+ workingDirectory: { type: 'string' },
94
+ configPath: { type: 'string' },
95
+ outDir: { type: 'string' },
96
+ zip: { type: 'boolean' },
97
+ zipOut: { type: 'string' },
98
+ profile: { type: 'string', enum: ['appstore', 'playstore', 'any'] },
99
+ timeoutMs: { type: 'integer', minimum: 1000, maximum: 1800000 },
100
+ },
101
+ },
102
+ buildArgs: (args) => {
103
+ const commandArgs = withConfigArg(['verify'], args);
104
+ pushOption(commandArgs, '--out', args.outDir);
105
+ pushOption(commandArgs, '--zip-out', args.zipOut);
106
+ pushOption(commandArgs, '--profile', args.profile);
107
+ pushFlag(commandArgs, '--zip', args.zip);
108
+ return commandArgs;
109
+ },
110
+ },
111
+ {
112
+ name: 'shipscreens_stage',
113
+ title: 'Stage upload root',
114
+ description: 'Copies upload-ready files into a clean staging directory.',
115
+ inputSchema: {
116
+ type: 'object',
117
+ additionalProperties: false,
118
+ required: ['outDir'],
119
+ properties: {
120
+ workingDirectory: { type: 'string' },
121
+ configPath: { type: 'string' },
122
+ fromDir: { type: 'string' },
123
+ outDir: { type: 'string' },
124
+ profile: { type: 'string', enum: ['appstore', 'playstore', 'any'] },
125
+ timeoutMs: { type: 'integer', minimum: 1000, maximum: 1800000 },
126
+ },
127
+ },
128
+ buildArgs: (args) => {
129
+ const commandArgs = withConfigArg(['stage'], args);
130
+ pushOption(commandArgs, '--from', args.fromDir);
131
+ pushOption(commandArgs, '--out', args.outDir);
132
+ pushOption(commandArgs, '--profile', args.profile);
133
+ return commandArgs;
134
+ },
135
+ },
136
+ {
137
+ name: 'shipscreens_plan',
138
+ title: 'Get deterministic plan',
139
+ description: 'Returns deterministic build/stage plan JSON for the current config.',
140
+ inputSchema: {
141
+ type: 'object',
142
+ additionalProperties: false,
143
+ properties: {
144
+ workingDirectory: { type: 'string' },
145
+ configPath: { type: 'string' },
146
+ outDir: { type: 'string' },
147
+ zipOut: { type: 'string' },
148
+ profile: { type: 'string', enum: ['appstore', 'playstore', 'any'] },
149
+ timeoutMs: { type: 'integer', minimum: 1000, maximum: 1800000 },
150
+ },
151
+ },
152
+ buildArgs: (args) => {
153
+ const commandArgs = withConfigArg(['plan'], args);
154
+ pushOption(commandArgs, '--out', args.outDir);
155
+ pushOption(commandArgs, '--zip-out', args.zipOut);
156
+ pushOption(commandArgs, '--profile', args.profile);
157
+ return commandArgs;
158
+ },
159
+ },
160
+ {
161
+ name: 'shipscreens_agent_run',
162
+ title: 'Run non-interactive pipeline',
163
+ description: 'Runs init (if needed) -> validate -> build -> verify in one command.',
164
+ inputSchema: {
165
+ type: 'object',
166
+ additionalProperties: false,
167
+ properties: {
168
+ workingDirectory: { type: 'string' },
169
+ dir: { type: 'string' },
170
+ slides: { type: 'integer', minimum: 1, maximum: 10 },
171
+ locales: { type: 'string' },
172
+ devices: { type: 'string' },
173
+ template: { type: 'string' },
174
+ mode: { type: 'string', enum: ['raw', 'rendered'] },
175
+ outDir: { type: 'string' },
176
+ zip: { type: 'boolean' },
177
+ profile: { type: 'string', enum: ['appstore', 'playstore', 'any'] },
178
+ requirePro: { type: 'boolean' },
179
+ force: { type: 'boolean' },
180
+ timeoutMs: { type: 'integer', minimum: 1000, maximum: 1800000 },
181
+ },
182
+ },
183
+ buildArgs: (args) => {
184
+ const commandArgs = ['agent-run'];
185
+ pushOption(commandArgs, '--dir', args.dir);
186
+ pushOption(commandArgs, '--slides', args.slides);
187
+ pushOption(commandArgs, '--locales', args.locales);
188
+ pushOption(commandArgs, '--devices', args.devices);
189
+ pushOption(commandArgs, '--template', args.template);
190
+ pushOption(commandArgs, '--mode', args.mode);
191
+ pushOption(commandArgs, '--out', args.outDir);
192
+ pushOption(commandArgs, '--profile', args.profile);
193
+ pushFlag(commandArgs, '--zip', args.zip);
194
+ pushFlag(commandArgs, '--require-pro', args.requirePro);
195
+ pushFlag(commandArgs, '--force', args.force);
196
+ return commandArgs;
197
+ },
198
+ },
199
+ {
200
+ name: 'shipscreens_demo',
201
+ title: 'Run demo export',
202
+ description: 'Creates a demo project and runs validate/lock/build/verify/stage.',
203
+ inputSchema: {
204
+ type: 'object',
205
+ additionalProperties: false,
206
+ properties: {
207
+ workingDirectory: { type: 'string' },
208
+ outDir: { type: 'string' },
209
+ slides: { type: 'integer', minimum: 1, maximum: 10 },
210
+ locales: { type: 'string' },
211
+ devices: { type: 'string' },
212
+ template: { type: 'string' },
213
+ mode: { type: 'string', enum: ['raw', 'rendered'] },
214
+ profile: { type: 'string', enum: ['appstore', 'playstore', 'any'] },
215
+ force: { type: 'boolean' },
216
+ timeoutMs: { type: 'integer', minimum: 1000, maximum: 1800000 },
217
+ },
218
+ },
219
+ buildArgs: (args) => {
220
+ const commandArgs = ['demo'];
221
+ pushOption(commandArgs, '--out', args.outDir);
222
+ pushOption(commandArgs, '--slides', args.slides);
223
+ pushOption(commandArgs, '--locales', args.locales);
224
+ pushOption(commandArgs, '--devices', args.devices);
225
+ pushOption(commandArgs, '--template', args.template);
226
+ pushOption(commandArgs, '--mode', args.mode);
227
+ pushOption(commandArgs, '--profile', args.profile);
228
+ pushFlag(commandArgs, '--force', args.force);
229
+ return commandArgs;
230
+ },
231
+ },
232
+ ];
233
+
234
+ const TOOL_MAP = new Map(TOOL_DEFINITIONS.map((tool) => [tool.name, tool]));
235
+
236
+ const SERVER_INFO = {
237
+ name: 'shipscreens-mcp',
238
+ title: 'ShipScreens MCP Server',
239
+ version: '0.1.0',
240
+ };
241
+
242
+ function withConfigArg(baseArgs, args) {
243
+ const commandArgs = [...baseArgs];
244
+ pushOption(commandArgs, '--config', args.configPath);
245
+ return commandArgs;
246
+ }
247
+
248
+ function pushOption(target, flag, value) {
249
+ if (value === undefined || value === null || value === '') return;
250
+ target.push(flag, String(value));
251
+ }
252
+
253
+ function pushFlag(target, flag, enabled) {
254
+ if (enabled) target.push(flag);
255
+ }
256
+
257
+ function toJsonRpcError({ code, message, data }) {
258
+ const err = { code, message };
259
+ if (data !== undefined) err.data = data;
260
+ return err;
261
+ }
262
+
263
+ function createToolResultText({ toolName, commandArgs, payload, stderr }) {
264
+ const command = ['shipscreens', ...commandArgs].join(' ');
265
+ const summary = [`tool=${toolName}`, `command=${command}`];
266
+ if (stderr) summary.push(`stderr=${stderr.trim()}`);
267
+ const json = JSON.stringify(payload, null, 2);
268
+ return `${summary.join('\n')}\n\n${json}`;
269
+ }
270
+
271
+ function parseClientMessage(raw) {
272
+ if (!raw || typeof raw !== 'object') {
273
+ throw new Error('Expected JSON-RPC object.');
274
+ }
275
+ return raw;
276
+ }
277
+
278
+ function createStdioMessageParser(onMessage, onError) {
279
+ let buffer = Buffer.alloc(0);
280
+ return (chunk) => {
281
+ buffer = Buffer.concat([buffer, chunk]);
282
+ while (true) {
283
+ const headerEnd = buffer.indexOf('\r\n\r\n');
284
+ if (headerEnd < 0) return;
285
+
286
+ const headerBlock = buffer.subarray(0, headerEnd).toString('utf8');
287
+ const headers = headerBlock.split('\r\n');
288
+ let contentLength = -1;
289
+ for (const line of headers) {
290
+ const idx = line.indexOf(':');
291
+ if (idx < 0) continue;
292
+ const key = line.slice(0, idx).trim().toLowerCase();
293
+ const value = line.slice(idx + 1).trim();
294
+ if (key === 'content-length') {
295
+ contentLength = Number(value);
296
+ break;
297
+ }
298
+ }
299
+ if (!Number.isFinite(contentLength) || contentLength < 0) {
300
+ onError(new Error('Invalid MCP framing: missing Content-Length header.'));
301
+ buffer = Buffer.alloc(0);
302
+ return;
303
+ }
304
+
305
+ const messageStart = headerEnd + 4;
306
+ const messageEnd = messageStart + contentLength;
307
+ if (buffer.length < messageEnd) return;
308
+
309
+ const body = buffer.subarray(messageStart, messageEnd).toString('utf8');
310
+ buffer = buffer.subarray(messageEnd);
311
+ try {
312
+ const parsed = JSON.parse(body);
313
+ onMessage(parseClientMessage(parsed));
314
+ } catch (err) {
315
+ onError(new Error(`Invalid MCP JSON payload: ${err?.message || String(err)}`));
316
+ return;
317
+ }
318
+ }
319
+ };
320
+ }
321
+
322
+ function createStdioWriter(stream) {
323
+ return (message) => {
324
+ const json = JSON.stringify(message);
325
+ const body = Buffer.from(json, 'utf8');
326
+ stream.write(`Content-Length: ${body.length}\r\n\r\n`);
327
+ stream.write(body);
328
+ };
329
+ }
330
+
331
+ async function runShipScreensCommand({
332
+ packageRoot,
333
+ commandArgs,
334
+ workingDirectory,
335
+ timeoutMs = 10 * 60 * 1000,
336
+ }) {
337
+ const cliPath = path.join(packageRoot, 'bin', 'shipscreens.js');
338
+ const resolvedCwd = workingDirectory
339
+ ? path.resolve(process.cwd(), workingDirectory)
340
+ : process.cwd();
341
+ await fs.stat(resolvedCwd);
342
+
343
+ return new Promise((resolve) => {
344
+ const child = spawn(process.execPath, [cliPath, ...commandArgs, '--json'], {
345
+ cwd: resolvedCwd,
346
+ stdio: ['ignore', 'pipe', 'pipe'],
347
+ });
348
+
349
+ let stdout = '';
350
+ let stderr = '';
351
+ let settled = false;
352
+ const timer = setTimeout(() => {
353
+ if (settled) return;
354
+ settled = true;
355
+ child.kill('SIGTERM');
356
+ resolve({
357
+ ok: false,
358
+ code: -1,
359
+ stdout,
360
+ stderr: `${stderr}\nMCP tool timeout after ${timeoutMs}ms`.trim(),
361
+ });
362
+ }, timeoutMs);
363
+
364
+ child.stdout.on('data', (buf) => {
365
+ stdout += buf.toString('utf8');
366
+ });
367
+ child.stderr.on('data', (buf) => {
368
+ stderr += buf.toString('utf8');
369
+ });
370
+ child.on('close', (code) => {
371
+ if (settled) return;
372
+ settled = true;
373
+ clearTimeout(timer);
374
+ resolve({
375
+ ok: code === 0,
376
+ code,
377
+ stdout,
378
+ stderr,
379
+ });
380
+ });
381
+ });
382
+ }
383
+
384
+ function parseToolPayload(stdout) {
385
+ const text = String(stdout || '').trim();
386
+ if (!text) return null;
387
+ return JSON.parse(text);
388
+ }
389
+
390
+ function sanitizeTimeout(value) {
391
+ if (value === undefined || value === null) return 10 * 60 * 1000;
392
+ const n = Number(value);
393
+ if (!Number.isInteger(n) || n < 1000 || n > 1800000) {
394
+ throw new Error('timeoutMs must be an integer between 1000 and 1800000.');
395
+ }
396
+ return n;
397
+ }
398
+
399
+ function ensureObject(value, label) {
400
+ if (value === undefined || value === null) return {};
401
+ if (typeof value !== 'object' || Array.isArray(value)) {
402
+ throw new Error(`${label} must be an object.`);
403
+ }
404
+ return value;
405
+ }
406
+
407
+ function pickProtocolVersion(requested) {
408
+ if (typeof requested === 'string' && SUPPORTED_PROTOCOL_VERSIONS.includes(requested)) {
409
+ return requested;
410
+ }
411
+ return DEFAULT_PROTOCOL_VERSION;
412
+ }
413
+
414
+ function buildToolListResponse() {
415
+ return {
416
+ tools: TOOL_DEFINITIONS.map((tool) => ({
417
+ name: tool.name,
418
+ title: tool.title,
419
+ description: tool.description,
420
+ inputSchema: tool.inputSchema,
421
+ })),
422
+ };
423
+ }
424
+
425
+ export async function runMcpServer() {
426
+ const packageRoot = getPackageRoot();
427
+ const write = createStdioWriter(process.stdout);
428
+ let isInitialized = false;
429
+
430
+ const handleRequest = async (request) => {
431
+ const { id, method, params } = request;
432
+
433
+ const sendResult = (result) => write({ jsonrpc: '2.0', id, result });
434
+ const sendError = (error) => write({ jsonrpc: '2.0', id, error });
435
+
436
+ try {
437
+ if (method === 'initialize') {
438
+ const requestedVersion = params?.protocolVersion;
439
+ isInitialized = true;
440
+ sendResult({
441
+ protocolVersion: pickProtocolVersion(requestedVersion),
442
+ capabilities: {
443
+ tools: {
444
+ listChanged: false,
445
+ },
446
+ },
447
+ serverInfo: SERVER_INFO,
448
+ instructions:
449
+ 'Use tools to run deterministic ShipScreens CLI workflows (validate/build/verify/stage/plan) in local or CI contexts.',
450
+ });
451
+ return;
452
+ }
453
+
454
+ if (method === 'ping') {
455
+ sendResult({});
456
+ return;
457
+ }
458
+
459
+ if (!isInitialized) {
460
+ sendError(toJsonRpcError({ code: -32002, message: 'Server not initialized.' }));
461
+ return;
462
+ }
463
+
464
+ if (method === 'tools/list') {
465
+ sendResult(buildToolListResponse());
466
+ return;
467
+ }
468
+
469
+ if (method === 'tools/call') {
470
+ const callParams = ensureObject(params, 'tools/call params');
471
+ const toolName = String(callParams.name || '').trim();
472
+ const toolArgs = ensureObject(callParams.arguments, 'tools/call arguments');
473
+ if (!toolName) {
474
+ sendError(toJsonRpcError({ code: -32602, message: 'tools/call requires name.' }));
475
+ return;
476
+ }
477
+ const tool = TOOL_MAP.get(toolName);
478
+ if (!tool) {
479
+ sendError(toJsonRpcError({ code: -32602, message: `Unknown tool: ${toolName}` }));
480
+ return;
481
+ }
482
+
483
+ const timeoutMs = sanitizeTimeout(toolArgs.timeoutMs);
484
+ const commandArgs = tool.buildArgs(toolArgs);
485
+ const result = await runShipScreensCommand({
486
+ packageRoot,
487
+ commandArgs,
488
+ workingDirectory: toolArgs.workingDirectory,
489
+ timeoutMs,
490
+ });
491
+
492
+ if (!result.ok) {
493
+ sendResult({
494
+ content: [
495
+ {
496
+ type: 'text',
497
+ text:
498
+ `ShipScreens command failed: shipscreens ${commandArgs.join(' ')}\n` +
499
+ `exitCode=${result.code}\n` +
500
+ `${result.stderr || '(no stderr output)'}`,
501
+ },
502
+ ],
503
+ isError: true,
504
+ });
505
+ return;
506
+ }
507
+
508
+ let payload = null;
509
+ try {
510
+ payload = parseToolPayload(result.stdout);
511
+ } catch (err) {
512
+ sendResult({
513
+ content: [
514
+ {
515
+ type: 'text',
516
+ text:
517
+ `ShipScreens command output was not valid JSON.\n` +
518
+ `error=${err?.message || String(err)}\n` +
519
+ `${result.stdout || '(empty stdout)'}`,
520
+ },
521
+ ],
522
+ isError: true,
523
+ });
524
+ return;
525
+ }
526
+
527
+ sendResult({
528
+ content: [
529
+ {
530
+ type: 'text',
531
+ text: createToolResultText({
532
+ toolName,
533
+ commandArgs,
534
+ payload,
535
+ stderr: result.stderr,
536
+ }),
537
+ },
538
+ ],
539
+ isError: false,
540
+ });
541
+ return;
542
+ }
543
+
544
+ sendError(toJsonRpcError({ code: -32601, message: `Method not found: ${method}` }));
545
+ } catch (err) {
546
+ sendError(
547
+ toJsonRpcError({
548
+ code: -32603,
549
+ message: err?.message || String(err),
550
+ })
551
+ );
552
+ }
553
+ };
554
+
555
+ const onMessage = (message) => {
556
+ if (Object.prototype.hasOwnProperty.call(message, 'id')) {
557
+ void handleRequest(message);
558
+ return;
559
+ }
560
+ // notifications/initialized and other notifications are no-op for this server.
561
+ };
562
+
563
+ const onError = (err) => {
564
+ process.stderr.write(`mcp-server: ${err?.message || String(err)}\n`);
565
+ };
566
+
567
+ const parseChunk = createStdioMessageParser(onMessage, onError);
568
+ process.stdin.on('data', parseChunk);
569
+ process.stdin.on('error', onError);
570
+ process.stdin.on('end', () => {
571
+ process.exit(0);
572
+ });
573
+ }