@mastra/factory 0.13.0 → 0.13.1-alpha.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 (37) hide show
  1. package/README.md +21 -0
  2. package/dist/factory.d.ts +3 -2
  3. package/dist/factory.d.ts.map +1 -1
  4. package/dist/factory.js +5 -2
  5. package/dist/factory.js.map +1 -1
  6. package/dist/integrations/incidentio/api.d.ts +400 -0
  7. package/dist/integrations/incidentio/api.d.ts.map +1 -0
  8. package/dist/integrations/incidentio/api.js +192 -0
  9. package/dist/integrations/incidentio/api.js.map +1 -0
  10. package/dist/integrations/incidentio/intake.d.ts +10 -0
  11. package/dist/integrations/incidentio/intake.d.ts.map +1 -0
  12. package/dist/integrations/incidentio/intake.js +307 -0
  13. package/dist/integrations/incidentio/intake.js.map +1 -0
  14. package/dist/integrations/incidentio/integration.d.ts +17 -0
  15. package/dist/integrations/incidentio/integration.d.ts.map +1 -0
  16. package/dist/integrations/incidentio/integration.js +54 -0
  17. package/dist/integrations/incidentio/integration.js.map +1 -0
  18. package/dist/integrations/incidentio/issue-reconciler.d.ts +8 -0
  19. package/dist/integrations/incidentio/issue-reconciler.d.ts.map +1 -0
  20. package/dist/integrations/incidentio/issue-reconciler.js +39 -0
  21. package/dist/integrations/incidentio/issue-reconciler.js.map +1 -0
  22. package/dist/integrations/incidentio/reconciliation-config.d.ts +3 -0
  23. package/dist/integrations/incidentio/reconciliation-config.d.ts.map +1 -0
  24. package/dist/integrations/incidentio/reconciliation-config.js +17 -0
  25. package/dist/integrations/incidentio/reconciliation-config.js.map +1 -0
  26. package/dist/integrations/linear/reconciliation-config.d.ts.map +1 -1
  27. package/dist/integrations/linear/reconciliation-config.js +4 -10
  28. package/dist/integrations/linear/reconciliation-config.js.map +1 -1
  29. package/dist/integrations/platform/incidentio/integration.d.ts +17 -0
  30. package/dist/integrations/platform/incidentio/integration.d.ts.map +1 -0
  31. package/dist/integrations/platform/incidentio/integration.js +56 -0
  32. package/dist/integrations/platform/incidentio/integration.js.map +1 -0
  33. package/dist/integrations/reconciliation-config.d.ts +1 -0
  34. package/dist/integrations/reconciliation-config.d.ts.map +1 -1
  35. package/dist/integrations/reconciliation-config.js +8 -1
  36. package/dist/integrations/reconciliation-config.js.map +1 -1
  37. package/package.json +7 -7
