@credal/actions 0.2.215 → 0.2.217

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 (31) hide show
  1. package/dist/actions/autogen/templates.js +39 -23
  2. package/dist/actions/autogen/types.d.ts +27 -26
  3. package/dist/actions/autogen/types.js +299 -242
  4. package/dist/actions/parse.js +10 -2
  5. package/dist/actions/providers/github/searchRepository.js +7 -7
  6. package/dist/actions/providers/google-oauth/appendRowsToSpreadsheet.js +8 -7
  7. package/dist/actions/providers/google-oauth/listFilesWithAssignedComments.d.ts +3 -0
  8. package/dist/actions/providers/google-oauth/listFilesWithAssignedComments.js +41 -0
  9. package/dist/actions/providers/google-oauth/updateRowsInSpreadsheet.js +18 -12
  10. package/dist/actions/providers/jira/getJiraDCIssuesByQuery.d.ts +4 -3
  11. package/dist/actions/providers/jira/getJiraDCIssuesByQuery.js +7 -3
  12. package/dist/actions/providers/jira/getJiraIssuesByQuery.js +8 -1
  13. package/dist/actions/providers/jira/updateServiceDeskRequest.d.ts +3 -0
  14. package/dist/actions/providers/jira/updateServiceDeskRequest.js +72 -0
  15. package/dist/actions/providers/microsoft/sendOutlookEmail.d.ts +3 -0
  16. package/dist/actions/providers/microsoft/sendOutlookEmail.js +48 -0
  17. package/package.json +1 -1
  18. package/dist/actions/groups.d.ts +0 -6
  19. package/dist/actions/groups.js +0 -248
  20. package/dist/actions/providers/credal/callCopilot.d.ts +0 -3
  21. package/dist/actions/providers/credal/callCopilot.js +0 -36
  22. package/dist/actions/providers/math/index.d.ts +0 -1
  23. package/dist/actions/providers/math/index.js +0 -37
  24. package/dist/actions/providers/salesforce/getSalesforceRecordByQuery.d.ts +0 -3
  25. package/dist/actions/providers/salesforce/getSalesforceRecordByQuery.js +0 -43
  26. package/dist/actions/providers/slack/archiveChannel.d.ts +0 -3
  27. package/dist/actions/providers/slack/archiveChannel.js +0 -35
  28. package/dist/actions/providers/slack/index.d.ts +0 -1
  29. package/dist/actions/providers/slack/index.js +0 -37
  30. package/dist/actions/providers/slack/listConversations.d.ts +0 -3
  31. package/dist/actions/providers/slack/listConversations.js +0 -41
@@ -125,8 +125,16 @@ async function addActionTypes({ file, prefix, action }) {
125
125
  });
126
126
  }
