runline 0.11.6 → 0.13.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 (256) hide show
  1. package/dist/commands/actions.js +3 -1
  2. package/dist/core/engine.js +3 -0
  3. package/dist/index.d.ts +1 -1
  4. package/dist/plugin/api.d.ts +2 -1
  5. package/dist/plugin/types.d.ts +2 -0
  6. package/dist/plugins/_shared/googleSchemas.js +23 -0
  7. package/dist/plugins/actionNetwork/src/index.js +23 -0
  8. package/dist/plugins/activeCampaign/src/index.js +48 -0
  9. package/dist/plugins/adalo/src/index.js +5 -0
  10. package/dist/plugins/affinity/src/index.js +16 -0
  11. package/dist/plugins/agileCrm/src/index.js +15 -0
  12. package/dist/plugins/airtable/src/index.js +10 -0
  13. package/dist/plugins/airtop/src/index.js +24 -0
  14. package/dist/plugins/apiTemplateIo/src/index.js +4 -0
  15. package/dist/plugins/asana/src/index.js +22 -0
  16. package/dist/plugins/autopilot/src/index.js +11 -0
  17. package/dist/plugins/bambooHr/src/index.js +11 -0
  18. package/dist/plugins/bannerbear/src/index.js +4 -0
  19. package/dist/plugins/baserow/src/index.js +8 -0
  20. package/dist/plugins/beeminder/src/index.js +18 -0
  21. package/dist/plugins/bitly/src/index.js +3 -0
  22. package/dist/plugins/bitwarden/src/index.js +19 -0
  23. package/dist/plugins/box/src/index.js +11 -0
  24. package/dist/plugins/brandfetch/src/index.js +5 -0
  25. package/dist/plugins/brevo/src/index.js +15 -0
  26. package/dist/plugins/bubble/src/index.js +5 -0
  27. package/dist/plugins/chargebee/src/index.js +5 -0
  28. package/dist/plugins/circleci/src/index.js +3 -0
  29. package/dist/plugins/ciscoWebex/src/index.js +10 -0
  30. package/dist/plugins/clearbit/src/index.js +3 -0
  31. package/dist/plugins/clickup/src/index.js +61 -0
  32. package/dist/plugins/clockify/src/index.js +25 -0
  33. package/dist/plugins/cloudflare/src/index.js +4 -0
  34. package/dist/plugins/cockpit/src/index.js +5 -0
  35. package/dist/plugins/coda/src/index.js +18 -0
  36. package/dist/plugins/coingecko/src/index.js +10 -0
  37. package/dist/plugins/contentful/src/index.js +7 -0
  38. package/dist/plugins/convertkit/src/index.js +16 -0
  39. package/dist/plugins/copper/src/index.js +7 -0
  40. package/dist/plugins/cortex/src/index.js +4 -0
  41. package/dist/plugins/currents/src/index.js +22 -0
  42. package/dist/plugins/customerIo/src/index.js +9 -0
  43. package/dist/plugins/databricks/src/index.js +34 -0
  44. package/dist/plugins/deepl/src/index.js +2 -0
  45. package/dist/plugins/demio/src/index.js +4 -0
  46. package/dist/plugins/dhl/src/index.js +1 -0
  47. package/dist/plugins/discord/src/index.js +13 -0
  48. package/dist/plugins/discourse/src/index.js +16 -0
  49. package/dist/plugins/disqus/src/index.js +4 -0
  50. package/dist/plugins/docker/src/index.js +5 -0
  51. package/dist/plugins/drift/src/index.js +5 -0
  52. package/dist/plugins/dropbox/src/index.js +9 -0
  53. package/dist/plugins/dropcontact/src/index.js +2 -0
  54. package/dist/plugins/egoi/src/index.js +4 -0
  55. package/dist/plugins/elasticsearch/src/index.js +9 -0
  56. package/dist/plugins/emelia/src/index.js +9 -0
  57. package/dist/plugins/erpnext/src/index.js +5 -0
  58. package/dist/plugins/facebookGraph/src/index.js +1 -0
  59. package/dist/plugins/freshdesk/src/index.js +10 -0
  60. package/dist/plugins/freshservice/src/index.js +7 -0
  61. package/dist/plugins/freshworksCrm/src/index.js +7 -0
  62. package/dist/plugins/getresponse/src/index.js +5 -0
  63. package/dist/plugins/ghost/src/index.js +5 -0
  64. package/dist/plugins/github/src/index.js +37 -0
  65. package/dist/plugins/gitlab/src/index.js +17 -0
  66. package/dist/plugins/gmail/src/index.js +200 -184
  67. package/dist/plugins/gong/src/index.js +4 -0
  68. package/dist/plugins/googleAppsScript/src/index.js +98 -43
  69. package/dist/plugins/googleCalendar/src/index.js +329 -250
  70. package/dist/plugins/googleContacts/src/index.js +144 -145
  71. package/dist/plugins/googleDocs/src/documents.js +31 -38
  72. package/dist/plugins/googleDocs/src/formatting.js +51 -47
  73. package/dist/plugins/googleDocs/src/images.js +23 -26
  74. package/dist/plugins/googleDocs/src/shared.js +55 -0
  75. package/dist/plugins/googleDocs/src/structure.js +111 -123
  76. package/dist/plugins/googleDocs/src/tables.js +103 -154
  77. package/dist/plugins/googleDocs/src/tabs.js +27 -23
  78. package/dist/plugins/googleDocs/src/text.js +106 -136
  79. package/dist/plugins/googleDrive/src/index.js +461 -408
  80. package/dist/plugins/googleImage/src/index.js +14 -16
  81. package/dist/plugins/googleSheets/src/index.js +527 -339
  82. package/dist/plugins/googleSlides/src/index.js +92 -72
  83. package/dist/plugins/googleTasks/src/index.js +94 -92
  84. package/dist/plugins/gotify/src/index.js +3 -0
  85. package/dist/plugins/gotowebinar/src/index.js +20 -0
  86. package/dist/plugins/grafana/src/index.js +17 -0
  87. package/dist/plugins/graphql/src/index.js +2 -0
  88. package/dist/plugins/grist/src/index.js +4 -0
  89. package/dist/plugins/hackernews/src/index.js +6 -0
  90. package/dist/plugins/halopsa/src/index.js +5 -0
  91. package/dist/plugins/harvest/src/index.js +14 -0
  92. package/dist/plugins/helpscout/src/index.js +13 -0
  93. package/dist/plugins/highlevel/src/index.js +17 -0
  94. package/dist/plugins/homeAssistant/src/index.js +13 -0
  95. package/dist/plugins/hubspot/src/index.js +14 -0
  96. package/dist/plugins/humanticAi/src/index.js +3 -0
  97. package/dist/plugins/hunter/src/index.js +3 -0
  98. package/dist/plugins/intercom/src/index.js +10 -0
  99. package/dist/plugins/iterable/src/index.js +6 -0
  100. package/dist/plugins/jenkins/src/index.js +11 -0
  101. package/dist/plugins/jira/src/index.js +16 -0
  102. package/dist/plugins/keap/src/index.js +28 -0
  103. package/dist/plugins/kobotoolbox/src/index.js +17 -0
  104. package/dist/plugins/lemlist/src/index.js +15 -0
  105. package/dist/plugins/linear/src/attachments.js +6 -0
  106. package/dist/plugins/linear/src/comments.js +5 -0
  107. package/dist/plugins/linear/src/cycles.js +2 -0
  108. package/dist/plugins/linear/src/initiatives.js +5 -0
  109. package/dist/plugins/linear/src/issues.js +14 -0
  110. package/dist/plugins/linear/src/labels.js +5 -0
  111. package/dist/plugins/linear/src/organization.js +1 -0
  112. package/dist/plugins/linear/src/projects.js +11 -0
  113. package/dist/plugins/linear/src/shared.js +2 -0
  114. package/dist/plugins/linear/src/states.js +2 -0
  115. package/dist/plugins/linear/src/teams.js +3 -0
  116. package/dist/plugins/linear/src/users.js +2 -0
  117. package/dist/plugins/linear/src/views.js +4 -0
  118. package/dist/plugins/linear/src/webhooks.js +4 -0
  119. package/dist/plugins/lingvanex/src/index.js +1 -0
  120. package/dist/plugins/linkedin/src/index.js +1 -0
  121. package/dist/plugins/lonescale/src/index.js +4 -0
  122. package/dist/plugins/magento/src/index.js +15 -0
  123. package/dist/plugins/mailcheck/src/index.js +1 -0
  124. package/dist/plugins/mailchimp/src/index.js +14 -0
  125. package/dist/plugins/mailerlite/src/index.js +4 -0
  126. package/dist/plugins/mailgun/src/index.js +1 -0
  127. package/dist/plugins/mailjet/src/index.js +3 -0
  128. package/dist/plugins/mandrill/src/index.js +2 -0
  129. package/dist/plugins/marketstack/src/index.js +3 -0
  130. package/dist/plugins/matrix/src/index.js +10 -0
  131. package/dist/plugins/mattermost/src/index.js +19 -0
  132. package/dist/plugins/mautic/src/index.js +20 -0
  133. package/dist/plugins/medium/src/index.js +3 -0
  134. package/dist/plugins/messagebird/src/index.js +2 -0
  135. package/dist/plugins/metabase/src/index.js +10 -0
  136. package/dist/plugins/microsoftCalendar/src/index.js +2 -0
  137. package/dist/plugins/microsoftFiles/src/index.js +5 -0
  138. package/dist/plugins/microsoftMail/src/index.js +4 -0
  139. package/dist/plugins/misp/src/index.js +44 -0
  140. package/dist/plugins/mocean/src/index.js +2 -0
  141. package/dist/plugins/monday/src/index.js +18 -0
  142. package/dist/plugins/monicaCrm/src/index.js +5 -0
  143. package/dist/plugins/msg91/src/index.js +1 -0
  144. package/dist/plugins/nasa/src/index.js +7 -0
  145. package/dist/plugins/netlify/src/index.js +7 -0
  146. package/dist/plugins/netscalerAdc/src/index.js +3 -0
  147. package/dist/plugins/nextcloud/src/index.js +13 -0
  148. package/dist/plugins/nocodb/src/index.js +5 -0
  149. package/dist/plugins/node/src/index.js +38 -0
  150. package/dist/plugins/notion/src/index.js +14 -0
  151. package/dist/plugins/npm/src/index.js +5 -0
  152. package/dist/plugins/odoo/src/index.js +6 -0
  153. package/dist/plugins/okta/src/index.js +5 -0
  154. package/dist/plugins/oneSimpleApi/src/index.js +10 -0
  155. package/dist/plugins/onfleet/src/index.js +24 -0
  156. package/dist/plugins/openThesaurus/src/index.js +1 -0
  157. package/dist/plugins/openai/src/index.js +1 -0
  158. package/dist/plugins/openweathermap/src/index.js +2 -0
  159. package/dist/plugins/oura/src/index.js +2 -0
  160. package/dist/plugins/paddle/src/index.js +9 -0
  161. package/dist/plugins/pagerduty/src/index.js +9 -0
  162. package/dist/plugins/parallel/src/index.js +1 -0
  163. package/dist/plugins/paypal/src/index.js +4 -0
  164. package/dist/plugins/peekalink/src/index.js +2 -0
  165. package/dist/plugins/phantombuster/src/index.js +5 -0
  166. package/dist/plugins/philipsHue/src/index.js +4 -0
  167. package/dist/plugins/pipedrive/src/index.js +14 -0
  168. package/dist/plugins/plivo/src/index.js +3 -0
  169. package/dist/plugins/postbin/src/index.js +6 -0
  170. package/dist/plugins/posthog/src/index.js +5 -0
  171. package/dist/plugins/profitwell/src/index.js +2 -0
  172. package/dist/plugins/pushbullet/src/index.js +4 -0
  173. package/dist/plugins/pushcut/src/index.js +1 -0
  174. package/dist/plugins/pushover/src/index.js +1 -0
  175. package/dist/plugins/quickbase/src/index.js +8 -0
  176. package/dist/plugins/quickbooks/src/index.js +5 -0
  177. package/dist/plugins/quickchart/src/index.js +1 -0
  178. package/dist/plugins/raindrop/src/index.js +13 -0
  179. package/dist/plugins/recraft/src/index.js +1 -0
  180. package/dist/plugins/reddit/src/index.js +10 -0
  181. package/dist/plugins/replicate/src/index.js +1 -0
  182. package/dist/plugins/rocketchat/src/index.js +1 -0
  183. package/dist/plugins/rundeck/src/index.js +2 -0
  184. package/dist/plugins/salesforce/src/metadata.js +4 -0
  185. package/dist/plugins/salesforce/src/query.js +5 -0
  186. package/dist/plugins/salesforce/src/sobjects.js +12 -0
  187. package/dist/plugins/salesmate/src/index.js +5 -0
  188. package/dist/plugins/securityScorecard/src/index.js +14 -0
  189. package/dist/plugins/segment/src/index.js +4 -0
  190. package/dist/plugins/sendgrid/src/index.js +10 -0
  191. package/dist/plugins/sendy/src/index.js +6 -0
  192. package/dist/plugins/sentry/src/index.js +24 -0
  193. package/dist/plugins/servicenow/src/index.js +10 -0
  194. package/dist/plugins/shiftLabs/src/index.js +6 -0
  195. package/dist/plugins/shiftLabs/src/issues.js +4 -0
  196. package/dist/plugins/shiftLabs/src/pages.js +10 -0
  197. package/dist/plugins/shiftLabs/src/shared.js +2 -0
  198. package/dist/plugins/shiftLabs/src/transcription.js +203 -0
  199. package/dist/plugins/shopify/src/index.js +10 -0
  200. package/dist/plugins/signl4/src/index.js +2 -0
  201. package/dist/plugins/slack/src/index.js +38 -0
  202. package/dist/plugins/sms77/src/index.js +2 -0
  203. package/dist/plugins/splunk/src/index.js +16 -0
  204. package/dist/plugins/spotify/src/index.js +30 -0
  205. package/dist/plugins/stackby/src/index.js +4 -0
  206. package/dist/plugins/steel/src/browser.js +7 -0
  207. package/dist/plugins/steel/src/captchas.js +3 -0
  208. package/dist/plugins/steel/src/credentials.js +4 -0
  209. package/dist/plugins/steel/src/extensions.js +5 -0
  210. package/dist/plugins/steel/src/files.js +10 -0
  211. package/dist/plugins/steel/src/profiles.js +4 -0
  212. package/dist/plugins/steel/src/sessions.js +11 -0
  213. package/dist/plugins/storyblok/src/index.js +7 -0
  214. package/dist/plugins/strapi/src/index.js +5 -0
  215. package/dist/plugins/strava/src/index.js +6 -0
  216. package/dist/plugins/stripe/src/index.js +20 -0
  217. package/dist/plugins/supabase/src/index.js +5 -0
  218. package/dist/plugins/syncromsp/src/index.js +20 -0
  219. package/dist/plugins/tapfiliate/src/index.js +11 -0
  220. package/dist/plugins/telegram/src/index.js +21 -0
  221. package/dist/plugins/thehive/src/index.js +23 -0
  222. package/dist/plugins/thehiveProject/src/index.js +31 -0
  223. package/dist/plugins/todoist/src/index.js +31 -0
  224. package/dist/plugins/together/src/index.js +1 -0
  225. package/dist/plugins/travisci/src/index.js +5 -0
  226. package/dist/plugins/trello/src/index.js +37 -0
  227. package/dist/plugins/twake/src/index.js +1 -0
  228. package/dist/plugins/twilio/src/index.js +2 -0
  229. package/dist/plugins/twist/src/index.js +22 -0
  230. package/dist/plugins/twitter/src/index.js +8 -0
  231. package/dist/plugins/unleashedSoftware/src/index.js +3 -0
  232. package/dist/plugins/uplead/src/index.js +2 -0
  233. package/dist/plugins/uproc/src/index.js +1 -0
  234. package/dist/plugins/uptimerobot/src/index.js +22 -0
  235. package/dist/plugins/urlscanio/src/index.js +3 -0
  236. package/dist/plugins/vercel/src/account.js +1 -0
  237. package/dist/plugins/vercel/src/deployments.js +5 -0
  238. package/dist/plugins/vercel/src/env.js +4 -0
  239. package/dist/plugins/vercel/src/projects.js +2 -0
  240. package/dist/plugins/vercel/src/shared.js +1 -0
  241. package/dist/plugins/vero/src/index.js +6 -0
  242. package/dist/plugins/vonage/src/index.js +1 -0
  243. package/dist/plugins/wekan/src/index.js +24 -0
  244. package/dist/plugins/woocommerce/src/index.js +5 -0
  245. package/dist/plugins/wordpress/src/index.js +10 -0
  246. package/dist/plugins/xai/src/index.js +1 -0
  247. package/dist/plugins/xero/src/index.js +8 -0
  248. package/dist/plugins/yourls/src/index.js +3 -0
  249. package/dist/plugins/zammad/src/index.js +12 -0
  250. package/dist/plugins/zendesk/src/index.js +18 -0
  251. package/dist/plugins/zoho/src/index.js +6 -0
  252. package/dist/plugins/zoom/src/index.js +5 -0
  253. package/dist/plugins/zulip/src/index.js +15 -0
  254. package/dist/sdk.d.ts +2 -1
  255. package/dist/sdk.js +1 -0
  256. package/package.json +1 -1
