@commandable/integration-data 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (335) hide show
  1. package/dist/credentials-index.d.ts +30 -0
  2. package/dist/credentials-index.d.ts.map +1 -0
  3. package/dist/credentials-index.js +292 -0
  4. package/dist/credentials-index.js.map +1 -0
  5. package/dist/index.d.ts +3 -0
  6. package/dist/index.d.ts.map +1 -0
  7. package/dist/index.js +2 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/loader.d.ts +69 -0
  10. package/dist/loader.d.ts.map +1 -0
  11. package/dist/loader.js +164 -0
  12. package/dist/loader.js.map +1 -0
  13. package/integrations/README.md +52 -0
  14. package/integrations/airtable/__tests__/get_handlers.test.ts +137 -0
  15. package/integrations/airtable/__tests__/usage_parity.test.ts +35 -0
  16. package/integrations/airtable/__tests__/write_and_admin_handlers.test.ts +113 -0
  17. package/integrations/airtable/credentials.json +20 -0
  18. package/integrations/airtable/credentials_hint.md +4 -0
  19. package/integrations/airtable/handlers/create_record.js +12 -0
  20. package/integrations/airtable/handlers/delete_record.js +7 -0
  21. package/integrations/airtable/handlers/get_record.js +4 -0
  22. package/integrations/airtable/handlers/get_table_schema.js +6 -0
  23. package/integrations/airtable/handlers/list_bases.js +4 -0
  24. package/integrations/airtable/handlers/list_records.js +25 -0
  25. package/integrations/airtable/handlers/list_table_fields.js +6 -0
  26. package/integrations/airtable/handlers/list_tables.js +4 -0
  27. package/integrations/airtable/handlers/list_views.js +6 -0
  28. package/integrations/airtable/handlers/search_records.js +6 -0
  29. package/integrations/airtable/handlers/update_record.js +11 -0
  30. package/integrations/airtable/manifest.json +83 -0
  31. package/integrations/airtable/schemas/create_record.json +12 -0
  32. package/integrations/airtable/schemas/delete_record.json +11 -0
  33. package/integrations/airtable/schemas/empty.json +6 -0
  34. package/integrations/airtable/schemas/get_record.json +11 -0
  35. package/integrations/airtable/schemas/id_base.json +9 -0
  36. package/integrations/airtable/schemas/id_base_table.json +10 -0
  37. package/integrations/airtable/schemas/list_records.json +26 -0
  38. package/integrations/airtable/schemas/search_records.json +12 -0
  39. package/integrations/airtable/schemas/update_record.json +13 -0
  40. package/integrations/github/__tests__/get_handlers.test.ts +117 -0
  41. package/integrations/github/__tests__/usage_parity.test.ts +34 -0
  42. package/integrations/github/__tests__/write_handlers.test.ts +311 -0
  43. package/integrations/github/credentials.json +20 -0
  44. package/integrations/github/credentials_hint.md +7 -0
  45. package/integrations/github/handlers/add_labels_to_issue.js +12 -0
  46. package/integrations/github/handlers/close_issue.js +5 -0
  47. package/integrations/github/handlers/comment_on_issue.js +5 -0
  48. package/integrations/github/handlers/create_branch.js +33 -0
  49. package/integrations/github/handlers/create_commit.js +91 -0
  50. package/integrations/github/handlers/create_issue.js +10 -0
  51. package/integrations/github/handlers/create_or_update_file.js +21 -0
  52. package/integrations/github/handlers/create_pull_request.js +16 -0
  53. package/integrations/github/handlers/create_repo.js +11 -0
  54. package/integrations/github/handlers/delete_repo.js +6 -0
  55. package/integrations/github/handlers/get_issue.js +4 -0
  56. package/integrations/github/handlers/get_repo.js +4 -0
  57. package/integrations/github/handlers/list_branches.js +4 -0
  58. package/integrations/github/handlers/list_commits.js +12 -0
  59. package/integrations/github/handlers/list_issues.js +12 -0
  60. package/integrations/github/handlers/list_pull_requests.js +8 -0
  61. package/integrations/github/handlers/list_repos_install.js +4 -0
  62. package/integrations/github/handlers/list_repos_user.js +4 -0
  63. package/integrations/github/handlers/merge_pull_request.js +14 -0
  64. package/integrations/github/handlers/update_issue.js +15 -0
  65. package/integrations/github/manifest.json +26 -0
  66. package/integrations/github/schemas/add_labels_to_issue.json +12 -0
  67. package/integrations/github/schemas/close_issue.json +10 -0
  68. package/integrations/github/schemas/comment_on_issue.json +11 -0
  69. package/integrations/github/schemas/create_branch.json +12 -0
  70. package/integrations/github/schemas/create_commit.json +25 -0
  71. package/integrations/github/schemas/create_issue.json +13 -0
  72. package/integrations/github/schemas/create_or_update_file.json +15 -0
  73. package/integrations/github/schemas/create_pull_request.json +15 -0
  74. package/integrations/github/schemas/create_repo.json +12 -0
  75. package/integrations/github/schemas/delete_repo.json +10 -0
  76. package/integrations/github/schemas/empty.json +5 -0
  77. package/integrations/github/schemas/get_issue.json +10 -0
  78. package/integrations/github/schemas/get_repo.json +9 -0
  79. package/integrations/github/schemas/list_commits.json +12 -0
  80. package/integrations/github/schemas/list_issues.json +12 -0
  81. package/integrations/github/schemas/list_pull_requests.json +10 -0
  82. package/integrations/github/schemas/merge_pull_request.json +14 -0
  83. package/integrations/github/schemas/owner_repo.json +9 -0
  84. package/integrations/github/schemas/update_issue.json +15 -0
  85. package/integrations/google-calendar/__tests__/get_handlers.test.ts +112 -0
  86. package/integrations/google-calendar/__tests__/usage_parity.test.ts +34 -0
  87. package/integrations/google-calendar/__tests__/write_and_admin_handlers.test.ts +161 -0
  88. package/integrations/google-calendar/credentials.json +36 -0
  89. package/integrations/google-calendar/credentials_hint.md +9 -0
  90. package/integrations/google-calendar/handlers/create_event.js +6 -0
  91. package/integrations/google-calendar/handlers/delete_acl.js +6 -0
  92. package/integrations/google-calendar/handlers/delete_event.js +7 -0
  93. package/integrations/google-calendar/handlers/freebusy_query.js +4 -0
  94. package/integrations/google-calendar/handlers/get_acl.js +5 -0
  95. package/integrations/google-calendar/handlers/get_calendar.js +4 -0
  96. package/integrations/google-calendar/handlers/get_event.js +5 -0
  97. package/integrations/google-calendar/handlers/insert_acl.js +6 -0
  98. package/integrations/google-calendar/handlers/list_acl.js +5 -0
  99. package/integrations/google-calendar/handlers/list_calendars.js +4 -0
  100. package/integrations/google-calendar/handlers/list_colors.js +4 -0
  101. package/integrations/google-calendar/handlers/list_events.js +21 -0
  102. package/integrations/google-calendar/handlers/list_settings.js +4 -0
  103. package/integrations/google-calendar/handlers/move_event.js +6 -0
  104. package/integrations/google-calendar/handlers/patch_event.js +5 -0
  105. package/integrations/google-calendar/handlers/quick_add.js +6 -0
  106. package/integrations/google-calendar/handlers/update_acl.js +7 -0
  107. package/integrations/google-calendar/handlers/update_event.js +5 -0
  108. package/integrations/google-calendar/manifest.json +26 -0
  109. package/integrations/google-calendar/schemas/create_event.json +34 -0
  110. package/integrations/google-calendar/schemas/delete_acl.json +9 -0
  111. package/integrations/google-calendar/schemas/empty.json +1 -0
  112. package/integrations/google-calendar/schemas/freebusy_query.json +13 -0
  113. package/integrations/google-calendar/schemas/get_acl.json +9 -0
  114. package/integrations/google-calendar/schemas/id_calendar.json +8 -0
  115. package/integrations/google-calendar/schemas/id_calendar_event.json +9 -0
  116. package/integrations/google-calendar/schemas/insert_acl.json +18 -0
  117. package/integrations/google-calendar/schemas/list_events.json +15 -0
  118. package/integrations/google-calendar/schemas/move_event.json +10 -0
  119. package/integrations/google-calendar/schemas/patch_event.json +10 -0
  120. package/integrations/google-calendar/schemas/quick_add.json +9 -0
  121. package/integrations/google-calendar/schemas/update_acl.json +10 -0
  122. package/integrations/google-calendar/schemas/update_event.json +10 -0
  123. package/integrations/google-docs/__tests__/get_handlers.test.ts +72 -0
  124. package/integrations/google-docs/__tests__/usage_parity.test.ts +34 -0
  125. package/integrations/google-docs/__tests__/write_handlers.test.ts +249 -0
  126. package/integrations/google-docs/credentials.json +36 -0
  127. package/integrations/google-docs/credentials_hint.md +9 -0
  128. package/integrations/google-docs/handlers/append_text.js +12 -0
  129. package/integrations/google-docs/handlers/batch_update.js +13 -0
  130. package/integrations/google-docs/handlers/create_document.js +9 -0
  131. package/integrations/google-docs/handlers/delete_first_match.js +50 -0
  132. package/integrations/google-docs/handlers/get_document.js +12 -0
  133. package/integrations/google-docs/handlers/get_document_structured.js +6 -0
  134. package/integrations/google-docs/handlers/get_document_text.js +17 -0
  135. package/integrations/google-docs/handlers/insert_inline_image_after_first_match.js +41 -0
  136. package/integrations/google-docs/handlers/insert_page_break_after_first_match.js +49 -0
  137. package/integrations/google-docs/handlers/insert_table_after_first_match.js +49 -0
  138. package/integrations/google-docs/handlers/insert_text_after_first_match.js +51 -0
  139. package/integrations/google-docs/handlers/replace_all_text.js +8 -0
  140. package/integrations/google-docs/handlers/style_first_match.js +42 -0
  141. package/integrations/google-docs/handlers/update_document_style.js +8 -0
  142. package/integrations/google-docs/handlers/update_paragraph_style_for_first_match.js +48 -0
  143. package/integrations/google-docs/manifest.json +58 -0
  144. package/integrations/google-docs/schemas/append_text.json +10 -0
  145. package/integrations/google-docs/schemas/apply_text_style.json +13 -0
  146. package/integrations/google-docs/schemas/batch_update.json +16 -0
  147. package/integrations/google-docs/schemas/create_document.json +8 -0
  148. package/integrations/google-docs/schemas/delete_content_range.json +11 -0
  149. package/integrations/google-docs/schemas/delete_first_match.json +10 -0
  150. package/integrations/google-docs/schemas/get_document.json +11 -0
  151. package/integrations/google-docs/schemas/get_document_structured.json +9 -0
  152. package/integrations/google-docs/schemas/get_document_text.json +9 -0
  153. package/integrations/google-docs/schemas/insert_inline_image.json +12 -0
  154. package/integrations/google-docs/schemas/insert_inline_image_after_first_match.json +13 -0
  155. package/integrations/google-docs/schemas/insert_page_break.json +10 -0
  156. package/integrations/google-docs/schemas/insert_page_break_after_first_match.json +11 -0
  157. package/integrations/google-docs/schemas/insert_table.json +12 -0
  158. package/integrations/google-docs/schemas/insert_table_after_first_match.json +13 -0
  159. package/integrations/google-docs/schemas/insert_text_after_first_match.json +12 -0
  160. package/integrations/google-docs/schemas/insert_text_at.json +11 -0
  161. package/integrations/google-docs/schemas/replace_all_text.json +12 -0
  162. package/integrations/google-docs/schemas/style_first_match.json +12 -0
  163. package/integrations/google-docs/schemas/update_document_style.json +11 -0
  164. package/integrations/google-docs/schemas/update_paragraph_style.json +13 -0
  165. package/integrations/google-docs/schemas/update_paragraph_style_for_first_match.json +12 -0
  166. package/integrations/google-sheet/__tests__/get_handlers.test.ts +129 -0
  167. package/integrations/google-sheet/__tests__/usage_parity.test.ts +35 -0
  168. package/integrations/google-sheet/__tests__/write_handlers.test.ts +171 -0
  169. package/integrations/google-sheet/credentials.json +36 -0
  170. package/integrations/google-sheet/credentials_hint.md +9 -0
  171. package/integrations/google-sheet/handlers/append_values.js +18 -0
  172. package/integrations/google-sheet/handlers/batch_clear_values.js +6 -0
  173. package/integrations/google-sheet/handlers/batch_clear_values_by_data_filter.js +6 -0
  174. package/integrations/google-sheet/handlers/batch_get_values.js +16 -0
  175. package/integrations/google-sheet/handlers/batch_update.js +14 -0
  176. package/integrations/google-sheet/handlers/batch_update_values.js +16 -0
  177. package/integrations/google-sheet/handlers/batch_update_values_by_data_filter.js +16 -0
  178. package/integrations/google-sheet/handlers/clear_values.js +6 -0
  179. package/integrations/google-sheet/handlers/copy_to_spreadsheet.js +6 -0
  180. package/integrations/google-sheet/handlers/create_spreadsheet.js +5 -0
  181. package/integrations/google-sheet/handlers/get_developer_metadata.js +6 -0
  182. package/integrations/google-sheet/handlers/get_spreadsheet.js +12 -0
  183. package/integrations/google-sheet/handlers/get_spreadsheet_by_data_filter.js +10 -0
  184. package/integrations/google-sheet/handlers/get_values.js +14 -0
  185. package/integrations/google-sheet/handlers/get_values_by_data_filter.js +14 -0
  186. package/integrations/google-sheet/handlers/search_developer_metadata.js +7 -0
  187. package/integrations/google-sheet/handlers/update_values.js +16 -0
  188. package/integrations/google-sheet/manifest.json +125 -0
  189. package/integrations/google-sheet/schemas/append_values.json +16 -0
  190. package/integrations/google-sheet/schemas/batch_clear_values.json +10 -0
  191. package/integrations/google-sheet/schemas/batch_clear_values_by_data_filter.json +10 -0
  192. package/integrations/google-sheet/schemas/batch_get_values.json +13 -0
  193. package/integrations/google-sheet/schemas/batch_update.json +13 -0
  194. package/integrations/google-sheet/schemas/batch_update_values.json +25 -0
  195. package/integrations/google-sheet/schemas/batch_update_values_by_data_filter.json +25 -0
  196. package/integrations/google-sheet/schemas/clear_values.json +10 -0
  197. package/integrations/google-sheet/schemas/copy_to_spreadsheet.json +11 -0
  198. package/integrations/google-sheet/schemas/create_spreadsheet.json +11 -0
  199. package/integrations/google-sheet/schemas/get_developer_metadata.json +10 -0
  200. package/integrations/google-sheet/schemas/get_spreadsheet.json +15 -0
  201. package/integrations/google-sheet/schemas/get_spreadsheet_by_data_filter.json +11 -0
  202. package/integrations/google-sheet/schemas/get_values.json +13 -0
  203. package/integrations/google-sheet/schemas/get_values_by_data_filter.json +17 -0
  204. package/integrations/google-sheet/schemas/search_developer_metadata.json +14 -0
  205. package/integrations/google-sheet/schemas/update_values.json +15 -0
  206. package/integrations/google-slides/__tests__/get_handlers.test.ts +69 -0
  207. package/integrations/google-slides/__tests__/usage_parity.test.ts +34 -0
  208. package/integrations/google-slides/__tests__/write_handlers.test.ts +125 -0
  209. package/integrations/google-slides/credentials.json +36 -0
  210. package/integrations/google-slides/credentials_hint.md +9 -0
  211. package/integrations/google-slides/handlers/append_text_to_title_of_first_slide.js +17 -0
  212. package/integrations/google-slides/handlers/batch_update.js +15 -0
  213. package/integrations/google-slides/handlers/create_presentation.js +8 -0
  214. package/integrations/google-slides/handlers/create_slide_after_first_match.js +20 -0
  215. package/integrations/google-slides/handlers/get_page_thumbnail.js +12 -0
  216. package/integrations/google-slides/handlers/get_presentation.js +6 -0
  217. package/integrations/google-slides/handlers/insert_image_after_first_match.js +19 -0
  218. package/integrations/google-slides/handlers/insert_shape_after_first_match.js +21 -0
  219. package/integrations/google-slides/handlers/replace_text_first_match.js +9 -0
  220. package/integrations/google-slides/handlers/set_background_color_for_slide_index.js +15 -0
  221. package/integrations/google-slides/handlers/style_text_first_match.js +48 -0
  222. package/integrations/google-slides/manifest.json +41 -0
  223. package/integrations/google-slides/schemas/append_text_to_title_of_first_slide.json +11 -0
  224. package/integrations/google-slides/schemas/batch_update.json +13 -0
  225. package/integrations/google-slides/schemas/create_presentation.json +8 -0
  226. package/integrations/google-slides/schemas/create_slide_after_first_match.json +11 -0
  227. package/integrations/google-slides/schemas/get_page_thumbnail.json +12 -0
  228. package/integrations/google-slides/schemas/get_presentation.json +9 -0
  229. package/integrations/google-slides/schemas/insert_image_after_first_match.json +13 -0
  230. package/integrations/google-slides/schemas/insert_shape_after_first_match.json +13 -0
  231. package/integrations/google-slides/schemas/replace_text_first_match.json +12 -0
  232. package/integrations/google-slides/schemas/set_background_color_for_slide_index.json +11 -0
  233. package/integrations/google-slides/schemas/style_text_first_match.json +12 -0
  234. package/integrations/new_integration_prompt.md +41 -0
  235. package/integrations/notion/__tests__/get_handlers.test.ts +153 -0
  236. package/integrations/notion/__tests__/usage_parity.test.ts +34 -0
  237. package/integrations/notion/__tests__/write_and_admin_handlers.test.ts +190 -0
  238. package/integrations/notion/credentials.json +21 -0
  239. package/integrations/notion/credentials_hint.md +5 -0
  240. package/integrations/notion/handlers/append_block_children.js +7 -0
  241. package/integrations/notion/handlers/create_comment.js +10 -0
  242. package/integrations/notion/handlers/create_database.js +11 -0
  243. package/integrations/notion/handlers/create_page.js +13 -0
  244. package/integrations/notion/handlers/delete_block.js +8 -0
  245. package/integrations/notion/handlers/get_me.js +4 -0
  246. package/integrations/notion/handlers/list_block_children.js +10 -0
  247. package/integrations/notion/handlers/list_comments.js +14 -0
  248. package/integrations/notion/handlers/list_users.js +10 -0
  249. package/integrations/notion/handlers/query_database.js +10 -0
  250. package/integrations/notion/handlers/retrieve_block.js +4 -0
  251. package/integrations/notion/handlers/retrieve_database.js +4 -0
  252. package/integrations/notion/handlers/retrieve_page.js +4 -0
  253. package/integrations/notion/handlers/retrieve_page_property_item.js +10 -0
  254. package/integrations/notion/handlers/retrieve_user.js +4 -0
  255. package/integrations/notion/handlers/search.js +11 -0
  256. package/integrations/notion/handlers/update_block.js +7 -0
  257. package/integrations/notion/handlers/update_database.js +10 -0
  258. package/integrations/notion/handlers/update_page_properties.js +10 -0
  259. package/integrations/notion/manifest.json +139 -0
  260. package/integrations/notion/prompt.md +26 -0
  261. package/integrations/notion/schemas/append_block_children.json +10 -0
  262. package/integrations/notion/schemas/create_comment.json +18 -0
  263. package/integrations/notion/schemas/create_database.json +18 -0
  264. package/integrations/notion/schemas/create_page.json +22 -0
  265. package/integrations/notion/schemas/delete_block.json +9 -0
  266. package/integrations/notion/schemas/empty.json +6 -0
  267. package/integrations/notion/schemas/id_block.json +9 -0
  268. package/integrations/notion/schemas/id_database.json +9 -0
  269. package/integrations/notion/schemas/id_page.json +9 -0
  270. package/integrations/notion/schemas/id_user.json +9 -0
  271. package/integrations/notion/schemas/list_block_children.json +11 -0
  272. package/integrations/notion/schemas/list_comments.json +15 -0
  273. package/integrations/notion/schemas/list_users.json +9 -0
  274. package/integrations/notion/schemas/query_database.json +13 -0
  275. package/integrations/notion/schemas/retrieve_page_property_item.json +12 -0
  276. package/integrations/notion/schemas/search.json +27 -0
  277. package/integrations/notion/schemas/update_block.json +10 -0
  278. package/integrations/notion/schemas/update_database.json +13 -0
  279. package/integrations/notion/schemas/update_page_properties.json +13 -0
  280. package/integrations/trello/__tests__/get_handlers.test.ts +240 -0
  281. package/integrations/trello/__tests__/usage_parity.test.ts +34 -0
  282. package/integrations/trello/__tests__/write_and_admin_handlers.test.ts +189 -0
  283. package/integrations/trello/credentials.json +26 -0
  284. package/integrations/trello/credentials_hint.md +4 -0
  285. package/integrations/trello/handlers/add_checklist_to_card.js +5 -0
  286. package/integrations/trello/handlers/add_member_to_card.js +5 -0
  287. package/integrations/trello/handlers/archive_list.js +5 -0
  288. package/integrations/trello/handlers/create_card.js +13 -0
  289. package/integrations/trello/handlers/create_list.js +7 -0
  290. package/integrations/trello/handlers/delete_card.js +9 -0
  291. package/integrations/trello/handlers/get_board.js +4 -0
  292. package/integrations/trello/handlers/get_board_cards.js +4 -0
  293. package/integrations/trello/handlers/get_board_custom_fields.js +4 -0
  294. package/integrations/trello/handlers/get_board_labels.js +4 -0
  295. package/integrations/trello/handlers/get_board_lists.js +4 -0
  296. package/integrations/trello/handlers/get_board_members.js +4 -0
  297. package/integrations/trello/handlers/get_board_memberships.js +4 -0
  298. package/integrations/trello/handlers/get_card.js +4 -0
  299. package/integrations/trello/handlers/get_card_actions.js +4 -0
  300. package/integrations/trello/handlers/get_card_attachments.js +4 -0
  301. package/integrations/trello/handlers/get_card_checklists.js +4 -0
  302. package/integrations/trello/handlers/get_card_custom_field_items.js +4 -0
  303. package/integrations/trello/handlers/get_card_members.js +4 -0
  304. package/integrations/trello/handlers/get_list.js +4 -0
  305. package/integrations/trello/handlers/get_list_cards.js +4 -0
  306. package/integrations/trello/handlers/get_member.js +4 -0
  307. package/integrations/trello/handlers/get_member_boards.js +4 -0
  308. package/integrations/trello/handlers/get_member_organizations.js +4 -0
  309. package/integrations/trello/handlers/get_organization.js +4 -0
  310. package/integrations/trello/handlers/get_organization_boards.js +4 -0
  311. package/integrations/trello/handlers/move_card_to_list.js +5 -0
  312. package/integrations/trello/handlers/remove_member_from_card.js +9 -0
  313. package/integrations/trello/handlers/search.js +5 -0
  314. package/integrations/trello/handlers/update_card.js +19 -0
  315. package/integrations/trello/handlers/update_list.js +11 -0
  316. package/integrations/trello/manifest.json +231 -0
  317. package/integrations/trello/schemas/add_checklist_to_card.json +10 -0
  318. package/integrations/trello/schemas/add_member_to_card.json +10 -0
  319. package/integrations/trello/schemas/archive_list.json +9 -0
  320. package/integrations/trello/schemas/create_card.json +13 -0
  321. package/integrations/trello/schemas/create_list.json +11 -0
  322. package/integrations/trello/schemas/delete_card.json +9 -0
  323. package/integrations/trello/schemas/display_trello_cards.json +45 -0
  324. package/integrations/trello/schemas/empty.json +5 -0
  325. package/integrations/trello/schemas/get_member.json +5 -0
  326. package/integrations/trello/schemas/id_board.json +8 -0
  327. package/integrations/trello/schemas/id_card.json +8 -0
  328. package/integrations/trello/schemas/id_list.json +8 -0
  329. package/integrations/trello/schemas/id_org.json +8 -0
  330. package/integrations/trello/schemas/move_card_to_list.json +10 -0
  331. package/integrations/trello/schemas/remove_member_from_card.json +10 -0
  332. package/integrations/trello/schemas/search.json +8 -0
  333. package/integrations/trello/schemas/update_card.json +16 -0
  334. package/integrations/trello/schemas/update_list.json +12 -0
  335. package/package.json +45 -0