127
127
  async function addTypesToFile({ file, obj, fallback, name, }) {
128
- // Tool calling framework currently having trouble filling in records as opposed to objects
129
- const zodSchema = obj ? convert(obj).replace(/z\.record\(z\.any\(\)\)/g, "z.object({}).catchall(z.any())") : fallback;
128
+ // Tool calling framework currently having trouble filling in records as opposed to objects.
129
+ // Also coerce numeric types from strings: LLMs often emit numbers as JSON strings (e.g. "2"
130
+ // instead of 2) even when the schema specifies integer/number, causing Zod validation failures.
131
+ // z.coerce.number() is a no-op for actual numbers, so this is fully backward-compatible.
132
+ const zodSchema = obj
133
+ ? convert(obj)
134
+ .replace(/z\.record\(z\.any\(\)\)/g, "z.object({}).catchall(z.any())")
135
+ .replace(/z\.number\(\)\.int\(\)/g, "z.coerce.number().int()")
136
+ .replace(/z\.number\(\)/g, "z.coerce.number()")
137
+ : fallback;
130
138
  const zodName = `${name}Schema`;
131
139
  file.addVariableStatement({
132
140
  declarationKind: VariableDeclarationKind.Const,
@@ -47,7 +47,7 @@ const searchRepository = (_a) => __awaiter(void 0, [_a], void 0, function* ({ pa
47
47
  name: item.name,
48
48
  path: item.path,
49
49
  sha: item.sha.slice(0, 7),
50
- url: item.html_url,
50
+ url: item.url,
51
51
  score: item.score,
52
52
  textMatches: item.text_matches
53
53
  ? item.text_matches.map(match => {
@@ -68,7 +68,7 @@ const searchRepository = (_a) => __awaiter(void 0, [_a], void 0, function* ({ pa
68
68
  const full = commitDetails.find(c => c.data.sha === item.sha);
69
69
  return {
70
70
  sha: item.sha,
71
- url: item.html_url,
71
+ url: item.url,
72
72
  commit: {
73
73
  message: item.commit.message,
74
74
  author: item.commit.author,
@@ -76,11 +76,11 @@ const searchRepository = (_a) => __awaiter(void 0, [_a], void 0, function* ({ pa
76
76
  score: item.score,
77
77
  author: (_a = item.author) !== null && _a !== void 0 ? _a : undefined,
78
78
  files: ((_b = full === null || full === void 0 ? void 0 : full.data.files) === null || _b === void 0 ? void 0 : _b.slice(0, MAX_FILES_PER_COMMIT).map(f => {
79
- var _a, _b, _c;
79
+ var _a;
80
80
  return ({
81
81
  filename: f.filename,
82
82
  status: f.status,
83
- patch: (_c = (_b = (_a = f.patch) === null || _a === void 0 ? void 0 : _a.split("\n")) === null || _b === void 0 ? void 0 : _b.slice(0, MAX_PATCH_LINES)) === null || _c === void 0 ? void 0 : _c.join("\n"),
83
+ patch: (_a = f.patch) === null || _a === void 0 ? void 0 : _a.split("\n").slice(0, MAX_PATCH_LINES).join("\n"),
84
84
  });
85
85
  })) || [],
86
86
  };
@@ -104,18 +104,18 @@ const searchRepository = (_a) => __awaiter(void 0, [_a], void 0, function* ({ pa
104
104
  const prIndex = prNumbers.indexOf(item.number);
105
105
  const files = isPR && prIndex !== -1
106
106
  ? prFiles[prIndex].data.slice(0, MAX_FILES_PER_PR).map(f => {
107
- var _a, _b, _c;
107
+ var _a;
108
108
  return ({
109
109
  filename: f.filename,
110
110
  status: f.status,
111
- patch: (_c = (_b = (_a = f.patch) === null || _a === void 0 ? void 0 : _a.split("\n")) === null || _b === void 0 ? void 0 : _b.slice(0, MAX_PATCH_LINES)) === null || _c === void 0 ? void 0 : _c.join("\n"),
111
+ patch: (_a = f.patch) === null || _a === void 0 ? void 0 : _a.split("\n").slice(0, MAX_PATCH_LINES).join("\n"),
112
112
  });
113
113
  })
114
114
  : undefined;
115
115
  return {
116
116
  number: item.number,
117
117
  title: item.title,
118
- url: item.html_url,
118
+ html_url: item.html_url,
119
119
  state: item.state,
120
120
  isPullRequest: isPR,
121
121
  body: item.body,
@@ -9,16 +9,17 @@ const appendRowsToSpreadsheet = async ({ params, authParams, }) => {
9
9
  throw new Error(MISSING_AUTH_TOKEN);
10
10
  }
11
11
  const { spreadsheetId, sheetName, rows } = params;
12
- // Transform rows from schema format to Google Sheets API format
13
- // Schema: [[{ stringValue: "cell1" }, { stringValue: "cell2" }], ...]
14
- // API expects: [["cell1", "cell2"], ...]
15
- const values = rows.map(row => row.map(cell => cell.stringValue));
16
- const appendUrl = `https://sheets.googleapis.com/v4/spreadsheets/${spreadsheetId}/values/'${sheetName ?? "Sheet1"}':append`;
17
12
  try {
13
+ if (rows.length === 0) {
14
+ throw new Error("rows array cannot be empty");
15
+ }
16
+ const sheet = sheetName ?? "Sheet1";
17
+ const quotedSheet = /[\s'!]/.test(sheet) ? `'${sheet.replace(/'/g, "''")}'` : sheet;
18
+ const appendUrl = `https://sheets.googleapis.com/v4/spreadsheets/${spreadsheetId}/values/${encodeURIComponent(quotedSheet)}:append`;
18
19
  const response = await axiosClient.post(appendUrl, {
19
- values,
20
+ values: rows,
20
21
  majorDimension: "ROWS",
21
- range: `'${sheetName}'`,
22
+ range: quotedSheet,
22
23
  }, {
23
24
  headers: {
24
25
  Authorization: `Bearer ${authParams.authToken}`,
@@ -0,0 +1,3 @@
1
+ import type { googleOauthListFilesWithAssignedCommentsFunction } from "../../autogen/types.js";
2
+ declare const listFilesWithAssignedComments: googleOauthListFilesWithAssignedCommentsFunction;
3
+ export default listFilesWithAssignedComments;
@@ -0,0 +1,41 @@
1
+ import { axiosClient } from "../../util/axiosClient.js";
2
+ import { MISSING_AUTH_TOKEN } from "../../util/missingAuthConstants.js";
3
+ import { dedupeByIdKeepFirst, filterReadableFiles } from "./utils.js";
4
+ const ASSIGNED_COMMENTS_QUERY = "followup='assignedcomments' and trashed=false";
5
+ const listFilesWithAssignedComments = async ({ params, authParams, }) => {
6
+ if (!authParams.authToken) {
7
+ return { success: false, error: MISSING_AUTH_TOKEN, files: [] };
8
+ }
9
+ const { limit } = params;
10
+ try {
11
+ const allDrivesUrl = `https://www.googleapis.com/drive/v3/files?q=${encodeURIComponent(ASSIGNED_COMMENTS_QUERY)}&fields=files(id,name,mimeType,webViewLink)&supportsAllDrives=true&includeItemsFromAllDrives=true&corpora=allDrives&pageSize=100`;
12
+ const orgWideUrl = `https://www.googleapis.com/drive/v3/files?q=${encodeURIComponent(ASSIGNED_COMMENTS_QUERY)}&fields=files(id,name,mimeType,webViewLink)&corpora=domain&pageSize=100`;
13
+ const [allDrivesRes, orgWideRes] = await Promise.all([
14
+ axiosClient.get(allDrivesUrl, { headers: { Authorization: `Bearer ${authParams.authToken}` } }),
15
+ axiosClient.get(orgWideUrl, { headers: { Authorization: `Bearer ${authParams.authToken}` } }),
16
+ ]);
17
+ const rawFiles = [allDrivesRes.data.files, orgWideRes.data.files]
18
+ .filter(Boolean)
19
+ .flatMap(files => filterReadableFiles(files));
20
+ const files = rawFiles.map((file) => ({
21
+ id: file.id || "",
22
+ name: file.name || "",
23
+ mimeType: file.mimeType || "",
24
+ url: file.webViewLink || "",
25
+ }));
26
+ const dedupedFiles = dedupeByIdKeepFirst(files);
27
+ return {
28
+ success: true,
29
+ files: limit ? dedupedFiles.slice(0, limit) : dedupedFiles,
30
+ };
31
+ }
32
+ catch (error) {
33
+ console.error("Error listing files with assigned comments", error);
34
+ return {
35
+ success: false,
36
+ error: error instanceof Error ? error.message : "Unknown error",
37
+ files: [],
38
+ };
39
+ }
40
+ };
41
+ export default listFilesWithAssignedComments;
@@ -8,20 +8,26 @@ const updateRowsInSpreadsheet = async ({ params, authParams, }) => {
8
8
  if (!authParams.authToken) {
9
9
  throw new Error(MISSING_AUTH_TOKEN);
10
10
  }
11
- const { spreadsheetId, sheetName, startRow, rows } = params;
12
- if (rows.length === 0) {
13
- throw new Error("rows array cannot be empty");
14
- }
15
- const values = rows.map(row => row.map(cell => cell.stringValue));
16
- if (startRow < 1) {
17
- throw new Error("startRow must be >= 1");
18
- }
19
- const endRow = startRow + rows.length - 1;
20
- const range = `'${sheetName ?? "Sheet1"}'!A${startRow}:ZZ${endRow}`;
21
- const updateUrl = `https://sheets.googleapis.com/v4/spreadsheets/${spreadsheetId}/values/${encodeURIComponent(range)}`;
11
+ const { spreadsheetId, sheetName, startRow, startColumn, rows } = params;
22
12
  try {
13
+ if (rows.length === 0) {
14
+ throw new Error("rows array cannot be empty");
15
+ }
16
+ if (startRow < 1) {
17
+ throw new Error("startRow must be >= 1");
18
+ }
19
+ const col = startColumn ?? "A";
20
+ if (!/^[A-Za-z]+$/.test(col)) {
21
+ throw new Error(`startColumn must be a column letter (e.g. "A", "BE"), got: "${col}"`);
22
+ }
23
+ const endRow = startRow + rows.length - 1;
24
+ const sheet = sheetName ?? "Sheet1";
25
+ // Only quote sheet names that contain spaces or special characters
26
+ const quotedSheet = /[\s'!]/.test(sheet) ? `'${sheet.replace(/'/g, "''")}'` : sheet;
27
+ const range = `${quotedSheet}!${col}${startRow}:ZZ${endRow}`;
28
+ const updateUrl = `https://sheets.googleapis.com/v4/spreadsheets/${spreadsheetId}/values/${encodeURIComponent(range)}`;
23
29
  const response = await axiosClient.put(updateUrl, {
24
- values,
30
+ values: rows,
25
31
  majorDimension: "ROWS",
26
32
  range,
27
33
  }, {
@@ -1,8 +1,9 @@
1
1
  import type { jiraGetJiraIssuesByQueryFunction } from "../../autogen/types.js";
2
2
  /**
3
- * Get Jira issues from Jira Data Center
4
- * Uses startAt parameter to paginate through the results while
5
- * getJiraIssuesByQuery uses nextPageToken parameter to paginate through the results.
3
+ * Get Jira issues from Jira Data Center using offset-based pagination (startAt).
4
+ * Returns `total` from the Jira API response so callers can detect truncation by
5
+ * comparing total > results.length. Does not return `truncated` — use `total` instead.
6
+ * (Contrast with the Cloud implementation which returns `truncated` but not `total`.)
6
7
  */
7
8
  declare const getJiraDCIssuesByQuery: jiraGetJiraIssuesByQueryFunction;
8
9
  export default getJiraDCIssuesByQuery;
@@ -2,9 +2,10 @@ import { axiosClient } from "../../util/axiosClient.js";
2
2
  import { getJiraApiConfig, getErrorMessage, extractPlainText } from "./utils.js";
3
3
  const DEFAULT_LIMIT = 100;
4
4
  /**
5
- * Get Jira issues from Jira Data Center
6
- * Uses startAt parameter to paginate through the results while
7
- * getJiraIssuesByQuery uses nextPageToken parameter to paginate through the results.
5
+ * Get Jira issues from Jira Data Center using offset-based pagination (startAt).
6
+ * Returns `total` from the Jira API response so callers can detect truncation by
7
+ * comparing total > results.length. Does not return `truncated` — use `total` instead.
8
+ * (Contrast with the Cloud implementation which returns `truncated` but not `total`.)
8
9
  */
9
10
  const getJiraDCIssuesByQuery = async ({ params, authParams, }) => {
10
11
  const { authToken } = authParams;
@@ -36,6 +37,7 @@ const getJiraDCIssuesByQuery = async ({ params, authParams, }) => {
36
37
  const requestedLimit = limit ?? DEFAULT_LIMIT;
37
38
  const allIssues = [];
38
39
  let startAt = 0;
40
+ let jiraTotal = undefined;
39
41
  try {
40
42
  // Keep fetching pages until we have all requested issues
41
43
  while (allIssues.length < requestedLimit) {
@@ -55,6 +57,7 @@ const getJiraDCIssuesByQuery = async ({ params, authParams, }) => {
55
57
  },
56
58
  });
57
59
  const { issues, total } = response.data;
60
+ jiraTotal = total;
58
61
  allIssues.push(...issues);
59
62
  if (allIssues.length >= total || issues.length === 0) {
60
63
  break;
@@ -62,6 +65,7 @@ const getJiraDCIssuesByQuery = async ({ params, authParams, }) => {
62
65
  startAt += issues.length;
63
66
  }
64
67
  return {
68
+ total: jiraTotal,
65
69
  results: allIssues.map(issue => {
66
70
  const { id, key, fields } = issue;
67
71
  const { summary, description, project, issuetype, status, assignee, reporter, creator, created, updated, resolution, duedate, } = fields;
@@ -1,6 +1,10 @@
1
1
  import { Version3Client } from "jira.js";
2
2
  import { getJiraApiConfig, getErrorMessage, extractPlainText, getUserInfoFromAccountId } from "./utils.js";
3
3
  const DEFAULT_LIMIT = 100;
4
+ // Jira Cloud implementation using the enhanced search API (cursor-based pagination).
5
+ // Returns `truncated: true` when results were cut off at the limit and more pages exist.
6
+ // Note: the enhanced API does not expose a total count, so `total` is never returned here.
7
+ // Use `jiraDataCenter` provider if you need the exact total count.
4
8
  const getJiraIssuesByQuery = async ({ params, authParams, }) => {
5
9
  const { authToken, cloudId } = authParams;
6
10
  const { query, limit } = params;
@@ -31,6 +35,7 @@ const getJiraIssuesByQuery = async ({ params, authParams, }) => {
31
35
  const requestedLimit = limit ?? DEFAULT_LIMIT;
32
36
  const allIssues = [];
33
37
  let nextPageToken = undefined;
38
+ let truncated = false;
34
39
  try {
35
40
  // Initialize jira.js client with OAuth 2.0 authentication
36
41
  const client = new Version3Client({
@@ -59,6 +64,8 @@ const getJiraIssuesByQuery = async ({ params, authParams, }) => {
59
64
  allIssues.push(...searchResults.issues);
60
65
  // Check if we've reached the end or have enough results
61
66
  if (allIssues.length >= requestedLimit || !searchResults.nextPageToken || searchResults.issues.length === 0) {
67
+ // Truncated when we hit the limit but Jira still has more pages
68
+ truncated = allIssues.length >= requestedLimit && !!searchResults.nextPageToken;
62
69
  break;
63
70
  }
64
71
  nextPageToken = searchResults.nextPageToken;
@@ -106,7 +113,7 @@ const getJiraIssuesByQuery = async ({ params, authParams, }) => {
106
113
  },
107
114
  };
108
115
  }));
109
- return { results };
116
+ return { results, truncated };
110
117
  }
111
118
  catch (error) {
112
119
  console.error("Error retrieving Jira issues:", error);
@@ -0,0 +1,3 @@
1
+ import type { jiraUpdateServiceDeskRequestFunction } from "../../autogen/types.js";
2
+ declare const updateServiceDeskRequest: jiraUpdateServiceDeskRequestFunction;
3
+ export default updateServiceDeskRequest;
@@ -0,0 +1,72 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { axiosClient } from "../../util/axiosClient.js";
11
+ const updateServiceDeskRequest = (_a) => __awaiter(void 0, [_a], void 0, function* ({ params, authParams, }) {
12
+ const { issueId, requestTypeId, summary, description, priority, customFields } = params;
13
+ const { authToken, cloudId, baseUrl } = authParams;
14
+ if (!cloudId || !authToken) {
15
+ throw new Error("Valid Cloud ID and auth token are required to update service desk request");
16
+ }
17
+ // Use the regular Jira API for updating service desk requests as they are still Jira issues
18
+ const apiUrl = `https://api.atlassian.com/ex/jira/${cloudId}/rest/api/3/issue/${issueId}`;
19
+ const formattedDescription = description
20
+ ? {
21
+ type: "doc",
22
+ version: 1,
23
+ content: [
24
+ {
25
+ type: "paragraph",
26
+ content: [
27
+ {
28
+ type: "text",
29
+ text: description,
30
+ },
31
+ ],
32
+ },
33
+ ],
34
+ }
35
+ : undefined;
36
+ const payload = {
37
+ fields: Object.assign(Object.assign(Object.assign(Object.assign({}, (summary && { summary })), (formattedDescription && { description: formattedDescription })), (priority && { priority: { name: priority } })), (customFields && Object.assign({}, customFields))),
38
+ };
39
+ try {
40
+ yield axiosClient.put(apiUrl, payload, {
41
+ headers: {
42
+ Authorization: `Bearer ${authToken}`,
43
+ Accept: "application/json",
44
+ "Content-Type": "application/json",
45
+ },
46
+ });
47
+ // Get the updated issue details to return current status and web link
48
+ const getResponse = yield axiosClient.get(apiUrl, {
49
+ headers: {
50
+ Authorization: `Bearer ${authToken}`,
51
+ Accept: "application/json",
52
+ },
53
+ });
54
+ const issueKey = getResponse.data.key;
55
+ const currentStatus = getResponse.data.fields.status.name;
56
+ const webLink = `${baseUrl}/browse/${issueKey}`;
57
+ return {
58
+ success: true,
59
+ issueKey,
60
+ webLink,
61
+ currentStatus,
62
+ };
63
+ }
64
+ catch (error) {
65
+ console.error("Error updating service desk request:", error);
66
+ return {
67
+ success: false,
68
+ error: error instanceof Error ? error.message : "Unknown error",
69
+ };
70
+ }
71
+ });
72
+ export default updateServiceDeskRequest;
@@ -0,0 +1,3 @@
1
+ import type { microsoftSendOutlookEmailFunction } from "../../autogen/types.js";
2
+ declare const sendEmail: microsoftSendOutlookEmailFunction;
3
+ export default sendEmail;
@@ -0,0 +1,48 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { getGraphClient } from "./utils.js";
11
+ const sendEmail = (_a) => __awaiter(void 0, [_a], void 0, function* ({ params, authParams, }) {
12
+ const { toRecipients, subject, body, ccRecipients, bccRecipients } = params;
13
+ let client = undefined;
14
+ try {
15
+ client = yield getGraphClient(authParams);
16
+ }
17
+ catch (error) {
18
+ return {
19
+ success: false,
20
+ error: "Error while authorizing: " + (error instanceof Error ? error.message : "Unknown error"),
21
+ };
22
+ }
23
+ try {
24
+ const message = {
25
+ message: Object.assign(Object.assign({ subject, body: {
26
+ contentType: "HTML",
27
+ content: body,
28
+ }, toRecipients: toRecipients.map(email => ({ emailAddress: { address: email } })) }, (ccRecipients && ccRecipients.length > 0
29
+ ? { ccRecipients: ccRecipients.map(email => ({ emailAddress: { address: email } })) }
30
+ : {})), (bccRecipients && bccRecipients.length > 0
31
+ ? { bccRecipients: bccRecipients.map(email => ({ emailAddress: { address: email } })) }
32
+ : {})),
33
+ saveToSentItems: true,
34
+ };
35
+ yield client.api("/me/sendMail").post(message);
36
+ return {
37
+ success: true,
38
+ };
39
+ }
40
+ catch (error) {
41
+ console.error(error);
42
+ return {
43
+ success: false,
44
+ error: "Error sending email: " + (error instanceof Error ? error.message : "Unknown error"),
45
+ };
46
+ }
47
+ });
48
+ export default sendEmail;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@credal/actions",
3
- "version": "0.2.215",
3
+ "version": "0.2.217",
4
4
  "type": "module",
5
5
  "description": "AI Actions by Credal AI",
6
6
  "sideEffects": false,
@@ -1,6 +0,0 @@
1
- import type { ActionTemplate } from "./parse.js";
2
- export type ActionGroups = Record<string, {
3
- description: string;
4
- actions: ActionTemplate[];
5
- }>;
6
- export declare const ACTION_GROUPS: ActionGroups;