@@ -28,6 +28,7 @@ async function apiRequest(conn, method, endpoint, body, qs) {
28
28
  }
29
29
  function registerCrud(rl, resource, basePath, idField, extraCreateFields) {
30
30
  rl.registerAction(`${resource}.get`, {
31
+ access: "read",
31
32
  description: `Get a ${resource} by ${idField}`,
32
33
  inputSchema: {
33
34
  [idField]: { type: "string", required: true },
@@ -39,6 +40,7 @@ function registerCrud(rl, resource, basePath, idField, extraCreateFields) {
39
40
  },
40
41
  });
41
42
  rl.registerAction(`${resource}.list`, {
43
+ access: "read",
42
44
  description: `List ${resource}s`,
43
45
  inputSchema: {
44
46
  org: { type: "string", required: true },
@@ -63,6 +65,7 @@ function registerCrud(rl, resource, basePath, idField, extraCreateFields) {
63
65
  },
64
66
  });
65
67
  rl.registerAction(`${resource}.delete`, {
68
+ access: "write",
66
69
  description: `Delete a ${resource}`,
67
70
  inputSchema: {
68
71
  [idField]: { type: "string", required: true },
@@ -94,6 +97,7 @@ export default function sentry(rl) {
94
97
  });
95
98
  // ── Event ───────────────────────────────────────────
96
99
  rl.registerAction("event.get", {
100
+ access: "read",
97
101
  description: "Get a project event by ID",
98
102
  inputSchema: {
99
103
  org: { type: "string", required: true },
@@ -106,6 +110,7 @@ export default function sentry(rl) {
106
110
  },
107
111
  });
108
112
  rl.registerAction("event.list", {
113
+ access: "read",
109
114
  description: "List project events",
110
115
  inputSchema: {
111
116
  org: { type: "string", required: true },
@@ -125,6 +130,7 @@ export default function sentry(rl) {
125
130
  });
126
131
  // ── Issue ───────────────────────────────────────────
127
132
  rl.registerAction("issue.get", {
133
+ access: "read",
128
134
  description: "Get an issue by ID",
129
135
  inputSchema: { issueId: { type: "string", required: true } },
130
136
  async execute(input, ctx) {
@@ -132,6 +138,7 @@ export default function sentry(rl) {
132
138
  },
133
139
  });
134
140
  rl.registerAction("issue.list", {
141
+ access: "read",
135
142
  description: "List issues for a project",
136
143
  inputSchema: {
137
144
  org: { type: "string", required: true },
@@ -150,6 +157,7 @@ export default function sentry(rl) {
150
157
  },
151
158
  });
152
159
  rl.registerAction("issue.update", {
160
+ access: "write",
153
161
  description: "Update an issue",
154
162
  inputSchema: {
155
163
  issueId: { type: "string", required: true },
@@ -164,6 +172,7 @@ export default function sentry(rl) {
164
172
  },
165
173
  });
166
174
  rl.registerAction("issue.delete", {
175
+ access: "write",
167
176
  description: "Delete an issue",
168
177
  inputSchema: { issueId: { type: "string", required: true } },
169
178
  async execute(input, ctx) {
@@ -173,6 +182,7 @@ export default function sentry(rl) {
173
182
  });
174
183
  // ── Organization ────────────────────────────────────
175
184
  rl.registerAction("organization.get", {
185
+ access: "read",
176
186
  description: "Get an organization",
177
187
  inputSchema: { org: { type: "string", required: true } },
178
188
  async execute(input, ctx) {
@@ -180,6 +190,7 @@ export default function sentry(rl) {
180
190
  },
181
191
  });
182
192
  rl.registerAction("organization.list", {
193
+ access: "read",
183
194
  description: "List organizations",
184
195
  inputSchema: { limit: { type: "number", required: false } },
185
196
  async execute(input, ctx) {
@@ -190,6 +201,7 @@ export default function sentry(rl) {
190
201
  },
191
202
  });
192
203
  rl.registerAction("organization.create", {
204
+ access: "write",
193
205
  description: "Create an organization",
194
206
  inputSchema: {
195
207
  name: { type: "string", required: true },
@@ -206,6 +218,7 @@ export default function sentry(rl) {
206
218
  });
207
219
  // ── Project ─────────────────────────────────────────
208
220
  rl.registerAction("project.get", {
221
+ access: "read",
209
222
  description: "Get a project",
210
223
  inputSchema: {
211
224
  org: { type: "string", required: true },
@@ -217,6 +230,7 @@ export default function sentry(rl) {
217
230
  },
218
231
  });
219
232
  rl.registerAction("project.list", {
233
+ access: "read",
220
234
  description: "List all projects",
221
235
  inputSchema: { limit: { type: "number", required: false } },
222
236
  async execute(input, ctx) {
@@ -226,6 +240,7 @@ export default function sentry(rl) {
226
240
  },
227
241
  });
228
242
  rl.registerAction("project.create", {
243
+ access: "write",
229
244
  description: "Create a project",
230
245
  inputSchema: {
231
246
  org: { type: "string", required: true },
@@ -245,6 +260,7 @@ export default function sentry(rl) {
245
260
  },
246
261
  });
247
262
  rl.registerAction("project.delete", {
263
+ access: "write",
248
264
  description: "Delete a project",
249
265
  inputSchema: {
250
266
  org: { type: "string", required: true },
@@ -258,6 +274,7 @@ export default function sentry(rl) {
258
274
  });
259
275
  // ── Release ─────────────────────────────────────────
260
276
  rl.registerAction("release.get", {
277
+ access: "read",
261
278
  description: "Get a release",
262
279
  inputSchema: {
263
280
  org: { type: "string", required: true },
@@ -269,6 +286,7 @@ export default function sentry(rl) {
269
286
  },
270
287
  });
271
288
  rl.registerAction("release.list", {
289
+ access: "read",
272
290
  description: "List releases",
273
291
  inputSchema: {
274
292
  org: { type: "string", required: true },
@@ -286,6 +304,7 @@ export default function sentry(rl) {
286
304
  },
287
305
  });
288
306
  rl.registerAction("release.create", {
307
+ access: "write",
289
308
  description: "Create a release",
290
309
  inputSchema: {
291
310
  org: { type: "string", required: true },
@@ -309,6 +328,7 @@ export default function sentry(rl) {
309
328
  },
310
329
  });
311
330
  rl.registerAction("release.delete", {
331
+ access: "write",
312
332
  description: "Delete a release",
313
333
  inputSchema: {
314
334
  org: { type: "string", required: true },
@@ -322,6 +342,7 @@ export default function sentry(rl) {
322
342
  });
323
343
  // ── Team ────────────────────────────────────────────
324
344
  rl.registerAction("team.get", {
345
+ access: "read",
325
346
  description: "Get a team",
326
347
  inputSchema: {
327
348
  org: { type: "string", required: true },
@@ -333,6 +354,7 @@ export default function sentry(rl) {
333
354
  },
334
355
  });
335
356
  rl.registerAction("team.list", {
357
+ access: "read",
336
358
  description: "List teams in an organization",
337
359
  inputSchema: {
338
360
  org: { type: "string", required: true },
@@ -344,6 +366,7 @@ export default function sentry(rl) {
344
366
  },
345
367
  });
346
368
  rl.registerAction("team.create", {
369
+ access: "write",
347
370
  description: "Create a team",
348
371
  inputSchema: {
349
372
  org: { type: "string", required: true },
@@ -359,6 +382,7 @@ export default function sentry(rl) {
359
382
  },
360
383
  });
361
384
  rl.registerAction("team.delete", {
385
+ access: "write",
362
386
  description: "Delete a team",
363
387
  inputSchema: {
364
388
  org: { type: "string", required: true },
@@ -40,6 +40,7 @@ const TABLES = {
40
40
  };
41
41
  function registerTableResource(rl, resource, table, conn) {
42
42
  rl.registerAction(`${resource}.create`, {
43
+ access: "write",
43
44
  description: `Create a ${resource}`,
44
45
  inputSchema: { data: { type: "object", required: true } },
45
46
  async execute(input, ctx) {
@@ -48,6 +49,7 @@ function registerTableResource(rl, resource, table, conn) {
48
49
  },
49
50
  });
50
51
  rl.registerAction(`${resource}.get`, {
52
+ access: "read",
51
53
  description: `Get a ${resource} by sys_id`,
52
54
  inputSchema: { sysId: { type: "string", required: true } },
53
55
  async execute(input, ctx) {
@@ -56,6 +58,7 @@ function registerTableResource(rl, resource, table, conn) {
56
58
  },
57
59
  });
58
60
  rl.registerAction(`${resource}.list`, {
61
+ access: "read",
59
62
  description: `List ${resource}s`,
60
63
  inputSchema: {
61
64
  limit: { type: "number", required: false },
@@ -84,6 +87,7 @@ function registerTableResource(rl, resource, table, conn) {
84
87
  },
85
88
  });
86
89
  rl.registerAction(`${resource}.update`, {
90
+ access: "write",
87
91
  description: `Update a ${resource}`,
88
92
  inputSchema: {
89
93
  sysId: { type: "string", required: true },
@@ -96,6 +100,7 @@ function registerTableResource(rl, resource, table, conn) {
96
100
  },
97
101
  });
98
102
  rl.registerAction(`${resource}.delete`, {
103
+ access: "write",
99
104
  description: `Delete a ${resource}`,
100
105
  inputSchema: { sysId: { type: "string", required: true } },
101
106
  async execute(input, ctx) {
@@ -132,6 +137,7 @@ export default function servicenow(rl) {
132
137
  }
133
138
  // ── Generic Table Record ────────────────────────────
134
139
  rl.registerAction("tableRecord.create", {
140
+ access: "write",
135
141
  description: "Create a record in any table",
136
142
  inputSchema: {
137
143
  tableName: { type: "string", required: true },
@@ -144,6 +150,7 @@ export default function servicenow(rl) {
144
150
  },
145
151
  });
146
152
  rl.registerAction("tableRecord.get", {
153
+ access: "read",
147
154
  description: "Get a record from any table",
148
155
  inputSchema: {
149
156
  tableName: { type: "string", required: true },
@@ -156,6 +163,7 @@ export default function servicenow(rl) {
156
163
  },
157
164
  });
158
165
  rl.registerAction("tableRecord.list", {
166
+ access: "read",
159
167
  description: "List records from any table",
160
168
  inputSchema: {
161
169
  tableName: { type: "string", required: true },
@@ -174,6 +182,7 @@ export default function servicenow(rl) {
174
182
  },
175
183
  });
176
184
  rl.registerAction("tableRecord.update", {
185
+ access: "write",
177
186
  description: "Update a record in any table",
178
187
  inputSchema: {
179
188
  tableName: { type: "string", required: true },
@@ -187,6 +196,7 @@ export default function servicenow(rl) {
187
196
  },
188
197
  });
189
198
  rl.registerAction("tableRecord.delete", {
199
+ access: "write",
190
200
  description: "Delete a record from any table",
191
201
  inputSchema: {
192
202
  tableName: { type: "string", required: true },
@@ -1,6 +1,7 @@
1
1
  import * as t from "typebox";
2
2
  import { registerIssueActions } from "./issues.js";
3
3
  import { registerPageActions } from "./pages.js";
4
+ import { registerTranscriptionActions } from "./transcription.js";
4
5
  export default function shiftLabs(rl) {
5
6
  rl.setName("shiftLabs");
6
7
  rl.setVersion("0.1.0");
@@ -9,7 +10,12 @@ export default function shiftLabs(rl) {
9
10
  description: "Shift Labs API key",
10
11
  env: "SHIFT_LABS_API_KEY",
11
12
  }),
13
+ organizationId: t.Optional(t.String({
14
+ description: "Shift Labs organization ID (required for transcription actions)",
15
+ env: "SHIFT_LABS_ORG_ID",
16
+ })),
12
17
  }));
13
18
  registerIssueActions(rl);
14
19
  registerPageActions(rl);
20
+ registerTranscriptionActions(rl);
15
21
  }
@@ -2,6 +2,7 @@ import * as t from "typebox";
2
2
  import { enumSchema, ISSUE_KIND, ISSUE_PRIORITY, ISSUE_SEVERITY, ISSUE_SOURCE, ISSUE_STATUS, request, } from "./shared.js";
3
3
  export function registerIssueActions(rl) {
4
4
  rl.registerAction("issue.list", {
5
+ access: "read",
5
6
  description: "List Shift Labs issues for the API key's organization.",
6
7
  inputSchema: t.Object({
7
8
  status: t.Optional(enumSchema("Issue status", ISSUE_STATUS)),
@@ -22,6 +23,7 @@ export function registerIssueActions(rl) {
22
23
  },
23
24
  });
24
25
  rl.registerAction("issue.get", {
26
+ access: "read",
25
27
  description: "Get a Shift Labs issue by ID.",
26
28
  inputSchema: t.Object({ id: t.String({ description: "Issue ID" }) }),
27
29
  async execute(input, ctx) {
@@ -31,6 +33,7 @@ export function registerIssueActions(rl) {
31
33
  },
32
34
  });
33
35
  rl.registerAction("issue.create", {
36
+ access: "write",
34
37
  description: "Create a Shift Labs issue. The issue starts in triage.",
35
38
  inputSchema: t.Object({
36
39
  title: t.String({ description: "Issue title" }),
@@ -56,6 +59,7 @@ export function registerIssueActions(rl) {
56
59
  },
57
60
  });
58
61
  rl.registerAction("issue.comment", {
62
+ access: "write",
59
63
  description: "Add a comment to a Shift Labs issue.",
60
64
  inputSchema: t.Object({
61
65
  id: t.String({ description: "Issue ID" }),
@@ -2,6 +2,7 @@ import * as t from "typebox";
2
2
  import { enumSchema, PAGE_STATUS, PAGE_VISIBILITY, pageRenderUrl, request, } from "./shared.js";
3
3
  export function registerPageActions(rl) {
4
4
  rl.registerAction("page.list", {
5
+ access: "read",
5
6
  description: "List Shift Labs pages for the API key's organization.",
6
7
  inputSchema: t.Object({
7
8
  status: t.Optional(enumSchema("Page status", PAGE_STATUS)),
@@ -19,6 +20,7 @@ export function registerPageActions(rl) {
19
20
  },
20
21
  });
21
22
  rl.registerAction("page.get", {
23
+ access: "read",
22
24
  description: "Get a Shift Labs page by ID.",
23
25
  inputSchema: t.Object({ id: t.String({ description: "Page ID" }) }),
24
26
  async execute(input, ctx) {
@@ -28,6 +30,7 @@ export function registerPageActions(rl) {
28
30
  },
29
31
  });
30
32
  rl.registerAction("page.create", {
33
+ access: "write",
31
34
  description: "Create a draft hosted HTML page. Agents can publish it with page.publish.",
32
35
  inputSchema: t.Object({
33
36
  slug: t.String({ description: "Lowercase kebab-case page slug" }),
@@ -49,6 +52,7 @@ export function registerPageActions(rl) {
49
52
  },
50
53
  });
51
54
  rl.registerAction("page.update", {
55
+ access: "write",
52
56
  description: "Update a hosted HTML page's slug, title, visibility, or HTML.",
53
57
  inputSchema: t.Object({
54
58
  id: t.String({ description: "Page ID" }),
@@ -67,6 +71,7 @@ export function registerPageActions(rl) {
67
71
  },
68
72
  });
69
73
  rl.registerAction("page.publish", {
74
+ access: "write",
70
75
  description: "Publish a Shift Labs hosted HTML page.",
71
76
  inputSchema: t.Object({ id: t.String({ description: "Page ID" }) }),
72
77
  async execute(input, ctx) {
@@ -76,6 +81,7 @@ export function registerPageActions(rl) {
76
81
  },
77
82
  });
78
83
  rl.registerAction("page.archive", {
84
+ access: "write",
79
85
  description: "Archive a Shift Labs page.",
80
86
  inputSchema: t.Object({ id: t.String({ description: "Page ID" }) }),
81
87
  async execute(input, ctx) {
@@ -85,6 +91,7 @@ export function registerPageActions(rl) {
85
91
  },
86
92
  });
87
93
  rl.registerAction("page.shares", {
94
+ access: "read",
88
95
  description: "List shares for a Shift Labs page.",
89
96
  inputSchema: t.Object({ pageId: t.String({ description: "Page ID" }) }),
90
97
  async execute(input, ctx) {
@@ -94,6 +101,7 @@ export function registerPageActions(rl) {
94
101
  },
95
102
  });
96
103
  rl.registerAction("page.share", {
104
+ access: "write",
97
105
  description: "Create a viewer share for a Shift Labs page.",
98
106
  inputSchema: t.Object({
99
107
  pageId: t.String({ description: "Page ID" }),
@@ -110,6 +118,7 @@ export function registerPageActions(rl) {
110
118
  },
111
119
  });
112
120
  rl.registerAction("page.revokeShare", {
121
+ access: "write",
113
122
  description: "Revoke a Shift Labs page share.",
114
123
  inputSchema: t.Object({
115
124
  shareId: t.String({ description: "Page share ID" }),
@@ -123,6 +132,7 @@ export function registerPageActions(rl) {
123
132
  },
124
133
  });
125
134
  rl.registerAction("page.renderUrl", {
135
+ access: "read",
126
136
  description: "Return the authenticated render URL for a page.",
127
137
  inputSchema: t.Object({
128
138
  pageId: t.String({ description: "Page ID" }),
@@ -61,6 +61,8 @@ export const ISSUE_SOURCE = [
61
61
  ];
62
62
  export const PAGE_STATUS = ["draft", "published", "archived"];
63
63
  export const PAGE_VISIBILITY = ["org", "invited"];
64
+ export const TRANSCRIPTION_LANGUAGE = ["auto", "en", "he"];
65
+ export const TRANSCRIPT_FORMAT = ["txt", "srt", "vtt", "json"];
64
66
  export function enumDescription(name, values) {
65
67
  return `${name}: ${values.join(" | ")}`;
66
68
  }
@@ -0,0 +1,203 @@
1
+ import { openAsBlob } from "node:fs";
2
+ import { readFile, stat } from "node:fs/promises";
3
+ import { extname } from "node:path";
4
+ import * as t from "typebox";
5
+ import { enumSchema, pathSegment, request, TRANSCRIPT_FORMAT, TRANSCRIPTION_LANGUAGE, } from "./shared.js";
6
+ const MEDIA_TYPES = {
7
+ aac: "audio/aac",
8
+ flac: "audio/flac",
9
+ m4a: "audio/m4a",
10
+ mov: "video/quicktime",
11
+ mp3: "audio/mpeg",
12
+ mp4: "video/mp4",
13
+ mpeg: "video/mpeg",
14
+ mpg: "video/mpeg",
15
+ oga: "audio/ogg",
16
+ ogg: "audio/ogg",
17
+ opus: "audio/ogg",
18
+ wav: "audio/wav",
19
+ wave: "audio/wav",
20
+ webm: "video/webm",
21
+ };
22
+ /** Mirrors the public service contract's 5 GiB source-object ceiling. */
23
+ const MAX_MEDIA_BYTES = 5 * 1024 * 1024 * 1024;
24
+ /** Transcript previews returned into the sandbox are capped, not truncated silently. */
25
+ const MAX_TRANSCRIPT_BYTES = 2 * 1024 * 1024;
26
+ const STRICT_OBJECT = { additionalProperties: false };
27
+ const Id = t.String({ minLength: 1, pattern: "\\S" });
28
+ function organizationId(ctx) {
29
+ const value = ctx.connection.config.organizationId;
30
+ if (typeof value !== "string" || !value) {
31
+ throw new Error("SHIFT_LABS_ORG_ID is not set. Transcription actions need the organization ID that owns the API key.");
32
+ }
33
+ return value;
34
+ }
35
+ function mediaTypeFor(path) {
36
+ const mediaType = MEDIA_TYPES[extname(path).slice(1).toLowerCase()];
37
+ if (!mediaType) {
38
+ throw new Error(`Unsupported media extension for ${path}. Supported: ${Object.keys(MEDIA_TYPES).join(", ")}`);
39
+ }
40
+ return mediaType;
41
+ }
42
+ async function fileBody(path, sizeBytes) {
43
+ try {
44
+ return await openAsBlob(path);
45
+ }
46
+ catch {
47
+ // Runtimes without fs.openAsBlob fall back to buffering; refuse to
48
+ // buffer files that would strain the host process.
49
+ if (sizeBytes > 512 * 1024 * 1024) {
50
+ throw new Error("This runtime cannot stream uploads and the file is too large to buffer.");
51
+ }
52
+ return await readFile(path);
53
+ }
54
+ }
55
+ export function registerTranscriptionActions(rl) {
56
+ rl.registerAction("transcription.transcribe", {
57
+ access: "write",
58
+ description: "Upload a local audio or video file and start a transcription job. " +
59
+ "Returns the job; poll transcription.job.get, then read the result " +
60
+ "with transcription.transcript. Diarization labels speakers but is " +
61
+ "much slower.",
62
+ inputSchema: t.Object({
63
+ path: t.String({
64
+ minLength: 1,
65
+ pattern: "\\S",
66
+ description: "Host path of the media file",
67
+ }),
68
+ language: t.Optional(enumSchema("Language (auto handles mixed media)", [
69
+ ...TRANSCRIPTION_LANGUAGE,
70
+ ])),
71
+ diarize: t.Optional(t.Boolean({ description: "Label speakers (slower). Default false" })),
72
+ name: t.Optional(t.String({
73
+ minLength: 1,
74
+ maxLength: 200,
75
+ pattern: "\\S",
76
+ description: "Label shown in Shift Cloud",
77
+ })),
78
+ waitSeconds: t.Optional(t.Number({
79
+ minimum: 0,
80
+ maximum: 120,
81
+ description: "Block up to this many seconds for completion. Longer media should be polled instead.",
82
+ })),
83
+ }, STRICT_OBJECT),
84
+ async execute(input, ctx) {
85
+ const fields = input;
86
+ const org = organizationId(ctx);
87
+ const contentType = mediaTypeFor(fields.path);
88
+ const file = await stat(fields.path);
89
+ if (!file.isFile())
90
+ throw new Error(`${fields.path} is not a file`);
91
+ if (file.size === 0)
92
+ throw new Error("Media file is empty");
93
+ if (file.size > MAX_MEDIA_BYTES) {
94
+ throw new Error(`Media file is larger than the ${MAX_MEDIA_BYTES}-byte service limit`);
95
+ }
96
+ const created = await request(ctx, "/v1/services/transcription/assets", {
97
+ method: "POST",
98
+ body: JSON.stringify({
99
+ organizationId: org,
100
+ contentType,
101
+ sizeBytes: file.size,
102
+ }),
103
+ });
104
+ const uploadHeaders = new Headers(created.upload.headers);
105
+ if (!uploadHeaders.has("content-type")) {
106
+ uploadHeaders.set("content-type", contentType);
107
+ }
108
+ const upload = await fetch(created.upload.url, {
109
+ method: created.upload.method,
110
+ headers: uploadHeaders,
111
+ body: await fileBody(fields.path, file.size),
112
+ });
113
+ if (!upload.ok) {
114
+ throw new Error(`Media upload failed: HTTP ${upload.status}`);
115
+ }
116
+ await request(ctx, `/v1/services/transcription/assets/${pathSegment(created.asset.id)}/complete`, { method: "POST" });
117
+ const job = await request(ctx, "/v1/services/transcription/jobs", {
118
+ method: "POST",
119
+ body: JSON.stringify({
120
+ organizationId: org,
121
+ assetId: created.asset.id,
122
+ language: fields.language,
123
+ diarize: fields.diarize,
124
+ name: fields.name,
125
+ }),
126
+ });
127
+ if (!fields.waitSeconds)
128
+ return job;
129
+ const timeoutMs = Math.min(Math.max(fields.waitSeconds, 1), 120) * 1000;
130
+ return request(ctx, `/v1/services/transcription/jobs/${pathSegment(job.id)}/await?timeoutMs=${timeoutMs}`, { method: "POST" });
131
+ },
132
+ });
133
+ rl.registerAction("transcription.job.list", {
134
+ access: "read",
135
+ description: "List transcription jobs for the API key's organization, newest first.",
136
+ inputSchema: t.Object({}, STRICT_OBJECT),
137
+ async execute(_input, ctx) {
138
+ const body = await request(ctx, `/v1/services/transcription/jobs?organizationId=${pathSegment(organizationId(ctx))}`);
139
+ return body.jobs;
140
+ },
141
+ });
142
+ rl.registerAction("transcription.job.get", {
143
+ access: "read",
144
+ description: "Get a transcription job: status, progress, duration, speaker count.",
145
+ inputSchema: t.Object({ id: Id }, STRICT_OBJECT),
146
+ async execute(input, ctx) {
147
+ const { id } = input;
148
+ return request(ctx, `/v1/services/transcription/jobs/${pathSegment(id)}`);
149
+ },
150
+ });
151
+ rl.registerAction("transcription.job.cancel", {
152
+ access: "write",
153
+ description: "Cancel a queued or running transcription job.",
154
+ inputSchema: t.Object({ id: Id }, STRICT_OBJECT),
155
+ async execute(input, ctx) {
156
+ const { id } = input;
157
+ return request(ctx, `/v1/services/transcription/jobs/${pathSegment(id)}/cancel`, { method: "POST" });
158
+ },
159
+ });
160
+ rl.registerAction("transcription.artifact.list", {
161
+ access: "read",
162
+ description: "List the available transcript artifacts for a job.",
163
+ inputSchema: t.Object({ jobId: Id }, STRICT_OBJECT),
164
+ async execute(input, ctx) {
165
+ const { jobId } = input;
166
+ const body = await request(ctx, `/v1/services/transcription/jobs/${pathSegment(jobId)}/artifacts`);
167
+ return body.artifacts;
168
+ },
169
+ });
170
+ rl.registerAction("transcription.transcript", {
171
+ access: "read",
172
+ description: "Fetch a finished job's transcript. txt returns plain text; srt/vtt " +
173
+ "return subtitles; json returns the full timestamped document. Set " +
174
+ "downloadOnly=true to return the short-lived signed download grant.",
175
+ inputSchema: t.Object({
176
+ jobId: Id,
177
+ format: t.Optional(enumSchema("Transcript format", [...TRANSCRIPT_FORMAT])),
178
+ downloadOnly: t.Optional(t.Boolean({ description: "Return a signed download grant only" })),
179
+ }, STRICT_OBJECT),
180
+ async execute(input, ctx) {
181
+ const fields = input;
182
+ const format = fields.format ?? "txt";
183
+ const grant = await request(ctx, `/v1/services/transcription/jobs/${pathSegment(fields.jobId)}/artifacts/${pathSegment(format)}/download`, { method: "POST" });
184
+ if (fields.downloadOnly ||
185
+ grant.artifact.sizeBytes > MAX_TRANSCRIPT_BYTES) {
186
+ return { format, ...grant };
187
+ }
188
+ const response = await fetch(grant.download.url, {
189
+ method: grant.download.method,
190
+ });
191
+ if (!response.ok) {
192
+ throw new Error(`Transcript download failed: HTTP ${response.status}`);
193
+ }
194
+ const content = await response.text();
195
+ if (Buffer.byteLength(content, "utf8") > MAX_TRANSCRIPT_BYTES) {
196
+ return { format, ...grant };
197
+ }
198
+ return format === "json"
199
+ ? { format, document: JSON.parse(content) }
200
+ : { format, content };
201
+ },
202
+ });
203
+ }
@@ -75,6 +75,7 @@ export default function shopify(rl) {
75
75
  });
76
76
  // ── Order ───────────────────────────────────────────
77
77
  rl.registerAction("order.create", {
78
+ access: "write",
78
79
  description: "Create an order",
79
80
  inputSchema: {
80
81
  lineItems: {
@@ -110,6 +111,7 @@ export default function shopify(rl) {
110
111
  },
111
112
  });
112
113
  rl.registerAction("order.get", {
114
+ access: "read",
113
115
  description: "Get an order by ID",
114
116
  inputSchema: {
115
117
  orderId: { type: "string", required: true },
@@ -125,6 +127,7 @@ export default function shopify(rl) {
125
127
  },
126
128
  });
127
129
  rl.registerAction("order.list", {
130
+ access: "read",
128
131
  description: "List orders",
129
132
  inputSchema: {
130
133
  status: {
@@ -155,6 +158,7 @@ export default function shopify(rl) {
155
158
  },
156
159
  });
157
160
  rl.registerAction("order.update", {
161
+ access: "write",
158
162
  description: "Update an order",
159
163
  inputSchema: {
160
164
  orderId: { type: "string", required: true },
@@ -176,6 +180,7 @@ export default function shopify(rl) {
176
180
  },
177
181
  });
178
182
  rl.registerAction("order.delete", {
183
+ access: "write",
179
184
  description: "Delete an order",
180
185
  inputSchema: { orderId: { type: "string", required: true } },
181
186
  async execute(input, ctx) {
@@ -185,6 +190,7 @@ export default function shopify(rl) {
185
190
  });
186
191
  // ── Product ─────────────────────────────────────────
187
192
  rl.registerAction("product.create", {
193
+ access: "write",
188
194
  description: "Create a product",
189
195
  inputSchema: {
190
196
  title: { type: "string", required: true },
@@ -202,6 +208,7 @@ export default function shopify(rl) {
202
208
  },
203
209
  });
204
210
  rl.registerAction("product.get", {
211
+ access: "read",
205
212
  description: "Get a product by ID",
206
213
  inputSchema: {
207
214
  productId: { type: "string", required: true },
@@ -217,6 +224,7 @@ export default function shopify(rl) {
217
224
  },
218
225
  });
219
226
  rl.registerAction("product.list", {
227
+ access: "read",
220
228
  description: "List products",
221
229
  inputSchema: {
222
230
  limit: { type: "number", required: false },
@@ -237,6 +245,7 @@ export default function shopify(rl) {
237
245
  },
238
246
  });
239
247
  rl.registerAction("product.update", {
248
+ access: "write",
240
249
  description: "Update a product",
241
250
  inputSchema: {
242
251
  productId: { type: "string", required: true },
@@ -253,6 +262,7 @@ export default function shopify(rl) {
253
262
  },
254
263
  });
255
264
  rl.registerAction("product.delete", {
265
+ access: "write",
256
266
  description: "Delete a product",
257
267
  inputSchema: { productId: { type: "string", required: true } },
258
268
  async execute(input, ctx) {