runline 0.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 (230) hide show
  1. package/.pi/extensions/runline-context/index.ts +135 -0
  2. package/.pi/extensions/runline-context/package.json +17 -0
  3. package/README.md +273 -0
  4. package/dist/commands/actions.d.ts +3 -0
  5. package/dist/commands/actions.js +43 -0
  6. package/dist/commands/connection.d.ts +11 -0
  7. package/dist/commands/connection.js +56 -0
  8. package/dist/commands/exec.d.ts +5 -0
  9. package/dist/commands/exec.js +46 -0
  10. package/dist/commands/init.d.ts +4 -0
  11. package/dist/commands/init.js +26 -0
  12. package/dist/commands/plugin.d.ts +10 -0
  13. package/dist/commands/plugin.js +57 -0
  14. package/dist/config/index.d.ts +3 -0
  15. package/dist/config/index.js +2 -0
  16. package/dist/config/loader.d.ts +11 -0
  17. package/dist/config/loader.js +82 -0
  18. package/dist/config/types.d.ts +9 -0
  19. package/dist/config/types.js +5 -0
  20. package/dist/core/engine.d.ts +21 -0
  21. package/dist/core/engine.js +280 -0
  22. package/dist/index.d.ts +16 -0
  23. package/dist/index.js +9 -0
  24. package/dist/main.d.ts +2 -0
  25. package/dist/main.js +127 -0
  26. package/dist/plugin/api.d.ts +32 -0
  27. package/dist/plugin/api.js +68 -0
  28. package/dist/plugin/installer.d.ts +27 -0
  29. package/dist/plugin/installer.js +181 -0
  30. package/dist/plugin/loader.d.ts +13 -0
  31. package/dist/plugin/loader.js +164 -0
  32. package/dist/plugin/registry.d.ts +18 -0
  33. package/dist/plugin/registry.js +43 -0
  34. package/dist/plugin/types.d.ts +40 -0
  35. package/dist/plugin/types.js +1 -0
  36. package/dist/plugins/actionNetwork/src/index.js +353 -0
  37. package/dist/plugins/activeCampaign/src/index.js +711 -0
  38. package/dist/plugins/adalo/src/index.js +131 -0
  39. package/dist/plugins/affinity/src/index.js +279 -0
  40. package/dist/plugins/agileCrm/src/index.js +415 -0
  41. package/dist/plugins/airtable/src/index.js +280 -0
  42. package/dist/plugins/airtop/src/index.js +527 -0
  43. package/dist/plugins/apiTemplateIo/src/index.js +86 -0
  44. package/dist/plugins/asana/src/index.js +413 -0
  45. package/dist/plugins/autopilot/src/index.js +203 -0
  46. package/dist/plugins/bambooHr/src/index.js +252 -0
  47. package/dist/plugins/bannerbear/src/index.js +100 -0
  48. package/dist/plugins/baserow/src/index.js +180 -0
  49. package/dist/plugins/beeminder/src/index.js +298 -0
  50. package/dist/plugins/bitly/src/index.js +107 -0
  51. package/dist/plugins/bitwarden/src/index.js +383 -0
  52. package/dist/plugins/box/src/index.js +300 -0
  53. package/dist/plugins/brandfetch/src/index.js +80 -0
  54. package/dist/plugins/brevo/src/index.js +305 -0
  55. package/dist/plugins/bubble/src/index.js +181 -0
  56. package/dist/plugins/chargebee/src/index.js +126 -0
  57. package/dist/plugins/circleci/src/index.js +111 -0
  58. package/dist/plugins/ciscoWebex/src/index.js +245 -0
  59. package/dist/plugins/clearbit/src/index.js +103 -0
  60. package/dist/plugins/clickup/src/index.js +1043 -0
  61. package/dist/plugins/clockify/src/index.js +443 -0
  62. package/dist/plugins/cloudflare/src/index.js +93 -0
  63. package/dist/plugins/cockpit/src/index.js +131 -0
  64. package/dist/plugins/coda/src/index.js +327 -0
  65. package/dist/plugins/coingecko/src/index.js +244 -0
  66. package/dist/plugins/contentful/src/index.js +146 -0
  67. package/dist/plugins/convertkit/src/index.js +270 -0
  68. package/dist/plugins/copper/src/index.js +140 -0
  69. package/dist/plugins/cortex/src/index.js +147 -0
  70. package/dist/plugins/currents/src/index.js +405 -0
  71. package/dist/plugins/customerIo/src/index.js +184 -0
  72. package/dist/plugins/databricks/src/index.js +342 -0
  73. package/dist/plugins/deepl/src/index.js +87 -0
  74. package/dist/plugins/demio/src/index.js +111 -0
  75. package/dist/plugins/dhl/src/index.js +40 -0
  76. package/dist/plugins/discord/src/index.js +275 -0
  77. package/dist/plugins/discourse/src/index.js +273 -0
  78. package/dist/plugins/disqus/src/index.js +145 -0
  79. package/dist/plugins/docker/src/index.js +76 -0
  80. package/dist/plugins/drift/src/index.js +89 -0
  81. package/dist/plugins/dropbox/src/index.js +159 -0
  82. package/dist/plugins/dropcontact/src/index.js +59 -0
  83. package/dist/plugins/egoi/src/index.js +151 -0
  84. package/dist/plugins/elasticsearch/src/index.js +157 -0
  85. package/dist/plugins/emelia/src/index.js +174 -0
  86. package/dist/plugins/erpnext/src/index.js +121 -0
  87. package/dist/plugins/facebookGraph/src/index.js +57 -0
  88. package/dist/plugins/freshdesk/src/index.js +320 -0
  89. package/dist/plugins/freshservice/src/index.js +146 -0
  90. package/dist/plugins/freshworksCrm/src/index.js +149 -0
  91. package/dist/plugins/getresponse/src/index.js +140 -0
  92. package/dist/plugins/ghost/src/index.js +192 -0
  93. package/dist/plugins/github/src/index.js +630 -0
  94. package/dist/plugins/gitlab/src/index.js +358 -0
  95. package/dist/plugins/gong/src/index.js +126 -0
  96. package/dist/plugins/gotify/src/index.js +77 -0
  97. package/dist/plugins/gotowebinar/src/index.js +316 -0
  98. package/dist/plugins/grafana/src/index.js +250 -0
  99. package/dist/plugins/graphql/src/index.js +78 -0
  100. package/dist/plugins/grist/src/index.js +106 -0
  101. package/dist/plugins/hackernews/src/index.js +89 -0
  102. package/dist/plugins/halopsa/src/index.js +79 -0
  103. package/dist/plugins/harvest/src/index.js +163 -0
  104. package/dist/plugins/helpscout/src/index.js +176 -0
  105. package/dist/plugins/highlevel/src/index.js +172 -0
  106. package/dist/plugins/homeAssistant/src/index.js +148 -0
  107. package/dist/plugins/hubspot/src/index.js +176 -0
  108. package/dist/plugins/humanticAi/src/index.js +60 -0
  109. package/dist/plugins/hunter/src/index.js +59 -0
  110. package/dist/plugins/intercom/src/index.js +156 -0
  111. package/dist/plugins/iterable/src/index.js +139 -0
  112. package/dist/plugins/jenkins/src/index.js +132 -0
  113. package/dist/plugins/jira/src/index.js +229 -0
  114. package/dist/plugins/keap/src/index.js +502 -0
  115. package/dist/plugins/kobotoolbox/src/index.js +281 -0
  116. package/dist/plugins/lemlist/src/index.js +231 -0
  117. package/dist/plugins/linear/src/index.js +133 -0
  118. package/dist/plugins/lingvanex/src/index.js +31 -0
  119. package/dist/plugins/linkedin/src/index.js +80 -0
  120. package/dist/plugins/lonescale/src/index.js +119 -0
  121. package/dist/plugins/magento/src/index.js +300 -0
  122. package/dist/plugins/mailcheck/src/index.js +27 -0
  123. package/dist/plugins/mailchimp/src/index.js +321 -0
  124. package/dist/plugins/mailerlite/src/index.js +123 -0
  125. package/dist/plugins/mailgun/src/index.js +48 -0
  126. package/dist/plugins/mailjet/src/index.js +155 -0
  127. package/dist/plugins/mandrill/src/index.js +145 -0
  128. package/dist/plugins/marketstack/src/index.js +97 -0
  129. package/dist/plugins/matrix/src/index.js +194 -0
  130. package/dist/plugins/mattermost/src/index.js +331 -0
  131. package/dist/plugins/mautic/src/index.js +311 -0
  132. package/dist/plugins/medium/src/index.js +77 -0
  133. package/dist/plugins/messagebird/src/index.js +57 -0
  134. package/dist/plugins/metabase/src/index.js +130 -0
  135. package/dist/plugins/misp/src/index.js +476 -0
  136. package/dist/plugins/mocean/src/index.js +67 -0
  137. package/dist/plugins/monday/src/index.js +231 -0
  138. package/dist/plugins/monicaCrm/src/index.js +52 -0
  139. package/dist/plugins/msg91/src/index.js +31 -0
  140. package/dist/plugins/nasa/src/index.js +146 -0
  141. package/dist/plugins/netlify/src/index.js +151 -0
  142. package/dist/plugins/netscalerAdc/src/index.js +131 -0
  143. package/dist/plugins/nextcloud/src/index.js +263 -0
  144. package/dist/plugins/nocodb/src/index.js +130 -0
  145. package/dist/plugins/notion/src/index.js +112 -0
  146. package/dist/plugins/npm/src/index.js +104 -0
  147. package/dist/plugins/odoo/src/index.js +157 -0
  148. package/dist/plugins/okta/src/index.js +141 -0
  149. package/dist/plugins/oneSimpleApi/src/index.js +155 -0
  150. package/dist/plugins/onfleet/src/index.js +254 -0
  151. package/dist/plugins/openThesaurus/src/index.js +32 -0
  152. package/dist/plugins/openweathermap/src/index.js +60 -0
  153. package/dist/plugins/oura/src/index.js +62 -0
  154. package/dist/plugins/paddle/src/index.js +247 -0
  155. package/dist/plugins/pagerduty/src/index.js +201 -0
  156. package/dist/plugins/paypal/src/index.js +106 -0
  157. package/dist/plugins/peekalink/src/index.js +35 -0
  158. package/dist/plugins/phantombuster/src/index.js +94 -0
  159. package/dist/plugins/philipsHue/src/index.js +98 -0
  160. package/dist/plugins/pipedrive/src/index.js +169 -0
  161. package/dist/plugins/plivo/src/index.js +66 -0
  162. package/dist/plugins/postbin/src/index.js +93 -0
  163. package/dist/plugins/posthog/src/index.js +113 -0
  164. package/dist/plugins/profitwell/src/index.js +50 -0
  165. package/dist/plugins/pushbullet/src/index.js +102 -0
  166. package/dist/plugins/pushcut/src/index.js +39 -0
  167. package/dist/plugins/pushover/src/index.js +65 -0
  168. package/dist/plugins/quickbase/src/index.js +153 -0
  169. package/dist/plugins/quickbooks/src/index.js +73 -0
  170. package/dist/plugins/quickchart/src/index.js +36 -0
  171. package/dist/plugins/raindrop/src/index.js +209 -0
  172. package/dist/plugins/reddit/src/index.js +185 -0
  173. package/dist/plugins/rocketchat/src/index.js +53 -0
  174. package/dist/plugins/rundeck/src/index.js +62 -0
  175. package/dist/plugins/salesforce/src/index.js +94 -0
  176. package/dist/plugins/salesmate/src/index.js +83 -0
  177. package/dist/plugins/securityScorecard/src/index.js +200 -0
  178. package/dist/plugins/segment/src/index.js +125 -0
  179. package/dist/plugins/sendgrid/src/index.js +187 -0
  180. package/dist/plugins/sendy/src/index.js +138 -0
  181. package/dist/plugins/sentry/src/index.js +233 -0
  182. package/dist/plugins/servicenow/src/index.js +108 -0
  183. package/dist/plugins/shopify/src/index.js +222 -0
  184. package/dist/plugins/signl4/src/index.js +61 -0
  185. package/dist/plugins/slack/src/index.js +236 -0
  186. package/dist/plugins/sms77/src/index.js +63 -0
  187. package/dist/plugins/splunk/src/index.js +207 -0
  188. package/dist/plugins/spotify/src/index.js +188 -0
  189. package/dist/plugins/stackby/src/index.js +82 -0
  190. package/dist/plugins/storyblok/src/index.js +141 -0
  191. package/dist/plugins/strapi/src/index.js +152 -0
  192. package/dist/plugins/strava/src/index.js +137 -0
  193. package/dist/plugins/stripe/src/index.js +222 -0
  194. package/dist/plugins/supabase/src/index.js +121 -0
  195. package/dist/plugins/syncromsp/src/index.js +255 -0
  196. package/dist/plugins/tapfiliate/src/index.js +125 -0
  197. package/dist/plugins/telegram/src/index.js +233 -0
  198. package/dist/plugins/thehive/src/index.js +142 -0
  199. package/dist/plugins/thehiveProject/src/index.js +194 -0
  200. package/dist/plugins/todoist/src/index.js +244 -0
  201. package/dist/plugins/travisci/src/index.js +71 -0
  202. package/dist/plugins/trello/src/index.js +341 -0
  203. package/dist/plugins/twake/src/index.js +40 -0
  204. package/dist/plugins/twilio/src/index.js +75 -0
  205. package/dist/plugins/twist/src/index.js +90 -0
  206. package/dist/plugins/twitter/src/index.js +123 -0
  207. package/dist/plugins/unleashedSoftware/src/index.js +84 -0
  208. package/dist/plugins/uplead/src/index.js +59 -0
  209. package/dist/plugins/uproc/src/index.js +34 -0
  210. package/dist/plugins/uptimerobot/src/index.js +264 -0
  211. package/dist/plugins/urlscanio/src/index.js +64 -0
  212. package/dist/plugins/vero/src/index.js +80 -0
  213. package/dist/plugins/vonage/src/index.js +42 -0
  214. package/dist/plugins/wekan/src/index.js +91 -0
  215. package/dist/plugins/woocommerce/src/index.js +92 -0
  216. package/dist/plugins/wordpress/src/index.js +121 -0
  217. package/dist/plugins/xero/src/index.js +136 -0
  218. package/dist/plugins/yourls/src/index.js +56 -0
  219. package/dist/plugins/zammad/src/index.js +91 -0
  220. package/dist/plugins/zendesk/src/index.js +137 -0
  221. package/dist/plugins/zoho/src/index.js +85 -0
  222. package/dist/plugins/zoom/src/index.js +122 -0
  223. package/dist/plugins/zulip/src/index.js +170 -0
  224. package/dist/sdk.d.ts +38 -0
  225. package/dist/sdk.js +105 -0
  226. package/dist/utils/cli.d.ts +13 -0
  227. package/dist/utils/cli.js +32 -0
  228. package/dist/utils/output.d.ts +4 -0
  229. package/dist/utils/output.js +13 -0
  230. package/package.json +57 -0
