@sanity/cli 6.0.0-alpha.9 → 6.1.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 (613) hide show
  1. package/README.md +602 -291
  2. package/bin/run.js +2 -0
  3. package/dist/SanityHelp.js +51 -23
  4. package/dist/SanityHelp.js.map +1 -1
  5. package/dist/actions/auth/authServer.js +28 -22
  6. package/dist/actions/auth/authServer.js.map +1 -1
  7. package/dist/actions/auth/login/getProvider.js +49 -38
  8. package/dist/actions/auth/login/getProvider.js.map +1 -1
  9. package/dist/actions/auth/login/getSSOProvider.js +25 -19
  10. package/dist/actions/auth/login/getSSOProvider.js.map +1 -1
  11. package/dist/actions/auth/login/login.js +12 -33
  12. package/dist/actions/auth/login/login.js.map +1 -1
  13. package/dist/actions/auth/types.js.map +1 -1
  14. package/dist/actions/backup/downloadAsset.js +9 -9
  15. package/dist/actions/backup/downloadAsset.js.map +1 -1
  16. package/dist/actions/backup/downloadDocument.js +8 -8
  17. package/dist/actions/backup/downloadDocument.js.map +1 -1
  18. package/dist/actions/build/buildApp.js +55 -18
  19. package/dist/actions/build/buildApp.js.map +1 -1
  20. package/dist/actions/build/buildStaticFiles.js +3 -2
  21. package/dist/actions/build/buildStaticFiles.js.map +1 -1
  22. package/dist/actions/build/buildStudio.js +72 -44
  23. package/dist/actions/build/buildStudio.js.map +1 -1
  24. package/dist/actions/build/buildVendorDependencies.js +18 -52
  25. package/dist/actions/build/buildVendorDependencies.js.map +1 -1
  26. package/dist/actions/build/checkRequiredDependencies.js +13 -8
  27. package/dist/actions/build/checkRequiredDependencies.js.map +1 -1
  28. package/dist/actions/build/checkStudioDependencyVersions.js +19 -17
  29. package/dist/actions/build/checkStudioDependencyVersions.js.map +1 -1
  30. package/dist/actions/build/createExternalFromImportMap.js +1 -1
  31. package/dist/actions/build/createExternalFromImportMap.js.map +1 -1
  32. package/dist/actions/build/determineBasePath.js +5 -2
  33. package/dist/actions/build/determineBasePath.js.map +1 -1
  34. package/dist/actions/build/getViteConfig.js +47 -4
  35. package/dist/actions/build/getViteConfig.js.map +1 -1
  36. package/dist/actions/build/handlePrereleaseVersions.js +44 -0
  37. package/dist/actions/build/handlePrereleaseVersions.js.map +1 -0
  38. package/dist/actions/build/renderDocument.js +6 -10
  39. package/dist/actions/build/renderDocument.js.map +1 -1
  40. package/dist/actions/build/renderDocumentWorker/components/BasicDocument.js +4 -4
  41. package/dist/actions/build/renderDocumentWorker/components/BasicDocument.js.map +1 -1
  42. package/dist/actions/build/renderDocumentWorker/components/DefaultDocument.js +3 -3
  43. package/dist/actions/build/renderDocumentWorker/components/DefaultDocument.js.map +1 -1
  44. package/dist/actions/build/renderDocumentWorker/components/GlobalErrorHandler.js +1 -0
  45. package/dist/actions/build/renderDocumentWorker/components/GlobalErrorHandler.js.map +1 -1
  46. package/dist/actions/build/renderDocumentWorker/getDocumentComponent.js +2 -2
  47. package/dist/actions/build/renderDocumentWorker/getDocumentComponent.js.map +1 -1
  48. package/dist/actions/build/renderDocumentWorker/renderDocumentWorker.js +1 -1
  49. package/dist/actions/build/renderDocumentWorker/renderDocumentWorker.js.map +1 -1
  50. package/dist/actions/build/shouldAutoUpdate.js +2 -0
  51. package/dist/actions/build/shouldAutoUpdate.js.map +1 -1
  52. package/dist/actions/build/types.js.map +1 -1
  53. package/dist/actions/build/writeFavicons.js +3 -5
  54. package/dist/actions/build/writeFavicons.js.map +1 -1
  55. package/dist/actions/build/writeSanityRuntime.js +4 -3
  56. package/dist/actions/build/writeSanityRuntime.js.map +1 -1
  57. package/dist/actions/codemods/reactIconsV3.js +2 -2
  58. package/dist/actions/codemods/reactIconsV3.js.map +1 -1
  59. package/dist/actions/dataset/create.js +7 -1
  60. package/dist/actions/dataset/create.js.map +1 -1
  61. package/dist/actions/dataset/determineDatasetAclMode.js.map +1 -1
  62. package/dist/actions/dataset/resolveDataset.js +26 -0
  63. package/dist/actions/dataset/resolveDataset.js.map +1 -0
  64. package/dist/actions/debug/formatters.js +22 -0
  65. package/dist/actions/debug/formatters.js.map +1 -0
  66. package/dist/actions/deploy/createStudioUserApplication.js +17 -4
  67. package/dist/actions/deploy/createStudioUserApplication.js.map +1 -1
  68. package/dist/actions/deploy/deployApp.js +41 -15
  69. package/dist/actions/deploy/deployApp.js.map +1 -1
  70. package/dist/actions/deploy/deployStudio.js +92 -44
  71. package/dist/actions/deploy/deployStudio.js.map +1 -1
  72. package/dist/actions/deploy/deployStudioSchemasAndManifests.js +55 -0
  73. package/dist/actions/deploy/deployStudioSchemasAndManifests.js.map +1 -0
  74. package/dist/actions/deploy/deployStudioSchemasAndManifests.worker.js +120 -0
  75. package/dist/actions/deploy/deployStudioSchemasAndManifests.worker.js.map +1 -0
  76. package/dist/actions/deploy/findUserApplicationForStudio.js +35 -12
  77. package/dist/actions/deploy/findUserApplicationForStudio.js.map +1 -1
  78. package/dist/actions/deploy/types.js +10 -1
  79. package/dist/actions/deploy/types.js.map +1 -1
  80. package/dist/actions/deploy/urlUtils.js +21 -0
  81. package/dist/actions/deploy/urlUtils.js.map +1 -0
  82. package/dist/actions/dev/getDashboardAppUrl.js +48 -0
  83. package/dist/actions/dev/getDashboardAppUrl.js.map +1 -0
  84. package/dist/actions/dev/getDevServerConfig.js +7 -3
  85. package/dist/actions/dev/getDevServerConfig.js.map +1 -1
  86. package/dist/actions/dev/startAppDevServer.js +3 -3
  87. package/dist/actions/dev/startAppDevServer.js.map +1 -1
  88. package/dist/actions/dev/startStudioDevServer.js +14 -14
  89. package/dist/actions/dev/startStudioDevServer.js.map +1 -1
  90. package/dist/actions/doctor/checks/cliInstallation.js +56 -0
  91. package/dist/actions/doctor/checks/cliInstallation.js.map +1 -0
  92. package/dist/actions/doctor/checks/index.js +16 -0
  93. package/dist/actions/doctor/checks/index.js.map +1 -0
  94. package/dist/actions/doctor/runDoctorChecks.js +56 -0
  95. package/dist/actions/doctor/runDoctorChecks.js.map +1 -0
  96. package/dist/actions/doctor/types.js +3 -0
  97. package/dist/actions/doctor/types.js.map +1 -0
  98. package/dist/actions/documents/types.js.map +1 -1
  99. package/dist/actions/documents/validate.js +11 -2
  100. package/dist/actions/documents/validate.js.map +1 -1
  101. package/dist/actions/documents/validateDocuments.worker.js +4 -4
  102. package/dist/actions/documents/validateDocuments.worker.js.map +1 -1
  103. package/dist/actions/documents/validation/reporters/jsonReporter.js +1 -1
  104. package/dist/actions/documents/validation/reporters/jsonReporter.js.map +1 -1
  105. package/dist/actions/documents/validation/reporters/ndjsonReporter.js +1 -1
  106. package/dist/actions/documents/validation/reporters/ndjsonReporter.js.map +1 -1
  107. package/dist/actions/documents/validation/reporters/prettyReporter/formatDocumentValidation.js +1 -1
  108. package/dist/actions/documents/validation/reporters/prettyReporter/formatDocumentValidation.js.map +1 -1
  109. package/dist/actions/documents/validation/reporters/prettyReporter/tree.js +108 -0
  110. package/dist/actions/documents/validation/reporters/prettyReporter/tree.js.map +1 -0
  111. package/dist/actions/graphql/SchemaError.js +4 -26
  112. package/dist/actions/graphql/SchemaError.js.map +1 -1
  113. package/dist/actions/graphql/__tests__/fixtures/many-self-refs.js +540 -0
  114. package/dist/actions/graphql/__tests__/fixtures/many-self-refs.js.map +1 -0
  115. package/dist/actions/graphql/__tests__/fixtures/test-studio.js +1143 -0
  116. package/dist/actions/graphql/__tests__/fixtures/test-studio.js.map +1 -0
  117. package/dist/actions/graphql/__tests__/fixtures/union-refs.js +591 -0
  118. package/dist/actions/graphql/__tests__/fixtures/union-refs.js.map +1 -0
  119. package/dist/actions/graphql/__tests__/helpers.js +23 -0
  120. package/dist/actions/graphql/__tests__/helpers.js.map +1 -0
  121. package/dist/actions/graphql/extractFromSanitySchema.js +5 -5
  122. package/dist/actions/graphql/extractFromSanitySchema.js.map +1 -1
  123. package/dist/actions/graphql/extractGraphQLAPIs.js +150 -0
  124. package/dist/actions/graphql/extractGraphQLAPIs.js.map +1 -0
  125. package/dist/actions/graphql/extractGraphQLAPIs.worker.js +12 -0
  126. package/dist/actions/graphql/extractGraphQLAPIs.worker.js.map +1 -0
  127. package/dist/actions/graphql/gen1/generateTypeFilters.js +1 -1
  128. package/dist/actions/graphql/gen1/generateTypeFilters.js.map +1 -1
  129. package/dist/actions/graphql/gen1/generateTypeQueries.js +2 -1
  130. package/dist/actions/graphql/gen1/generateTypeQueries.js.map +1 -1
  131. package/dist/actions/graphql/gen1/index.js +5 -5
  132. package/dist/actions/graphql/gen1/index.js.map +1 -1
  133. package/dist/actions/graphql/gen2/generateTypeQueries.js +1 -1
  134. package/dist/actions/graphql/gen2/generateTypeQueries.js.map +1 -1
  135. package/dist/actions/graphql/gen2/index.js +6 -6
  136. package/dist/actions/graphql/gen2/index.js.map +1 -1
  137. package/dist/actions/graphql/gen3/generateTypeQueries.js +3 -4
  138. package/dist/actions/graphql/gen3/generateTypeQueries.js.map +1 -1
  139. package/dist/actions/graphql/gen3/index.js +6 -7
  140. package/dist/actions/graphql/gen3/index.js.map +1 -1
  141. package/dist/actions/graphql/getGraphQLAPIs.js +15 -57
  142. package/dist/actions/graphql/getGraphQLAPIs.js.map +1 -1
  143. package/dist/actions/graphql/getGraphQLAPIs.worker.js +75 -106
  144. package/dist/actions/graphql/getGraphQLAPIs.worker.js.map +1 -1
  145. package/dist/actions/graphql/helpers.js +13 -0
  146. package/dist/actions/graphql/helpers.js.map +1 -1
  147. package/dist/actions/graphql/resolveGraphQLApisFromWorkspaces.js +187 -0
  148. package/dist/actions/graphql/resolveGraphQLApisFromWorkspaces.js.map +1 -0
  149. package/dist/actions/graphql/types.js +1 -1
  150. package/dist/actions/graphql/types.js.map +1 -1
  151. package/dist/actions/init/bootstrapLocalTemplate.js +10 -8
  152. package/dist/actions/init/bootstrapLocalTemplate.js.map +1 -1
  153. package/dist/actions/init/bootstrapRemoteTemplate.js +6 -5
  154. package/dist/actions/init/bootstrapRemoteTemplate.js.map +1 -1
  155. package/dist/actions/init/bootstrapTemplate.js.map +1 -1
  156. package/dist/actions/init/checkNextJsReactCompatibility.js +1 -1
  157. package/dist/actions/init/checkNextJsReactCompatibility.js.map +1 -1
  158. package/dist/actions/init/createAppCliConfig.js.map +1 -1
  159. package/dist/actions/init/createCliConfig.js.map +1 -1
  160. package/dist/actions/init/createPackageManifest.js +21 -9
  161. package/dist/actions/init/createPackageManifest.js.map +1 -1
  162. package/dist/actions/init/remoteTemplate.js +1 -2
  163. package/dist/actions/init/remoteTemplate.js.map +1 -1
  164. package/dist/actions/init/sdkAppDependencies.js +19 -0
  165. package/dist/actions/init/sdkAppDependencies.js.map +1 -0
  166. package/dist/actions/init/studioDependencies.js.map +1 -0
  167. package/dist/actions/init/templates/appQuickstart.js +1 -22
  168. package/dist/actions/init/templates/appQuickstart.js.map +1 -1
  169. package/dist/actions/init/templates/appSanityUi.js +3 -22
  170. package/dist/actions/init/templates/appSanityUi.js.map +1 -1
  171. package/dist/actions/init/types.js.map +1 -1
  172. package/dist/actions/manifest/SchemaIcon.js +6 -4
  173. package/dist/actions/manifest/SchemaIcon.js.map +1 -1
  174. package/dist/actions/manifest/blockTypeTransformer.js +67 -0
  175. package/dist/actions/manifest/blockTypeTransformer.js.map +1 -0
  176. package/dist/actions/manifest/debug.js +4 -0
  177. package/dist/actions/manifest/debug.js.map +1 -0
  178. package/dist/actions/manifest/extractAppManifest.js +39 -22
  179. package/dist/actions/manifest/extractAppManifest.js.map +1 -1
  180. package/dist/actions/manifest/extractManifest.js +27 -78
  181. package/dist/actions/manifest/extractManifest.js.map +1 -1
  182. package/dist/actions/manifest/extractManifest.worker.js +30 -0
  183. package/dist/actions/manifest/extractManifest.worker.js.map +1 -0
  184. package/dist/actions/manifest/extractWorkspaceManifest.js +31 -372
  185. package/dist/actions/manifest/extractWorkspaceManifest.js.map +1 -1
  186. package/dist/actions/manifest/iconResolver.js +30 -0
  187. package/dist/actions/manifest/iconResolver.js.map +1 -0
  188. package/dist/actions/manifest/referenceTransformer.js +51 -0
  189. package/dist/actions/manifest/referenceTransformer.js.map +1 -0
  190. package/dist/actions/manifest/schemaTypeHelpers.js +2 -2
  191. package/dist/actions/manifest/schemaTypeHelpers.js.map +1 -1
  192. package/dist/actions/manifest/schemaTypeTransformer.js +168 -0
  193. package/dist/actions/manifest/schemaTypeTransformer.js.map +1 -0
  194. package/dist/actions/manifest/transformerUtils.js +40 -0
  195. package/dist/actions/manifest/transformerUtils.js.map +1 -0
  196. package/dist/actions/manifest/types.js +5 -0
  197. package/dist/actions/manifest/types.js.map +1 -1
  198. package/dist/actions/manifest/validationTransformer.js +84 -0
  199. package/dist/actions/manifest/validationTransformer.js.map +1 -0
  200. package/dist/actions/manifest/writeManifestFile.js +30 -0
  201. package/dist/actions/manifest/writeManifestFile.js.map +1 -0
  202. package/dist/actions/manifest/writeWorkspaceFiles.js +30 -0
  203. package/dist/actions/manifest/writeWorkspaceFiles.js.map +1 -0
  204. package/dist/actions/mcp/detectAvailableEditors.js +34 -13
  205. package/dist/actions/mcp/detectAvailableEditors.js.map +1 -1
  206. package/dist/actions/mcp/editorConfigs.js +231 -109
  207. package/dist/actions/mcp/editorConfigs.js.map +1 -1
  208. package/dist/actions/mcp/promptForMCPSetup.js +16 -7
  209. package/dist/actions/mcp/promptForMCPSetup.js.map +1 -1
  210. package/dist/actions/mcp/setupMCP.js +62 -23
  211. package/dist/actions/mcp/setupMCP.js.map +1 -1
  212. package/dist/actions/mcp/types.js.map +1 -1
  213. package/dist/actions/mcp/validateEditorTokens.js +56 -0
  214. package/dist/actions/mcp/validateEditorTokens.js.map +1 -0
  215. package/dist/actions/mcp/writeMCPConfig.js +27 -15
  216. package/dist/actions/mcp/writeMCPConfig.js.map +1 -1
  217. package/dist/actions/media/buildNdjsonIndex.js +32 -0
  218. package/dist/actions/media/buildNdjsonIndex.js.map +1 -0
  219. package/dist/actions/media/importAspects.js +2 -11
  220. package/dist/actions/media/importAspects.js.map +1 -1
  221. package/dist/actions/media/importMedia.js +22 -18
  222. package/dist/actions/media/importMedia.js.map +1 -1
  223. package/dist/actions/organizations/findOrganizationByUserName.js +5 -0
  224. package/dist/actions/organizations/findOrganizationByUserName.js.map +1 -0
  225. package/dist/actions/organizations/getOrganization.js +3 -2
  226. package/dist/actions/organizations/getOrganization.js.map +1 -1
  227. package/dist/actions/organizations/getOrganizationChoices.js +27 -19
  228. package/dist/actions/organizations/getOrganizationChoices.js.map +1 -1
  229. package/dist/actions/organizations/types.js +3 -0
  230. package/dist/actions/organizations/types.js.map +1 -0
  231. package/dist/actions/projects/getManageUrl.js +1 -2
  232. package/dist/actions/projects/getManageUrl.js.map +1 -1
  233. package/dist/actions/schema/deleteSchemaAction.js +14 -30
  234. package/dist/actions/schema/deleteSchemaAction.js.map +1 -1
  235. package/dist/actions/schema/deploySchemas.js +22 -91
  236. package/dist/actions/schema/deploySchemas.js.map +1 -1
  237. package/dist/actions/schema/extractSanitySchema.worker.js +0 -5
  238. package/dist/actions/schema/extractSanitySchema.worker.js.map +1 -1
  239. package/dist/actions/schema/extractSanityWorkspace.worker.js +24 -0
  240. package/dist/actions/schema/extractSanityWorkspace.worker.js.map +1 -0
  241. package/dist/actions/schema/extractSchema.js +8 -40
  242. package/dist/actions/schema/extractSchema.js.map +1 -1
  243. package/dist/actions/schema/extractSchemaWatcher.js +128 -0
  244. package/dist/actions/schema/extractSchemaWatcher.js.map +1 -0
  245. package/dist/actions/schema/formatSchemaValidation.js +5 -1
  246. package/dist/actions/schema/formatSchemaValidation.js.map +1 -1
  247. package/dist/actions/schema/getExtractOptions.js +16 -0
  248. package/dist/actions/schema/getExtractOptions.js.map +1 -0
  249. package/dist/actions/schema/listSchemas.js +53 -56
  250. package/dist/actions/schema/listSchemas.js.map +1 -1
  251. package/dist/actions/schema/matchSchemaPattern.js +22 -0
  252. package/dist/actions/schema/matchSchemaPattern.js.map +1 -0
  253. package/dist/actions/schema/runSchemaExtraction.js +39 -0
  254. package/dist/actions/schema/runSchemaExtraction.js.map +1 -0
  255. package/dist/actions/schema/types.js +8 -0
  256. package/dist/actions/schema/types.js.map +1 -1
  257. package/dist/actions/schema/uniqueWorkspaces.worker.js +24 -0
  258. package/dist/actions/schema/uniqueWorkspaces.worker.js.map +1 -0
  259. package/dist/actions/schema/updateWorkspaceSchema.js +63 -0
  260. package/dist/actions/schema/updateWorkspaceSchema.js.map +1 -0
  261. package/dist/actions/schema/uploadSchemaToLexicon.js +87 -0
  262. package/dist/actions/schema/uploadSchemaToLexicon.js.map +1 -0
  263. package/dist/actions/schema/utils/SchemaExtractionError.js +10 -0
  264. package/dist/actions/schema/utils/SchemaExtractionError.js.map +1 -0
  265. package/dist/actions/schema/utils/schemaStoreValidation.js +1 -15
  266. package/dist/actions/schema/utils/schemaStoreValidation.js.map +1 -1
  267. package/dist/actions/schema/utils/uniqByProjectIdDataset.js +1 -1
  268. package/dist/actions/schema/utils/uniqByProjectIdDataset.js.map +1 -1
  269. package/dist/actions/schema/validateSchema.worker.js +1 -8
  270. package/dist/actions/schema/validateSchema.worker.js.map +1 -1
  271. package/dist/actions/schema/watchExtractSchema.js +72 -0
  272. package/dist/actions/schema/watchExtractSchema.js.map +1 -0
  273. package/dist/actions/telemetry/isTrueish.js +10 -0
  274. package/dist/actions/telemetry/isTrueish.js.map +1 -0
  275. package/dist/actions/telemetry/resolveConsent.js +2 -1
  276. package/dist/actions/telemetry/resolveConsent.js.map +1 -1
  277. package/dist/actions/telemetry/setConsent.js +2 -1
  278. package/dist/actions/telemetry/setConsent.js.map +1 -1
  279. package/dist/actions/telemetry/telemetryDebug.js +2 -2
  280. package/dist/actions/telemetry/telemetryDebug.js.map +1 -1
  281. package/dist/actions/users/getMembersForProject.js.map +1 -1
  282. package/dist/actions/users/getPendingInvitations.js +1 -1
  283. package/dist/actions/users/getPendingInvitations.js.map +1 -1
  284. package/dist/actions/users/types.js.map +1 -1
  285. package/dist/actions/versions/filterSanityModules.js.map +1 -1
  286. package/dist/actions/versions/findSanityModulesVersions.js +2 -3
  287. package/dist/actions/versions/findSanityModulesVersions.js.map +1 -1
  288. package/dist/actions/versions/getFormatters.js +1 -1
  289. package/dist/actions/versions/getFormatters.js.map +1 -1
  290. package/dist/actions/versions/tryFindLatestVersion.js +1 -1
  291. package/dist/actions/versions/tryFindLatestVersion.js.map +1 -1
  292. package/dist/commands/backup/disable.js +22 -7
  293. package/dist/commands/backup/disable.js.map +1 -1
  294. package/dist/commands/backup/download.js +19 -10
  295. package/dist/commands/backup/download.js.map +1 -1
  296. package/dist/commands/backup/enable.js +22 -7
  297. package/dist/commands/backup/enable.js.map +1 -1
  298. package/dist/commands/backup/list.js +20 -8
  299. package/dist/commands/backup/list.js.map +1 -1
  300. package/dist/commands/build.js +2 -5
  301. package/dist/commands/build.js.map +1 -1
  302. package/dist/commands/cors/add.js +20 -7
  303. package/dist/commands/cors/add.js.map +1 -1
  304. package/dist/commands/cors/delete.js +22 -7
  305. package/dist/commands/cors/delete.js.map +1 -1
  306. package/dist/commands/cors/list.js +22 -7
  307. package/dist/commands/cors/list.js.map +1 -1
  308. package/dist/commands/dataset/alias/create.js +26 -7
  309. package/dist/commands/dataset/alias/create.js.map +1 -1
  310. package/dist/commands/dataset/alias/delete.js +20 -7
  311. package/dist/commands/dataset/alias/delete.js.map +1 -1
  312. package/dist/commands/dataset/alias/link.js +20 -7
  313. package/dist/commands/dataset/alias/link.js.map +1 -1
  314. package/dist/commands/dataset/alias/unlink.js +20 -7
  315. package/dist/commands/dataset/alias/unlink.js.map +1 -1
  316. package/dist/commands/dataset/copy.js +45 -30
  317. package/dist/commands/dataset/copy.js.map +1 -1
  318. package/dist/commands/dataset/create.js +32 -7
  319. package/dist/commands/dataset/create.js.map +1 -1
  320. package/dist/commands/dataset/delete.js +16 -7
  321. package/dist/commands/dataset/delete.js.map +1 -1
  322. package/dist/commands/dataset/embeddings/disable.js +77 -0
  323. package/dist/commands/dataset/embeddings/disable.js.map +1 -0
  324. package/dist/commands/dataset/embeddings/enable.js +141 -0
  325. package/dist/commands/dataset/embeddings/enable.js.map +1 -0
  326. package/dist/commands/dataset/embeddings/status.js +72 -0
  327. package/dist/commands/dataset/embeddings/status.js.map +1 -0
  328. package/dist/commands/dataset/export.js +25 -16
  329. package/dist/commands/dataset/export.js.map +1 -1
  330. package/dist/commands/dataset/import.js +306 -1
  331. package/dist/commands/dataset/import.js.map +1 -1
  332. package/dist/commands/dataset/list.js +22 -7
  333. package/dist/commands/dataset/list.js.map +1 -1
  334. package/dist/commands/dataset/visibility/get.js +18 -7
  335. package/dist/commands/dataset/visibility/get.js.map +1 -1
  336. package/dist/commands/dataset/visibility/set.js +22 -7
  337. package/dist/commands/dataset/visibility/set.js.map +1 -1
  338. package/dist/commands/debug.js +4 -2
  339. package/dist/commands/debug.js.map +1 -1
  340. package/dist/commands/deploy.js +22 -11
  341. package/dist/commands/deploy.js.map +1 -1
  342. package/dist/commands/dev.js +2 -4
  343. package/dist/commands/dev.js.map +1 -1
  344. package/dist/commands/doctor.js +125 -0
  345. package/dist/commands/doctor.js.map +1 -0
  346. package/dist/commands/documents/create.js +19 -12
  347. package/dist/commands/documents/create.js.map +1 -1
  348. package/dist/commands/documents/delete.js +19 -12
  349. package/dist/commands/documents/delete.js.map +1 -1
  350. package/dist/commands/documents/get.js +17 -12
  351. package/dist/commands/documents/get.js.map +1 -1
  352. package/dist/commands/documents/query.js +26 -18
  353. package/dist/commands/documents/query.js.map +1 -1
  354. package/dist/commands/documents/validate.js +32 -10
  355. package/dist/commands/documents/validate.js.map +1 -1
  356. package/dist/commands/graphql/deploy.js +58 -30
  357. package/dist/commands/graphql/deploy.js.map +1 -1
  358. package/dist/commands/graphql/list.js +15 -7
  359. package/dist/commands/graphql/list.js.map +1 -1
  360. package/dist/commands/graphql/undeploy.js +37 -19
  361. package/dist/commands/graphql/undeploy.js.map +1 -1
  362. package/dist/commands/hook/attempt.js +22 -7
  363. package/dist/commands/hook/attempt.js.map +1 -1
  364. package/dist/commands/hook/create.js +23 -8
  365. package/dist/commands/hook/create.js.map +1 -1
  366. package/dist/commands/hook/delete.js +22 -7
  367. package/dist/commands/hook/delete.js.map +1 -1
  368. package/dist/commands/hook/list.js +22 -7
  369. package/dist/commands/hook/list.js.map +1 -1
  370. package/dist/commands/hook/logs.js +21 -8
  371. package/dist/commands/hook/logs.js.map +1 -1
  372. package/dist/commands/init.js +55 -32
  373. package/dist/commands/init.js.map +1 -1
  374. package/dist/commands/login.js +19 -6
  375. package/dist/commands/login.js.map +1 -1
  376. package/dist/commands/logout.js +8 -6
  377. package/dist/commands/logout.js.map +1 -1
  378. package/dist/commands/manage.js +0 -1
  379. package/dist/commands/manage.js.map +1 -1
  380. package/dist/commands/manifest/extract.js +14 -10
  381. package/dist/commands/manifest/extract.js.map +1 -1
  382. package/dist/commands/mcp/configure.js +4 -2
  383. package/dist/commands/mcp/configure.js.map +1 -1
  384. package/dist/commands/media/create-aspect.js +4 -4
  385. package/dist/commands/media/create-aspect.js.map +1 -1
  386. package/dist/commands/media/delete-aspect.js +9 -7
  387. package/dist/commands/media/delete-aspect.js.map +1 -1
  388. package/dist/commands/media/deploy-aspect.js +22 -9
  389. package/dist/commands/media/deploy-aspect.js.map +1 -1
  390. package/dist/commands/media/export.js +9 -7
  391. package/dist/commands/media/export.js.map +1 -1
  392. package/dist/commands/media/import.js +10 -8
  393. package/dist/commands/media/import.js.map +1 -1
  394. package/dist/commands/preview.js +5 -8
  395. package/dist/commands/preview.js.map +1 -1
  396. package/dist/commands/projects/list.js +2 -1
  397. package/dist/commands/projects/list.js.map +1 -1
  398. package/dist/commands/schema/delete.js +33 -34
  399. package/dist/commands/schema/delete.js.map +1 -1
  400. package/dist/commands/schema/deploy.js +19 -30
  401. package/dist/commands/schema/deploy.js.map +1 -1
  402. package/dist/commands/schema/extract.js +32 -4
  403. package/dist/commands/schema/extract.js.map +1 -1
  404. package/dist/commands/schema/list.js +10 -31
  405. package/dist/commands/schema/list.js.map +1 -1
  406. package/dist/commands/tokens/add.js +24 -7
  407. package/dist/commands/tokens/add.js.map +1 -1
  408. package/dist/commands/tokens/delete.js +20 -7
  409. package/dist/commands/tokens/delete.js.map +1 -1
  410. package/dist/commands/tokens/list.js +20 -7
  411. package/dist/commands/tokens/list.js.map +1 -1
  412. package/dist/commands/users/invite.js +24 -7
  413. package/dist/commands/users/invite.js.map +1 -1
  414. package/dist/commands/users/list.js +76 -33
  415. package/dist/commands/users/list.js.map +1 -1
  416. package/dist/commands/versions.js +1 -1
  417. package/dist/commands/versions.js.map +1 -1
  418. package/dist/config/createCliConfig.js +1 -2
  419. package/dist/config/createCliConfig.js.map +1 -1
  420. package/dist/exports/_internal.d.ts +132 -0
  421. package/dist/exports/_internal.js +4 -0
  422. package/dist/exports/_internal.js.map +1 -0
  423. package/dist/exports/index.d.ts +113 -0
  424. package/dist/exports/index.js +6 -0
  425. package/dist/exports/index.js.map +1 -0
  426. package/dist/hooks/init/checkForUpdates.js +14 -0
  427. package/dist/hooks/init/checkForUpdates.js.map +1 -0
  428. package/dist/hooks/prerun/flushTelemetry.worker.js +1 -1
  429. package/dist/hooks/prerun/flushTelemetry.worker.js.map +1 -1
  430. package/dist/hooks/prerun/injectEnvVariables.js +9 -1
  431. package/dist/hooks/prerun/injectEnvVariables.js.map +1 -1
  432. package/dist/hooks/prerun/setupTelemetry.js +16 -10
  433. package/dist/hooks/prerun/setupTelemetry.js.map +1 -1
  434. package/dist/prompts/promptForProject.js +64 -0
  435. package/dist/prompts/promptForProject.js.map +1 -0
  436. package/dist/{actions/auth/login/promptProviders.js → prompts/promptForProviders.js} +3 -3
  437. package/dist/prompts/promptForProviders.js.map +1 -0
  438. package/dist/prompts/selectMediaLibrary.js +1 -1
  439. package/dist/prompts/selectMediaLibrary.js.map +1 -1
  440. package/dist/server/devServer.js +4 -2
  441. package/dist/server/devServer.js.map +1 -1
  442. package/dist/server/previewServer.js +2 -2
  443. package/dist/server/previewServer.js.map +1 -1
  444. package/dist/server/vite/plugin-schema-extraction.js +201 -0
  445. package/dist/server/vite/plugin-schema-extraction.js.map +1 -0
  446. package/dist/server/vite/plugin-typegen.js +217 -0
  447. package/dist/server/vite/plugin-typegen.js.map +1 -0
  448. package/dist/services/auth.js +42 -3
  449. package/dist/services/auth.js.map +1 -1
  450. package/dist/services/datasets.js +7 -5
  451. package/dist/services/datasets.js.map +1 -1
  452. package/dist/services/docs.js +2 -2
  453. package/dist/services/docs.js.map +1 -1
  454. package/dist/services/embeddings.js +25 -0
  455. package/dist/services/embeddings.js.map +1 -0
  456. package/dist/services/getUrlHeaders.js +7 -18
  457. package/dist/services/getUrlHeaders.js.map +1 -1
  458. package/dist/services/grants.js +13 -0
  459. package/dist/services/grants.js.map +1 -0
  460. package/dist/services/graphql.js +1 -1
  461. package/dist/services/graphql.js.map +1 -1
  462. package/dist/services/mcp.js +55 -1
  463. package/dist/services/mcp.js.map +1 -1
  464. package/dist/services/projects.js +4 -2
  465. package/dist/services/projects.js.map +1 -1
  466. package/dist/services/schemas.js +1 -1
  467. package/dist/services/schemas.js.map +1 -1
  468. package/dist/services/telemetry.js +2 -1
  469. package/dist/services/telemetry.js.map +1 -1
  470. package/dist/services/userApplications.js +21 -6
  471. package/dist/services/userApplications.js.map +1 -1
  472. package/dist/telemetry/extractSchema.telemetry.js +10 -0
  473. package/dist/telemetry/extractSchema.telemetry.js.map +1 -1
  474. package/dist/types/grants.js +3 -0
  475. package/dist/types/grants.js.map +1 -0
  476. package/dist/types.js +3 -0
  477. package/dist/types.js.map +1 -1
  478. package/dist/util/checkProjectPermissions.js +21 -0
  479. package/dist/util/checkProjectPermissions.js.map +1 -0
  480. package/dist/util/cliClient.js +5 -3
  481. package/dist/util/cliClient.js.map +1 -1
  482. package/dist/util/compareDependencyVersions.js +74 -38
  483. package/dist/util/compareDependencyVersions.js.map +1 -1
  484. package/dist/util/createExpiringConfig.js +64 -0
  485. package/dist/util/createExpiringConfig.js.map +1 -0
  486. package/dist/util/detectFramework.js +135 -0
  487. package/dist/util/detectFramework.js.map +1 -0
  488. package/dist/util/errorMessages.js +0 -1
  489. package/dist/util/errorMessages.js.map +1 -1
  490. package/dist/util/extractDocumentsFromNdjsonOrTarball.js +1 -2
  491. package/dist/util/extractDocumentsFromNdjsonOrTarball.js.map +1 -1
  492. package/dist/util/getCliVersion.js +1 -1
  493. package/dist/util/getCliVersion.js.map +1 -1
  494. package/dist/util/getLocalPackageVersion.js +33 -23
  495. package/dist/util/getLocalPackageVersion.js.map +1 -1
  496. package/dist/util/getProjectDefaults.js +22 -28
  497. package/dist/util/getProjectDefaults.js.map +1 -1
  498. package/dist/util/getSharedServerConfig.js +1 -0
  499. package/dist/util/getSharedServerConfig.js.map +1 -1
  500. package/dist/util/getWorkspace.js +1 -1
  501. package/dist/util/getWorkspace.js.map +1 -1
  502. package/dist/util/gitConfig.js +45 -0
  503. package/dist/util/gitConfig.js.map +1 -0
  504. package/dist/util/isSchemaError.js +11 -0
  505. package/dist/util/isSchemaError.js.map +1 -0
  506. package/dist/util/isTar.js +8 -0
  507. package/dist/util/isTar.js.map +1 -0
  508. package/dist/util/packageManager/getPeerDependencies.js +44 -0
  509. package/dist/util/packageManager/getPeerDependencies.js.map +1 -0
  510. package/dist/util/packageManager/installationInfo/analyzeIssues.js +225 -0
  511. package/dist/util/packageManager/installationInfo/analyzeIssues.js.map +1 -0
  512. package/dist/util/packageManager/installationInfo/commands.js +73 -0
  513. package/dist/util/packageManager/installationInfo/commands.js.map +1 -0
  514. package/dist/util/packageManager/installationInfo/detectCliInstallation.js +66 -0
  515. package/dist/util/packageManager/installationInfo/detectCliInstallation.js.map +1 -0
  516. package/dist/util/packageManager/installationInfo/detectGlobals.js +295 -0
  517. package/dist/util/packageManager/installationInfo/detectGlobals.js.map +1 -0
  518. package/dist/util/packageManager/installationInfo/detectPackages.js +190 -0
  519. package/dist/util/packageManager/installationInfo/detectPackages.js.map +1 -0
  520. package/dist/util/packageManager/installationInfo/detectWorkspace.js +192 -0
  521. package/dist/util/packageManager/installationInfo/detectWorkspace.js.map +1 -0
  522. package/dist/util/packageManager/installationInfo/index.js +4 -0
  523. package/dist/util/packageManager/installationInfo/index.js.map +1 -0
  524. package/dist/util/packageManager/installationInfo/readJsonFile.js +14 -0
  525. package/dist/util/packageManager/installationInfo/readJsonFile.js.map +1 -0
  526. package/dist/util/packageManager/installationInfo/resolveVersionRange.js +42 -0
  527. package/dist/util/packageManager/installationInfo/resolveVersionRange.js.map +1 -0
  528. package/dist/util/packageManager/installationInfo/types.js +3 -0
  529. package/dist/util/packageManager/installationInfo/types.js.map +1 -0
  530. package/dist/util/packageManager/packageManagerChoice.js +1 -20
  531. package/dist/util/packageManager/packageManagerChoice.js.map +1 -1
  532. package/dist/util/packageManager/upgradePackages.js +4 -1
  533. package/dist/util/packageManager/upgradePackages.js.map +1 -1
  534. package/dist/util/promiseRaceWithTimeout.js +28 -0
  535. package/dist/util/promiseRaceWithTimeout.js.map +1 -0
  536. package/dist/util/readdirRecursive.js.map +1 -1
  537. package/dist/util/resolveLatestVersions.js +2 -2
  538. package/dist/util/resolveLatestVersions.js.map +1 -1
  539. package/dist/util/sharedFlags.js +54 -0
  540. package/dist/util/sharedFlags.js.map +1 -0
  541. package/dist/util/telemetry/cleanupOldTelemetryFiles.js +30 -0
  542. package/dist/util/telemetry/cleanupOldTelemetryFiles.js.map +1 -0
  543. package/dist/util/telemetry/createTelemetryStore.js +95 -0
  544. package/dist/util/telemetry/createTelemetryStore.js.map +1 -0
  545. package/dist/util/telemetry/createTraceId.js +10 -0
  546. package/dist/util/telemetry/createTraceId.js.map +1 -0
  547. package/dist/util/telemetry/findTelemetryFiles.js +35 -0
  548. package/dist/util/telemetry/findTelemetryFiles.js.map +1 -0
  549. package/dist/util/telemetry/flushTelemetryFiles.js +118 -0
  550. package/dist/util/telemetry/flushTelemetryFiles.js.map +1 -0
  551. package/dist/util/telemetry/generateTelemetryFilePath.js +30 -0
  552. package/dist/util/telemetry/generateTelemetryFilePath.js.map +1 -0
  553. package/dist/util/telemetry/logger.js +59 -0
  554. package/dist/util/telemetry/logger.js.map +1 -0
  555. package/dist/util/telemetry/readNDJSON.js +28 -0
  556. package/dist/util/telemetry/readNDJSON.js.map +1 -0
  557. package/dist/util/telemetry/telemetryStoreDebug.js +7 -0
  558. package/dist/util/telemetry/telemetryStoreDebug.js.map +1 -0
  559. package/dist/util/telemetry/trace.js +150 -0
  560. package/dist/util/telemetry/trace.js.map +1 -0
  561. package/dist/util/toForwardSlashes.js +8 -0
  562. package/dist/util/toForwardSlashes.js.map +1 -0
  563. package/dist/util/update/fetchLatestVersion.js +21 -0
  564. package/dist/util/update/fetchLatestVersion.js.map +1 -0
  565. package/dist/util/update/getUpdateCommand.js +20 -0
  566. package/dist/util/update/getUpdateCommand.js.map +1 -0
  567. package/dist/util/update/isInstalledUsingYarn.js +17 -0
  568. package/dist/util/update/isInstalledUsingYarn.js.map +1 -0
  569. package/dist/util/update/showNotificationUpdate.js +31 -0
  570. package/dist/util/update/showNotificationUpdate.js.map +1 -0
  571. package/dist/util/update/updateChecker.js +60 -0
  572. package/dist/util/update/updateChecker.js.map +1 -0
  573. package/dist/util/update/updateCheckerDebug.js +4 -0
  574. package/dist/util/update/updateCheckerDebug.js.map +1 -0
  575. package/oclif.config.js +1 -0
  576. package/oclif.manifest.json +1285 -492
  577. package/package.json +72 -73
  578. package/static/favicons/apple-touch-icon.png +0 -0
  579. package/static/favicons/favicon-192.png +0 -0
  580. package/static/favicons/favicon-512.png +0 -0
  581. package/static/favicons/favicon-96.png +0 -0
  582. package/static/favicons/favicon.ico +0 -0
  583. package/static/favicons/favicon.svg +12 -0
  584. package/dist/actions/auth/login/promptProviders.js.map +0 -1
  585. package/dist/actions/dev/getCoreAppUrl.js +0 -10
  586. package/dist/actions/dev/getCoreAppUrl.js.map +0 -1
  587. package/dist/actions/schema/schemaStoreTypes.js +0 -19
  588. package/dist/actions/schema/schemaStoreTypes.js.map +0 -1
  589. package/dist/actions/schema/utils/manifestExtractor.js +0 -33
  590. package/dist/actions/schema/utils/manifestExtractor.js.map +0 -1
  591. package/dist/actions/schema/utils/manifestReader.js +0 -71
  592. package/dist/actions/schema/utils/manifestReader.js.map +0 -1
  593. package/dist/index.d.ts +0 -2326
  594. package/dist/index.js +0 -6
  595. package/dist/index.js.map +0 -1
  596. package/dist/studioDependencies.js.map +0 -1
  597. package/dist/typings/deepSortObject.d.js +0 -2
  598. package/dist/typings/deepSortObject.d.js.map +0 -1
  599. package/dist/util/findNdjsonEntry.js +0 -21
  600. package/dist/util/findNdjsonEntry.js.map +0 -1
  601. package/dist/util/importStudioConfig.js +0 -40
  602. package/dist/util/importStudioConfig.js.map +0 -1
  603. package/dist/util/readModuleVersion.js +0 -15
  604. package/dist/util/readModuleVersion.js.map +0 -1
  605. package/dist/util/readPackageJson.js +0 -44
  606. package/dist/util/readPackageJson.js.map +0 -1
  607. package/dist/util/readPackageManifest.js +0 -46
  608. package/dist/util/readPackageManifest.js.map +0 -1
  609. package/dist/util/uniqBy.js +0 -14
  610. package/dist/util/uniqBy.js.map +0 -1
  611. package/dist/util/workerChannels.js +0 -172
  612. package/dist/util/workerChannels.js.map +0 -1
  613. /package/dist/{studioDependencies.js → actions/init/studioDependencies.js} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/actions/manifest/validationTransformer.ts"],"sourcesContent":["import {type Rule, type RuleSpec, type SchemaValidationValue} from '@sanity/types'\n\nimport {type SerializableProp} from './transformerUtils.js'\nimport {type ManifestValidationGroup, type ManifestValidationRule} from './types.js'\n\ntype Validation = Record<string, never> | {validation: ManifestValidationGroup[]}\ntype ManifestValidationFlag = ManifestValidationRule['flag']\ntype ValidationRuleTransformer = (rule: RuleSpec) => ManifestValidationRule | undefined\n\nconst transformTypeValidationRule: ValidationRuleTransformer = (rule) => {\n return {\n ...rule,\n constraint:\n 'constraint' in rule &&\n (typeof rule.constraint === 'string'\n ? rule.constraint.toLowerCase()\n : retainSerializablePropsForValidation(rule.constraint)),\n }\n}\n\nconst validationRuleTransformers: Partial<\n Record<ManifestValidationFlag, ValidationRuleTransformer>\n> = {\n type: transformTypeValidationRule,\n}\n\n/**\n * Transforms schema validation rules to their manifest representation\n */\nexport function transformValidation(\n validation: SchemaValidationValue,\n retainSerializableProps: (value: unknown, depth?: number) => SerializableProp,\n): Validation {\n const validationArray = (Array.isArray(validation) ? validation : [validation]).filter(\n (value): value is Rule => typeof value === 'object' && '_type' in value,\n )\n\n // we don't want type in the output as that is implicitly given by the typedef itself an will only bloat the payload\n const disallowedFlags = new Set(['type'])\n\n const serializedValidation = validationArray\n .map(({_level, _message, _rules}) => {\n const message: Partial<Pick<ManifestValidationGroup, 'message'>> =\n typeof _message === 'string' ? {message: _message} : {}\n\n const serializedRules = _rules\n .filter((rule) => {\n if (!('constraint' in rule)) {\n return false\n }\n\n const {constraint, flag} = rule\n\n if (disallowedFlags.has(flag)) {\n return false\n }\n\n // Validation rules that refer to other fields use symbols, which cannot be serialized. It would\n // be possible to transform these to a serializable type, but we haven't implemented that for now.\n const isFieldReference =\n typeof constraint === 'object' &&\n 'type' in constraint &&\n typeof constraint.type === 'symbol' &&\n (constraint.type.description === 'FIELD_REF' ||\n constraint.type.description === '@sanity/schema/field-ref')\n\n return !isFieldReference\n })\n .map((rule) => {\n const transformer: ValidationRuleTransformer =\n validationRuleTransformers[rule.flag] ??\n ((spec) => retainSerializableProps(spec) as ManifestValidationRule)\n\n const transformedRule = transformer(rule)\n\n if (!transformedRule) {\n return\n }\n\n return transformedRule\n })\n .filter((rule) => rule !== undefined)\n\n return {\n level: _level,\n rules: serializedRules,\n ...message,\n }\n })\n .filter((group) => group.rules.length > 0)\n\n return serializedValidation.length > 0 ? {validation: serializedValidation} : {}\n}\n\n/**\n * Helper function to retain serializable props specifically for validation transformation.\n * This is used internally by transformTypeValidationRule.\n */\nfunction retainSerializablePropsForValidation(value: unknown): SerializableProp {\n if (value === null || value === undefined) {\n return undefined\n }\n\n if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {\n if (value === '') {\n return undefined\n }\n return value\n }\n\n if (value instanceof RegExp) {\n return value.toString()\n }\n\n if (Array.isArray(value)) {\n const items = value\n .map((item) => retainSerializablePropsForValidation(item))\n .filter((item) => item !== undefined)\n return items.length > 0 ? (items as SerializableProp) : undefined\n }\n\n if (typeof value === 'object') {\n const entries = Object.entries(value)\n .map(([key, val]) => [key, retainSerializablePropsForValidation(val)])\n .filter(([, val]) => val !== undefined)\n return entries.length > 0 ? Object.fromEntries(entries) : undefined\n }\n\n return undefined\n}\n"],"names":["transformTypeValidationRule","rule","constraint","toLowerCase","retainSerializablePropsForValidation","validationRuleTransformers","type","transformValidation","validation","retainSerializableProps","validationArray","Array","isArray","filter","value","disallowedFlags","Set","serializedValidation","map","_level","_message","_rules","message","serializedRules","flag","has","isFieldReference","description","transformer","spec","transformedRule","undefined","level","rules","group","length","RegExp","toString","items","item","entries","Object","key","val","fromEntries"],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import { mkdir, writeFile } from 'node:fs/promises';
2
+ import { isAbsolute, join, resolve } from 'node:path';
3
+ import { subdebug } from '@sanity/cli-core';
4
+ import { getLocalPackageVersion } from '../../util/getLocalPackageVersion.js';
5
+ import { writeWorkspaceFiles } from './writeWorkspaceFiles.js';
6
+ const MANIFEST_FILENAME = 'create-manifest.json';
7
+ const debug = subdebug('writeManifestFile');
8
+ export async function writeManifestFile({ outPath, workDir, workspaceManifests }) {
9
+ const staticPath = isAbsolute(outPath) ? outPath : resolve(join(workDir, outPath));
10
+ debug('Writing manifest to %s', staticPath);
11
+ const path = join(staticPath, MANIFEST_FILENAME);
12
+ await mkdir(staticPath, {
13
+ recursive: true
14
+ });
15
+ const workspaceFiles = await writeWorkspaceFiles(workspaceManifests, staticPath);
16
+ const manifest = {
17
+ /**
18
+ * Version history:
19
+ * 1: Initial release.
20
+ * 2: Added tools file.
21
+ * 3. Added studioVersion field.
22
+ */ createdAt: new Date().toISOString(),
23
+ studioVersion: await getLocalPackageVersion('sanity', workDir),
24
+ version: 3,
25
+ workspaces: workspaceFiles
26
+ };
27
+ await writeFile(path, JSON.stringify(manifest, null, 2));
28
+ }
29
+
30
+ //# sourceMappingURL=writeManifestFile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/actions/manifest/writeManifestFile.ts"],"sourcesContent":["import {mkdir, writeFile} from 'node:fs/promises'\nimport {isAbsolute, join, resolve} from 'node:path'\n\nimport {subdebug} from '@sanity/cli-core'\n\nimport {getLocalPackageVersion} from '../../util/getLocalPackageVersion.js'\nimport {type CreateManifest, type CreateWorkspaceManifest} from './types.js'\nimport {writeWorkspaceFiles} from './writeWorkspaceFiles.js'\n\nconst MANIFEST_FILENAME = 'create-manifest.json'\n\nconst debug = subdebug('writeManifestFile')\n\nexport async function writeManifestFile({\n outPath,\n workDir,\n workspaceManifests,\n}: {\n outPath: string\n workDir: string\n workspaceManifests: CreateWorkspaceManifest[]\n}) {\n const staticPath = isAbsolute(outPath) ? outPath : resolve(join(workDir, outPath))\n debug('Writing manifest to %s', staticPath)\n const path = join(staticPath, MANIFEST_FILENAME)\n\n await mkdir(staticPath, {recursive: true})\n\n const workspaceFiles = await writeWorkspaceFiles(workspaceManifests, staticPath)\n\n const manifest: CreateManifest = {\n /**\n * Version history:\n * 1: Initial release.\n * 2: Added tools file.\n * 3. Added studioVersion field.\n */\n createdAt: new Date().toISOString(),\n studioVersion: await getLocalPackageVersion('sanity', workDir),\n version: 3,\n workspaces: workspaceFiles,\n }\n\n await writeFile(path, JSON.stringify(manifest, null, 2))\n}\n"],"names":["mkdir","writeFile","isAbsolute","join","resolve","subdebug","getLocalPackageVersion","writeWorkspaceFiles","MANIFEST_FILENAME","debug","writeManifestFile","outPath","workDir","workspaceManifests","staticPath","path","recursive","workspaceFiles","manifest","createdAt","Date","toISOString","studioVersion","version","workspaces","JSON","stringify"],"mappings":"AAAA,SAAQA,KAAK,EAAEC,SAAS,QAAO,mBAAkB;AACjD,SAAQC,UAAU,EAAEC,IAAI,EAAEC,OAAO,QAAO,YAAW;AAEnD,SAAQC,QAAQ,QAAO,mBAAkB;AAEzC,SAAQC,sBAAsB,QAAO,uCAAsC;AAE3E,SAAQC,mBAAmB,QAAO,2BAA0B;AAE5D,MAAMC,oBAAoB;AAE1B,MAAMC,QAAQJ,SAAS;AAEvB,OAAO,eAAeK,kBAAkB,EACtCC,OAAO,EACPC,OAAO,EACPC,kBAAkB,EAKnB;IACC,MAAMC,aAAaZ,WAAWS,WAAWA,UAAUP,QAAQD,KAAKS,SAASD;IACzEF,MAAM,0BAA0BK;IAChC,MAAMC,OAAOZ,KAAKW,YAAYN;IAE9B,MAAMR,MAAMc,YAAY;QAACE,WAAW;IAAI;IAExC,MAAMC,iBAAiB,MAAMV,oBAAoBM,oBAAoBC;IAErE,MAAMI,WAA2B;QAC/B;;;;;KAKC,GACDC,WAAW,IAAIC,OAAOC,WAAW;QACjCC,eAAe,MAAMhB,uBAAuB,UAAUM;QACtDW,SAAS;QACTC,YAAYP;IACd;IAEA,MAAMhB,UAAUc,MAAMU,KAAKC,SAAS,CAACR,UAAU,MAAM;AACvD"}
@@ -0,0 +1,30 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { writeFile } from 'node:fs/promises';
3
+ import { join } from 'node:path';
4
+ const SCHEMA_FILENAME_SUFFIX = '.create-schema.json';
5
+ const TOOLS_FILENAME_SUFFIX = '.create-tools.json';
6
+ export function writeWorkspaceFiles(manifestWorkspaces, staticPath) {
7
+ const output = manifestWorkspaces.map((workspace)=>writeWorkspaceFile(workspace, staticPath));
8
+ return Promise.all(output);
9
+ }
10
+ async function writeWorkspaceFile(workspace, staticPath) {
11
+ const [schemaFilename, toolsFilename] = await Promise.all([
12
+ createFile(staticPath, workspace.schema, SCHEMA_FILENAME_SUFFIX),
13
+ createFile(staticPath, workspace.tools, TOOLS_FILENAME_SUFFIX)
14
+ ]);
15
+ return {
16
+ ...workspace,
17
+ schema: schemaFilename,
18
+ tools: toolsFilename
19
+ };
20
+ }
21
+ async function createFile(path, content, filenameSuffix) {
22
+ const stringifiedContent = JSON.stringify(content, null, 2);
23
+ const hash = createHash('sha1').update(stringifiedContent).digest('hex');
24
+ const filename = `${hash.slice(0, 8)}${filenameSuffix}`;
25
+ // workspaces with identical data will overwrite each others file. This is ok, since they are identical and can be shared
26
+ await writeFile(join(path, filename), stringifiedContent);
27
+ return filename;
28
+ }
29
+
30
+ //# sourceMappingURL=writeWorkspaceFiles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/actions/manifest/writeWorkspaceFiles.ts"],"sourcesContent":["import {createHash} from 'node:crypto'\nimport {writeFile} from 'node:fs/promises'\nimport {join} from 'node:path'\n\nimport {type CreateWorkspaceManifest, type ManifestWorkspaceFile} from './types.js'\n\nconst SCHEMA_FILENAME_SUFFIX = '.create-schema.json'\nconst TOOLS_FILENAME_SUFFIX = '.create-tools.json'\n\nexport function writeWorkspaceFiles(\n manifestWorkspaces: CreateWorkspaceManifest[],\n staticPath: string,\n): Promise<ManifestWorkspaceFile[]> {\n const output = manifestWorkspaces.map((workspace) => writeWorkspaceFile(workspace, staticPath))\n\n return Promise.all(output)\n}\n\nasync function writeWorkspaceFile(\n workspace: CreateWorkspaceManifest,\n staticPath: string,\n): Promise<ManifestWorkspaceFile> {\n const [schemaFilename, toolsFilename] = await Promise.all([\n createFile(staticPath, workspace.schema, SCHEMA_FILENAME_SUFFIX),\n createFile(staticPath, workspace.tools, TOOLS_FILENAME_SUFFIX),\n ])\n\n return {\n ...workspace,\n schema: schemaFilename,\n tools: toolsFilename,\n }\n}\n\nasync function createFile(path: string, content: unknown, filenameSuffix: string) {\n const stringifiedContent = JSON.stringify(content, null, 2)\n const hash = createHash('sha1').update(stringifiedContent).digest('hex')\n const filename = `${hash.slice(0, 8)}${filenameSuffix}`\n\n // workspaces with identical data will overwrite each others file. This is ok, since they are identical and can be shared\n await writeFile(join(path, filename), stringifiedContent)\n\n return filename\n}\n"],"names":["createHash","writeFile","join","SCHEMA_FILENAME_SUFFIX","TOOLS_FILENAME_SUFFIX","writeWorkspaceFiles","manifestWorkspaces","staticPath","output","map","workspace","writeWorkspaceFile","Promise","all","schemaFilename","toolsFilename","createFile","schema","tools","path","content","filenameSuffix","stringifiedContent","JSON","stringify","hash","update","digest","filename","slice"],"mappings":"AAAA,SAAQA,UAAU,QAAO,cAAa;AACtC,SAAQC,SAAS,QAAO,mBAAkB;AAC1C,SAAQC,IAAI,QAAO,YAAW;AAI9B,MAAMC,yBAAyB;AAC/B,MAAMC,wBAAwB;AAE9B,OAAO,SAASC,oBACdC,kBAA6C,EAC7CC,UAAkB;IAElB,MAAMC,SAASF,mBAAmBG,GAAG,CAAC,CAACC,YAAcC,mBAAmBD,WAAWH;IAEnF,OAAOK,QAAQC,GAAG,CAACL;AACrB;AAEA,eAAeG,mBACbD,SAAkC,EAClCH,UAAkB;IAElB,MAAM,CAACO,gBAAgBC,cAAc,GAAG,MAAMH,QAAQC,GAAG,CAAC;QACxDG,WAAWT,YAAYG,UAAUO,MAAM,EAAEd;QACzCa,WAAWT,YAAYG,UAAUQ,KAAK,EAAEd;KACzC;IAED,OAAO;QACL,GAAGM,SAAS;QACZO,QAAQH;QACRI,OAAOH;IACT;AACF;AAEA,eAAeC,WAAWG,IAAY,EAAEC,OAAgB,EAAEC,cAAsB;IAC9E,MAAMC,qBAAqBC,KAAKC,SAAS,CAACJ,SAAS,MAAM;IACzD,MAAMK,OAAOzB,WAAW,QAAQ0B,MAAM,CAACJ,oBAAoBK,MAAM,CAAC;IAClE,MAAMC,WAAW,GAAGH,KAAKI,KAAK,CAAC,GAAG,KAAKR,gBAAgB;IAEvD,yHAAyH;IACzH,MAAMpB,UAAUC,KAAKiB,MAAMS,WAAWN;IAEtC,OAAOM;AACT"}
@@ -2,17 +2,29 @@ import { existsSync } from 'node:fs';
2
2
  import fs from 'node:fs/promises';
3
3
  import { subdebug } from '@sanity/cli-core';
4
4
  import { parse as parseJsonc } from 'jsonc-parser';
5
+ import { parse as parseToml } from 'smol-toml';
5
6
  import { EDITOR_CONFIGS } from './editorConfigs.js';
6
7
  const debug = subdebug('mcp:detectAvailableEditors');
7
8
  /**
8
- * Safely parse JSON/JSONC config file content
9
+ * Safely parse config file content
9
10
  * Returns parsed config or null if unparseable
10
- */ function parseConfig(content) {
11
+ */ function parseConfig(content, format) {
11
12
  const trimmed = content.trim();
12
13
  if (trimmed === '') {
13
14
  return {} // Empty file - safe to write, treat as empty config
14
15
  ;
15
16
  }
17
+ if (format === 'toml') {
18
+ try {
19
+ const parsed = parseToml(content);
20
+ if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
21
+ return null;
22
+ }
23
+ return parsed;
24
+ } catch {
25
+ return null;
26
+ }
27
+ }
16
28
  const errors = [];
17
29
  const parsed = parseJsonc(content, errors, {
18
30
  allowTrailingComma: true
@@ -25,9 +37,10 @@ const debug = subdebug('mcp:detectAvailableEditors');
25
37
  }
26
38
  /**
27
39
  * Check if an editor's config is usable and whether Sanity MCP is already configured.
40
+ * If configured, extracts the existing auth token.
28
41
  * Returns null only if config exists but can't be parsed (to avoid data loss).
29
42
  */ async function checkEditorConfig(name, configPath) {
30
- const { configKey } = EDITOR_CONFIGS[name];
43
+ const { configKey, format, readToken } = EDITOR_CONFIGS[name];
31
44
  // Config file doesn't exist - can create it
32
45
  if (!existsSync(configPath)) {
33
46
  return {
@@ -39,17 +52,24 @@ const debug = subdebug('mcp:detectAvailableEditors');
39
52
  // Config exists - try to parse it
40
53
  try {
41
54
  const content = await fs.readFile(configPath, 'utf8');
42
- const config = parseConfig(content);
55
+ const config = parseConfig(content, format);
43
56
  if (config === null) {
44
57
  debug('Skipping %s: could not parse %s', name, configPath);
45
58
  return null // Can't parse - skip this editor
46
59
  ;
47
60
  }
48
61
  // Check if Sanity MCP is already configured
49
- const configured = Boolean(config[configKey]?.Sanity);
62
+ const sanityConfig = config[configKey]?.Sanity;
63
+ const configured = Boolean(sanityConfig);
64
+ // Extract existing token if configured
65
+ let existingToken;
66
+ if (configured && typeof sanityConfig === 'object' && sanityConfig !== null) {
67
+ existingToken = readToken(sanityConfig);
68
+ }
50
69
  return {
51
70
  configPath,
52
71
  configured,
72
+ existingToken,
53
73
  name
54
74
  };
55
75
  } catch (err) {
@@ -61,15 +81,16 @@ const debug = subdebug('mcp:detectAvailableEditors');
61
81
  * Detect which editors are installed and have parseable configs.
62
82
  * Editors with unparseable configs are skipped to avoid data loss.
63
83
  */ export async function detectAvailableEditors() {
64
- const editors = [];
65
- for (const [name, config] of Object.entries(EDITOR_CONFIGS)){
84
+ // Detect all editors in parallel to avoid stacking timeouts —
85
+ // CLI-based editors (Claude Code, Codex CLI, OpenCode) each have a
86
+ // 5s execa timeout, so sequential detection can add ~15s on machines
87
+ // where none are installed.
88
+ const results = await Promise.all(Object.entries(EDITOR_CONFIGS).map(async ([name, config])=>{
66
89
  const configPath = await config.detect();
67
- if (configPath) {
68
- const editor = await checkEditorConfig(name, configPath);
69
- if (editor) editors.push(editor);
70
- }
71
- }
72
- return editors;
90
+ if (!configPath) return null;
91
+ return checkEditorConfig(name, configPath);
92
+ }));
93
+ return results.filter((editor)=>editor !== null);
73
94
  }
74
95
 
75
96
  //# sourceMappingURL=detectAvailableEditors.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/mcp/detectAvailableEditors.ts"],"sourcesContent":["import {existsSync} from 'node:fs'\nimport fs from 'node:fs/promises'\n\nimport {subdebug} from '@sanity/cli-core'\nimport {type ParseError, parse as parseJsonc} from 'jsonc-parser'\n\nimport {EDITOR_CONFIGS, type EditorName} from './editorConfigs.js'\n\nconst debug = subdebug('mcp:detectAvailableEditors')\n\nexport interface Editor {\n configPath: string\n /** Whether Sanity MCP is already configured for this editor */\n configured: boolean\n name: EditorName\n}\n\ninterface MCPConfig {\n [key: string]: Record<string, unknown> | undefined\n}\n\n/**\n * Safely parse JSON/JSONC config file content\n * Returns parsed config or null if unparseable\n */\nfunction parseConfig(content: string): MCPConfig | null {\n const trimmed = content.trim()\n if (trimmed === '') {\n return {} // Empty file - safe to write, treat as empty config\n }\n\n const errors: ParseError[] = []\n const parsed = parseJsonc(content, errors, {allowTrailingComma: true})\n\n if (errors.length > 0 || typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n return null // Parse failed\n }\n\n return parsed as MCPConfig\n}\n\n/**\n * Check if an editor's config is usable and whether Sanity MCP is already configured.\n * Returns null only if config exists but can't be parsed (to avoid data loss).\n */\nasync function checkEditorConfig(name: EditorName, configPath: string): Promise<Editor | null> {\n const {configKey} = EDITOR_CONFIGS[name]\n\n // Config file doesn't exist - can create it\n if (!existsSync(configPath)) {\n return {configPath, configured: false, name}\n }\n\n // Config exists - try to parse it\n try {\n const content = await fs.readFile(configPath, 'utf8')\n const config = parseConfig(content)\n\n if (config === null) {\n debug('Skipping %s: could not parse %s', name, configPath)\n return null // Can't parse - skip this editor\n }\n\n // Check if Sanity MCP is already configured\n const configured = Boolean(config[configKey]?.Sanity)\n\n return {configPath, configured, name}\n } catch (err) {\n debug('Skipping %s: could not read %s: %s', name, configPath, err)\n return null\n }\n}\n\n/**\n * Detect which editors are installed and have parseable configs.\n * Editors with unparseable configs are skipped to avoid data loss.\n */\nexport async function detectAvailableEditors(): Promise<Editor[]> {\n const editors: Editor[] = []\n\n for (const [name, config] of Object.entries(EDITOR_CONFIGS)) {\n const configPath = await config.detect()\n if (configPath) {\n const editor = await checkEditorConfig(name as EditorName, configPath)\n if (editor) editors.push(editor)\n }\n }\n\n return editors\n}\n"],"names":["existsSync","fs","subdebug","parse","parseJsonc","EDITOR_CONFIGS","debug","parseConfig","content","trimmed","trim","errors","parsed","allowTrailingComma","length","Array","isArray","checkEditorConfig","name","configPath","configKey","configured","readFile","config","Boolean","Sanity","err","detectAvailableEditors","editors","Object","entries","detect","editor","push"],"mappings":"AAAA,SAAQA,UAAU,QAAO,UAAS;AAClC,OAAOC,QAAQ,mBAAkB;AAEjC,SAAQC,QAAQ,QAAO,mBAAkB;AACzC,SAAyBC,SAASC,UAAU,QAAO,eAAc;AAEjE,SAAQC,cAAc,QAAwB,qBAAoB;AAElE,MAAMC,QAAQJ,SAAS;AAavB;;;CAGC,GACD,SAASK,YAAYC,OAAe;IAClC,MAAMC,UAAUD,QAAQE,IAAI;IAC5B,IAAID,YAAY,IAAI;QAClB,OAAO,CAAC,EAAE,oDAAoD;;IAChE;IAEA,MAAME,SAAuB,EAAE;IAC/B,MAAMC,SAASR,WAAWI,SAASG,QAAQ;QAACE,oBAAoB;IAAI;IAEpE,IAAIF,OAAOG,MAAM,GAAG,KAAK,OAAOF,WAAW,YAAYA,WAAW,QAAQG,MAAMC,OAAO,CAACJ,SAAS;QAC/F,OAAO,KAAK,eAAe;;IAC7B;IAEA,OAAOA;AACT;AAEA;;;CAGC,GACD,eAAeK,kBAAkBC,IAAgB,EAAEC,UAAkB;IACnE,MAAM,EAACC,SAAS,EAAC,GAAGf,cAAc,CAACa,KAAK;IAExC,4CAA4C;IAC5C,IAAI,CAAClB,WAAWmB,aAAa;QAC3B,OAAO;YAACA;YAAYE,YAAY;YAAOH;QAAI;IAC7C;IAEA,kCAAkC;IAClC,IAAI;QACF,MAAMV,UAAU,MAAMP,GAAGqB,QAAQ,CAACH,YAAY;QAC9C,MAAMI,SAAShB,YAAYC;QAE3B,IAAIe,WAAW,MAAM;YACnBjB,MAAM,mCAAmCY,MAAMC;YAC/C,OAAO,KAAK,iCAAiC;;QAC/C;QAEA,4CAA4C;QAC5C,MAAME,aAAaG,QAAQD,MAAM,CAACH,UAAU,EAAEK;QAE9C,OAAO;YAACN;YAAYE;YAAYH;QAAI;IACtC,EAAE,OAAOQ,KAAK;QACZpB,MAAM,sCAAsCY,MAAMC,YAAYO;QAC9D,OAAO;IACT;AACF;AAEA;;;CAGC,GACD,OAAO,eAAeC;IACpB,MAAMC,UAAoB,EAAE;IAE5B,KAAK,MAAM,CAACV,MAAMK,OAAO,IAAIM,OAAOC,OAAO,CAACzB,gBAAiB;QAC3D,MAAMc,aAAa,MAAMI,OAAOQ,MAAM;QACtC,IAAIZ,YAAY;YACd,MAAMa,SAAS,MAAMf,kBAAkBC,MAAoBC;YAC3D,IAAIa,QAAQJ,QAAQK,IAAI,CAACD;QAC3B;IACF;IAEA,OAAOJ;AACT"}
1
+ {"version":3,"sources":["../../../src/actions/mcp/detectAvailableEditors.ts"],"sourcesContent":["import {existsSync} from 'node:fs'\nimport fs from 'node:fs/promises'\n\nimport {subdebug} from '@sanity/cli-core'\nimport {type ParseError, parse as parseJsonc} from 'jsonc-parser'\nimport {parse as parseToml} from 'smol-toml'\n\nimport {EDITOR_CONFIGS, type EditorName} from './editorConfigs.js'\nimport {type Editor} from './types.js'\n\nconst debug = subdebug('mcp:detectAvailableEditors')\n\ninterface MCPConfig {\n [key: string]: Record<string, unknown> | undefined\n}\n\n/**\n * Safely parse config file content\n * Returns parsed config or null if unparseable\n */\nfunction parseConfig(content: string, format: 'jsonc' | 'toml'): MCPConfig | null {\n const trimmed = content.trim()\n if (trimmed === '') {\n return {} // Empty file - safe to write, treat as empty config\n }\n\n if (format === 'toml') {\n try {\n const parsed = parseToml(content)\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n return null\n }\n\n return parsed as MCPConfig\n } catch {\n return null\n }\n }\n\n const errors: ParseError[] = []\n const parsed = parseJsonc(content, errors, {allowTrailingComma: true})\n\n if (errors.length > 0 || typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n return null // Parse failed\n }\n\n return parsed as MCPConfig\n}\n\n/**\n * Check if an editor's config is usable and whether Sanity MCP is already configured.\n * If configured, extracts the existing auth token.\n * Returns null only if config exists but can't be parsed (to avoid data loss).\n */\nasync function checkEditorConfig(name: EditorName, configPath: string): Promise<Editor | null> {\n const {configKey, format, readToken} = EDITOR_CONFIGS[name]\n\n // Config file doesn't exist - can create it\n if (!existsSync(configPath)) {\n return {configPath, configured: false, name}\n }\n\n // Config exists - try to parse it\n try {\n const content = await fs.readFile(configPath, 'utf8')\n const config = parseConfig(content, format)\n\n if (config === null) {\n debug('Skipping %s: could not parse %s', name, configPath)\n return null // Can't parse - skip this editor\n }\n\n // Check if Sanity MCP is already configured\n const sanityConfig = config[configKey]?.Sanity\n const configured = Boolean(sanityConfig)\n\n // Extract existing token if configured\n let existingToken: string | undefined\n if (configured && typeof sanityConfig === 'object' && sanityConfig !== null) {\n existingToken = readToken(sanityConfig as Record<string, unknown>)\n }\n\n return {configPath, configured, existingToken, name}\n } catch (err) {\n debug('Skipping %s: could not read %s: %s', name, configPath, err)\n return null\n }\n}\n\n/**\n * Detect which editors are installed and have parseable configs.\n * Editors with unparseable configs are skipped to avoid data loss.\n */\nexport async function detectAvailableEditors(): Promise<Editor[]> {\n // Detect all editors in parallel to avoid stacking timeouts —\n // CLI-based editors (Claude Code, Codex CLI, OpenCode) each have a\n // 5s execa timeout, so sequential detection can add ~15s on machines\n // where none are installed.\n const results = await Promise.all(\n Object.entries(EDITOR_CONFIGS).map(async ([name, config]) => {\n const configPath = await config.detect()\n if (!configPath) return null\n return checkEditorConfig(name as EditorName, configPath)\n }),\n )\n\n return results.filter((editor): editor is Editor => editor !== null)\n}\n"],"names":["existsSync","fs","subdebug","parse","parseJsonc","parseToml","EDITOR_CONFIGS","debug","parseConfig","content","format","trimmed","trim","parsed","Array","isArray","errors","allowTrailingComma","length","checkEditorConfig","name","configPath","configKey","readToken","configured","readFile","config","sanityConfig","Sanity","Boolean","existingToken","err","detectAvailableEditors","results","Promise","all","Object","entries","map","detect","filter","editor"],"mappings":"AAAA,SAAQA,UAAU,QAAO,UAAS;AAClC,OAAOC,QAAQ,mBAAkB;AAEjC,SAAQC,QAAQ,QAAO,mBAAkB;AACzC,SAAyBC,SAASC,UAAU,QAAO,eAAc;AACjE,SAAQD,SAASE,SAAS,QAAO,YAAW;AAE5C,SAAQC,cAAc,QAAwB,qBAAoB;AAGlE,MAAMC,QAAQL,SAAS;AAMvB;;;CAGC,GACD,SAASM,YAAYC,OAAe,EAAEC,MAAwB;IAC5D,MAAMC,UAAUF,QAAQG,IAAI;IAC5B,IAAID,YAAY,IAAI;QAClB,OAAO,CAAC,EAAE,oDAAoD;;IAChE;IAEA,IAAID,WAAW,QAAQ;QACrB,IAAI;YACF,MAAMG,SAASR,UAAUI;YACzB,IAAI,OAAOI,WAAW,YAAYA,WAAW,QAAQC,MAAMC,OAAO,CAACF,SAAS;gBAC1E,OAAO;YACT;YAEA,OAAOA;QACT,EAAE,OAAM;YACN,OAAO;QACT;IACF;IAEA,MAAMG,SAAuB,EAAE;IAC/B,MAAMH,SAAST,WAAWK,SAASO,QAAQ;QAACC,oBAAoB;IAAI;IAEpE,IAAID,OAAOE,MAAM,GAAG,KAAK,OAAOL,WAAW,YAAYA,WAAW,QAAQC,MAAMC,OAAO,CAACF,SAAS;QAC/F,OAAO,KAAK,eAAe;;IAC7B;IAEA,OAAOA;AACT;AAEA;;;;CAIC,GACD,eAAeM,kBAAkBC,IAAgB,EAAEC,UAAkB;IACnE,MAAM,EAACC,SAAS,EAAEZ,MAAM,EAAEa,SAAS,EAAC,GAAGjB,cAAc,CAACc,KAAK;IAE3D,4CAA4C;IAC5C,IAAI,CAACpB,WAAWqB,aAAa;QAC3B,OAAO;YAACA;YAAYG,YAAY;YAAOJ;QAAI;IAC7C;IAEA,kCAAkC;IAClC,IAAI;QACF,MAAMX,UAAU,MAAMR,GAAGwB,QAAQ,CAACJ,YAAY;QAC9C,MAAMK,SAASlB,YAAYC,SAASC;QAEpC,IAAIgB,WAAW,MAAM;YACnBnB,MAAM,mCAAmCa,MAAMC;YAC/C,OAAO,KAAK,iCAAiC;;QAC/C;QAEA,4CAA4C;QAC5C,MAAMM,eAAeD,MAAM,CAACJ,UAAU,EAAEM;QACxC,MAAMJ,aAAaK,QAAQF;QAE3B,uCAAuC;QACvC,IAAIG;QACJ,IAAIN,cAAc,OAAOG,iBAAiB,YAAYA,iBAAiB,MAAM;YAC3EG,gBAAgBP,UAAUI;QAC5B;QAEA,OAAO;YAACN;YAAYG;YAAYM;YAAeV;QAAI;IACrD,EAAE,OAAOW,KAAK;QACZxB,MAAM,sCAAsCa,MAAMC,YAAYU;QAC9D,OAAO;IACT;AACF;AAEA;;;CAGC,GACD,OAAO,eAAeC;IACpB,8DAA8D;IAC9D,mEAAmE;IACnE,qEAAqE;IACrE,4BAA4B;IAC5B,MAAMC,UAAU,MAAMC,QAAQC,GAAG,CAC/BC,OAAOC,OAAO,CAAC/B,gBAAgBgC,GAAG,CAAC,OAAO,CAAClB,MAAMM,OAAO;QACtD,MAAML,aAAa,MAAMK,OAAOa,MAAM;QACtC,IAAI,CAAClB,YAAY,OAAO;QACxB,OAAOF,kBAAkBC,MAAoBC;IAC/C;IAGF,OAAOY,QAAQO,MAAM,CAAC,CAACC,SAA6BA,WAAW;AACjE"}
@@ -11,136 +11,258 @@ const defaultHttpConfig = (token)=>({
11
11
  url: MCP_SERVER_URL
12
12
  });
13
13
  const homeDir = os.homedir();
14
+ // -- Detect functions --
15
+ async function detectClaudeCode() {
16
+ try {
17
+ await execa('claude', [
18
+ '--version'
19
+ ], {
20
+ stdio: 'pipe',
21
+ timeout: 5000
22
+ });
23
+ return path.join(homeDir, '.claude.json');
24
+ } catch {
25
+ return null;
26
+ }
27
+ }
28
+ async function detectCodexCli() {
29
+ try {
30
+ await execa('codex', [
31
+ '--version'
32
+ ], {
33
+ stdio: 'pipe',
34
+ timeout: 5000
35
+ });
36
+ const codexHome = process.env.CODEX_HOME || path.join(homeDir, '.codex');
37
+ return path.join(codexHome, 'config.toml');
38
+ } catch {
39
+ return null;
40
+ }
41
+ }
42
+ async function detectCursor() {
43
+ const cursorDir = path.join(homeDir, '.cursor');
44
+ return existsSync(cursorDir) ? path.join(cursorDir, 'mcp.json') : null;
45
+ }
46
+ async function detectGeminiCli() {
47
+ const geminiDir = path.join(homeDir, '.gemini');
48
+ return existsSync(geminiDir) ? path.join(geminiDir, 'settings.json') : null;
49
+ }
50
+ async function detectGitHubCopilotCli() {
51
+ const copilotDir = process.platform === 'linux' && process.env.XDG_CONFIG_HOME ? path.join(process.env.XDG_CONFIG_HOME, 'copilot') : path.join(homeDir, '.copilot');
52
+ return existsSync(copilotDir) ? path.join(copilotDir, 'mcp-config.json') : null;
53
+ }
54
+ async function detectOpenCode() {
55
+ try {
56
+ await execa('opencode', [
57
+ '--version'
58
+ ], {
59
+ stdio: 'pipe',
60
+ timeout: 5000
61
+ });
62
+ return path.join(homeDir, '.config/opencode/opencode.json');
63
+ } catch {
64
+ return null;
65
+ }
66
+ }
67
+ async function detectVSCode() {
68
+ let configDir = null;
69
+ switch(process.platform){
70
+ case 'darwin':
71
+ {
72
+ configDir = path.join(homeDir, 'Library/Application Support/Code/User');
73
+ break;
74
+ }
75
+ case 'win32':
76
+ {
77
+ if (process.env.APPDATA) {
78
+ configDir = path.join(process.env.APPDATA, 'Code/User');
79
+ }
80
+ break;
81
+ }
82
+ default:
83
+ {
84
+ configDir = path.join(homeDir, '.config/Code/User');
85
+ }
86
+ }
87
+ return configDir && existsSync(configDir) ? path.join(configDir, 'mcp.json') : null;
88
+ }
89
+ async function detectVSCodeInsiders() {
90
+ let configDir = null;
91
+ switch(process.platform){
92
+ case 'darwin':
93
+ {
94
+ configDir = path.join(homeDir, 'Library/Application Support/Code - Insiders/User');
95
+ break;
96
+ }
97
+ case 'win32':
98
+ {
99
+ if (process.env.APPDATA) {
100
+ configDir = path.join(process.env.APPDATA, 'Code - Insiders/User');
101
+ }
102
+ break;
103
+ }
104
+ default:
105
+ {
106
+ configDir = path.join(homeDir, '.config/Code - Insiders/User');
107
+ }
108
+ }
109
+ return configDir && existsSync(configDir) ? path.join(configDir, 'mcp.json') : null;
110
+ }
111
+ async function detectZed() {
112
+ let configDir = null;
113
+ switch(process.platform){
114
+ case 'win32':
115
+ {
116
+ if (process.env.APPDATA) {
117
+ configDir = path.join(process.env.APPDATA, 'Zed');
118
+ }
119
+ break;
120
+ }
121
+ default:
122
+ {
123
+ configDir = path.join(homeDir, '.config/zed');
124
+ }
125
+ }
126
+ return configDir && existsSync(configDir) ? path.join(configDir, 'settings.json') : null;
127
+ }
128
+ // -- Read token helpers --
129
+ /**
130
+ * Extract a Bearer token from a headers-like object.
131
+ * Looks for `Authorization: "Bearer <token>"` and returns the token portion.
132
+ */ function extractBearerToken(headers) {
133
+ if (typeof headers !== 'object' || headers === null) return undefined;
134
+ const auth = headers.Authorization;
135
+ if (typeof auth !== 'string') return undefined;
136
+ const match = auth.match(/^Bearer\s+(.+)$/);
137
+ return match?.[1];
138
+ }
139
+ function readTokenFromHeaders(serverConfig) {
140
+ return extractBearerToken(serverConfig.headers);
141
+ }
142
+ function readTokenFromHttpHeaders(serverConfig) {
143
+ return extractBearerToken(serverConfig.http_headers);
144
+ }
145
+ // -- Build server config functions --
146
+ function buildClaudeCodeServerConfig(token) {
147
+ return defaultHttpConfig(token);
148
+ }
149
+ function buildCodexCliServerConfig(token) {
150
+ return {
151
+ http_headers: {
152
+ Authorization: `Bearer ${token}`
153
+ },
154
+ type: 'http',
155
+ url: MCP_SERVER_URL
156
+ };
157
+ }
158
+ function buildCursorServerConfig(token) {
159
+ return defaultHttpConfig(token);
160
+ }
161
+ function buildGeminiCliServerConfig(token) {
162
+ return defaultHttpConfig(token);
163
+ }
164
+ function buildGitHubCopilotCliServerConfig(token) {
165
+ return {
166
+ headers: {
167
+ Authorization: `Bearer ${token}`
168
+ },
169
+ tools: [
170
+ '*'
171
+ ],
172
+ type: 'http',
173
+ url: MCP_SERVER_URL
174
+ };
175
+ }
176
+ function buildOpenCodeServerConfig(token) {
177
+ return {
178
+ headers: {
179
+ Authorization: `Bearer ${token}`
180
+ },
181
+ type: 'remote',
182
+ url: MCP_SERVER_URL
183
+ };
184
+ }
185
+ function buildVSCodeServerConfig(token) {
186
+ return defaultHttpConfig(token);
187
+ }
188
+ function buildVSCodeInsidersServerConfig(token) {
189
+ return defaultHttpConfig(token);
190
+ }
191
+ function buildZedServerConfig(token) {
192
+ return {
193
+ headers: {
194
+ Authorization: `Bearer ${token}`
195
+ },
196
+ settings: {},
197
+ url: MCP_SERVER_URL
198
+ };
199
+ }
14
200
  /**
15
201
  * Centralized editor configuration including detection logic.
16
202
  * To add a new editor: add an entry here - EditorName type is derived automatically.
17
203
  */ export const EDITOR_CONFIGS = {
18
204
  'Claude Code': {
19
- buildServerConfig: defaultHttpConfig,
205
+ buildServerConfig: buildClaudeCodeServerConfig,
20
206
  configKey: 'mcpServers',
21
- detect: async ()=>{
22
- try {
23
- await execa('claude', [
24
- '--version'
25
- ], {
26
- stdio: 'pipe',
27
- timeout: 5000
28
- });
29
- return path.join(homeDir, '.claude.json');
30
- } catch {
31
- return null;
32
- }
33
- }
207
+ detect: detectClaudeCode,
208
+ format: 'jsonc',
209
+ readToken: readTokenFromHeaders
210
+ },
211
+ 'Codex CLI': {
212
+ buildServerConfig: buildCodexCliServerConfig,
213
+ configKey: 'mcp_servers',
214
+ detect: detectCodexCli,
215
+ format: 'toml',
216
+ readToken: readTokenFromHttpHeaders
34
217
  },
35
218
  Cursor: {
36
- buildServerConfig: defaultHttpConfig,
219
+ buildServerConfig: buildCursorServerConfig,
220
+ configKey: 'mcpServers',
221
+ detect: detectCursor,
222
+ format: 'jsonc',
223
+ readToken: readTokenFromHeaders
224
+ },
225
+ 'Gemini CLI': {
226
+ buildServerConfig: buildGeminiCliServerConfig,
227
+ configKey: 'mcpServers',
228
+ detect: detectGeminiCli,
229
+ format: 'jsonc',
230
+ readToken: readTokenFromHeaders
231
+ },
232
+ 'GitHub Copilot CLI': {
233
+ buildServerConfig: buildGitHubCopilotCliServerConfig,
37
234
  configKey: 'mcpServers',
38
- detect: async ()=>{
39
- const cursorDir = path.join(homeDir, '.cursor');
40
- return existsSync(cursorDir) ? path.join(cursorDir, 'mcp.json') : null;
41
- }
235
+ detect: detectGitHubCopilotCli,
236
+ format: 'jsonc',
237
+ readToken: readTokenFromHeaders
42
238
  },
43
239
  OpenCode: {
44
- buildServerConfig: (token)=>({
45
- headers: {
46
- Authorization: `Bearer ${token}`
47
- },
48
- type: 'remote',
49
- url: MCP_SERVER_URL
50
- }),
240
+ buildServerConfig: buildOpenCodeServerConfig,
51
241
  configKey: 'mcp',
52
- detect: async ()=>{
53
- try {
54
- await execa('opencode', [
55
- '--version'
56
- ], {
57
- stdio: 'pipe',
58
- timeout: 5000
59
- });
60
- return path.join(homeDir, '.config/opencode/opencode.json');
61
- } catch {
62
- return null;
63
- }
64
- }
242
+ detect: detectOpenCode,
243
+ format: 'jsonc',
244
+ readToken: readTokenFromHeaders
65
245
  },
66
246
  'VS Code': {
67
- buildServerConfig: defaultHttpConfig,
247
+ buildServerConfig: buildVSCodeServerConfig,
68
248
  configKey: 'servers',
69
- detect: async ()=>{
70
- let configDir = null;
71
- switch(process.platform){
72
- case 'darwin':
73
- {
74
- configDir = path.join(homeDir, 'Library/Application Support/Code/User');
75
- break;
76
- }
77
- case 'win32':
78
- {
79
- if (process.env.APPDATA) {
80
- configDir = path.join(process.env.APPDATA, 'Code/User');
81
- }
82
- break;
83
- }
84
- default:
85
- {
86
- configDir = path.join(homeDir, '.config/Code/User');
87
- }
88
- }
89
- return configDir && existsSync(configDir) ? path.join(configDir, 'mcp.json') : null;
90
- }
249
+ detect: detectVSCode,
250
+ format: 'jsonc',
251
+ readToken: readTokenFromHeaders
91
252
  },
92
253
  'VS Code Insiders': {
93
- buildServerConfig: defaultHttpConfig,
254
+ buildServerConfig: buildVSCodeInsidersServerConfig,
94
255
  configKey: 'servers',
95
- detect: async ()=>{
96
- let configDir = null;
97
- switch(process.platform){
98
- case 'darwin':
99
- {
100
- configDir = path.join(homeDir, 'Library/Application Support/Code - Insiders/User');
101
- break;
102
- }
103
- case 'win32':
104
- {
105
- if (process.env.APPDATA) {
106
- configDir = path.join(process.env.APPDATA, 'Code - Insiders/User');
107
- }
108
- break;
109
- }
110
- default:
111
- {
112
- configDir = path.join(homeDir, '.config/Code - Insiders/User');
113
- }
114
- }
115
- return configDir && existsSync(configDir) ? path.join(configDir, 'mcp.json') : null;
116
- }
256
+ detect: detectVSCodeInsiders,
257
+ format: 'jsonc',
258
+ readToken: readTokenFromHeaders
117
259
  },
118
260
  Zed: {
119
- buildServerConfig: (token)=>({
120
- headers: {
121
- Authorization: `Bearer ${token}`
122
- },
123
- settings: {},
124
- url: MCP_SERVER_URL
125
- }),
261
+ buildServerConfig: buildZedServerConfig,
126
262
  configKey: 'context_servers',
127
- detect: async ()=>{
128
- let configDir = null;
129
- switch(process.platform){
130
- case 'win32':
131
- {
132
- if (process.env.APPDATA) {
133
- configDir = path.join(process.env.APPDATA, 'Zed');
134
- }
135
- break;
136
- }
137
- default:
138
- {
139
- configDir = path.join(homeDir, '.config/zed');
140
- }
141
- }
142
- return configDir && existsSync(configDir) ? path.join(configDir, 'settings.json') : null;
143
- }
263
+ detect: detectZed,
264
+ format: 'jsonc',
265
+ readToken: readTokenFromHeaders
144
266
  }
145
267
  };
146
268
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/mcp/editorConfigs.ts"],"sourcesContent":["import {existsSync} from 'node:fs'\nimport os from 'node:os'\nimport path from 'node:path'\n\nimport {execa} from 'execa'\n\nimport {MCP_SERVER_URL} from '../../services/mcp.js'\n\ninterface EditorConfig {\n buildServerConfig: (token: string) => Record<string, unknown>\n configKey: string\n /** Returns the config file path if editor is detected, null otherwise */\n detect: () => Promise<string | null>\n}\n\nconst defaultHttpConfig = (token: string) => ({\n headers: {Authorization: `Bearer ${token}`},\n type: 'http',\n url: MCP_SERVER_URL,\n})\n\nconst homeDir = os.homedir()\n\n/**\n * Centralized editor configuration including detection logic.\n * To add a new editor: add an entry here - EditorName type is derived automatically.\n */\nexport const EDITOR_CONFIGS = {\n 'Claude Code': {\n buildServerConfig: defaultHttpConfig,\n configKey: 'mcpServers',\n detect: async () => {\n try {\n await execa('claude', ['--version'], {stdio: 'pipe', timeout: 5000})\n return path.join(homeDir, '.claude.json')\n } catch {\n return null\n }\n },\n },\n Cursor: {\n buildServerConfig: defaultHttpConfig,\n configKey: 'mcpServers',\n detect: async () => {\n const cursorDir = path.join(homeDir, '.cursor')\n return existsSync(cursorDir) ? path.join(cursorDir, 'mcp.json') : null\n },\n },\n OpenCode: {\n buildServerConfig: (token) => ({\n headers: {Authorization: `Bearer ${token}`},\n type: 'remote',\n url: MCP_SERVER_URL,\n }),\n configKey: 'mcp',\n detect: async () => {\n try {\n await execa('opencode', ['--version'], {stdio: 'pipe', timeout: 5000})\n return path.join(homeDir, '.config/opencode/opencode.json')\n } catch {\n return null\n }\n },\n },\n 'VS Code': {\n buildServerConfig: defaultHttpConfig,\n configKey: 'servers',\n detect: async () => {\n let configDir: string | null = null\n switch (process.platform) {\n case 'darwin': {\n configDir = path.join(homeDir, 'Library/Application Support/Code/User')\n break\n }\n case 'win32': {\n if (process.env.APPDATA) {\n configDir = path.join(process.env.APPDATA, 'Code/User')\n }\n break\n }\n default: {\n configDir = path.join(homeDir, '.config/Code/User')\n }\n }\n return configDir && existsSync(configDir) ? path.join(configDir, 'mcp.json') : null\n },\n },\n 'VS Code Insiders': {\n buildServerConfig: defaultHttpConfig,\n configKey: 'servers',\n detect: async () => {\n let configDir: string | null = null\n switch (process.platform) {\n case 'darwin': {\n configDir = path.join(homeDir, 'Library/Application Support/Code - Insiders/User')\n break\n }\n case 'win32': {\n if (process.env.APPDATA) {\n configDir = path.join(process.env.APPDATA, 'Code - Insiders/User')\n }\n break\n }\n default: {\n configDir = path.join(homeDir, '.config/Code - Insiders/User')\n }\n }\n return configDir && existsSync(configDir) ? path.join(configDir, 'mcp.json') : null\n },\n },\n Zed: {\n buildServerConfig: (token) => ({\n headers: {Authorization: `Bearer ${token}`},\n settings: {},\n url: MCP_SERVER_URL,\n }),\n configKey: 'context_servers',\n detect: async () => {\n let configDir: string | null = null\n switch (process.platform) {\n case 'win32': {\n if (process.env.APPDATA) {\n configDir = path.join(process.env.APPDATA, 'Zed')\n }\n break\n }\n default: {\n configDir = path.join(homeDir, '.config/zed')\n }\n }\n return configDir && existsSync(configDir) ? path.join(configDir, 'settings.json') : null\n },\n },\n} satisfies Record<string, EditorConfig>\n\n/** Derived from EDITOR_CONFIGS keys - add a new editor there and this updates automatically */\nexport type EditorName = keyof typeof EDITOR_CONFIGS\n"],"names":["existsSync","os","path","execa","MCP_SERVER_URL","defaultHttpConfig","token","headers","Authorization","type","url","homeDir","homedir","EDITOR_CONFIGS","buildServerConfig","configKey","detect","stdio","timeout","join","Cursor","cursorDir","OpenCode","configDir","process","platform","env","APPDATA","Zed","settings"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/actions/mcp/editorConfigs.ts"],"sourcesContent":["import {existsSync} from 'node:fs'\nimport os from 'node:os'\nimport path from 'node:path'\n\nimport {execa} from 'execa'\n\nimport {MCP_SERVER_URL} from '../../services/mcp.js'\n\ninterface EditorConfig {\n buildServerConfig: (token: string) => Record<string, unknown>\n configKey: string\n /** Returns the config file path if editor is detected, null otherwise */\n detect: () => Promise<string | null>\n format: 'jsonc' | 'toml'\n /** Extracts the auth token from a parsed Sanity server config block */\n readToken: (serverConfig: Record<string, unknown>) => string | undefined\n}\n\nconst defaultHttpConfig = (token: string) => ({\n headers: {Authorization: `Bearer ${token}`},\n type: 'http',\n url: MCP_SERVER_URL,\n})\n\nconst homeDir = os.homedir()\n\n// -- Detect functions --\n\nasync function detectClaudeCode(): Promise<string | null> {\n try {\n await execa('claude', ['--version'], {stdio: 'pipe', timeout: 5000})\n return path.join(homeDir, '.claude.json')\n } catch {\n return null\n }\n}\n\nasync function detectCodexCli(): Promise<string | null> {\n try {\n await execa('codex', ['--version'], {stdio: 'pipe', timeout: 5000})\n const codexHome = process.env.CODEX_HOME || path.join(homeDir, '.codex')\n return path.join(codexHome, 'config.toml')\n } catch {\n return null\n }\n}\n\nasync function detectCursor(): Promise<string | null> {\n const cursorDir = path.join(homeDir, '.cursor')\n return existsSync(cursorDir) ? path.join(cursorDir, 'mcp.json') : null\n}\n\nasync function detectGeminiCli(): Promise<string | null> {\n const geminiDir = path.join(homeDir, '.gemini')\n return existsSync(geminiDir) ? path.join(geminiDir, 'settings.json') : null\n}\n\nasync function detectGitHubCopilotCli(): Promise<string | null> {\n const copilotDir =\n process.platform === 'linux' && process.env.XDG_CONFIG_HOME\n ? path.join(process.env.XDG_CONFIG_HOME, 'copilot')\n : path.join(homeDir, '.copilot')\n return existsSync(copilotDir) ? path.join(copilotDir, 'mcp-config.json') : null\n}\n\nasync function detectOpenCode(): Promise<string | null> {\n try {\n await execa('opencode', ['--version'], {stdio: 'pipe', timeout: 5000})\n return path.join(homeDir, '.config/opencode/opencode.json')\n } catch {\n return null\n }\n}\n\nasync function detectVSCode(): Promise<string | null> {\n let configDir: string | null = null\n switch (process.platform) {\n case 'darwin': {\n configDir = path.join(homeDir, 'Library/Application Support/Code/User')\n break\n }\n case 'win32': {\n if (process.env.APPDATA) {\n configDir = path.join(process.env.APPDATA, 'Code/User')\n }\n break\n }\n default: {\n configDir = path.join(homeDir, '.config/Code/User')\n }\n }\n return configDir && existsSync(configDir) ? path.join(configDir, 'mcp.json') : null\n}\n\nasync function detectVSCodeInsiders(): Promise<string | null> {\n let configDir: string | null = null\n switch (process.platform) {\n case 'darwin': {\n configDir = path.join(homeDir, 'Library/Application Support/Code - Insiders/User')\n break\n }\n case 'win32': {\n if (process.env.APPDATA) {\n configDir = path.join(process.env.APPDATA, 'Code - Insiders/User')\n }\n break\n }\n default: {\n configDir = path.join(homeDir, '.config/Code - Insiders/User')\n }\n }\n return configDir && existsSync(configDir) ? path.join(configDir, 'mcp.json') : null\n}\n\nasync function detectZed(): Promise<string | null> {\n let configDir: string | null = null\n switch (process.platform) {\n case 'win32': {\n if (process.env.APPDATA) {\n configDir = path.join(process.env.APPDATA, 'Zed')\n }\n break\n }\n default: {\n configDir = path.join(homeDir, '.config/zed')\n }\n }\n return configDir && existsSync(configDir) ? path.join(configDir, 'settings.json') : null\n}\n\n// -- Read token helpers --\n\n/**\n * Extract a Bearer token from a headers-like object.\n * Looks for `Authorization: \"Bearer <token>\"` and returns the token portion.\n */\nfunction extractBearerToken(headers: unknown): string | undefined {\n if (typeof headers !== 'object' || headers === null) return undefined\n const auth = (headers as Record<string, unknown>).Authorization\n if (typeof auth !== 'string') return undefined\n const match = auth.match(/^Bearer\\s+(.+)$/)\n return match?.[1]\n}\n\nfunction readTokenFromHeaders(serverConfig: Record<string, unknown>): string | undefined {\n return extractBearerToken(serverConfig.headers)\n}\n\nfunction readTokenFromHttpHeaders(serverConfig: Record<string, unknown>): string | undefined {\n return extractBearerToken(serverConfig.http_headers)\n}\n\n// -- Build server config functions --\n\nfunction buildClaudeCodeServerConfig(token: string): Record<string, unknown> {\n return defaultHttpConfig(token)\n}\n\nfunction buildCodexCliServerConfig(token: string): Record<string, unknown> {\n return {\n http_headers: {Authorization: `Bearer ${token}`},\n type: 'http',\n url: MCP_SERVER_URL,\n }\n}\n\nfunction buildCursorServerConfig(token: string): Record<string, unknown> {\n return defaultHttpConfig(token)\n}\n\nfunction buildGeminiCliServerConfig(token: string): Record<string, unknown> {\n return defaultHttpConfig(token)\n}\n\nfunction buildGitHubCopilotCliServerConfig(token: string): Record<string, unknown> {\n return {\n headers: {Authorization: `Bearer ${token}`},\n tools: ['*'],\n type: 'http',\n url: MCP_SERVER_URL,\n }\n}\n\nfunction buildOpenCodeServerConfig(token: string): Record<string, unknown> {\n return {\n headers: {Authorization: `Bearer ${token}`},\n type: 'remote',\n url: MCP_SERVER_URL,\n }\n}\n\nfunction buildVSCodeServerConfig(token: string): Record<string, unknown> {\n return defaultHttpConfig(token)\n}\n\nfunction buildVSCodeInsidersServerConfig(token: string): Record<string, unknown> {\n return defaultHttpConfig(token)\n}\n\nfunction buildZedServerConfig(token: string): Record<string, unknown> {\n return {\n headers: {Authorization: `Bearer ${token}`},\n settings: {},\n url: MCP_SERVER_URL,\n }\n}\n\n/**\n * Centralized editor configuration including detection logic.\n * To add a new editor: add an entry here - EditorName type is derived automatically.\n */\nexport const EDITOR_CONFIGS = {\n 'Claude Code': {\n buildServerConfig: buildClaudeCodeServerConfig,\n configKey: 'mcpServers',\n detect: detectClaudeCode,\n format: 'jsonc',\n readToken: readTokenFromHeaders,\n },\n 'Codex CLI': {\n buildServerConfig: buildCodexCliServerConfig,\n configKey: 'mcp_servers',\n detect: detectCodexCli,\n format: 'toml',\n readToken: readTokenFromHttpHeaders,\n },\n Cursor: {\n buildServerConfig: buildCursorServerConfig,\n configKey: 'mcpServers',\n detect: detectCursor,\n format: 'jsonc',\n readToken: readTokenFromHeaders,\n },\n 'Gemini CLI': {\n buildServerConfig: buildGeminiCliServerConfig,\n configKey: 'mcpServers',\n detect: detectGeminiCli,\n format: 'jsonc',\n readToken: readTokenFromHeaders,\n },\n 'GitHub Copilot CLI': {\n buildServerConfig: buildGitHubCopilotCliServerConfig,\n configKey: 'mcpServers',\n detect: detectGitHubCopilotCli,\n format: 'jsonc',\n readToken: readTokenFromHeaders,\n },\n OpenCode: {\n buildServerConfig: buildOpenCodeServerConfig,\n configKey: 'mcp',\n detect: detectOpenCode,\n format: 'jsonc',\n readToken: readTokenFromHeaders,\n },\n 'VS Code': {\n buildServerConfig: buildVSCodeServerConfig,\n configKey: 'servers',\n detect: detectVSCode,\n format: 'jsonc',\n readToken: readTokenFromHeaders,\n },\n 'VS Code Insiders': {\n buildServerConfig: buildVSCodeInsidersServerConfig,\n configKey: 'servers',\n detect: detectVSCodeInsiders,\n format: 'jsonc',\n readToken: readTokenFromHeaders,\n },\n Zed: {\n buildServerConfig: buildZedServerConfig,\n configKey: 'context_servers',\n detect: detectZed,\n format: 'jsonc',\n readToken: readTokenFromHeaders,\n },\n} satisfies Record<string, EditorConfig>\n\n/** Derived from EDITOR_CONFIGS keys - add a new editor there and this updates automatically */\nexport type EditorName = keyof typeof EDITOR_CONFIGS\n"],"names":["existsSync","os","path","execa","MCP_SERVER_URL","defaultHttpConfig","token","headers","Authorization","type","url","homeDir","homedir","detectClaudeCode","stdio","timeout","join","detectCodexCli","codexHome","process","env","CODEX_HOME","detectCursor","cursorDir","detectGeminiCli","geminiDir","detectGitHubCopilotCli","copilotDir","platform","XDG_CONFIG_HOME","detectOpenCode","detectVSCode","configDir","APPDATA","detectVSCodeInsiders","detectZed","extractBearerToken","undefined","auth","match","readTokenFromHeaders","serverConfig","readTokenFromHttpHeaders","http_headers","buildClaudeCodeServerConfig","buildCodexCliServerConfig","buildCursorServerConfig","buildGeminiCliServerConfig","buildGitHubCopilotCliServerConfig","tools","buildOpenCodeServerConfig","buildVSCodeServerConfig","buildVSCodeInsidersServerConfig","buildZedServerConfig","settings","EDITOR_CONFIGS","buildServerConfig","configKey","detect","format","readToken","Cursor","OpenCode","Zed"],"mappings":"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"}