@@ -0,0 +1,16 @@
1
+ async (input) => {
2
+ const body = {
3
+ title: input.title,
4
+ body: input.body,
5
+ head: input.head,
6
+ base: input.base,
7
+ draft: input.draft,
8
+ }
9
+
10
+ const res = await integration.fetch(`/repos/${input.owner}/${input.repo}/pulls`, {
11
+ method: 'POST',
12
+ body
13
+ })
14
+ return await res.json()
15
+ }
16
+
@@ -0,0 +1,11 @@
1
+ async (input) => {
2
+ const body = {
3
+ name: input.name,
4
+ description: input.description,
5
+ private: input.private,
6
+ auto_init: input.auto_init,
7
+ }
8
+ const res = await integration.fetch('/user/repos', { method: 'POST', body })
9
+ return await res.json()
10
+ }
11
+
@@ -0,0 +1,6 @@
1
+ async (input) => {
2
+ const res = await integration.fetch(`/repos/${input.owner}/${input.repo}`, { method: 'DELETE' })
3
+ // DELETE returns 204 No Content on success
4
+ return { success: res.status === 204, status: res.status }
5
+ }
6
+
@@ -0,0 +1,4 @@
1
+ async (input) => {
2
+ const res = await integration.fetch(`/repos/${input.owner}/${input.repo}/issues/${input.issue_number}`)
3
+ return await res.json()
4
+ }
@@ -0,0 +1,4 @@
1
+ async (input) => {
2
+ const res = await integration.fetch(`/repos/${input.owner}/${input.repo}`)
3
+ return await res.json()
4
+ }
@@ -0,0 +1,4 @@
1
+ async (input) => {
2
+ const res = await integration.fetch(`/repos/${input.owner}/${input.repo}/branches`)
3
+ return await res.json()
4
+ }
@@ -0,0 +1,12 @@
1
+ async (input) => {
2
+ const params = new URLSearchParams()
3
+ if (input.sha)
4
+ params.set('sha', input.sha)
5
+ if (typeof input.path === 'string' && input.path.length > 0)
6
+ params.set('path', input.path)
7
+ if (input.author)
8
+ params.set('author', input.author)
9
+ const query = params.toString() ? `?${params.toString()}` : ''
10
+ const res = await integration.fetch(`/repos/${input.owner}/${input.repo}/commits${query}`)
11
+ return await res.json()
12
+ }
@@ -0,0 +1,12 @@
1
+ async (input) => {
2
+ const params = new URLSearchParams()
3
+ if (input.state)
4
+ params.set('state', input.state)
5
+ if (input.labels)
6
+ params.set('labels', input.labels)
7
+ if (input.assignee)
8
+ params.set('assignee', input.assignee)
9
+ const query = params.toString() ? `?${params.toString()}` : ''
10
+ const res = await integration.fetch(`/repos/${input.owner}/${input.repo}/issues${query}`)
11
+ return await res.json()
12
+ }
@@ -0,0 +1,8 @@
1
+ async (input) => {
2
+ const params = new URLSearchParams()
3
+ if (input.state)
4
+ params.set('state', input.state)
5
+ const query = params.toString() ? `?${params.toString()}` : ''
6
+ const res = await integration.fetch(`/repos/${input.owner}/${input.repo}/pulls${query}`)
7
+ return await res.json()
8
+ }
@@ -0,0 +1,4 @@
1
+ async () => {
2
+ const res = await integration.fetch('/installation/repositories')
3
+ return await res.json()
4
+ }
@@ -0,0 +1,4 @@
1
+ async () => {
2
+ const res = await integration.fetch('/user/repos')
3
+ return await res.json()
4
+ }
@@ -0,0 +1,14 @@
1
+ async (input) => {
2
+ const body = {
3
+ commit_title: input.commit_title,
4
+ commit_message: input.commit_message,
5
+ merge_method: input.merge_method || 'merge',
6
+ }
7
+
8
+ const res = await integration.fetch(`/repos/${input.owner}/${input.repo}/pulls/${input.pull_number}/merge`, {
9
+ method: 'PUT',
10
+ body
11
+ })
12
+ return await res.json()
13
+ }
14
+
@@ -0,0 +1,15 @@
1
+ async (input) => {
2
+ const body = {}
3
+ if (input.title !== undefined)
4
+ body.title = input.title
5
+ if (input.body !== undefined)
6
+ body.body = input.body
7
+ if (input.state !== undefined)
8
+ body.state = input.state
9
+ if (input.assignees !== undefined)
10
+ body.assignees = input.assignees
11
+ if (input.labels !== undefined)
12
+ body.labels = input.labels
13
+ const res = await integration.fetch(`/repos/${input.owner}/${input.repo}/issues/${input.issue_number}`, { method: 'PATCH', body })
14
+ return await res.json()
15
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "github",
3
+ "version": "0.1.0",
4
+ "tools": [
5
+ { "name": "list_repos", "description": "List repositories for the authenticated user.", "inputSchema": "schemas/empty.json", "handler": "handlers/list_repos_user.js", "scope": "read" },
6
+ { "name": "get_repo", "description": "Get a repository by owner and name.", "inputSchema": "schemas/get_repo.json", "handler": "handlers/get_repo.js", "scope": "read" },
7
+ { "name": "list_issues", "description": "List issues for a repository.", "inputSchema": "schemas/list_issues.json", "handler": "handlers/list_issues.js", "scope": "read" },
8
+ { "name": "get_issue", "description": "Get a specific issue by number.", "inputSchema": "schemas/get_issue.json", "handler": "handlers/get_issue.js", "scope": "read" },
9
+ { "name": "list_pull_requests", "description": "List pull requests for a repository.", "inputSchema": "schemas/list_pull_requests.json", "handler": "handlers/list_pull_requests.js", "scope": "read" },
10
+ { "name": "list_branches", "description": "List branches for a repository.", "inputSchema": "schemas/owner_repo.json", "handler": "handlers/list_branches.js", "scope": "read" },
11
+ { "name": "list_commits", "description": "List commits for a repository.", "inputSchema": "schemas/list_commits.json", "handler": "handlers/list_commits.js", "scope": "read" },
12
+
13
+ { "name": "create_repo", "description": "Create a new repository.", "inputSchema": "schemas/create_repo.json", "handler": "handlers/create_repo.js", "scope": "write" },
14
+ { "name": "delete_repo", "description": "Delete a repository (requires delete_repo scope).", "inputSchema": "schemas/delete_repo.json", "handler": "handlers/delete_repo.js", "scope": "write" },
15
+ { "name": "create_branch", "description": "Create a new branch in a repository.", "inputSchema": "schemas/create_branch.json", "handler": "handlers/create_branch.js", "scope": "write" },
16
+ { "name": "create_or_update_file", "description": "Create or update a single file (content must be plain text; base64 handled internally).", "inputSchema": "schemas/create_or_update_file.json", "handler": "handlers/create_or_update_file.js", "scope": "write" },
17
+ { "name": "create_commit", "description": "Create a commit with multiple files (content must be plain text; base64 handled internally).", "inputSchema": "schemas/create_commit.json", "handler": "handlers/create_commit.js", "scope": "write" },
18
+ { "name": "create_pull_request", "description": "Create a pull request.", "inputSchema": "schemas/create_pull_request.json", "handler": "handlers/create_pull_request.js", "scope": "write" },
19
+ { "name": "merge_pull_request", "description": "Merge a pull request.", "inputSchema": "schemas/merge_pull_request.json", "handler": "handlers/merge_pull_request.js", "scope": "write" },
20
+ { "name": "create_issue", "description": "Create an issue in a repository.", "inputSchema": "schemas/create_issue.json", "handler": "handlers/create_issue.js", "scope": "write" },
21
+ { "name": "update_issue", "description": "Update fields on an issue.", "inputSchema": "schemas/update_issue.json", "handler": "handlers/update_issue.js", "scope": "write" },
22
+ { "name": "comment_on_issue", "description": "Add a comment to an issue.", "inputSchema": "schemas/comment_on_issue.json", "handler": "handlers/comment_on_issue.js", "scope": "write" },
23
+ { "name": "add_labels_to_issue", "description": "Add labels to an issue or pull request.", "inputSchema": "schemas/add_labels_to_issue.json", "handler": "handlers/add_labels_to_issue.js", "scope": "write" },
24
+ { "name": "close_issue", "description": "Close an issue.", "inputSchema": "schemas/close_issue.json", "handler": "handlers/close_issue.js", "scope": "write" }
25
+ ]
26
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "type": "object",
3
+ "properties": {
4
+ "owner": { "type": "string", "description": "The account owner of the repository" },
5
+ "repo": { "type": "string", "description": "The name of the repository" },
6
+ "issue_number": { "type": "number", "description": "The number of the issue" },
7
+ "labels": { "type": "array", "items": { "type": "string" }, "description": "The names of the labels to add" }
8
+ },
9
+ "required": ["owner", "repo", "issue_number", "labels"],
10
+ "additionalProperties": false
11
+ }
12
+
@@ -0,0 +1,10 @@
1
+ {
2
+ "type": "object",
3
+ "properties": {
4
+ "owner": { "type": "string" },
5
+ "repo": { "type": "string" },
6
+ "issue_number": { "type": "integer", "minimum": 1 }
7
+ },
8
+ "required": ["owner", "repo", "issue_number"],
9
+ "additionalProperties": false
10
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "type": "object",
3
+ "properties": {
4
+ "owner": { "type": "string" },
5
+ "repo": { "type": "string" },
6
+ "issue_number": { "type": "integer", "minimum": 1 },
7
+ "body": { "type": "string" }
8
+ },
9
+ "required": ["owner", "repo", "issue_number", "body"],
10
+ "additionalProperties": false
11
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "type": "object",
3
+ "properties": {
4
+ "owner": { "type": "string", "description": "The account owner of the repository" },
5
+ "repo": { "type": "string", "description": "The name of the repository" },
6
+ "branch": { "type": "string", "description": "The name of the new branch" },
7
+ "from_branch": { "type": "string", "description": "The branch to create from. Defaults to the repository's default branch" }
8
+ },
9
+ "required": ["owner", "repo", "branch"],
10
+ "additionalProperties": false
11
+ }
12
+
@@ -0,0 +1,25 @@
1
+ {
2
+ "type": "object",
3
+ "properties": {
4
+ "owner": { "type": "string", "description": "The account owner of the repository" },
5
+ "repo": { "type": "string", "description": "The name of the repository" },
6
+ "branch": { "type": "string", "description": "The branch to commit to" },
7
+ "message": { "type": "string", "description": "The commit message" },
8
+ "files": {
9
+ "type": "array",
10
+ "description": "Array of files to add/update/delete in this commit",
11
+ "items": {
12
+ "type": "object",
13
+ "properties": {
14
+ "path": { "type": "string", "description": "File path in the repository" },
15
+ "content": { "type": "string", "description": "Plain text file content (omit to delete). Do NOT base64; encoding handled internally." },
16
+ "mode": { "type": "string", "enum": ["100644", "100755", "040000", "160000", "120000"], "description": "File mode (100644 for regular files, 100755 for executable)" }
17
+ },
18
+ "required": ["path"]
19
+ }
20
+ }
21
+ },
22
+ "required": ["owner", "repo", "branch", "message", "files"],
23
+ "additionalProperties": false
24
+ }
25
+
@@ -0,0 +1,13 @@
1
+ {
2
+ "type": "object",
3
+ "properties": {
4
+ "owner": { "type": "string" },
5
+ "repo": { "type": "string" },
6
+ "title": { "type": "string" },
7
+ "body": { "type": "string" },
8
+ "assignees": { "type": "array", "items": { "type": "string" } },
9
+ "labels": { "type": "array", "items": { "type": "string" } }
10
+ },
11
+ "required": ["owner", "repo", "title"],
12
+ "additionalProperties": false
13
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "type": "object",
3
+ "properties": {
4
+ "owner": { "type": "string", "description": "The account owner of the repository" },
5
+ "repo": { "type": "string", "description": "The name of the repository" },
6
+ "path": { "type": "string", "description": "Path to the file in the repository" },
7
+ "message": { "type": "string", "description": "The commit message" },
8
+ "content": { "type": "string", "description": "Plain text file content. Do NOT base64; encoding handled internally." },
9
+ "branch": { "type": "string", "description": "The branch name. Defaults to the repository's default branch" },
10
+ "sha": { "type": "string", "description": "Required if updating an existing file. The blob SHA of the file being replaced" }
11
+ },
12
+ "required": ["owner", "repo", "path", "message", "content"],
13
+ "additionalProperties": false
14
+ }
15
+
@@ -0,0 +1,15 @@
1
+ {
2
+ "type": "object",
3
+ "properties": {
4
+ "owner": { "type": "string", "description": "The account owner of the repository" },
5
+ "repo": { "type": "string", "description": "The name of the repository" },
6
+ "title": { "type": "string", "description": "The title of the pull request" },
7
+ "body": { "type": "string", "description": "The contents of the pull request" },
8
+ "head": { "type": "string", "description": "The name of the branch where your changes are implemented" },
9
+ "base": { "type": "string", "description": "The name of the branch you want the changes pulled into" },
10
+ "draft": { "type": "boolean", "description": "Whether to create the pull request as a draft" }
11
+ },
12
+ "required": ["owner", "repo", "title", "head", "base"],
13
+ "additionalProperties": false
14
+ }
15
+
@@ -0,0 +1,12 @@
1
+ {
2
+ "type": "object",
3
+ "properties": {
4
+ "name": { "type": "string", "description": "The name of the repository" },
5
+ "description": { "type": "string", "description": "A short description of the repository" },
6
+ "private": { "type": "boolean", "description": "Whether the repository is private", "default": false },
7
+ "auto_init": { "type": "boolean", "description": "Pass true to create an initial commit with empty README", "default": false }
8
+ },
9
+ "required": ["name"],
10
+ "additionalProperties": false
11
+ }
12
+
@@ -0,0 +1,10 @@
1
+ {
2
+ "type": "object",
3
+ "properties": {
4
+ "owner": { "type": "string", "description": "The account owner of the repository" },
5
+ "repo": { "type": "string", "description": "The name of the repository" }
6
+ },
7
+ "required": ["owner", "repo"],
8
+ "additionalProperties": false
9
+ }
10
+
@@ -0,0 +1,5 @@
1
+ {
2
+ "type": "object",
3
+ "properties": {},
4
+ "additionalProperties": false
5
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "type": "object",
3
+ "properties": {
4
+ "owner": { "type": "string" },
5
+ "repo": { "type": "string" },
6
+ "issue_number": { "type": "integer", "minimum": 1 }
7
+ },
8
+ "required": ["owner", "repo", "issue_number"],
9
+ "additionalProperties": false
10
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "type": "object",
3
+ "properties": {
4
+ "owner": { "type": "string" },
5
+ "repo": { "type": "string" }
6
+ },
7
+ "required": ["owner", "repo"],
8
+ "additionalProperties": false
9
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "type": "object",
3
+ "properties": {
4
+ "owner": { "type": "string" },
5
+ "repo": { "type": "string" },
6
+ "sha": { "type": "string" },
7
+ "path": { "type": "string" },
8
+ "author": { "type": "string" }
9
+ },
10
+ "required": ["owner", "repo"],
11
+ "additionalProperties": false
12
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "type": "object",
3
+ "properties": {
4
+ "owner": { "type": "string" },
5
+ "repo": { "type": "string" },
6
+ "state": { "type": "string", "enum": ["open", "closed", "all"], "default": "open" },
7
+ "labels": { "type": "string" },
8
+ "assignee": { "type": "string" }
9
+ },
10
+ "required": ["owner", "repo"],
11
+ "additionalProperties": false
12
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "type": "object",
3
+ "properties": {
4
+ "owner": { "type": "string" },
5
+ "repo": { "type": "string" },
6
+ "state": { "type": "string", "enum": ["open", "closed", "all"], "default": "open" }
7
+ },
8
+ "required": ["owner", "repo"],
9
+ "additionalProperties": false
10
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "type": "object",
3
+ "properties": {
4
+ "owner": { "type": "string", "description": "The account owner of the repository" },
5
+ "repo": { "type": "string", "description": "The name of the repository" },
6
+ "pull_number": { "type": "number", "description": "The number of the pull request" },
7
+ "commit_title": { "type": "string", "description": "Title for the automatic commit message" },
8
+ "commit_message": { "type": "string", "description": "Extra detail to append to automatic commit message" },
9
+ "merge_method": { "type": "string", "enum": ["merge", "squash", "rebase"], "description": "Merge method to use. Default is 'merge'" }
10
+ },
11
+ "required": ["owner", "repo", "pull_number"],
12
+ "additionalProperties": false
13
+ }
14
+
@@ -0,0 +1,9 @@
1
+ {
2
+ "type": "object",
3
+ "properties": {
4
+ "owner": { "type": "string" },
5
+ "repo": { "type": "string" }
6
+ },
7
+ "required": ["owner", "repo"],
8
+ "additionalProperties": false
9
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "type": "object",
3
+ "properties": {
4
+ "owner": { "type": "string" },
5
+ "repo": { "type": "string" },
6
+ "issue_number": { "type": "integer", "minimum": 1 },
7
+ "title": { "type": "string" },
8
+ "body": { "type": "string" },
9
+ "state": { "type": "string", "enum": ["open", "closed"] },
10
+ "assignees": { "type": "array", "items": { "type": "string" } },
11
+ "labels": { "type": "array", "items": { "type": "string" } }
12
+ },
13
+ "required": ["owner", "repo", "issue_number"],
14
+ "additionalProperties": false
15
+ }
@@ -0,0 +1,112 @@
1
+ import { beforeAll, describe, expect, it } from 'vitest'
2
+ import { IntegrationProxy } from '../../../../server/src/integrations/proxy.js'
3
+ import { loadIntegrationTools } from '../../../../server/src/integrations/dataLoader.js'
4
+
5
+ // LIVE Google Calendar read tests using managed OAuth
6
+ // Required env vars:
7
+ // - COMMANDABLE_MANAGED_OAUTH_BASE_URL
8
+ // - COMMANDABLE_MANAGED_OAUTH_SECRET_KEY
9
+ // - GCAL_TEST_CONNECTION_ID (managed OAuth connection for provider 'google-calendar')
10
+
11
+ interface Ctx {
12
+ calendarId?: string
13
+ eventId?: string
14
+ }
15
+
16
+ const env = process.env as Record<string, string>
17
+ const hasEnv = (...keys: string[]) => keys.every(k => !!env[k] && env[k].trim().length > 0)
18
+ const suite = hasEnv(
19
+ 'COMMANDABLE_MANAGED_OAUTH_BASE_URL',
20
+ 'COMMANDABLE_MANAGED_OAUTH_SECRET_KEY',
21
+ 'GCAL_TEST_CONNECTION_ID',
22
+ )
23
+ ? describe
24
+ : describe.skip
25
+
26
+ suite('google-calendar read handlers (live)', () => {
27
+ const ctx: Ctx = {}
28
+ let buildHandler: (name: string) => ((input: any) => Promise<any>)
29
+
30
+ beforeAll(async () => {
31
+ const { COMMANDABLE_MANAGED_OAUTH_BASE_URL, COMMANDABLE_MANAGED_OAUTH_SECRET_KEY, GCAL_TEST_CONNECTION_ID } = env
32
+
33
+ const proxy = new IntegrationProxy({
34
+ managedOAuthBaseUrl: COMMANDABLE_MANAGED_OAUTH_BASE_URL,
35
+ managedOAuthSecretKey: COMMANDABLE_MANAGED_OAUTH_SECRET_KEY,
36
+ })
37
+ const integrationNode = { id: 'node-gcal', type: 'google-calendar', label: 'Google Calendar', connectionId: GCAL_TEST_CONNECTION_ID } as any
38
+
39
+ const tools = loadIntegrationTools('google-calendar')
40
+ expect(tools).toBeTruthy()
41
+
42
+ buildHandler = (name: string) => {
43
+ const tool = tools!.read.find(t => t.name === name)
44
+ expect(tool, `tool ${name} exists`).toBeTruthy()
45
+ const integration = { fetch: (path: string, init?: RequestInit) => proxy.call(integrationNode, path, init) }
46
+ const build = new Function('integration', `return (${tool!.handlerCode});`)
47
+ return build(integration) as (input: any) => Promise<any>
48
+ }
49
+
50
+ const list_calendars = buildHandler('list_calendars')
51
+ const calendars = await list_calendars({})
52
+ ctx.calendarId = calendars?.items?.[0]?.id || 'primary'
53
+
54
+ if (ctx.calendarId) {
55
+ const list_events = buildHandler('list_events')
56
+ const events = await list_events({ calendarId: ctx.calendarId, maxResults: 1, singleEvents: true, orderBy: 'startTime', timeMin: new Date(Date.now() - 7 * 24 * 3600 * 1000).toISOString() })
57
+ ctx.eventId = events?.items?.[0]?.id
58
+ }
59
+ }, 60000)
60
+
61
+ it('list_calendars returns calendars', async () => {
62
+ const handler = buildHandler('list_calendars')
63
+ const result = await handler({})
64
+ expect(result).toBeTruthy()
65
+ }, 30000)
66
+
67
+ it('get_calendar returns a calendar', async () => {
68
+ const handler = buildHandler('get_calendar')
69
+ const result = await handler({ calendarId: ctx.calendarId || 'primary' })
70
+ expect(result?.id).toBeTruthy()
71
+ }, 30000)
72
+
73
+ it('list_events returns events', async () => {
74
+ if (!ctx.calendarId)
75
+ return expect(true).toBe(true)
76
+ const handler = buildHandler('list_events')
77
+ const result = await handler({ calendarId: ctx.calendarId, maxResults: 3, singleEvents: true })
78
+ expect(result).toBeTruthy()
79
+ }, 30000)
80
+
81
+ it('get_event returns an event by id when available', async () => {
82
+ if (!ctx.calendarId || !ctx.eventId)
83
+ return expect(true).toBe(true)
84
+ const handler = buildHandler('get_event')
85
+ const result = await handler({ calendarId: ctx.calendarId, eventId: ctx.eventId })
86
+ expect(result?.id).toBe(ctx.eventId)
87
+ }, 30000)
88
+
89
+ it('list_colors returns colors', async () => {
90
+ const handler = buildHandler('list_colors')
91
+ const result = await handler({})
92
+ expect(result?.calendar || result?.event).toBeTruthy()
93
+ }, 30000)
94
+
95
+ it('list_settings returns user settings', async () => {
96
+ const handler = buildHandler('list_settings')
97
+ const result = await handler({})
98
+ expect(Array.isArray(result?.items) || result?.kind === 'calendar#settings').toBe(true)
99
+ }, 30000)
100
+
101
+ it('freebusy_query returns availability', async () => {
102
+ const handler = buildHandler('freebusy_query')
103
+ const now = new Date()
104
+ const inOneHour = new Date(now.getTime() + 60 * 60 * 1000)
105
+ const result = await handler({
106
+ timeMin: now.toISOString(),
107
+ timeMax: inOneHour.toISOString(),
108
+ items: [{ id: ctx.calendarId || 'primary' }],
109
+ })
110
+ expect(result?.calendars || result?.groups).toBeTruthy()
111
+ }, 30000)
112
+ })
@@ -0,0 +1,34 @@
1
+ import { existsSync, readdirSync, readFileSync } from 'node:fs'
2
+ import { resolve } from 'node:path'
3
+ import { fileURLToPath } from 'node:url'
4
+ import { describe, expect, it } from 'vitest'
5
+ import { loadIntegrationManifest } from '../../../src/integrations/dataLoader.js'
6
+
7
+ function escapeRegExp(str: string): string {
8
+ return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
9
+ }
10
+
11
+ describe('google-calendar static usage parity', () => {
12
+ it('every manifest tool is referenced in tests via build*(name)', () => {
13
+ const manifest = loadIntegrationManifest('google-calendar')!
14
+ const toolNames = (manifest.tools as any[]).map(t => t.name)
15
+
16
+ const testsDir = fileURLToPath(new URL('.', import.meta.url))
17
+ expect(existsSync(testsDir)).toBe(true)
18
+ const testFiles = readdirSync(testsDir)
19
+ .filter(f => /\.test\.(t|j)s$/.test(f) && !f.includes('usage_parity.test'))
20
+ .map(f => resolve(testsDir, f))
21
+
22
+ const fileContents = testFiles.map(f => readFileSync(f, 'utf8'))
23
+
24
+ const missing: string[] = []
25
+ for (const name of toolNames) {
26
+ const nameRe = new RegExp(`build(?:Read|Write|Admin|Handler)\\(\\s*['\"\`]${escapeRegExp(name)}['\"\`]\\s*\\)`, 'm')
27
+ const found = fileContents.some(src => nameRe.test(src))
28
+ if (!found)
29
+ missing.push(name)
30
+ }
31
+
32
+ expect(missing, `Missing handler usages in tests: ${missing.join(', ')}`).toEqual([])
33
+ })
34
+ })