@@ -0,0 +1,77 @@
1
+ const BASE_URL = "https://api.medium.com/v1";
2
+ async function apiRequest(token, method, endpoint, body) {
3
+ const opts = {
4
+ method,
5
+ headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json", Accept: "application/json", "Accept-Charset": "utf-8" },
6
+ };
7
+ if (body && Object.keys(body).length > 0 && method !== "GET")
8
+ opts.body = JSON.stringify(body);
9
+ const res = await fetch(`${BASE_URL}${endpoint}`, opts);
10
+ if (!res.ok)
11
+ throw new Error(`Medium API error ${res.status}: ${await res.text()}`);
12
+ return res.json();
13
+ }
14
+ export default function medium(rl) {
15
+ rl.setName("medium");
16
+ rl.setVersion("0.1.0");
17
+ rl.setConnectionSchema({
18
+ accessToken: { type: "string", required: true, description: "Medium integration token", env: "MEDIUM_ACCESS_TOKEN" },
19
+ });
20
+ const tok = (ctx) => ctx.connection.config.accessToken;
21
+ rl.registerAction("post.create", {
22
+ description: "Create a post on Medium. Posts under the authenticated user by default, or under a publication if publicationId is provided.",
23
+ inputSchema: {
24
+ title: { type: "string", required: true, description: "Post title (max 100 chars)" },
25
+ contentFormat: { type: "string", required: true, description: "'html' or 'markdown'" },
26
+ content: { type: "string", required: true, description: "Post body in the specified format" },
27
+ publicationId: { type: "string", required: false, description: "Publication ID to post under (omit for personal post)" },
28
+ tags: { type: "array", required: false, description: "Array of tag strings (max 5, each max 25 chars)" },
29
+ canonicalUrl: { type: "string", required: false, description: "Original URL if cross-posting" },
30
+ publishStatus: { type: "string", required: false, description: "'public' (default), 'draft', or 'unlisted'" },
31
+ license: { type: "string", required: false, description: "License: all-rights-reserved, cc-40-by, cc-40-by-nc, cc-40-by-nc-nd, cc-40-by-nc-sa, cc-40-by-nd, cc-40-by-sa, cc-40-zero, public-domain" },
32
+ notifyFollowers: { type: "boolean", required: false, description: "Notify followers" },
33
+ },
34
+ async execute(input, ctx) {
35
+ const { title, contentFormat, content, publicationId, tags, canonicalUrl, publishStatus, license, notifyFollowers } = input;
36
+ const body = { title, contentFormat, content, tags: tags ?? [] };
37
+ if (canonicalUrl)
38
+ body.canonicalUrl = canonicalUrl;
39
+ if (publishStatus)
40
+ body.publishStatus = publishStatus;
41
+ if (license)
42
+ body.license = license;
43
+ if (notifyFollowers !== undefined)
44
+ body.notifyFollowers = notifyFollowers;
45
+ if (publicationId) {
46
+ const resp = (await apiRequest(tok(ctx), "POST", `/publications/${publicationId}/posts`, body));
47
+ return resp.data;
48
+ }
49
+ // Get authenticated user ID first
50
+ const me = (await apiRequest(tok(ctx), "GET", "/me"));
51
+ const authorId = me.data.id;
52
+ const resp = (await apiRequest(tok(ctx), "POST", `/users/${authorId}/posts`, body));
53
+ return resp.data;
54
+ },
55
+ });
56
+ rl.registerAction("publication.list", {
57
+ description: "List publications for the authenticated user",
58
+ inputSchema: { limit: { type: "number", required: false } },
59
+ async execute(input, ctx) {
60
+ const { limit } = (input ?? {});
61
+ const me = (await apiRequest(tok(ctx), "GET", "/me"));
62
+ const userId = me.data.id;
63
+ const resp = (await apiRequest(tok(ctx), "GET", `/users/${userId}/publications`));
64
+ let data = resp.data;
65
+ if (limit)
66
+ data = data.slice(0, limit);
67
+ return data;
68
+ },
69
+ });
70
+ rl.registerAction("me", {
71
+ description: "Get the authenticated user's profile",
72
+ async execute(_input, ctx) {
73
+ const resp = (await apiRequest(tok(ctx), "GET", "/me"));
74
+ return resp.data;
75
+ },
76
+ });
77
+ }
@@ -0,0 +1,57 @@
1
+ const BASE_URL = "https://rest.messagebird.com";
2
+ async function apiRequest(accessKey, method, endpoint, body) {
3
+ const opts = {
4
+ method,
5
+ headers: { Authorization: `AccessKey ${accessKey}`, Accept: "application/json", "Content-Type": "application/json" },
6
+ };
7
+ if (body && Object.keys(body).length > 0 && method !== "GET")
8
+ opts.body = JSON.stringify(body);
9
+ const res = await fetch(`${BASE_URL}${endpoint}`, opts);
10
+ if (!res.ok)
11
+ throw new Error(`MessageBird API error ${res.status}: ${await res.text()}`);
12
+ return res.json();
13
+ }
14
+ export default function messagebird(rl) {
15
+ rl.setName("messagebird");
16
+ rl.setVersion("0.1.0");
17
+ rl.setConnectionSchema({
18
+ accessKey: { type: "string", required: true, description: "MessageBird access key", env: "MESSAGEBIRD_ACCESS_KEY" },
19
+ });
20
+ const key = (ctx) => ctx.connection.config.accessKey;
21
+ rl.registerAction("sms.send", {
22
+ description: "Send an SMS message",
23
+ inputSchema: {
24
+ originator: { type: "string", required: true, description: "Sender number or alphanumeric (max 11 chars)" },
25
+ recipients: { type: "string", required: true, description: "Comma-separated recipient phone numbers (international format)" },
26
+ body: { type: "string", required: true, description: "Message text" },
27
+ type: { type: "string", required: false, description: "sms (default), binary, or flash" },
28
+ datacoding: { type: "string", required: false, description: "auto, plain, or unicode" },
29
+ reference: { type: "string", required: false, description: "Client reference" },
30
+ reportUrl: { type: "string", required: false, description: "Status report webhook URL (requires reference)" },
31
+ validity: { type: "number", required: false, description: "Validity in seconds" },
32
+ gateway: { type: "number", required: false, description: "SMS route gateway" },
33
+ mclass: { type: "number", required: false, description: "0=normal, 1=flash" },
34
+ scheduledDatetime: { type: "string", required: false, description: "Scheduled send time (RFC3339)" },
35
+ groupIds: { type: "string", required: false, description: "Comma-separated group IDs (alternative to recipients)" },
36
+ },
37
+ async execute(input, ctx) {
38
+ const p = input;
39
+ const body = {
40
+ originator: p.originator,
41
+ body: p.body,
42
+ recipients: p.recipients.split(",").map((r) => Number.parseInt(r.trim(), 10)),
43
+ };
44
+ for (const k of ["type", "datacoding", "reference", "reportUrl", "validity", "gateway", "mclass", "scheduledDatetime", "groupIds"]) {
45
+ if (p[k] !== undefined && p[k] !== null)
46
+ body[k] = p[k];
47
+ }
48
+ return apiRequest(key(ctx), "POST", "/messages", body);
49
+ },
50
+ });
51
+ rl.registerAction("balance.get", {
52
+ description: "Get current account balance",
53
+ async execute(_input, ctx) {
54
+ return apiRequest(key(ctx), "GET", "/balance");
55
+ },
56
+ });
57
+ }
@@ -0,0 +1,130 @@
1
+ async function apiRequest(baseUrl, sessionToken, method, endpoint, body) {
2
+ const opts = {
3
+ method,
4
+ headers: { "X-Metabase-Session": sessionToken, "Content-Type": "application/json" },
5
+ };
6
+ if (body && Object.keys(body).length > 0 && method !== "GET" && method !== "DELETE")
7
+ opts.body = JSON.stringify(body);
8
+ const res = await fetch(`${baseUrl}${endpoint}`, opts);
9
+ if (!res.ok)
10
+ throw new Error(`Metabase API error ${res.status}: ${await res.text()}`);
11
+ return res.json();
12
+ }
13
+ export default function metabase(rl) {
14
+ rl.setName("metabase");
15
+ rl.setVersion("0.1.0");
16
+ rl.setConnectionSchema({
17
+ url: { type: "string", required: true, description: "Metabase instance URL (e.g. https://metabase.example.com)", env: "METABASE_URL" },
18
+ sessionToken: { type: "string", required: true, description: "Metabase session token (from POST /api/session)", env: "METABASE_SESSION_TOKEN" },
19
+ });
20
+ const conn = (ctx) => ({
21
+ baseUrl: ctx.connection.config.url.replace(/\/$/, ""),
22
+ token: ctx.connection.config.sessionToken,
23
+ });
24
+ // ── Question (Card) ─────────────────────────────────
25
+ rl.registerAction("question.get", {
26
+ description: "Get a specific question/card",
27
+ inputSchema: { questionId: { type: "number", required: true } },
28
+ async execute(input, ctx) {
29
+ const { baseUrl, token } = conn(ctx);
30
+ return apiRequest(baseUrl, token, "GET", `/api/card/${input.questionId}`);
31
+ },
32
+ });
33
+ rl.registerAction("question.list", {
34
+ description: "List all questions/cards",
35
+ async execute(_input, ctx) {
36
+ const { baseUrl, token } = conn(ctx);
37
+ return apiRequest(baseUrl, token, "GET", "/api/card/");
38
+ },
39
+ });
40
+ rl.registerAction("question.getResults", {
41
+ description: "Get the results of a question as JSON",
42
+ inputSchema: {
43
+ questionId: { type: "number", required: true },
44
+ format: { type: "string", required: false, description: "json (default), csv, xlsx — note: only json returns structured data" },
45
+ },
46
+ async execute(input, ctx) {
47
+ const { questionId, format = "json" } = input;
48
+ const { baseUrl, token } = conn(ctx);
49
+ return apiRequest(baseUrl, token, "POST", `/api/card/${questionId}/query/${format}`);
50
+ },
51
+ });
52
+ // ── Alert ───────────────────────────────────────────
53
+ rl.registerAction("alert.get", {
54
+ description: "Get a specific alert",
55
+ inputSchema: { alertId: { type: "number", required: true } },
56
+ async execute(input, ctx) {
57
+ const { baseUrl, token } = conn(ctx);
58
+ return apiRequest(baseUrl, token, "GET", `/api/alert/${input.alertId}`);
59
+ },
60
+ });
61
+ rl.registerAction("alert.list", {
62
+ description: "List all alerts",
63
+ async execute(_input, ctx) {
64
+ const { baseUrl, token } = conn(ctx);
65
+ return apiRequest(baseUrl, token, "GET", "/api/alert/");
66
+ },
67
+ });
68
+ // ── Database ────────────────────────────────────────
69
+ rl.registerAction("database.list", {
70
+ description: "List all databases",
71
+ async execute(_input, ctx) {
72
+ const { baseUrl, token } = conn(ctx);
73
+ const data = (await apiRequest(baseUrl, token, "GET", "/api/database/"));
74
+ return data.data;
75
+ },
76
+ });
77
+ rl.registerAction("database.getFields", {
78
+ description: "Get fields from a database",
79
+ inputSchema: { databaseId: { type: "number", required: true } },
80
+ async execute(input, ctx) {
81
+ const { baseUrl, token } = conn(ctx);
82
+ return apiRequest(baseUrl, token, "GET", `/api/database/${input.databaseId}/fields`);
83
+ },
84
+ });
85
+ rl.registerAction("database.add", {
86
+ description: "Add a new database/datasource",
87
+ inputSchema: {
88
+ name: { type: "string", required: true, description: "Display name" },
89
+ engine: { type: "string", required: true, description: "postgres, mysql, h2, sqlite, mongo, redshift" },
90
+ host: { type: "string", required: false, description: "Database host (for postgres/mysql/mongo/redshift)" },
91
+ port: { type: "number", required: false, description: "Database port" },
92
+ user: { type: "string", required: false, description: "Database user" },
93
+ password: { type: "string", required: false, description: "Database password" },
94
+ dbName: { type: "string", required: false, description: "Database name or file path (for h2/sqlite)" },
95
+ isFullSync: { type: "boolean", required: false, description: "Full sync (default true)" },
96
+ },
97
+ async execute(input, ctx) {
98
+ const { name, engine, host, port, user, password, dbName, isFullSync = true } = input;
99
+ const { baseUrl, token } = conn(ctx);
100
+ const details = {};
101
+ if (host)
102
+ details.host = host;
103
+ if (port)
104
+ details.port = port;
105
+ if (user)
106
+ details.user = user;
107
+ if (password)
108
+ details.password = password;
109
+ if (dbName)
110
+ details.db = dbName;
111
+ return apiRequest(baseUrl, token, "POST", "/api/database", { name, engine, details, is_full_sync: isFullSync });
112
+ },
113
+ });
114
+ // ── Metric ──────────────────────────────────────────
115
+ rl.registerAction("metric.get", {
116
+ description: "Get a specific metric",
117
+ inputSchema: { metricId: { type: "number", required: true } },
118
+ async execute(input, ctx) {
119
+ const { baseUrl, token } = conn(ctx);
120
+ return apiRequest(baseUrl, token, "GET", `/api/metric/${input.metricId}`);
121
+ },
122
+ });
123
+ rl.registerAction("metric.list", {
124
+ description: "List all metrics",
125
+ async execute(_input, ctx) {
126
+ const { baseUrl, token } = conn(ctx);
127
+ return apiRequest(baseUrl, token, "GET", "/api/metric/");
128
+ },
129
+ });
130
+ }