@@ -0,0 +1 @@
1
+ {"version":3,"file":"intake.d.ts","sourceRoot":"","sources":["../../../src/integrations/incidentio/intake.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AAC9E,OAAO,KAAK,EAEV,MAAM,EASP,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,mBAAmB,EAKpB,MAAM,UAAU,CAAC;AAElB,eAAO,MAAM,8BAA8B,yBAAyB,CAAC;AACrE,eAAO,MAAM,+BAA+B,0BAA0B,CAAC;AAavE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE;IAC7C,GAAG,EAAE,mBAAmB,CAAC;IACzB,UAAU,EAAE,qBAAqB,CAAC;CACnC,GAAG,MAAM,CAqIT"}
@@ -0,0 +1,307 @@
1
+ import { IncidentioApiError } from "./api.js";
2
+ //#region src/integrations/incidentio/intake.ts
3
+ const INCIDENTIO_INCIDENTS_SOURCE_ID = "incidentio:incidents";
4
+ const INCIDENTIO_FOLLOW_UPS_SOURCE_ID = "incidentio:follow-ups";
5
+ const INCIDENT_PREFIX = "incidentio:incident:";
6
+ const FOLLOW_UP_PREFIX = "incidentio:follow-up:";
7
+ const SOURCE_IDS = [INCIDENTIO_INCIDENTS_SOURCE_ID, INCIDENTIO_FOLLOW_UPS_SOURCE_ID];
8
+ function createIncidentioIntake(config) {
9
+ const assertConnection = (connection) => {
10
+ if (connection.type !== config.connection.type || connection.type !== "oauth" || config.connection.type !== "oauth" || connection.accessToken !== config.connection.accessToken) throw new Error("incident.io Intake received a connection it did not create.");
11
+ };
12
+ const listIssueEntries = async ({ sourceIds, labels, cursor }) => {
13
+ const selectedSources = SOURCE_IDS.filter((sourceId) => sourceIds.includes(sourceId));
14
+ const decodedCursor = decodePageCursor(cursor);
15
+ if (decodedCursor.sourceIndex >= selectedSources.length) return {
16
+ entries: [],
17
+ nextCursor: null
18
+ };
19
+ const sourceId = selectedSources[decodedCursor.sourceIndex];
20
+ let entries;
21
+ let providerCursor;
22
+ if (sourceId === "incidentio:incidents") {
23
+ const page = await config.api.listIncidents(decodedCursor.provider);
24
+ entries = page.items.map((incident) => {
25
+ const issue = incidentToIntakeIssue(incident);
26
+ return {
27
+ issue,
28
+ metadata: incidentIntakeMetadata(incident, issue)
29
+ };
30
+ });
31
+ providerCursor = page.nextCursor;
32
+ } else {
33
+ const page = await config.api.listFollowUps(decodedCursor.provider);
34
+ entries = page.items.map((followUp) => {
35
+ const issue = followUpToIntakeIssue(followUp);
36
+ return {
37
+ issue,
38
+ metadata: followUpIntakeMetadata(followUp, issue)
39
+ };
40
+ });
41
+ providerCursor = page.nextCursor;
42
+ }
43
+ entries = entries.filter(({ issue }) => isActive(issue.stateType) && matchesLabels(issue.labels, labels));
44
+ const nextCursor = providerCursor ? encodePageCursor({
45
+ sourceIndex: decodedCursor.sourceIndex,
46
+ provider: providerCursor
47
+ }) : decodedCursor.sourceIndex + 1 < selectedSources.length ? encodePageCursor({ sourceIndex: decodedCursor.sourceIndex + 1 }) : null;
48
+ return {
49
+ entries,
50
+ nextCursor
51
+ };
52
+ };
53
+ const listIssues = async (input) => {
54
+ const page = await listIssueEntries(input);
55
+ return {
56
+ issues: page.entries.map(({ issue }) => issue),
57
+ nextCursor: page.nextCursor
58
+ };
59
+ };
60
+ const getIssue = async ({ connection, issueId }) => {
61
+ assertConnection(connection);
62
+ const reference = decodeItemReference(issueId);
63
+ if (!reference) return null;
64
+ try {
65
+ if (reference.type === "incident") {
66
+ const incident = await config.api.getIncident(reference.id);
67
+ return {
68
+ ...incidentToIntakeIssue(incident),
69
+ description: incident.summary ?? null,
70
+ comments: []
71
+ };
72
+ }
73
+ const followUp = await config.api.getFollowUp(reference.id);
74
+ return {
75
+ ...followUpToIntakeIssue(followUp),
76
+ description: followUp.description ?? null,
77
+ comments: []
78
+ };
79
+ } catch (error) {
80
+ if (error instanceof IncidentioApiError && error.status === 404) return null;
81
+ throw error;
82
+ }
83
+ };
84
+ return {
85
+ resolveIntakeDispatch: (input) => {
86
+ if (input.externalSource.type !== "issue") return Promise.resolve(null);
87
+ const reference = decodeItemReference(input.externalSource.externalId);
88
+ if (!reference) return Promise.resolve(null);
89
+ return Promise.resolve({
90
+ connection: config.connection,
91
+ sourceId: reference.type === "incident" ? INCIDENTIO_INCIDENTS_SOURCE_ID : INCIDENTIO_FOLLOW_UPS_SOURCE_ID,
92
+ issueId: input.externalSource.externalId
93
+ });
94
+ },
95
+ listSources: async () => [{
96
+ id: INCIDENTIO_INCIDENTS_SOURCE_ID,
97
+ name: "Incidents",
98
+ type: "incident"
99
+ }, {
100
+ id: INCIDENTIO_FOLLOW_UPS_SOURCE_ID,
101
+ name: "Incident follow-ups",
102
+ type: "follow-up"
103
+ }],
104
+ listItems: async (input) => {
105
+ const page = await listIssueEntries({
106
+ connection: config.connection,
107
+ sourceIds: input.sourceIds,
108
+ ...input.cursor ? { cursor: input.cursor } : {}
109
+ });
110
+ return {
111
+ items: page.entries.map(({ issue, metadata }) => ({
112
+ source: {
113
+ type: "issue",
114
+ externalId: issue.id,
115
+ url: issue.url
116
+ },
117
+ sourceId: issue.id.startsWith(INCIDENT_PREFIX) ? INCIDENTIO_INCIDENTS_SOURCE_ID : INCIDENTIO_FOLLOW_UPS_SOURCE_ID,
118
+ title: `${issue.identifier}: ${issue.title}`,
119
+ status: issue.state ?? void 0,
120
+ labels: issue.labels,
121
+ assignee: issue.assignee,
122
+ createdAt: issue.createdAt,
123
+ updatedAt: issue.updatedAt,
124
+ metadata
125
+ })),
126
+ nextCursor: page.nextCursor
127
+ };
128
+ },
129
+ listIssues: async (input) => {
130
+ assertConnection(input.connection);
131
+ return listIssues(input);
132
+ },
133
+ getIssue,
134
+ createComment: async (input) => {
135
+ assertConnection(input.connection);
136
+ return null;
137
+ },
138
+ updateIssue: async (input) => {
139
+ assertConnection(input.connection);
140
+ const reference = decodeItemReference(input.issueId);
141
+ if (!reference || reference.type !== "follow-up") return null;
142
+ let followUp;
143
+ try {
144
+ followUp = await config.api.getFollowUp(reference.id);
145
+ } catch (error) {
146
+ if (error instanceof IncidentioApiError && error.status === 404) return null;
147
+ throw error;
148
+ }
149
+ const status = followUpStatusForTarget(input);
150
+ if (!status) return null;
151
+ if (followUp.status === status) return followUpToIntakeIssue(followUp);
152
+ return followUpToIntakeIssue(await config.api.updateFollowUp(followUp, status));
153
+ }
154
+ };
155
+ }
156
+ function incidentToIntakeIssue(incident) {
157
+ const labels = [
158
+ incident.severity?.name,
159
+ incident.incident_type?.name,
160
+ incident.mode
161
+ ].filter((label) => Boolean(label));
162
+ return {
163
+ id: `${INCIDENT_PREFIX}${incident.id}`,
164
+ identifier: incident.reference,
165
+ title: incident.name,
166
+ url: incident.permalink ?? incident.slack_channel_url ?? incident.postmortem_document_url ?? `https://app.incident.io/incidents/${encodeURIComponent(incident.id)}`,
167
+ author: actorName(incident.creator),
168
+ state: incident.incident_status.name,
169
+ stateType: incidentStateType(incident.incident_status.category),
170
+ priority: incident.severity?.name ?? null,
171
+ assignee: null,
172
+ source: "Incident",
173
+ labels,
174
+ commentCount: 0,
175
+ createdAt: incident.created_at,
176
+ updatedAt: incident.updated_at
177
+ };
178
+ }
179
+ function followUpToIntakeIssue(followUp) {
180
+ const assignees = [followUp.assignee?.name, followUp.assignee_team?.name].filter((assignee) => Boolean(assignee));
181
+ return {
182
+ id: `${FOLLOW_UP_PREFIX}${followUp.id}`,
183
+ identifier: followUp.external_issue_reference?.issue_name ?? followUp.id,
184
+ title: followUp.title,
185
+ url: followUp.external_issue_reference?.issue_permalink ?? `https://app.incident.io/incidents/${encodeURIComponent(followUp.incident_id)}`,
186
+ author: actorName(followUp.creator),
187
+ state: followUp.status,
188
+ stateType: followUpStateType(followUp.status),
189
+ priority: followUp.priority?.name ?? null,
190
+ assignee: assignees[0] ?? null,
191
+ assignees,
192
+ source: "Follow-up",
193
+ labels: followUp.labels,
194
+ commentCount: 0,
195
+ createdAt: followUp.created_at,
196
+ updatedAt: followUp.updated_at
197
+ };
198
+ }
199
+ function intakeMetadata(issue) {
200
+ return {
201
+ identifier: issue.identifier,
202
+ autoStartCandidate: issue.stateType === "unstarted" || issue.stateType === "started",
203
+ incidentioState: issue.state,
204
+ incidentioStateType: issue.stateType,
205
+ incidentioPriority: issue.priority,
206
+ incidentioAssignee: issue.assignee,
207
+ stateType: issue.stateType,
208
+ priority: issue.priority,
209
+ source: issue.source,
210
+ assignee: issue.assignee,
211
+ assignees: issue.assignees ?? [],
212
+ creator: issue.author,
213
+ author: issue.author,
214
+ labels: issue.labels,
215
+ updatedAt: issue.updatedAt
216
+ };
217
+ }
218
+ function incidentIntakeMetadata(incident, issue) {
219
+ return {
220
+ ...intakeMetadata(issue),
221
+ incidentioItemType: "incident",
222
+ incidentioIncidentId: incident.id,
223
+ ...incident.summary ? { incidentioDescription: incident.summary } : {}
224
+ };
225
+ }
226
+ function followUpIntakeMetadata(followUp, issue) {
227
+ return {
228
+ ...intakeMetadata(issue),
229
+ incidentioItemType: "follow-up",
230
+ incidentioIncidentId: followUp.incident_id,
231
+ ...followUp.description ? { incidentioDescription: followUp.description } : {}
232
+ };
233
+ }
234
+ function actorName(actor) {
235
+ return actor.user?.name ?? actor.api_key?.name ?? actor.workflow?.name ?? actor.alert?.title ?? null;
236
+ }
237
+ function incidentStateType(category) {
238
+ switch (category) {
239
+ case "triage": return "unstarted";
240
+ case "declined":
241
+ case "canceled": return "canceled";
242
+ case "merged":
243
+ case "closed": return "completed";
244
+ case "live":
245
+ case "learning":
246
+ case "paused": return "started";
247
+ default: return null;
248
+ }
249
+ }
250
+ function followUpStateType(status) {
251
+ switch (status) {
252
+ case "outstanding": return "unstarted";
253
+ case "completed": return "completed";
254
+ case "deleted":
255
+ case "not_doing": return "canceled";
256
+ default: return null;
257
+ }
258
+ }
259
+ function followUpStatusForTarget(input) {
260
+ if (input.state.kind === "byType") switch (input.state.stateType) {
261
+ case "unstarted":
262
+ case "started": return "outstanding";
263
+ case "completed": return "completed";
264
+ case "canceled": return "not_doing";
265
+ }
266
+ const status = input.state.name.toLowerCase().replaceAll("-", "_").replaceAll(" ", "_");
267
+ return status === "outstanding" || status === "completed" || status === "not_doing" ? status : null;
268
+ }
269
+ function isActive(stateType) {
270
+ return stateType !== "completed" && stateType !== "canceled";
271
+ }
272
+ function matchesLabels(issueLabels, requestedLabels) {
273
+ if (!requestedLabels?.length) return true;
274
+ const labels = new Set(issueLabels.map((label) => label.toLowerCase()));
275
+ return requestedLabels.every((label) => labels.has(label.toLowerCase()));
276
+ }
277
+ function decodeItemReference(value) {
278
+ if (value.startsWith(INCIDENT_PREFIX)) return {
279
+ type: "incident",
280
+ id: value.slice(20)
281
+ };
282
+ if (value.startsWith(FOLLOW_UP_PREFIX)) return {
283
+ type: "follow-up",
284
+ id: value.slice(21)
285
+ };
286
+ return null;
287
+ }
288
+ function encodePageCursor(cursor) {
289
+ return Buffer.from(JSON.stringify(cursor)).toString("base64url");
290
+ }
291
+ function decodePageCursor(cursor) {
292
+ if (!cursor) return { sourceIndex: 0 };
293
+ try {
294
+ const parsed = JSON.parse(Buffer.from(cursor, "base64url").toString("utf8"));
295
+ if (!Number.isSafeInteger(parsed.sourceIndex) || (parsed.sourceIndex ?? -1) < 0) return { sourceIndex: 0 };
296
+ return {
297
+ sourceIndex: parsed.sourceIndex,
298
+ ...typeof parsed.provider === "string" && parsed.provider ? { provider: parsed.provider } : {}
299
+ };
300
+ } catch {
301
+ return { sourceIndex: 0 };
302
+ }
303
+ }
304
+ //#endregion
305
+ export { INCIDENTIO_FOLLOW_UPS_SOURCE_ID, INCIDENTIO_INCIDENTS_SOURCE_ID, createIncidentioIntake };
306
+
307
+ //# sourceMappingURL=intake.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"intake.js","names":[],"sources":["../../../src/integrations/incidentio/intake.ts"],"sourcesContent":["import type { IntegrationConnection } from '../../capabilities/connection.js';\nimport type {\n GetIntakeIssueInput,\n Intake,\n IntakeIssue,\n IntakeIssueDetail,\n IntakeItemPage,\n ListIntakeIssuesInput,\n ListIntakeItemsInput,\n ResolveIntakeDispatchInput,\n ResolvedIntakeDispatch,\n UpdateIntakeIssueInput,\n} from '../../capabilities/intake.js';\nimport {\n IncidentioApiClient,\n IncidentioApiError,\n type IncidentioActor,\n type IncidentioFollowUp,\n type IncidentioIncident,\n} from './api.js';\n\nexport const INCIDENTIO_INCIDENTS_SOURCE_ID = 'incidentio:incidents';\nexport const INCIDENTIO_FOLLOW_UPS_SOURCE_ID = 'incidentio:follow-ups';\n\nconst INCIDENT_PREFIX = 'incidentio:incident:';\nconst FOLLOW_UP_PREFIX = 'incidentio:follow-up:';\nconst SOURCE_IDS = [INCIDENTIO_INCIDENTS_SOURCE_ID, INCIDENTIO_FOLLOW_UPS_SOURCE_ID] as const;\n\ntype IncidentioItemReference = { type: 'incident' | 'follow-up'; id: string };\ntype IncidentioPageCursor = { sourceIndex: number; provider?: string };\ninterface ListedIncidentioIssue {\n issue: IntakeIssue;\n metadata: Record<string, unknown>;\n}\n\nexport function createIncidentioIntake(config: {\n api: IncidentioApiClient;\n connection: IntegrationConnection;\n}): Intake {\n const assertConnection = (connection: IntegrationConnection): void => {\n if (\n connection.type !== config.connection.type ||\n connection.type !== 'oauth' ||\n config.connection.type !== 'oauth' ||\n connection.accessToken !== config.connection.accessToken\n ) {\n throw new Error('incident.io Intake received a connection it did not create.');\n }\n };\n\n const listIssueEntries = async ({ sourceIds, labels, cursor }: ListIntakeIssuesInput) => {\n const selectedSources = SOURCE_IDS.filter(sourceId => sourceIds.includes(sourceId));\n const decodedCursor = decodePageCursor(cursor);\n if (decodedCursor.sourceIndex >= selectedSources.length) {\n return { entries: [] as ListedIncidentioIssue[], nextCursor: null };\n }\n\n const sourceId = selectedSources[decodedCursor.sourceIndex]!;\n let entries: ListedIncidentioIssue[];\n let providerCursor: string | null;\n if (sourceId === INCIDENTIO_INCIDENTS_SOURCE_ID) {\n const page = await config.api.listIncidents(decodedCursor.provider);\n entries = page.items.map(incident => {\n const issue = incidentToIntakeIssue(incident);\n return { issue, metadata: incidentIntakeMetadata(incident, issue) };\n });\n providerCursor = page.nextCursor;\n } else {\n const page = await config.api.listFollowUps(decodedCursor.provider);\n entries = page.items.map(followUp => {\n const issue = followUpToIntakeIssue(followUp);\n return { issue, metadata: followUpIntakeMetadata(followUp, issue) };\n });\n providerCursor = page.nextCursor;\n }\n entries = entries.filter(({ issue }) => isActive(issue.stateType) && matchesLabels(issue.labels, labels));\n const nextCursor = providerCursor\n ? encodePageCursor({ sourceIndex: decodedCursor.sourceIndex, provider: providerCursor })\n : decodedCursor.sourceIndex + 1 < selectedSources.length\n ? encodePageCursor({ sourceIndex: decodedCursor.sourceIndex + 1 })\n : null;\n return { entries, nextCursor };\n };\n\n const listIssues = async (input: ListIntakeIssuesInput) => {\n const page = await listIssueEntries(input);\n return { issues: page.entries.map(({ issue }) => issue), nextCursor: page.nextCursor };\n };\n\n const getIssue = async ({ connection, issueId }: GetIntakeIssueInput): Promise<IntakeIssueDetail | null> => {\n assertConnection(connection);\n const reference = decodeItemReference(issueId);\n if (!reference) return null;\n try {\n if (reference.type === 'incident') {\n const incident = await config.api.getIncident(reference.id);\n return { ...incidentToIntakeIssue(incident), description: incident.summary ?? null, comments: [] };\n }\n const followUp = await config.api.getFollowUp(reference.id);\n return { ...followUpToIntakeIssue(followUp), description: followUp.description ?? null, comments: [] };\n } catch (error) {\n if (error instanceof IncidentioApiError && error.status === 404) return null;\n throw error;\n }\n };\n\n return {\n resolveIntakeDispatch: (input: ResolveIntakeDispatchInput): Promise<ResolvedIntakeDispatch | null> => {\n if (input.externalSource.type !== 'issue') return Promise.resolve(null);\n const reference = decodeItemReference(input.externalSource.externalId);\n if (!reference) return Promise.resolve(null);\n return Promise.resolve({\n connection: config.connection,\n sourceId:\n reference.type === 'incident' ? INCIDENTIO_INCIDENTS_SOURCE_ID : INCIDENTIO_FOLLOW_UPS_SOURCE_ID,\n issueId: input.externalSource.externalId,\n });\n },\n listSources: async () => [\n { id: INCIDENTIO_INCIDENTS_SOURCE_ID, name: 'Incidents', type: 'incident' },\n { id: INCIDENTIO_FOLLOW_UPS_SOURCE_ID, name: 'Incident follow-ups', type: 'follow-up' },\n ],\n listItems: async (input: ListIntakeItemsInput): Promise<IntakeItemPage> => {\n const page = await listIssueEntries({\n connection: config.connection,\n sourceIds: input.sourceIds,\n ...(input.cursor ? { cursor: input.cursor } : {}),\n });\n return {\n items: page.entries.map(({ issue, metadata }) => ({\n source: { type: 'issue', externalId: issue.id, url: issue.url },\n sourceId: issue.id.startsWith(INCIDENT_PREFIX)\n ? INCIDENTIO_INCIDENTS_SOURCE_ID\n : INCIDENTIO_FOLLOW_UPS_SOURCE_ID,\n title: `${issue.identifier}: ${issue.title}`,\n status: issue.state ?? undefined,\n labels: issue.labels,\n assignee: issue.assignee,\n createdAt: issue.createdAt,\n updatedAt: issue.updatedAt,\n metadata,\n })),\n nextCursor: page.nextCursor,\n };\n },\n listIssues: async input => {\n assertConnection(input.connection);\n return listIssues(input);\n },\n getIssue,\n createComment: async input => {\n assertConnection(input.connection);\n return null;\n },\n updateIssue: async (input: UpdateIntakeIssueInput): Promise<IntakeIssue | null> => {\n assertConnection(input.connection);\n const reference = decodeItemReference(input.issueId);\n if (!reference || reference.type !== 'follow-up') return null;\n let followUp: IncidentioFollowUp;\n try {\n followUp = await config.api.getFollowUp(reference.id);\n } catch (error) {\n if (error instanceof IncidentioApiError && error.status === 404) return null;\n throw error;\n }\n const status = followUpStatusForTarget(input);\n if (!status) return null;\n if (followUp.status === status) return followUpToIntakeIssue(followUp);\n return followUpToIntakeIssue(await config.api.updateFollowUp(followUp, status));\n },\n };\n}\n\nfunction incidentToIntakeIssue(incident: IncidentioIncident): IntakeIssue {\n const labels = [incident.severity?.name, incident.incident_type?.name, incident.mode].filter(\n (label): label is string => Boolean(label),\n );\n return {\n id: `${INCIDENT_PREFIX}${incident.id}`,\n identifier: incident.reference,\n title: incident.name,\n url:\n incident.permalink ??\n incident.slack_channel_url ??\n incident.postmortem_document_url ??\n `https://app.incident.io/incidents/${encodeURIComponent(incident.id)}`,\n author: actorName(incident.creator),\n state: incident.incident_status.name,\n stateType: incidentStateType(incident.incident_status.category),\n priority: incident.severity?.name ?? null,\n assignee: null,\n source: 'Incident',\n labels,\n commentCount: 0,\n createdAt: incident.created_at,\n updatedAt: incident.updated_at,\n };\n}\n\nfunction followUpToIntakeIssue(followUp: IncidentioFollowUp): IntakeIssue {\n const assignees = [followUp.assignee?.name, followUp.assignee_team?.name].filter(\n (assignee): assignee is string => Boolean(assignee),\n );\n return {\n id: `${FOLLOW_UP_PREFIX}${followUp.id}`,\n identifier: followUp.external_issue_reference?.issue_name ?? followUp.id,\n title: followUp.title,\n url:\n followUp.external_issue_reference?.issue_permalink ??\n `https://app.incident.io/incidents/${encodeURIComponent(followUp.incident_id)}`,\n author: actorName(followUp.creator),\n state: followUp.status,\n stateType: followUpStateType(followUp.status),\n priority: followUp.priority?.name ?? null,\n assignee: assignees[0] ?? null,\n assignees,\n source: 'Follow-up',\n labels: followUp.labels,\n commentCount: 0,\n createdAt: followUp.created_at,\n updatedAt: followUp.updated_at,\n };\n}\n\nfunction intakeMetadata(issue: IntakeIssue): Record<string, unknown> {\n return {\n identifier: issue.identifier,\n autoStartCandidate: issue.stateType === 'unstarted' || issue.stateType === 'started',\n incidentioState: issue.state,\n incidentioStateType: issue.stateType,\n incidentioPriority: issue.priority,\n incidentioAssignee: issue.assignee,\n stateType: issue.stateType,\n priority: issue.priority,\n source: issue.source,\n assignee: issue.assignee,\n assignees: issue.assignees ?? [],\n creator: issue.author,\n author: issue.author,\n labels: issue.labels,\n updatedAt: issue.updatedAt,\n };\n}\n\nfunction incidentIntakeMetadata(incident: IncidentioIncident, issue: IntakeIssue): Record<string, unknown> {\n return {\n ...intakeMetadata(issue),\n incidentioItemType: 'incident',\n incidentioIncidentId: incident.id,\n ...(incident.summary ? { incidentioDescription: incident.summary } : {}),\n };\n}\n\nfunction followUpIntakeMetadata(followUp: IncidentioFollowUp, issue: IntakeIssue): Record<string, unknown> {\n return {\n ...intakeMetadata(issue),\n incidentioItemType: 'follow-up',\n incidentioIncidentId: followUp.incident_id,\n ...(followUp.description ? { incidentioDescription: followUp.description } : {}),\n };\n}\n\nfunction actorName(actor: IncidentioActor): string | null {\n return actor.user?.name ?? actor.api_key?.name ?? actor.workflow?.name ?? actor.alert?.title ?? null;\n}\n\nfunction incidentStateType(category: string): string | null {\n switch (category) {\n case 'triage':\n return 'unstarted';\n case 'declined':\n case 'canceled':\n return 'canceled';\n case 'merged':\n case 'closed':\n return 'completed';\n case 'live':\n case 'learning':\n case 'paused':\n return 'started';\n default:\n return null;\n }\n}\n\nfunction followUpStateType(status: IncidentioFollowUp['status']): string | null {\n switch (status) {\n case 'outstanding':\n return 'unstarted';\n case 'completed':\n return 'completed';\n case 'deleted':\n case 'not_doing':\n return 'canceled';\n default:\n return null;\n }\n}\n\nfunction followUpStatusForTarget(input: UpdateIntakeIssueInput): IncidentioFollowUp['status'] | null {\n if (input.state.kind === 'byType') {\n switch (input.state.stateType) {\n case 'unstarted':\n case 'started':\n return 'outstanding';\n case 'completed':\n return 'completed';\n case 'canceled':\n return 'not_doing';\n }\n }\n const status = input.state.name.toLowerCase().replaceAll('-', '_').replaceAll(' ', '_');\n return status === 'outstanding' || status === 'completed' || status === 'not_doing' ? status : null;\n}\n\nfunction isActive(stateType: string | null): boolean {\n return stateType !== 'completed' && stateType !== 'canceled';\n}\n\nfunction matchesLabels(issueLabels: string[], requestedLabels: string[] | undefined): boolean {\n if (!requestedLabels?.length) return true;\n const labels = new Set(issueLabels.map(label => label.toLowerCase()));\n return requestedLabels.every(label => labels.has(label.toLowerCase()));\n}\n\nfunction decodeItemReference(value: string): IncidentioItemReference | null {\n if (value.startsWith(INCIDENT_PREFIX)) return { type: 'incident', id: value.slice(INCIDENT_PREFIX.length) };\n if (value.startsWith(FOLLOW_UP_PREFIX)) return { type: 'follow-up', id: value.slice(FOLLOW_UP_PREFIX.length) };\n return null;\n}\n\nfunction encodePageCursor(cursor: IncidentioPageCursor): string {\n return Buffer.from(JSON.stringify(cursor)).toString('base64url');\n}\n\nfunction decodePageCursor(cursor: string | undefined): IncidentioPageCursor {\n if (!cursor) return { sourceIndex: 0 };\n try {\n const parsed = JSON.parse(Buffer.from(cursor, 'base64url').toString('utf8')) as Partial<IncidentioPageCursor>;\n if (!Number.isSafeInteger(parsed.sourceIndex) || (parsed.sourceIndex ?? -1) < 0) return { sourceIndex: 0 };\n return {\n sourceIndex: parsed.sourceIndex!,\n ...(typeof parsed.provider === 'string' && parsed.provider ? { provider: parsed.provider } : {}),\n };\n } catch {\n return { sourceIndex: 0 };\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { MastraWorker } from '@mastra/core/worker';
2
+ import type { FactoryIntegration, IntegrationContext } from '../base.js';
3
+ export interface IncidentioIntegrationConfig {
4
+ apiKey?: string;
5
+ fetchImpl?: typeof fetch;
6
+ baseUrl?: string;
7
+ }
8
+ export declare class IncidentioIntegration implements FactoryIntegration {
9
+ #private;
10
+ readonly id = "incidentio";
11
+ readonly intake: import("../../capabilities/intake.js").Intake;
12
+ constructor(config?: IncidentioIntegrationConfig);
13
+ workers(ctx: IntegrationContext): MastraWorker[];
14
+ routes(): [];
15
+ diagnostics(): Record<string, unknown>;
16
+ }
17
+ //# sourceMappingURL=integration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration.d.ts","sourceRoot":"","sources":["../../../src/integrations/incidentio/integration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAOzE,MAAM,WAAW,2BAA2B;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAID,qBAAa,qBAAsB,YAAW,kBAAkB;;IAC9D,QAAQ,CAAC,EAAE,gBAAgB;IAC3B,QAAQ,CAAC,MAAM,gDAAC;gBAGJ,MAAM,GAAE,2BAAgC;IAkBpD,OAAO,CAAC,GAAG,EAAE,kBAAkB,GAAG,YAAY,EAAE;IAchD,MAAM,IAAI,EAAE;IAIZ,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAGvC"}
@@ -0,0 +1,54 @@
1
+ import { IncidentioApiClient } from "./api.js";
2
+ import { createIncidentioIntake } from "./intake.js";
3
+ import { attachIncidentioIssueReconciler } from "./issue-reconciler.js";
4
+ import { incidentioReconciliationEnabled, incidentioReconciliationInterval } from "./reconciliation-config.js";
5
+ import { IssueReconcileWorker } from "../issue-reconcile-worker.js";
6
+ //#region src/integrations/incidentio/integration.ts
7
+ const DIRECT_CONNECTION_TOKEN = "incidentio-direct-api-key";
8
+ var IncidentioIntegration = class {
9
+ id = "incidentio";
10
+ intake;
11
+ #endpointHost;
12
+ constructor(config = {}) {
13
+ const apiKey = config.apiKey?.trim() || process.env.INCIDENT_IO_API_KEY?.trim();
14
+ if (!apiKey) throw new Error("IncidentioIntegration: missing required INCIDENT_IO_API_KEY.");
15
+ const baseUrl = config.baseUrl ?? "https://api.incident.io";
16
+ this.#endpointHost = new URL(baseUrl).host;
17
+ const api = new IncidentioApiClient({
18
+ baseUrl,
19
+ accessToken: apiKey,
20
+ ...config.fetchImpl ? { fetchImpl: config.fetchImpl } : {}
21
+ });
22
+ this.intake = createIncidentioIntake({
23
+ api,
24
+ connection: {
25
+ type: "oauth",
26
+ accessToken: DIRECT_CONNECTION_TOKEN
27
+ }
28
+ });
29
+ }
30
+ workers(ctx) {
31
+ if (!incidentioReconciliationEnabled()) return [];
32
+ const reconcile = attachIncidentioIssueReconciler(this, ctx);
33
+ if (!reconcile) return [];
34
+ const intervalMs = incidentioReconciliationInterval();
35
+ return [new IssueReconcileWorker({
36
+ integrationId: this.id,
37
+ reconcile,
38
+ ...intervalMs ? { intervalMs } : {}
39
+ })];
40
+ }
41
+ routes() {
42
+ return [];
43
+ }
44
+ diagnostics() {
45
+ return {
46
+ mode: "api-key",
47
+ endpointHost: this.#endpointHost
48
+ };
49
+ }
50
+ };
51
+ //#endregion
52
+ export { IncidentioIntegration };
53
+
54
+ //# sourceMappingURL=integration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration.js","names":["#endpointHost"],"sources":["../../../src/integrations/incidentio/integration.ts"],"sourcesContent":["import type { MastraWorker } from '@mastra/core/worker';\n\nimport type { FactoryIntegration, IntegrationContext } from '../base.js';\nimport { IssueReconcileWorker } from '../issue-reconcile-worker.js';\nimport { IncidentioApiClient } from './api.js';\nimport { createIncidentioIntake } from './intake.js';\nimport { attachIncidentioIssueReconciler } from './issue-reconciler.js';\nimport { incidentioReconciliationEnabled, incidentioReconciliationInterval } from './reconciliation-config.js';\n\nexport interface IncidentioIntegrationConfig {\n apiKey?: string;\n fetchImpl?: typeof fetch;\n baseUrl?: string;\n}\n\nconst DIRECT_CONNECTION_TOKEN = 'incidentio-direct-api-key';\n\nexport class IncidentioIntegration implements FactoryIntegration {\n readonly id = 'incidentio';\n readonly intake;\n readonly #endpointHost: string;\n\n constructor(config: IncidentioIntegrationConfig = {}) {\n const apiKey = config.apiKey?.trim() || process.env.INCIDENT_IO_API_KEY?.trim();\n if (!apiKey) {\n throw new Error('IncidentioIntegration: missing required INCIDENT_IO_API_KEY.');\n }\n const baseUrl = config.baseUrl ?? 'https://api.incident.io';\n this.#endpointHost = new URL(baseUrl).host;\n const api = new IncidentioApiClient({\n baseUrl,\n accessToken: apiKey,\n ...(config.fetchImpl ? { fetchImpl: config.fetchImpl } : {}),\n });\n this.intake = createIncidentioIntake({\n api,\n connection: { type: 'oauth', accessToken: DIRECT_CONNECTION_TOKEN },\n });\n }\n\n workers(ctx: IntegrationContext): MastraWorker[] {\n if (!incidentioReconciliationEnabled()) return [];\n const reconcile = attachIncidentioIssueReconciler(this, ctx);\n if (!reconcile) return [];\n const intervalMs = incidentioReconciliationInterval();\n return [\n new IssueReconcileWorker({\n integrationId: this.id,\n reconcile,\n ...(intervalMs ? { intervalMs } : {}),\n }),\n ];\n }\n\n routes(): [] {\n return [];\n }\n\n diagnostics(): Record<string, unknown> {\n return { mode: 'api-key', endpointHost: this.#endpointHost };\n }\n}\n"],"mappings":";;;;;;AAeA,MAAM,0BAA0B;AAEhC,IAAa,wBAAb,MAAiE;CAC/D,KAAc;CACd;CACA;CAEA,YAAY,SAAsC,CAAC,GAAG;EACpD,MAAM,SAAS,OAAO,QAAQ,KAAK,KAAK,QAAQ,IAAI,qBAAqB,KAAK;EAC9E,IAAI,CAAC,QACH,MAAM,IAAI,MAAM,8DAA8D;EAEhF,MAAM,UAAU,OAAO,WAAW;EAClC,KAAKA,gBAAgB,IAAI,IAAI,OAAO,CAAC,CAAC;EACtC,MAAM,MAAM,IAAI,oBAAoB;GAClC;GACA,aAAa;GACb,GAAI,OAAO,YAAY,EAAE,WAAW,OAAO,UAAU,IAAI,CAAC;EAC5D,CAAC;EACD,KAAK,SAAS,uBAAuB;GACnC;GACA,YAAY;IAAE,MAAM;IAAS,aAAa;GAAwB;EACpE,CAAC;CACH;CAEA,QAAQ,KAAyC;EAC/C,IAAI,CAAC,gCAAgC,GAAG,OAAO,CAAC;EAChD,MAAM,YAAY,gCAAgC,MAAM,GAAG;EAC3D,IAAI,CAAC,WAAW,OAAO,CAAC;EACxB,MAAM,aAAa,iCAAiC;EACpD,OAAO,CACL,IAAI,qBAAqB;GACvB,eAAe,KAAK;GACpB;GACA,GAAI,aAAa,EAAE,WAAW,IAAI,CAAC;EACrC,CAAC,CACH;CACF;CAEA,SAAa;EACX,OAAO,CAAC;CACV;CAEA,cAAuC;EACrC,OAAO;GAAE,MAAM;GAAW,cAAc,KAAKA;EAAc;CAC7D;AACF"}
@@ -0,0 +1,8 @@
1
+ import type { Intake } from '../../capabilities/intake.js';
2
+ import type { IntegrationContext } from '../base.js';
3
+ import type { IssueReconciler } from '../issue-reconciler.js';
4
+ export type IncidentioIssueReconciler = IssueReconciler;
5
+ export declare function attachIncidentioIssueReconciler(incidentio: {
6
+ intake: Intake;
7
+ }, context: IntegrationContext): IncidentioIssueReconciler | undefined;
8
+ //# sourceMappingURL=issue-reconciler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"issue-reconciler.d.ts","sourceRoot":"","sources":["../../../src/integrations/incidentio/issue-reconciler.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,8BAA8B,CAAC;AAC3D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE9D,MAAM,MAAM,yBAAyB,GAAG,eAAe,CAAC;AAExD,wBAAgB,+BAA+B,CAC7C,UAAU,EAAE;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,EAC9B,OAAO,EAAE,kBAAkB,GAC1B,yBAAyB,GAAG,SAAS,CA+BvC"}
@@ -0,0 +1,39 @@
1
+ import { workItemPhaseSemantics } from "../../boards/semantics.js";
2
+ import "../../boards/index.js";
3
+ import { createIssueReconciler } from "../issue-reconciler.js";
4
+ //#region src/integrations/incidentio/issue-reconciler.ts
5
+ function attachIncidentioIssueReconciler(incidentio, context) {
6
+ if (!context.runtime || !incidentio.intake.resolveIntakeDispatch) return void 0;
7
+ const boards = context.runtime.boards;
8
+ return createIssueReconciler({
9
+ integrationId: "incidentio",
10
+ intake: incidentio.intake,
11
+ projects: context.storage.projects,
12
+ storage: context.runtime.workItems,
13
+ isTerminal: (item) => workItemPhaseSemantics(boards, item)?.kind === "terminal",
14
+ issueId: (item) => item.externalSource?.externalId,
15
+ metadata: (_item, issue) => ({
16
+ identifier: issue.identifier,
17
+ autoStartCandidate: issue.stateType === "unstarted" || issue.stateType === "started",
18
+ incidentioItemType: issue.source === "Follow-up" ? "follow-up" : "incident",
19
+ incidentioState: issue.state,
20
+ incidentioStateType: issue.stateType,
21
+ incidentioPriority: issue.priority,
22
+ incidentioAssignee: issue.assignee,
23
+ incidentioDescription: "description" in issue && typeof issue.description === "string" ? issue.description : null,
24
+ stateType: issue.stateType,
25
+ priority: issue.priority,
26
+ source: issue.source,
27
+ assignee: issue.assignee,
28
+ assignees: issue.assignees ?? [],
29
+ creator: issue.author,
30
+ author: issue.author,
31
+ labels: issue.labels ?? [],
32
+ updatedAt: issue.updatedAt
33
+ })
34
+ });
35
+ }
36
+ //#endregion
37
+ export { attachIncidentioIssueReconciler };
38
+
39
+ //# sourceMappingURL=issue-reconciler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"issue-reconciler.js","names":[],"sources":["../../../src/integrations/incidentio/issue-reconciler.ts"],"sourcesContent":["import { workItemPhaseSemantics } from '../../boards/index.js';\nimport type { Intake } from '../../capabilities/intake.js';\nimport type { IntegrationContext } from '../base.js';\nimport { createIssueReconciler } from '../issue-reconciler.js';\nimport type { IssueReconciler } from '../issue-reconciler.js';\n\nexport type IncidentioIssueReconciler = IssueReconciler;\n\nexport function attachIncidentioIssueReconciler(\n incidentio: { intake: Intake },\n context: IntegrationContext,\n): IncidentioIssueReconciler | undefined {\n if (!context.runtime || !incidentio.intake.resolveIntakeDispatch) return undefined;\n const boards = context.runtime.boards;\n\n return createIssueReconciler({\n integrationId: 'incidentio',\n intake: incidentio.intake,\n projects: context.storage.projects,\n storage: context.runtime.workItems,\n isTerminal: item => workItemPhaseSemantics(boards, item)?.kind === 'terminal',\n issueId: item => item.externalSource?.externalId,\n metadata: (_item, issue) => ({\n identifier: issue.identifier,\n autoStartCandidate: issue.stateType === 'unstarted' || issue.stateType === 'started',\n incidentioItemType: issue.source === 'Follow-up' ? 'follow-up' : 'incident',\n incidentioState: issue.state,\n incidentioStateType: issue.stateType,\n incidentioPriority: issue.priority,\n incidentioAssignee: issue.assignee,\n incidentioDescription: 'description' in issue && typeof issue.description === 'string' ? issue.description : null,\n stateType: issue.stateType,\n priority: issue.priority,\n source: issue.source,\n assignee: issue.assignee,\n assignees: issue.assignees ?? [],\n creator: issue.author,\n author: issue.author,\n labels: issue.labels ?? [],\n updatedAt: issue.updatedAt,\n }),\n });\n}\n"],"mappings":";;;;AAQA,SAAgB,gCACd,YACA,SACuC;CACvC,IAAI,CAAC,QAAQ,WAAW,CAAC,WAAW,OAAO,uBAAuB,OAAO,KAAA;CACzE,MAAM,SAAS,QAAQ,QAAQ;CAE/B,OAAO,sBAAsB;EAC3B,eAAe;EACf,QAAQ,WAAW;EACnB,UAAU,QAAQ,QAAQ;EAC1B,SAAS,QAAQ,QAAQ;EACzB,aAAY,SAAQ,uBAAuB,QAAQ,IAAI,CAAC,EAAE,SAAS;EACnE,UAAS,SAAQ,KAAK,gBAAgB;EACtC,WAAW,OAAO,WAAW;GAC3B,YAAY,MAAM;GAClB,oBAAoB,MAAM,cAAc,eAAe,MAAM,cAAc;GAC3E,oBAAoB,MAAM,WAAW,cAAc,cAAc;GACjE,iBAAiB,MAAM;GACvB,qBAAqB,MAAM;GAC3B,oBAAoB,MAAM;GAC1B,oBAAoB,MAAM;GAC1B,uBAAuB,iBAAiB,SAAS,OAAO,MAAM,gBAAgB,WAAW,MAAM,cAAc;GAC7G,WAAW,MAAM;GACjB,UAAU,MAAM;GAChB,QAAQ,MAAM;GACd,UAAU,MAAM;GAChB,WAAW,MAAM,aAAa,CAAC;GAC/B,SAAS,MAAM;GACf,QAAQ,MAAM;GACd,QAAQ,MAAM,UAAU,CAAC;GACzB,WAAW,MAAM;EACnB;CACF,CAAC;AACH"}
@@ -0,0 +1,3 @@
1
+ export declare function incidentioReconciliationEnabled(): boolean;
2
+ export declare function incidentioReconciliationInterval(): number | undefined;
3
+ //# sourceMappingURL=reconciliation-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconciliation-config.d.ts","sourceRoot":"","sources":["../../../src/integrations/incidentio/reconciliation-config.ts"],"names":[],"mappings":"AAIA,wBAAgB,+BAA+B,IAAI,OAAO,CAQzD;AAED,wBAAgB,gCAAgC,IAAI,MAAM,GAAG,SAAS,CAQrE"}
@@ -0,0 +1,17 @@
1
+ import { optionalBoolean, optionalPositiveInteger } from "../reconciliation-config.js";
2
+ //#region src/integrations/incidentio/reconciliation-config.ts
3
+ const RECONCILIATION_LABEL = "incident.io reconciliation";
4
+ function incidentioReconciliationEnabled() {
5
+ return optionalBoolean("MASTRACODE_INCIDENT_IO_RECONCILE_ENABLED", process.env.MASTRACODE_INCIDENT_IO_RECONCILE_ENABLED, RECONCILIATION_LABEL) ?? true;
6
+ }
7
+ function incidentioReconciliationInterval() {
8
+ const name = "MASTRACODE_INCIDENT_IO_RECONCILE_INTERVAL_MS";
9
+ const value = process.env.MASTRACODE_INCIDENT_IO_RECONCILE_INTERVAL_MS;
10
+ const interval = optionalPositiveInteger(value);
11
+ if (value?.trim() && interval === void 0) console.warn(`[${RECONCILIATION_LABEL}] ${name} must be a positive integer; received ${JSON.stringify(value)}.`);
12
+ return interval;
13
+ }
14
+ //#endregion
15
+ export { incidentioReconciliationEnabled, incidentioReconciliationInterval };
16
+
17
+ //# sourceMappingURL=reconciliation-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconciliation-config.js","names":[],"sources":["../../../src/integrations/incidentio/reconciliation-config.ts"],"sourcesContent":["import { optionalBoolean, optionalPositiveInteger } from '../reconciliation-config.js';\n\nconst RECONCILIATION_LABEL = 'incident.io reconciliation';\n\nexport function incidentioReconciliationEnabled(): boolean {\n return (\n optionalBoolean(\n 'MASTRACODE_INCIDENT_IO_RECONCILE_ENABLED',\n process.env.MASTRACODE_INCIDENT_IO_RECONCILE_ENABLED,\n RECONCILIATION_LABEL,\n ) ?? true\n );\n}\n\nexport function incidentioReconciliationInterval(): number | undefined {\n const name = 'MASTRACODE_INCIDENT_IO_RECONCILE_INTERVAL_MS';\n const value = process.env.MASTRACODE_INCIDENT_IO_RECONCILE_INTERVAL_MS;\n const interval = optionalPositiveInteger(value);\n if (value?.trim() && interval === undefined) {\n console.warn(`[${RECONCILIATION_LABEL}] ${name} must be a positive integer; received ${JSON.stringify(value)}.`);\n }\n return interval;\n}\n"],"mappings":";;AAEA,MAAM,uBAAuB;AAE7B,SAAgB,kCAA2C;CACzD,OACE,gBACE,4CACA,QAAQ,IAAI,0CACZ,oBACF,KAAK;AAET;AAEA,SAAgB,mCAAuD;CACrE,MAAM,OAAO;CACb,MAAM,QAAQ,QAAQ,IAAI;CAC1B,MAAM,WAAW,wBAAwB,KAAK;CAC9C,IAAI,OAAO,KAAK,KAAK,aAAa,KAAA,GAChC,QAAQ,KAAK,IAAI,qBAAqB,IAAI,KAAK,wCAAwC,KAAK,UAAU,KAAK,EAAE,EAAE;CAEjH,OAAO;AACT"}
@@ -1 +1 @@
1
- {"version":3,"file":"reconciliation-config.d.ts","sourceRoot":"","sources":["../../../src/integrations/linear/reconciliation-config.ts"],"names":[],"mappings":"AA4BA,wBAAgB,gCAAgC,IAAI,OAAO,CAO1D;AAED,wBAAgB,iCAAiC,IAAI,MAAM,GAAG,SAAS,CAWtE"}
1
+ {"version":3,"file":"reconciliation-config.d.ts","sourceRoot":"","sources":["../../../src/integrations/linear/reconciliation-config.ts"],"names":[],"mappings":"AAyBA,wBAAgB,gCAAgC,IAAI,OAAO,CAO1D;AAED,wBAAgB,iCAAiC,IAAI,MAAM,GAAG,SAAS,CAWtE"}
@@ -1,20 +1,14 @@
1
- import { optionalPositiveInteger } from "../reconciliation-config.js";
1
+ import { optionalBoolean, optionalPositiveInteger } from "../reconciliation-config.js";
2
2
  //#region src/integrations/linear/reconciliation-config.ts
3
+ const RECONCILIATION_LABEL = "Linear reconciliation";
3
4
  function reconciliationEnabled(childName, childValue, legacyName, legacyValue) {
4
- return parseBoolean(childName, childValue) ?? parseBoolean(legacyName, legacyValue) ?? true;
5
+ return optionalBoolean(childName, childValue, RECONCILIATION_LABEL) ?? optionalBoolean(legacyName, legacyValue, RECONCILIATION_LABEL) ?? true;
5
6
  }
6
7
  function optionalPositiveInterval(name, value) {
7
8
  const interval = optionalPositiveInteger(value);
8
- if (value?.trim() && interval === void 0) console.warn(`[Linear reconciliation] ${name} must be a positive integer; received ${JSON.stringify(value)}.`);
9
+ if (value?.trim() && interval === void 0) console.warn(`[${RECONCILIATION_LABEL}] ${name} must be a positive integer; received ${JSON.stringify(value)}.`);
9
10
  return interval;
10
11
  }
11
- function parseBoolean(name, value) {
12
- const normalized = value?.trim().toLowerCase();
13
- if (!normalized) return void 0;
14
- if (normalized === "true") return true;
15
- if (normalized === "false") return false;
16
- console.warn(`[Linear reconciliation] ${name} must be true or false; received ${JSON.stringify(value)}.`);
17
- }
18
12
  function linearIssueReconciliationEnabled() {
19
13
  return reconciliationEnabled("MASTRACODE_LINEAR_ISSUE_RECONCILE_ENABLED", process.env.MASTRACODE_LINEAR_ISSUE_RECONCILE_ENABLED, "MASTRACODE_LINEAR_RECONCILE_ENABLED", process.env.MASTRACODE_LINEAR_RECONCILE_ENABLED);
20
14
  }
@@ -1 +1 @@
1
- {"version":3,"file":"reconciliation-config.js","names":[],"sources":["../../../src/integrations/linear/reconciliation-config.ts"],"sourcesContent":["import { optionalPositiveInteger } from '../reconciliation-config.js';\n\nfunction reconciliationEnabled(\n childName: string,\n childValue: string | undefined,\n legacyName: string,\n legacyValue: string | undefined,\n): boolean {\n return parseBoolean(childName, childValue) ?? parseBoolean(legacyName, legacyValue) ?? true;\n}\n\nfunction optionalPositiveInterval(name: string, value: string | undefined): number | undefined {\n const interval = optionalPositiveInteger(value);\n if (value?.trim() && interval === undefined) {\n console.warn(`[Linear reconciliation] ${name} must be a positive integer; received ${JSON.stringify(value)}.`);\n }\n return interval;\n}\n\nfunction parseBoolean(name: string, value: string | undefined): boolean | undefined {\n const normalized = value?.trim().toLowerCase();\n if (!normalized) return undefined;\n if (normalized === 'true') return true;\n if (normalized === 'false') return false;\n console.warn(`[Linear reconciliation] ${name} must be true or false; received ${JSON.stringify(value)}.`);\n return undefined;\n}\n\nexport function linearIssueReconciliationEnabled(): boolean {\n return reconciliationEnabled(\n 'MASTRACODE_LINEAR_ISSUE_RECONCILE_ENABLED',\n process.env.MASTRACODE_LINEAR_ISSUE_RECONCILE_ENABLED,\n 'MASTRACODE_LINEAR_RECONCILE_ENABLED',\n process.env.MASTRACODE_LINEAR_RECONCILE_ENABLED,\n );\n}\n\nexport function linearIssueReconciliationInterval(): number | undefined {\n return (\n optionalPositiveInterval(\n 'MASTRACODE_LINEAR_ISSUE_RECONCILE_INTERVAL_MS',\n process.env.MASTRACODE_LINEAR_ISSUE_RECONCILE_INTERVAL_MS,\n ) ??\n optionalPositiveInterval(\n 'MASTRACODE_LINEAR_RECONCILE_INTERVAL_MS',\n process.env.MASTRACODE_LINEAR_RECONCILE_INTERVAL_MS,\n )\n );\n}\n"],"mappings":";;AAEA,SAAS,sBACP,WACA,YACA,YACA,aACS;CACT,OAAO,aAAa,WAAW,UAAU,KAAK,aAAa,YAAY,WAAW,KAAK;AACzF;AAEA,SAAS,yBAAyB,MAAc,OAA+C;CAC7F,MAAM,WAAW,wBAAwB,KAAK;CAC9C,IAAI,OAAO,KAAK,KAAK,aAAa,KAAA,GAChC,QAAQ,KAAK,2BAA2B,KAAK,wCAAwC,KAAK,UAAU,KAAK,EAAE,EAAE;CAE/G,OAAO;AACT;AAEA,SAAS,aAAa,MAAc,OAAgD;CAClF,MAAM,aAAa,OAAO,KAAK,CAAC,CAAC,YAAY;CAC7C,IAAI,CAAC,YAAY,OAAO,KAAA;CACxB,IAAI,eAAe,QAAQ,OAAO;CAClC,IAAI,eAAe,SAAS,OAAO;CACnC,QAAQ,KAAK,2BAA2B,KAAK,mCAAmC,KAAK,UAAU,KAAK,EAAE,EAAE;AAE1G;AAEA,SAAgB,mCAA4C;CAC1D,OAAO,sBACL,6CACA,QAAQ,IAAI,2CACZ,uCACA,QAAQ,IAAI,mCACd;AACF;AAEA,SAAgB,oCAAwD;CACtE,OACE,yBACE,iDACA,QAAQ,IAAI,6CACd,KACA,yBACE,2CACA,QAAQ,IAAI,uCACd;AAEJ"}
1
+ {"version":3,"file":"reconciliation-config.js","names":[],"sources":["../../../src/integrations/linear/reconciliation-config.ts"],"sourcesContent":["import { optionalBoolean, optionalPositiveInteger } from '../reconciliation-config.js';\n\nconst RECONCILIATION_LABEL = 'Linear reconciliation';\n\nfunction reconciliationEnabled(\n childName: string,\n childValue: string | undefined,\n legacyName: string,\n legacyValue: string | undefined,\n): boolean {\n return (\n optionalBoolean(childName, childValue, RECONCILIATION_LABEL) ??\n optionalBoolean(legacyName, legacyValue, RECONCILIATION_LABEL) ??\n true\n );\n}\n\nfunction optionalPositiveInterval(name: string, value: string | undefined): number | undefined {\n const interval = optionalPositiveInteger(value);\n if (value?.trim() && interval === undefined) {\n console.warn(`[${RECONCILIATION_LABEL}] ${name} must be a positive integer; received ${JSON.stringify(value)}.`);\n }\n return interval;\n}\n\nexport function linearIssueReconciliationEnabled(): boolean {\n return reconciliationEnabled(\n 'MASTRACODE_LINEAR_ISSUE_RECONCILE_ENABLED',\n process.env.MASTRACODE_LINEAR_ISSUE_RECONCILE_ENABLED,\n 'MASTRACODE_LINEAR_RECONCILE_ENABLED',\n process.env.MASTRACODE_LINEAR_RECONCILE_ENABLED,\n );\n}\n\nexport function linearIssueReconciliationInterval(): number | undefined {\n return (\n optionalPositiveInterval(\n 'MASTRACODE_LINEAR_ISSUE_RECONCILE_INTERVAL_MS',\n process.env.MASTRACODE_LINEAR_ISSUE_RECONCILE_INTERVAL_MS,\n ) ??\n optionalPositiveInterval(\n 'MASTRACODE_LINEAR_RECONCILE_INTERVAL_MS',\n process.env.MASTRACODE_LINEAR_RECONCILE_INTERVAL_MS,\n )\n );\n}\n"],"mappings":";;AAEA,MAAM,uBAAuB;AAE7B,SAAS,sBACP,WACA,YACA,YACA,aACS;CACT,OACE,gBAAgB,WAAW,YAAY,oBAAoB,KAC3D,gBAAgB,YAAY,aAAa,oBAAoB,KAC7D;AAEJ;AAEA,SAAS,yBAAyB,MAAc,OAA+C;CAC7F,MAAM,WAAW,wBAAwB,KAAK;CAC9C,IAAI,OAAO,KAAK,KAAK,aAAa,KAAA,GAChC,QAAQ,KAAK,IAAI,qBAAqB,IAAI,KAAK,wCAAwC,KAAK,UAAU,KAAK,EAAE,EAAE;CAEjH,OAAO;AACT;AAEA,SAAgB,mCAA4C;CAC1D,OAAO,sBACL,6CACA,QAAQ,IAAI,2CACZ,uCACA,QAAQ,IAAI,mCACd;AACF;AAEA,SAAgB,oCAAwD;CACtE,OACE,yBACE,iDACA,QAAQ,IAAI,6CACd,KACA,yBACE,2CACA,QAAQ,IAAI,uCACd;AAEJ"}
@@ -0,0 +1,17 @@
1
+ import type { MastraWorker } from '@mastra/core/worker';
2
+ import type { FactoryIntegration, IntegrationContext } from '../../base.js';
3
+ import { type PlatformApiClientConfig } from '../api-client.js';
4
+ export interface PlatformIncidentioIntegrationConfig {
5
+ clientConfig?: PlatformApiClientConfig;
6
+ connectionId?: string;
7
+ }
8
+ export declare class PlatformIncidentioIntegration implements FactoryIntegration {
9
+ #private;
10
+ readonly id = "incidentio";
11
+ readonly intake: import("../../../capabilities/intake.js").Intake;
12
+ constructor(config?: PlatformIncidentioIntegrationConfig);
13
+ workers(ctx: IntegrationContext): MastraWorker[];
14
+ routes(): [];
15
+ diagnostics(): Record<string, unknown>;
16
+ }
17
+ //# sourceMappingURL=integration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration.d.ts","sourceRoot":"","sources":["../../../../src/integrations/platform/incidentio/integration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAS5E,OAAO,EAAkC,KAAK,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAEhG,MAAM,WAAW,mCAAmC;IAClD,YAAY,CAAC,EAAE,uBAAuB,CAAC;IACvC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAID,qBAAa,6BAA8B,YAAW,kBAAkB;;IACtE,QAAQ,CAAC,EAAE,gBAAgB;IAC3B,QAAQ,CAAC,MAAM,mDAAC;gBAGJ,MAAM,GAAE,mCAAwC;IAsB5D,OAAO,CAAC,GAAG,EAAE,kBAAkB,GAAG,YAAY,EAAE;IAchD,MAAM,IAAI,EAAE;IAIZ,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAGvC"}