@mastra/factory 0.16.0-alpha.6 → 0.16.0-alpha.8

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 (123) hide show
  1. package/README.md +4 -3
  2. package/dist/boards/work.d.ts.map +1 -1
  3. package/dist/boards/work.js +37 -3
  4. package/dist/boards/work.js.map +1 -1
  5. package/dist/factory.d.ts +6 -3
  6. package/dist/factory.d.ts.map +1 -1
  7. package/dist/factory.js +15 -6
  8. package/dist/factory.js.map +1 -1
  9. package/dist/integrations/base.d.ts +2 -0
  10. package/dist/integrations/base.d.ts.map +1 -1
  11. package/dist/integrations/incidentio/agent-tools.d.ts +49 -0
  12. package/dist/integrations/incidentio/agent-tools.d.ts.map +1 -0
  13. package/dist/integrations/incidentio/agent-tools.js +90 -0
  14. package/dist/integrations/incidentio/agent-tools.js.map +1 -0
  15. package/dist/integrations/incidentio/claim.d.ts +8 -0
  16. package/dist/integrations/incidentio/claim.d.ts.map +1 -0
  17. package/dist/integrations/incidentio/claim.js +14 -0
  18. package/dist/integrations/incidentio/claim.js.map +1 -0
  19. package/dist/integrations/incidentio/default-rules.d.ts +46 -0
  20. package/dist/integrations/incidentio/default-rules.d.ts.map +1 -0
  21. package/dist/integrations/incidentio/default-rules.js +66 -0
  22. package/dist/integrations/incidentio/default-rules.js.map +1 -0
  23. package/dist/integrations/incidentio/integration.d.ts +48 -2
  24. package/dist/integrations/incidentio/integration.d.ts.map +1 -1
  25. package/dist/integrations/incidentio/integration.js +88 -2
  26. package/dist/integrations/incidentio/integration.js.map +1 -1
  27. package/dist/integrations/incidentio/issue-reconciler.d.ts +2 -0
  28. package/dist/integrations/incidentio/issue-reconciler.d.ts.map +1 -1
  29. package/dist/integrations/incidentio/issue-reconciler.js +38 -2
  30. package/dist/integrations/incidentio/issue-reconciler.js.map +1 -1
  31. package/dist/integrations/incidentio/routes.d.ts +71 -0
  32. package/dist/integrations/incidentio/routes.d.ts.map +1 -0
  33. package/dist/integrations/incidentio/routes.js +245 -0
  34. package/dist/integrations/incidentio/routes.js.map +1 -0
  35. package/dist/integrations/incidentio/rules.d.ts +55 -0
  36. package/dist/integrations/incidentio/rules.d.ts.map +1 -0
  37. package/dist/integrations/incidentio/rules.js +175 -0
  38. package/dist/integrations/incidentio/rules.js.map +1 -0
  39. package/dist/integrations/jira/adf.d.ts +26 -0
  40. package/dist/integrations/jira/adf.d.ts.map +1 -0
  41. package/dist/integrations/jira/adf.js +73 -0
  42. package/dist/integrations/jira/adf.js.map +1 -0
  43. package/dist/integrations/jira/agent-tools.d.ts +45 -0
  44. package/dist/integrations/jira/agent-tools.d.ts.map +1 -0
  45. package/dist/integrations/jira/agent-tools.js +87 -0
  46. package/dist/integrations/jira/agent-tools.js.map +1 -0
  47. package/dist/integrations/jira/api.d.ts +157 -0
  48. package/dist/integrations/jira/api.d.ts.map +1 -0
  49. package/dist/integrations/jira/api.js +141 -0
  50. package/dist/integrations/jira/api.js.map +1 -0
  51. package/dist/integrations/jira/claim.d.ts +9 -0
  52. package/dist/integrations/jira/claim.d.ts.map +1 -0
  53. package/dist/integrations/jira/claim.js +15 -0
  54. package/dist/integrations/jira/claim.js.map +1 -0
  55. package/dist/integrations/jira/default-rules.d.ts +47 -0
  56. package/dist/integrations/jira/default-rules.d.ts.map +1 -0
  57. package/dist/integrations/jira/default-rules.js +67 -0
  58. package/dist/integrations/jira/default-rules.js.map +1 -0
  59. package/dist/integrations/jira/integration.d.ts +114 -0
  60. package/dist/integrations/jira/integration.d.ts.map +1 -0
  61. package/dist/integrations/jira/integration.js +401 -0
  62. package/dist/integrations/jira/integration.js.map +1 -0
  63. package/dist/integrations/jira/issue-reconciler.d.ts +10 -0
  64. package/dist/integrations/jira/issue-reconciler.d.ts.map +1 -0
  65. package/dist/integrations/jira/issue-reconciler.js +70 -0
  66. package/dist/integrations/jira/issue-reconciler.js.map +1 -0
  67. package/dist/integrations/jira/reconciliation-config.d.ts +3 -0
  68. package/dist/integrations/jira/reconciliation-config.d.ts.map +1 -0
  69. package/dist/integrations/jira/reconciliation-config.js +17 -0
  70. package/dist/integrations/jira/reconciliation-config.js.map +1 -0
  71. package/dist/integrations/jira/routes.d.ts +54 -0
  72. package/dist/integrations/jira/routes.d.ts.map +1 -0
  73. package/dist/integrations/jira/routes.js +260 -0
  74. package/dist/integrations/jira/routes.js.map +1 -0
  75. package/dist/integrations/jira/rules.d.ts +57 -0
  76. package/dist/integrations/jira/rules.d.ts.map +1 -0
  77. package/dist/integrations/jira/rules.js +175 -0
  78. package/dist/integrations/jira/rules.js.map +1 -0
  79. package/dist/integrations/platform/connect/routes.d.ts +39 -0
  80. package/dist/integrations/platform/connect/routes.d.ts.map +1 -0
  81. package/dist/integrations/platform/connect/routes.js +129 -0
  82. package/dist/integrations/platform/connect/routes.js.map +1 -0
  83. package/dist/integrations/platform/github/event-worker.js +1 -1
  84. package/dist/integrations/platform/github/integration.js +1 -1
  85. package/dist/integrations/platform/incidentio/integration.d.ts +61 -4
  86. package/dist/integrations/platform/incidentio/integration.d.ts.map +1 -1
  87. package/dist/integrations/platform/incidentio/integration.js +371 -22
  88. package/dist/integrations/platform/incidentio/integration.js.map +1 -1
  89. package/dist/integrations/platform/jira/agent-tools.d.ts +36 -0
  90. package/dist/integrations/platform/jira/agent-tools.d.ts.map +1 -0
  91. package/dist/integrations/platform/jira/agent-tools.js +85 -0
  92. package/dist/integrations/platform/jira/agent-tools.js.map +1 -0
  93. package/dist/integrations/platform/jira/integration.d.ts +65 -0
  94. package/dist/integrations/platform/jira/integration.d.ts.map +1 -0
  95. package/dist/integrations/platform/jira/integration.js +540 -0
  96. package/dist/integrations/platform/jira/integration.js.map +1 -0
  97. package/dist/integrations/platform/jira/routes.d.ts +55 -0
  98. package/dist/integrations/platform/jira/routes.d.ts.map +1 -0
  99. package/dist/integrations/platform/jira/routes.js +274 -0
  100. package/dist/integrations/platform/jira/routes.js.map +1 -0
  101. package/dist/routes/oauth.js +2 -5
  102. package/dist/routes/oauth.js.map +1 -1
  103. package/dist/routes/surface.d.ts.map +1 -1
  104. package/dist/routes/surface.js +24 -4
  105. package/dist/routes/surface.js.map +1 -1
  106. package/dist/rules/dispatcher.d.ts.map +1 -1
  107. package/dist/rules/dispatcher.js +1 -1
  108. package/dist/rules/dispatcher.js.map +1 -1
  109. package/dist/rules/index.d.ts +2 -2
  110. package/dist/rules/index.d.ts.map +1 -1
  111. package/dist/rules/index.js +2 -2
  112. package/dist/rules/types.d.ts +57 -3
  113. package/dist/rules/types.d.ts.map +1 -1
  114. package/dist/rules/types.js +9 -1
  115. package/dist/rules/types.js.map +1 -1
  116. package/dist/rules/validation.d.ts.map +1 -1
  117. package/dist/rules/validation.js +2 -0
  118. package/dist/rules/validation.js.map +1 -1
  119. package/dist/work-item-branch.d.ts +1 -1
  120. package/dist/work-item-branch.d.ts.map +1 -1
  121. package/dist/work-item-branch.js +4 -2
  122. package/dist/work-item-branch.js.map +1 -1
  123. package/package.json +7 -7
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Org-wide ownership key for an incident.io follow-up's Factory card. Keyed by
3
+ * the prefixed item reference the intake feed serves as `id`
4
+ * (`incidentio:follow-up:<ulid>`), which is globally unique across accounts,
5
+ * so a single live card holds the claim org-wide.
6
+ */
7
+ export declare function incidentioClaimKey(itemRef: string): string;
8
+ //# sourceMappingURL=claim.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claim.d.ts","sourceRoot":"","sources":["../../../src/integrations/incidentio/claim.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE1D"}
@@ -0,0 +1,14 @@
1
+ //#region src/integrations/incidentio/claim.ts
2
+ /**
3
+ * Org-wide ownership key for an incident.io follow-up's Factory card. Keyed by
4
+ * the prefixed item reference the intake feed serves as `id`
5
+ * (`incidentio:follow-up:<ulid>`), which is globally unique across accounts,
6
+ * so a single live card holds the claim org-wide.
7
+ */
8
+ function incidentioClaimKey(itemRef) {
9
+ return `incidentio:item:${itemRef}`;
10
+ }
11
+ //#endregion
12
+ export { incidentioClaimKey };
13
+
14
+ //# sourceMappingURL=claim.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claim.js","names":[],"sources":["../../../src/integrations/incidentio/claim.ts"],"sourcesContent":["/**\n * Org-wide ownership key for an incident.io follow-up's Factory card. Keyed by\n * the prefixed item reference the intake feed serves as `id`\n * (`incidentio:follow-up:<ulid>`), which is globally unique across accounts,\n * so a single live card holds the claim org-wide.\n */\nexport function incidentioClaimKey(itemRef: string): string {\n return `incidentio:item:${itemRef}`;\n}\n"],"mappings":";;;;;;;AAMA,SAAgB,mBAAmB,SAAyB;CAC1D,OAAO,mBAAmB;AAC5B"}
@@ -0,0 +1,46 @@
1
+ import type { FactoryIncidentioEventName, FactoryIncidentioRuleContext, FactoryRuleHandler } from '../../rules/types.js';
2
+ export type IncidentioRuleOverrides = Partial<Record<FactoryIncidentioEventName, FactoryRuleHandler<FactoryIncidentioRuleContext> | null | undefined>>;
3
+ export type IncidentioEventRules = Readonly<Record<FactoryIncidentioEventName, FactoryRuleHandler<FactoryIncidentioRuleContext> | null>>;
4
+ declare function incidentioFollowUpObserved(context: FactoryIncidentioRuleContext): {
5
+ readonly type: "upsertLinkedWorkItem";
6
+ readonly idempotencyKey: `${string}:follow-up-triage`;
7
+ readonly board: string;
8
+ readonly source: "incidentio-follow-up";
9
+ readonly sourceKey: string;
10
+ readonly claimKey: string;
11
+ readonly title: string;
12
+ readonly url: string;
13
+ readonly stage: string;
14
+ readonly metadata: {
15
+ readonly identifier: string;
16
+ readonly issueRef: string;
17
+ readonly sourceCreatedAt: string;
18
+ readonly state: string;
19
+ readonly stateType: string;
20
+ readonly priority: string;
21
+ readonly incident: string | null;
22
+ readonly assignee: string | null;
23
+ readonly assignees: string[];
24
+ readonly creator: string | null;
25
+ readonly author: string | null;
26
+ readonly labels: string[];
27
+ readonly createdAt: string;
28
+ readonly updatedAt: string;
29
+ };
30
+ } | undefined;
31
+ declare function incidentioFollowUpClosed(context: FactoryIncidentioRuleContext): {
32
+ readonly type: "transition";
33
+ readonly idempotencyKey: `${string}:follow-up-closed`;
34
+ readonly board: "work";
35
+ readonly stage: "done" | "canceled";
36
+ readonly message: {
37
+ readonly text: `incident.io follow-up ${string} was canceled; this Work card was moved to Done.` | `incident.io follow-up ${string} was canceled; this Work card was moved to Canceled.` | `incident.io follow-up ${string} was completed; this Work card was moved to Done.` | `incident.io follow-up ${string} was completed; this Work card was moved to Canceled.`;
38
+ };
39
+ } | undefined;
40
+ export declare const defaultIncidentioRules: Readonly<{
41
+ followUpObserved: typeof incidentioFollowUpObserved;
42
+ followUpClosed: typeof incidentioFollowUpClosed;
43
+ }>;
44
+ export declare function resolveIncidentioRules(overrides?: IncidentioRuleOverrides): IncidentioEventRules;
45
+ export {};
46
+ //# sourceMappingURL=default-rules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"default-rules.d.ts","sourceRoot":"","sources":["../../../src/integrations/incidentio/default-rules.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,0BAA0B,EAC1B,4BAA4B,EAC5B,kBAAkB,EACnB,MAAM,sBAAsB,CAAC;AAG9B,MAAM,MAAM,uBAAuB,GAAG,OAAO,CAC3C,MAAM,CAAC,0BAA0B,EAAE,kBAAkB,CAAC,4BAA4B,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,CACxG,CAAC;AACF,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CACzC,MAAM,CAAC,0BAA0B,EAAE,kBAAkB,CAAC,4BAA4B,CAAC,GAAG,IAAI,CAAC,CAC5F,CAAC;AAEF,iBAAS,0BAA0B,CAAC,OAAO,EAAE,4BAA4B;;;;;;;;;;;;;;;;;;;4BAuBI,MAAM,EAAE;;;yBAG1C,MAAM,EAAE;;;;cAKlD;AAED,iBAAS,wBAAwB,CAAC,OAAO,EAAE,4BAA4B;;;;;;;;cAkBtE;AAED,eAAO,MAAM,sBAAsB;;;EAGF,CAAC;AAElC,wBAAgB,sBAAsB,CAAC,SAAS,CAAC,EAAE,uBAAuB,GAAG,oBAAoB,CAwBhG"}
@@ -0,0 +1,66 @@
1
+ import { incidentioClaimKey } from "./claim.js";
2
+ //#region src/integrations/incidentio/default-rules.ts
3
+ function incidentioFollowUpObserved(context) {
4
+ if (context.item) return;
5
+ return {
6
+ type: "upsertLinkedWorkItem",
7
+ idempotencyKey: `${context.ingress.id}:follow-up-triage`,
8
+ board: context.intake?.board ?? "work",
9
+ source: "incidentio-follow-up",
10
+ sourceKey: context.issue.id,
11
+ claimKey: incidentioClaimKey(context.issue.id),
12
+ title: context.issue.title,
13
+ url: context.issue.url,
14
+ stage: context.intake?.initialPhase ?? "triage",
15
+ metadata: {
16
+ identifier: context.issue.identifier,
17
+ issueRef: context.issue.id,
18
+ sourceCreatedAt: context.issue.createdAt,
19
+ state: context.issue.state,
20
+ stateType: context.issue.stateType,
21
+ priority: context.issue.priorityLabel,
22
+ incident: context.issue.incident,
23
+ assignee: context.issue.assignee,
24
+ assignees: context.issue.assignee ? [context.issue.assignee] : [],
25
+ creator: context.issue.author,
26
+ author: context.issue.author,
27
+ labels: [...context.issue.labels],
28
+ createdAt: context.issue.createdAt,
29
+ updatedAt: context.issue.updatedAt
30
+ }
31
+ };
32
+ }
33
+ function incidentioFollowUpClosed(context) {
34
+ if (!context.item || context.item.source !== "incidentio-follow-up") return;
35
+ if (context.board !== "work") return;
36
+ if (context.item.stages.some((stage) => stage === "done" || stage === "canceled")) return;
37
+ const stateType = context.issue.stateType;
38
+ if (stateType !== "completed" && stateType !== "canceled") return;
39
+ const canceled = stateType === "canceled";
40
+ return {
41
+ type: "transition",
42
+ idempotencyKey: `${context.ingress.id}:follow-up-closed`,
43
+ board: "work",
44
+ stage: canceled ? "canceled" : "done",
45
+ message: { text: `incident.io follow-up ${context.issue.identifier} was ${canceled ? "canceled" : "completed"}; this Work card was moved to ${canceled ? "Canceled" : "Done"}.` }
46
+ };
47
+ }
48
+ const defaultIncidentioRules = Object.freeze({
49
+ followUpObserved: incidentioFollowUpObserved,
50
+ followUpClosed: incidentioFollowUpClosed
51
+ });
52
+ function resolveIncidentioRules(overrides) {
53
+ if (overrides !== void 0 && (overrides === null || typeof overrides !== "object" || Array.isArray(overrides) || ![Object.prototype, null].includes(Object.getPrototypeOf(overrides)))) throw new Error("incident.io rules must be a plain object.");
54
+ const rules = { ...defaultIncidentioRules };
55
+ for (const key of Reflect.ownKeys(overrides ?? {})) {
56
+ if (typeof key !== "string" || !Object.hasOwn(defaultIncidentioRules, key)) throw new Error(`Unknown incident.io rule event: ${String(key)}.`);
57
+ const handler = overrides?.[key];
58
+ if (handler !== void 0 && handler !== null && typeof handler !== "function") throw new Error(`incident.io rule ${key} must be a function, null, or undefined.`);
59
+ if (handler !== void 0) rules[key] = handler;
60
+ }
61
+ return Object.freeze(rules);
62
+ }
63
+ //#endregion
64
+ export { defaultIncidentioRules, resolveIncidentioRules };
65
+
66
+ //# sourceMappingURL=default-rules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"default-rules.js","names":[],"sources":["../../../src/integrations/incidentio/default-rules.ts"],"sourcesContent":["import type {\n FactoryIncidentioEventName,\n FactoryIncidentioRuleContext,\n FactoryRuleHandler,\n} from '../../rules/types.js';\nimport { incidentioClaimKey } from './claim.js';\n\nexport type IncidentioRuleOverrides = Partial<\n Record<FactoryIncidentioEventName, FactoryRuleHandler<FactoryIncidentioRuleContext> | null | undefined>\n>;\nexport type IncidentioEventRules = Readonly<\n Record<FactoryIncidentioEventName, FactoryRuleHandler<FactoryIncidentioRuleContext> | null>\n>;\n\nfunction incidentioFollowUpObserved(context: FactoryIncidentioRuleContext) {\n if (context.item) return;\n return {\n type: 'upsertLinkedWorkItem',\n idempotencyKey: `${context.ingress.id}:follow-up-triage`,\n // A source bound to a custom board lands on that board's initial phase;\n // otherwise Work auto-triages the new follow-up.\n board: context.intake?.board ?? 'work',\n source: 'incidentio-follow-up',\n sourceKey: context.issue.id,\n claimKey: incidentioClaimKey(context.issue.id),\n title: context.issue.title,\n url: context.issue.url,\n stage: context.intake?.initialPhase ?? 'triage',\n metadata: {\n identifier: context.issue.identifier,\n issueRef: context.issue.id,\n sourceCreatedAt: context.issue.createdAt,\n state: context.issue.state,\n stateType: context.issue.stateType,\n priority: context.issue.priorityLabel,\n incident: context.issue.incident,\n assignee: context.issue.assignee,\n assignees: (context.issue.assignee ? [context.issue.assignee] : []) as string[],\n creator: context.issue.author,\n author: context.issue.author,\n labels: [...context.issue.labels] as string[],\n createdAt: context.issue.createdAt,\n updatedAt: context.issue.updatedAt,\n },\n } as const;\n}\n\nfunction incidentioFollowUpClosed(context: FactoryIncidentioRuleContext) {\n if (!context.item || context.item.source !== 'incidentio-follow-up') return;\n if (context.board !== 'work') return;\n // Already off the board: nothing to reconcile.\n if (context.item.stages.some(stage => stage === 'done' || stage === 'canceled')) return;\n // Only terminal state types trigger close.\n const stateType = context.issue.stateType;\n if (stateType !== 'completed' && stateType !== 'canceled') return;\n const canceled = stateType === 'canceled';\n return {\n type: 'transition',\n idempotencyKey: `${context.ingress.id}:follow-up-closed`,\n board: 'work',\n stage: canceled ? 'canceled' : 'done',\n message: {\n text: `incident.io follow-up ${context.issue.identifier} was ${canceled ? 'canceled' : 'completed'}; this Work card was moved to ${canceled ? 'Canceled' : 'Done'}.`,\n },\n } as const;\n}\n\nexport const defaultIncidentioRules = Object.freeze({\n followUpObserved: incidentioFollowUpObserved,\n followUpClosed: incidentioFollowUpClosed,\n} satisfies IncidentioEventRules);\n\nexport function resolveIncidentioRules(overrides?: IncidentioRuleOverrides): IncidentioEventRules {\n if (\n overrides !== undefined &&\n (overrides === null ||\n typeof overrides !== 'object' ||\n Array.isArray(overrides) ||\n ![Object.prototype, null].includes(Object.getPrototypeOf(overrides)))\n ) {\n throw new Error('incident.io rules must be a plain object.');\n }\n const rules: Record<string, FactoryRuleHandler<FactoryIncidentioRuleContext> | null> = {\n ...defaultIncidentioRules,\n };\n for (const key of Reflect.ownKeys(overrides ?? {})) {\n if (typeof key !== 'string' || !Object.hasOwn(defaultIncidentioRules, key)) {\n throw new Error(`Unknown incident.io rule event: ${String(key)}.`);\n }\n const handler = overrides?.[key as FactoryIncidentioEventName];\n if (handler !== undefined && handler !== null && typeof handler !== 'function') {\n throw new Error(`incident.io rule ${key} must be a function, null, or undefined.`);\n }\n if (handler !== undefined) rules[key] = handler;\n }\n return Object.freeze(rules) as IncidentioEventRules;\n}\n"],"mappings":";;AAcA,SAAS,2BAA2B,SAAuC;CACzE,IAAI,QAAQ,MAAM;CAClB,OAAO;EACL,MAAM;EACN,gBAAgB,GAAG,QAAQ,QAAQ,GAAG;EAGtC,OAAO,QAAQ,QAAQ,SAAS;EAChC,QAAQ;EACR,WAAW,QAAQ,MAAM;EACzB,UAAU,mBAAmB,QAAQ,MAAM,EAAE;EAC7C,OAAO,QAAQ,MAAM;EACrB,KAAK,QAAQ,MAAM;EACnB,OAAO,QAAQ,QAAQ,gBAAgB;EACvC,UAAU;GACR,YAAY,QAAQ,MAAM;GAC1B,UAAU,QAAQ,MAAM;GACxB,iBAAiB,QAAQ,MAAM;GAC/B,OAAO,QAAQ,MAAM;GACrB,WAAW,QAAQ,MAAM;GACzB,UAAU,QAAQ,MAAM;GACxB,UAAU,QAAQ,MAAM;GACxB,UAAU,QAAQ,MAAM;GACxB,WAAY,QAAQ,MAAM,WAAW,CAAC,QAAQ,MAAM,QAAQ,IAAI,CAAC;GACjE,SAAS,QAAQ,MAAM;GACvB,QAAQ,QAAQ,MAAM;GACtB,QAAQ,CAAC,GAAG,QAAQ,MAAM,MAAM;GAChC,WAAW,QAAQ,MAAM;GACzB,WAAW,QAAQ,MAAM;EAC3B;CACF;AACF;AAEA,SAAS,yBAAyB,SAAuC;CACvE,IAAI,CAAC,QAAQ,QAAQ,QAAQ,KAAK,WAAW,wBAAwB;CACrE,IAAI,QAAQ,UAAU,QAAQ;CAE9B,IAAI,QAAQ,KAAK,OAAO,MAAK,UAAS,UAAU,UAAU,UAAU,UAAU,GAAG;CAEjF,MAAM,YAAY,QAAQ,MAAM;CAChC,IAAI,cAAc,eAAe,cAAc,YAAY;CAC3D,MAAM,WAAW,cAAc;CAC/B,OAAO;EACL,MAAM;EACN,gBAAgB,GAAG,QAAQ,QAAQ,GAAG;EACtC,OAAO;EACP,OAAO,WAAW,aAAa;EAC/B,SAAS,EACP,MAAM,yBAAyB,QAAQ,MAAM,WAAW,OAAO,WAAW,aAAa,YAAY,gCAAgC,WAAW,aAAa,OAAO,GACpK;CACF;AACF;AAEA,MAAa,yBAAyB,OAAO,OAAO;CAClD,kBAAkB;CAClB,gBAAgB;AAClB,CAAgC;AAEhC,SAAgB,uBAAuB,WAA2D;CAChG,IACE,cAAc,KAAA,MACb,cAAc,QACb,OAAO,cAAc,YACrB,MAAM,QAAQ,SAAS,KACvB,CAAC,CAAC,OAAO,WAAW,IAAI,CAAC,CAAC,SAAS,OAAO,eAAe,SAAS,CAAC,IAErE,MAAM,IAAI,MAAM,2CAA2C;CAE7D,MAAM,QAAiF,EACrF,GAAG,uBACL;CACA,KAAK,MAAM,OAAO,QAAQ,QAAQ,aAAa,CAAC,CAAC,GAAG;EAClD,IAAI,OAAO,QAAQ,YAAY,CAAC,OAAO,OAAO,wBAAwB,GAAG,GACvE,MAAM,IAAI,MAAM,mCAAmC,OAAO,GAAG,EAAE,EAAE;EAEnE,MAAM,UAAU,YAAY;EAC5B,IAAI,YAAY,KAAA,KAAa,YAAY,QAAQ,OAAO,YAAY,YAClE,MAAM,IAAI,MAAM,oBAAoB,IAAI,yCAAyC;EAEnF,IAAI,YAAY,KAAA,GAAW,MAAM,OAAO;CAC1C;CACA,OAAO,OAAO,OAAO,KAAK;AAC5B"}
@@ -1,17 +1,63 @@
1
+ import type { RequestContext } from '@mastra/core/request-context';
2
+ import type { ApiRoute } from '@mastra/core/server';
1
3
  import type { MastraWorker } from '@mastra/core/worker';
2
- import type { FactoryIntegration, IntegrationContext } from '../base.js';
4
+ import type { RouteAuth } from '../../routes/route.js';
5
+ import type { IntakeStorage } from '../../storage/domains/intake/base.js';
6
+ import type { FactoryProjectsStorage } from '../../storage/domains/projects/base.js';
7
+ import type { FactoryIntegration, IntegrationContext, IntegrationTools } from '../base.js';
8
+ import type { IncidentioEventRules, IncidentioRuleOverrides } from './default-rules.js';
3
9
  export interface IncidentioIntegrationConfig {
4
10
  apiKey?: string;
5
11
  fetchImpl?: typeof fetch;
6
12
  baseUrl?: string;
13
+ /** Per-event replacements for the default Factory incident.io rules. */
14
+ rules?: IncidentioRuleOverrides;
7
15
  }
8
16
  export declare class IncidentioIntegration implements FactoryIntegration {
9
17
  #private;
10
18
  readonly id = "incidentio";
11
19
  readonly intake: import("../../capabilities/intake.js").Intake;
12
20
  constructor(config?: IncidentioIntegrationConfig);
21
+ /** Event rules driving automatic follow-up materialization and close handling. */
22
+ get rules(): IncidentioEventRules;
23
+ /**
24
+ * Bind the projects domain and the host auth seam. incident.io has no
25
+ * per-org connection rows here — credentials are deployment-global
26
+ * constructor config.
27
+ */
28
+ initialize({ projects, auth, intake, }: {
29
+ projects: FactoryProjectsStorage;
30
+ auth: RouteAuth;
31
+ intake: IntakeStorage;
32
+ }): void;
33
+ /** Cross-integration intake selection/binding domain — agent-tool authorization. */
34
+ get intakeStorage(): IntakeStorage;
35
+ /** Factory projects domain — maps a session's resourceId to its owning org. */
36
+ get projects(): FactoryProjectsStorage;
37
+ /** Whether the host runs with web auth enabled; every surface is inert without it. */
38
+ get authEnabled(): boolean;
39
+ /**
40
+ * Map a session's resourceId (the factory project id) to its owning org.
41
+ * Same caching semantics as the Jira integration: definitive misses are
42
+ * cached, transient database failures are not.
43
+ */
44
+ resolveOrgId(resourceId: string): Promise<string | null>;
45
+ /** Test hook: clear the org cache between specs. */
46
+ clearCaches(): void;
47
+ /**
48
+ * Org-scoped agent tools: the read-only follow-up detail tool for sessions
49
+ * whose resource is a factory project, matching the Linear/Jira surface.
50
+ */
51
+ agentTools(args: {
52
+ requestContext: RequestContext;
53
+ }): Promise<IntegrationTools>;
13
54
  workers(ctx: IntegrationContext): MastraWorker[];
14
- routes(): [];
55
+ /**
56
+ * The integration's HTTP surface: `/web/incidentio/*` Mastra `apiRoutes`
57
+ * (status + follow-up listing/detail for Intake). Handlers operate on this
58
+ * instance; a board-scoped listing also feeds the incident.io event rules.
59
+ */
60
+ routes(ctx: IntegrationContext): ApiRoute[];
15
61
  diagnostics(): Record<string, unknown>;
16
62
  }
17
63
  //# sourceMappingURL=integration.d.ts.map
@@ -1 +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"}
1
+ {"version":3,"file":"integration.d.ts","sourceRoot":"","sources":["../../../src/integrations/incidentio/integration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AAC1E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AACrF,OAAO,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAK3F,OAAO,KAAK,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAOxF,MAAM,WAAW,2BAA2B;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,KAAK,CAAC,EAAE,uBAAuB,CAAC;CACjC;AAKD,qBAAa,qBAAsB,YAAW,kBAAkB;;IAC9D,QAAQ,CAAC,EAAE,gBAAgB;IAC3B,QAAQ,CAAC,MAAM,gDAAC;gBAUJ,MAAM,GAAE,2BAAgC;IAmBpD,kFAAkF;IAClF,IAAI,KAAK,IAAI,oBAAoB,CAEhC;IAED;;;;OAIG;IACH,UAAU,CAAC,EACT,QAAQ,EACR,IAAI,EACJ,MAAM,GACP,EAAE;QACD,QAAQ,EAAE,sBAAsB,CAAC;QACjC,IAAI,EAAE,SAAS,CAAC;QAChB,MAAM,EAAE,aAAa,CAAC;KACvB,GAAG,IAAI;IAMR,oFAAoF;IACpF,IAAI,aAAa,IAAI,aAAa,CAKjC;IAED,+EAA+E;IAC/E,IAAI,QAAQ,IAAI,sBAAsB,CAKrC;IAED,sFAAsF;IACtF,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED;;;;OAIG;IACG,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAqB9D,oDAAoD;IACpD,WAAW,IAAI,IAAI;IAInB;;;OAGG;IACG,UAAU,CAAC,IAAI,EAAE;QAAE,cAAc,EAAE,cAAc,CAAA;KAAE,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAIrF,OAAO,CAAC,GAAG,EAAE,kBAAkB,GAAG,YAAY,EAAE;IAchD;;;;OAIG;IACH,MAAM,CAAC,GAAG,EAAE,kBAAkB,GAAG,QAAQ,EAAE;IAS3C,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAGvC"}
@@ -1,15 +1,27 @@
1
1
  import { IncidentioApiClient } from "./api.js";
2
+ import { buildIncidentioRoutes } from "./routes.js";
3
+ import { buildIncidentioAgentTools } from "./agent-tools.js";
4
+ import { resolveIncidentioRules } from "./default-rules.js";
2
5
  import { createIncidentioIntake } from "./intake.js";
6
+ import { attachIncidentioRules } from "./rules.js";
3
7
  import { attachIncidentioIssueReconciler } from "./issue-reconciler.js";
4
8
  import { incidentioReconciliationEnabled, incidentioReconciliationInterval } from "./reconciliation-config.js";
5
9
  import { IssueReconcileWorker } from "../issue-reconcile-worker.js";
6
10
  //#region src/integrations/incidentio/integration.ts
7
11
  const DIRECT_CONNECTION_TOKEN = "incidentio-direct-api-key";
12
+ const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
8
13
  var IncidentioIntegration = class {
9
14
  id = "incidentio";
10
15
  intake;
11
16
  #endpointHost;
17
+ #rules;
18
+ /** Bound once by the factory via `initialize()` before any surface is used. */
19
+ #projects;
20
+ #auth;
21
+ #intakeStorage;
22
+ #orgIdByResourceId = /* @__PURE__ */ new Map();
12
23
  constructor(config = {}) {
24
+ this.#rules = resolveIncidentioRules(config.rules);
13
25
  const apiKey = config.apiKey?.trim() || process.env.INCIDENT_IO_API_KEY?.trim();
14
26
  if (!apiKey) throw new Error("IncidentioIntegration: missing required INCIDENT_IO_API_KEY.");
15
27
  const baseUrl = config.baseUrl ?? "https://api.incident.io";
@@ -27,6 +39,70 @@ var IncidentioIntegration = class {
27
39
  }
28
40
  });
29
41
  }
42
+ /** Event rules driving automatic follow-up materialization and close handling. */
43
+ get rules() {
44
+ return this.#rules;
45
+ }
46
+ /**
47
+ * Bind the projects domain and the host auth seam. incident.io has no
48
+ * per-org connection rows here — credentials are deployment-global
49
+ * constructor config.
50
+ */
51
+ initialize({ projects, auth, intake }) {
52
+ this.#projects = projects;
53
+ this.#auth = auth;
54
+ this.#intakeStorage = intake;
55
+ }
56
+ /** Cross-integration intake selection/binding domain — agent-tool authorization. */
57
+ get intakeStorage() {
58
+ if (!this.#intakeStorage) throw new Error("IncidentioIntegration is not initialized — the factory binds storage during prepare().");
59
+ return this.#intakeStorage;
60
+ }
61
+ /** Factory projects domain — maps a session's resourceId to its owning org. */
62
+ get projects() {
63
+ if (!this.#projects) throw new Error("IncidentioIntegration is not initialized — the factory binds storage during prepare().");
64
+ return this.#projects;
65
+ }
66
+ /** Whether the host runs with web auth enabled; every surface is inert without it. */
67
+ get authEnabled() {
68
+ return this.#auth?.enabled() ?? false;
69
+ }
70
+ /**
71
+ * Map a session's resourceId (the factory project id) to its owning org.
72
+ * Same caching semantics as the Jira integration: definitive misses are
73
+ * cached, transient database failures are not.
74
+ */
75
+ async resolveOrgId(resourceId) {
76
+ const cached = this.#orgIdByResourceId.get(resourceId);
77
+ if (cached !== void 0) return cached;
78
+ if (!UUID_PATTERN.test(resourceId)) {
79
+ this.#orgIdByResourceId.set(resourceId, null);
80
+ return null;
81
+ }
82
+ let orgId;
83
+ try {
84
+ await this.projects.ensureReady();
85
+ orgId = (await this.projects.getById({ id: resourceId }))?.orgId ?? null;
86
+ } catch {
87
+ return null;
88
+ }
89
+ this.#orgIdByResourceId.set(resourceId, orgId);
90
+ return orgId;
91
+ }
92
+ /** Test hook: clear the org cache between specs. */
93
+ clearCaches() {
94
+ this.#orgIdByResourceId.clear();
95
+ }
96
+ /**
97
+ * Org-scoped agent tools: the read-only follow-up detail tool for sessions
98
+ * whose resource is a factory project, matching the Linear/Jira surface.
99
+ */
100
+ async agentTools(args) {
101
+ return buildIncidentioAgentTools({
102
+ requestContext: args.requestContext,
103
+ incidentio: this
104
+ });
105
+ }
30
106
  workers(ctx) {
31
107
  if (!incidentioReconciliationEnabled()) return [];
32
108
  const reconcile = attachIncidentioIssueReconciler(this, ctx);
@@ -38,8 +114,18 @@ var IncidentioIntegration = class {
38
114
  ...intervalMs ? { intervalMs } : {}
39
115
  })];
40
116
  }
41
- routes() {
42
- return [];
117
+ /**
118
+ * The integration's HTTP surface: `/web/incidentio/*` Mastra `apiRoutes`
119
+ * (status + follow-up listing/detail for Intake). Handlers operate on this
120
+ * instance; a board-scoped listing also feeds the incident.io event rules.
121
+ */
122
+ routes(ctx) {
123
+ return buildIncidentioRoutes({
124
+ incidentio: this,
125
+ auth: ctx.auth,
126
+ intake: ctx.storage.intake,
127
+ ingestFactoryIssues: attachIncidentioRules(this, ctx)
128
+ });
43
129
  }
44
130
  diagnostics() {
45
131
  return {
@@ -1 +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"}
1
+ {"version":3,"file":"integration.js","names":["#endpointHost","#rules","#orgIdByResourceId","#projects","#auth","#intakeStorage"],"sources":["../../../src/integrations/incidentio/integration.ts"],"sourcesContent":["import type { RequestContext } from '@mastra/core/request-context';\nimport type { ApiRoute } from '@mastra/core/server';\nimport type { MastraWorker } from '@mastra/core/worker';\n\nimport type { RouteAuth } from '../../routes/route.js';\nimport type { IntakeStorage } from '../../storage/domains/intake/base.js';\nimport type { FactoryProjectsStorage } from '../../storage/domains/projects/base.js';\nimport type { FactoryIntegration, IntegrationContext, IntegrationTools } from '../base.js';\nimport { IssueReconcileWorker } from '../issue-reconcile-worker.js';\nimport { buildIncidentioAgentTools } from './agent-tools.js';\nimport { IncidentioApiClient } from './api.js';\nimport { resolveIncidentioRules } from './default-rules.js';\nimport type { IncidentioEventRules, IncidentioRuleOverrides } from './default-rules.js';\nimport { createIncidentioIntake } from './intake.js';\nimport { attachIncidentioIssueReconciler } from './issue-reconciler.js';\nimport { incidentioReconciliationEnabled, incidentioReconciliationInterval } from './reconciliation-config.js';\nimport { buildIncidentioRoutes } from './routes.js';\nimport { attachIncidentioRules } from './rules.js';\n\nexport interface IncidentioIntegrationConfig {\n apiKey?: string;\n fetchImpl?: typeof fetch;\n baseUrl?: string;\n /** Per-event replacements for the default Factory incident.io rules. */\n rules?: IncidentioRuleOverrides;\n}\n\nconst DIRECT_CONNECTION_TOKEN = 'incidentio-direct-api-key';\nconst UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\nexport class IncidentioIntegration implements FactoryIntegration {\n readonly id = 'incidentio';\n readonly intake;\n readonly #endpointHost: string;\n readonly #rules: IncidentioEventRules;\n\n /** Bound once by the factory via `initialize()` before any surface is used. */\n #projects: FactoryProjectsStorage | undefined;\n #auth: RouteAuth | undefined;\n #intakeStorage: IntakeStorage | undefined;\n readonly #orgIdByResourceId = new Map<string, string | null>();\n\n constructor(config: IncidentioIntegrationConfig = {}) {\n this.#rules = resolveIncidentioRules(config.rules);\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 /** Event rules driving automatic follow-up materialization and close handling. */\n get rules(): IncidentioEventRules {\n return this.#rules;\n }\n\n /**\n * Bind the projects domain and the host auth seam. incident.io has no\n * per-org connection rows here — credentials are deployment-global\n * constructor config.\n */\n initialize({\n projects,\n auth,\n intake,\n }: {\n projects: FactoryProjectsStorage;\n auth: RouteAuth;\n intake: IntakeStorage;\n }): void {\n this.#projects = projects;\n this.#auth = auth;\n this.#intakeStorage = intake;\n }\n\n /** Cross-integration intake selection/binding domain — agent-tool authorization. */\n get intakeStorage(): IntakeStorage {\n if (!this.#intakeStorage) {\n throw new Error('IncidentioIntegration is not initialized — the factory binds storage during prepare().');\n }\n return this.#intakeStorage;\n }\n\n /** Factory projects domain — maps a session's resourceId to its owning org. */\n get projects(): FactoryProjectsStorage {\n if (!this.#projects) {\n throw new Error('IncidentioIntegration is not initialized — the factory binds storage during prepare().');\n }\n return this.#projects;\n }\n\n /** Whether the host runs with web auth enabled; every surface is inert without it. */\n get authEnabled(): boolean {\n return this.#auth?.enabled() ?? false;\n }\n\n /**\n * Map a session's resourceId (the factory project id) to its owning org.\n * Same caching semantics as the Jira integration: definitive misses are\n * cached, transient database failures are not.\n */\n async resolveOrgId(resourceId: string): Promise<string | null> {\n const cached = this.#orgIdByResourceId.get(resourceId);\n if (cached !== undefined) return cached;\n if (!UUID_PATTERN.test(resourceId)) {\n this.#orgIdByResourceId.set(resourceId, null);\n return null;\n }\n let orgId: string | null;\n try {\n await this.projects.ensureReady();\n const project = await this.projects.getById({ id: resourceId });\n orgId = project?.orgId ?? null;\n } catch {\n // Transient database failure: skip the tools for this request but don't\n // cache the miss, so the next request retries the lookup.\n return null;\n }\n this.#orgIdByResourceId.set(resourceId, orgId);\n return orgId;\n }\n\n /** Test hook: clear the org cache between specs. */\n clearCaches(): void {\n this.#orgIdByResourceId.clear();\n }\n\n /**\n * Org-scoped agent tools: the read-only follow-up detail tool for sessions\n * whose resource is a factory project, matching the Linear/Jira surface.\n */\n async agentTools(args: { requestContext: RequestContext }): Promise<IntegrationTools> {\n return buildIncidentioAgentTools({ requestContext: args.requestContext, incidentio: this });\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 /**\n * The integration's HTTP surface: `/web/incidentio/*` Mastra `apiRoutes`\n * (status + follow-up listing/detail for Intake). Handlers operate on this\n * instance; a board-scoped listing also feeds the incident.io event rules.\n */\n routes(ctx: IntegrationContext): ApiRoute[] {\n return buildIncidentioRoutes({\n incidentio: this,\n auth: ctx.auth,\n intake: ctx.storage.intake,\n ingestFactoryIssues: attachIncidentioRules(this, ctx),\n });\n }\n\n diagnostics(): Record<string, unknown> {\n return { mode: 'api-key', endpointHost: this.#endpointHost };\n }\n}\n"],"mappings":";;;;;;;;;;AA2BA,MAAM,0BAA0B;AAChC,MAAM,eAAe;AAErB,IAAa,wBAAb,MAAiE;CAC/D,KAAc;CACd;CACA;CACA;;CAGA;CACA;CACA;CACA,qCAA8B,IAAI,IAA2B;CAE7D,YAAY,SAAsC,CAAC,GAAG;EACpD,KAAKC,SAAS,uBAAuB,OAAO,KAAK;EACjD,MAAM,SAAS,OAAO,QAAQ,KAAK,KAAK,QAAQ,IAAI,qBAAqB,KAAK;EAC9E,IAAI,CAAC,QACH,MAAM,IAAI,MAAM,8DAA8D;EAEhF,MAAM,UAAU,OAAO,WAAW;EAClC,KAAKD,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;;CAGA,IAAI,QAA8B;EAChC,OAAO,KAAKC;CACd;;;;;;CAOA,WAAW,EACT,UACA,MACA,UAKO;EACP,KAAKE,YAAY;EACjB,KAAKC,QAAQ;EACb,KAAKC,iBAAiB;CACxB;;CAGA,IAAI,gBAA+B;EACjC,IAAI,CAAC,KAAKA,gBACR,MAAM,IAAI,MAAM,wFAAwF;EAE1G,OAAO,KAAKA;CACd;;CAGA,IAAI,WAAmC;EACrC,IAAI,CAAC,KAAKF,WACR,MAAM,IAAI,MAAM,wFAAwF;EAE1G,OAAO,KAAKA;CACd;;CAGA,IAAI,cAAuB;EACzB,OAAO,KAAKC,OAAO,QAAQ,KAAK;CAClC;;;;;;CAOA,MAAM,aAAa,YAA4C;EAC7D,MAAM,SAAS,KAAKF,mBAAmB,IAAI,UAAU;EACrD,IAAI,WAAW,KAAA,GAAW,OAAO;EACjC,IAAI,CAAC,aAAa,KAAK,UAAU,GAAG;GAClC,KAAKA,mBAAmB,IAAI,YAAY,IAAI;GAC5C,OAAO;EACT;EACA,IAAI;EACJ,IAAI;GACF,MAAM,KAAK,SAAS,YAAY;GAEhC,SAAQ,MADc,KAAK,SAAS,QAAQ,EAAE,IAAI,WAAW,CAAC,EAAA,EAC7C,SAAS;EAC5B,QAAQ;GAGN,OAAO;EACT;EACA,KAAKA,mBAAmB,IAAI,YAAY,KAAK;EAC7C,OAAO;CACT;;CAGA,cAAoB;EAClB,KAAKA,mBAAmB,MAAM;CAChC;;;;;CAMA,MAAM,WAAW,MAAqE;EACpF,OAAO,0BAA0B;GAAE,gBAAgB,KAAK;GAAgB,YAAY;EAAK,CAAC;CAC5F;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;;;;;;CAOA,OAAO,KAAqC;EAC1C,OAAO,sBAAsB;GAC3B,YAAY;GACZ,MAAM,IAAI;GACV,QAAQ,IAAI,QAAQ;GACpB,qBAAqB,sBAAsB,MAAM,GAAG;EACtD,CAAC;CACH;CAEA,cAAuC;EACrC,OAAO;GAAE,MAAM;GAAW,cAAc,KAAKF;EAAc;CAC7D;AACF"}
@@ -1,8 +1,10 @@
1
1
  import type { Intake } from '../../capabilities/intake.js';
2
2
  import type { IntegrationContext } from '../base.js';
3
3
  import type { IssueReconciler } from '../issue-reconciler.js';
4
+ import type { IncidentioEventRules } from './default-rules.js';
4
5
  export type IncidentioIssueReconciler = IssueReconciler;
5
6
  export declare function attachIncidentioIssueReconciler(incidentio: {
6
7
  intake: Intake;
8
+ rules: IncidentioEventRules;
7
9
  }, context: IntegrationContext): IncidentioIssueReconciler | undefined;
8
10
  //# sourceMappingURL=issue-reconciler.d.ts.map
@@ -1 +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"}
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;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAI/D,MAAM,MAAM,yBAAyB,GAAG,eAAe,CAAC;AAoBxD,wBAAgB,+BAA+B,CAC7C,UAAU,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,oBAAoB,CAAA;CAAE,EAC3D,OAAO,EAAE,kBAAkB,GAC1B,yBAAyB,GAAG,SAAS,CAkDvC"}
@@ -1,10 +1,35 @@
1
1
  import { workItemPhaseSemantics } from "../../boards/semantics.js";
2
2
  import "../../boards/index.js";
3
3
  import { createIssueReconciler } from "../issue-reconciler.js";
4
+ import { IncidentioRules } from "./rules.js";
4
5
  //#region src/integrations/incidentio/issue-reconciler.ts
6
+ function issueToIngress(itemRef, issue) {
7
+ return {
8
+ id: itemRef,
9
+ identifier: issue.identifier,
10
+ title: issue.title,
11
+ url: issue.url,
12
+ state: issue.state ?? "",
13
+ stateType: issue.stateType ?? "",
14
+ priorityLabel: issue.priority ?? "",
15
+ assignee: issue.assignee ?? null,
16
+ author: issue.author ?? null,
17
+ incident: null,
18
+ labels: [...issue.labels ?? []],
19
+ createdAt: issue.createdAt,
20
+ updatedAt: issue.updatedAt
21
+ };
22
+ }
5
23
  function attachIncidentioIssueReconciler(incidentio, context) {
6
24
  if (!context.runtime || !incidentio.intake.resolveIntakeDispatch) return void 0;
7
25
  const boards = context.runtime.boards;
26
+ const rules = new IncidentioRules({
27
+ projects: context.storage.projects,
28
+ storage: context.runtime.workItems,
29
+ configVersion: context.runtime.configVersion,
30
+ boards,
31
+ incidentioRules: incidentio.rules
32
+ });
8
33
  return createIssueReconciler({
9
34
  integrationId: "incidentio",
10
35
  intake: incidentio.intake,
@@ -12,8 +37,9 @@ function attachIncidentioIssueReconciler(incidentio, context) {
12
37
  storage: context.runtime.workItems,
13
38
  isTerminal: (item) => workItemPhaseSemantics(boards, item)?.kind === "terminal",
14
39
  issueId: (item) => item.externalSource?.externalId,
15
- metadata: (_item, issue) => ({
40
+ metadata: (item, issue) => ({
16
41
  identifier: issue.identifier,
42
+ issueRef: item.externalSource?.externalId ?? issue.id,
17
43
  autoStartCandidate: issue.stateType === "unstarted" || issue.stateType === "started",
18
44
  incidentioItemType: issue.source === "Follow-up" ? "follow-up" : "incident",
19
45
  incidentioState: issue.state,
@@ -21,6 +47,7 @@ function attachIncidentioIssueReconciler(incidentio, context) {
21
47
  incidentioPriority: issue.priority,
22
48
  incidentioAssignee: issue.assignee,
23
49
  incidentioDescription: "description" in issue && typeof issue.description === "string" ? issue.description : null,
50
+ state: issue.state,
24
51
  stateType: issue.stateType,
25
52
  priority: issue.priority,
26
53
  source: issue.source,
@@ -29,8 +56,17 @@ function attachIncidentioIssueReconciler(incidentio, context) {
29
56
  creator: issue.author,
30
57
  author: issue.author,
31
58
  labels: issue.labels ?? [],
59
+ createdAt: issue.createdAt,
32
60
  updatedAt: issue.updatedAt
33
- })
61
+ }),
62
+ onClosed: async (item, issue, project) => {
63
+ await rules.ingest({
64
+ orgId: project.orgId,
65
+ userId: "factory-rule-dispatcher",
66
+ factoryProjectId: project.id,
67
+ issues: [issueToIngress(item.externalSource?.externalId ?? issue.id, issue)]
68
+ });
69
+ }
34
70
  });
35
71
  }
36
72
  //#endregion
@@ -1 +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"}
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, IntakeIssue } from '../../capabilities/intake.js';\nimport type { IntegrationContext } from '../base.js';\nimport { createIssueReconciler } from '../issue-reconciler.js';\nimport type { IssueReconciler } from '../issue-reconciler.js';\nimport type { IncidentioEventRules } from './default-rules.js';\nimport { IncidentioRules } from './rules.js';\nimport type { IncidentioIssueIngress } from './rules.js';\n\nexport type IncidentioIssueReconciler = IssueReconciler;\n\nfunction issueToIngress(itemRef: string, issue: IntakeIssue): IncidentioIssueIngress {\n return {\n id: itemRef,\n identifier: issue.identifier,\n title: issue.title,\n url: issue.url,\n state: issue.state ?? '',\n stateType: issue.stateType ?? '',\n priorityLabel: issue.priority ?? '',\n assignee: issue.assignee ?? null,\n author: issue.author ?? null,\n incident: null,\n labels: [...(issue.labels ?? [])],\n createdAt: issue.createdAt,\n updatedAt: issue.updatedAt,\n };\n}\n\nexport function attachIncidentioIssueReconciler(\n incidentio: { intake: Intake; rules: IncidentioEventRules },\n context: IntegrationContext,\n): IncidentioIssueReconciler | undefined {\n if (!context.runtime || !incidentio.intake.resolveIntakeDispatch) return undefined;\n const boards = context.runtime.boards;\n\n const rules = new IncidentioRules({\n projects: context.storage.projects,\n storage: context.runtime.workItems,\n configVersion: context.runtime.configVersion,\n boards,\n incidentioRules: incidentio.rules,\n });\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 issueRef: item.externalSource?.externalId ?? issue.id,\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 state: issue.state,\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 createdAt: issue.createdAt,\n updatedAt: issue.updatedAt,\n }),\n onClosed: async (item, issue, project) => {\n await rules.ingest({\n orgId: project.orgId,\n userId: 'factory-rule-dispatcher',\n factoryProjectId: project.id,\n issues: [issueToIngress(item.externalSource?.externalId ?? issue.id, issue)],\n });\n },\n });\n}\n"],"mappings":";;;;;AAWA,SAAS,eAAe,SAAiB,OAA4C;CACnF,OAAO;EACL,IAAI;EACJ,YAAY,MAAM;EAClB,OAAO,MAAM;EACb,KAAK,MAAM;EACX,OAAO,MAAM,SAAS;EACtB,WAAW,MAAM,aAAa;EAC9B,eAAe,MAAM,YAAY;EACjC,UAAU,MAAM,YAAY;EAC5B,QAAQ,MAAM,UAAU;EACxB,UAAU;EACV,QAAQ,CAAC,GAAI,MAAM,UAAU,CAAC,CAAE;EAChC,WAAW,MAAM;EACjB,WAAW,MAAM;CACnB;AACF;AAEA,SAAgB,gCACd,YACA,SACuC;CACvC,IAAI,CAAC,QAAQ,WAAW,CAAC,WAAW,OAAO,uBAAuB,OAAO,KAAA;CACzE,MAAM,SAAS,QAAQ,QAAQ;CAE/B,MAAM,QAAQ,IAAI,gBAAgB;EAChC,UAAU,QAAQ,QAAQ;EAC1B,SAAS,QAAQ,QAAQ;EACzB,eAAe,QAAQ,QAAQ;EAC/B;EACA,iBAAiB,WAAW;CAC9B,CAAC;CAED,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,MAAM,WAAW;GAC1B,YAAY,MAAM;GAClB,UAAU,KAAK,gBAAgB,cAAc,MAAM;GACnD,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,OAAO,MAAM;GACb,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;GACjB,WAAW,MAAM;EACnB;EACA,UAAU,OAAO,MAAM,OAAO,YAAY;GACxC,MAAM,MAAM,OAAO;IACjB,OAAO,QAAQ;IACf,QAAQ;IACR,kBAAkB,QAAQ;IAC1B,QAAQ,CAAC,eAAe,KAAK,gBAAgB,cAAc,MAAM,IAAI,KAAK,CAAC;GAC7E,CAAC;EACH;CACF,CAAC;AACH"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Mastra `apiRoutes` for the incident.io intake feature.
3
+ *
4
+ * Registered alongside the other `/web/*` routes, behind the host auth gate.
5
+ * Mirrors the Jira module: no connect/callback flow here — credentials are
6
+ * either deployment-global constructor config (direct) or Platform-managed
7
+ * connections discovered at runtime. Every route re-resolves the
8
+ * authenticated user from the request and scopes intake selections by the
9
+ * caller's org.
10
+ *
11
+ * When the feature is disabled (no auth, or no intake storage),
12
+ * `buildIncidentioRoutes` returns only `GET /web/incidentio/status`, which
13
+ * reports `enabled:false` so the SPA can cleanly hide all incident.io UI.
14
+ */
15
+ import type { ApiRoute } from '@mastra/core/server';
16
+ import type { Intake } from '../../capabilities/intake.js';
17
+ import type { RouteAuth } from '../../routes/route.js';
18
+ import type { IntakeStorage } from '../../storage/domains/intake/base.js';
19
+ import type { IncidentioRulesIngress } from './rules.js';
20
+ /**
21
+ * Non-secret diagnostic snapshot of every incident.io feature gate, mirroring
22
+ * the Jira diagnostics shape. Only booleans — never values.
23
+ */
24
+ export interface IncidentioFeatureDiagnostics {
25
+ incidentioConfigured: boolean;
26
+ factoryAuthEnabled: boolean;
27
+ }
28
+ export interface MountIncidentioRoutesOptions {
29
+ /**
30
+ * The integration's intake capability providing incident.io access. Required
31
+ * for everything beyond the disabled `status` route.
32
+ */
33
+ incidentio?: {
34
+ intake: Intake;
35
+ id: string;
36
+ };
37
+ /** Host auth seam. Intake selections are org-owned, so the feature is inert without it. */
38
+ auth: RouteAuth;
39
+ /**
40
+ * Cross-integration intake selection domain. Required for the issues route's
41
+ * project filter; when absent, only the disabled `status` route is served.
42
+ */
43
+ intake?: IntakeStorage;
44
+ /**
45
+ * Factory rules ingress for observed follow-ups. When present, a
46
+ * board-scoped listing also materializes new cards through the incident.io
47
+ * event rules — the same automatic intake Linear and Jira have.
48
+ */
49
+ ingestFactoryIssues?: (input: IncidentioRulesIngress) => Promise<unknown>;
50
+ }
51
+ /**
52
+ * Narrow the caller's selected incident.io sources to the ones that feed this
53
+ * Factory project. Routing is explicit: a source feeds this Factory only when
54
+ * its binding names both the Factory project and a board. Mirrors the Jira
55
+ * routes' scoping semantics — the generic binding storage is provider-neutral.
56
+ * Shared with the agent tools, which enforce the same source-level
57
+ * authorization before fetching item details.
58
+ */
59
+ export declare function scopeSourceIdsToProject({ intake, orgId, factoryProjectId, selectedIds, }: {
60
+ intake: IntakeStorage;
61
+ orgId: string;
62
+ factoryProjectId: string;
63
+ selectedIds: string[];
64
+ }): Promise<Record<string, string>>;
65
+ /**
66
+ * Build the incident.io routes as Mastra `apiRoutes`. When the feature is
67
+ * disabled, returns only the `status` route so the SPA can detect the
68
+ * disabled state.
69
+ */
70
+ export declare function buildIncidentioRoutes(options: MountIncidentioRoutesOptions): ApiRoute[];
71
+ //# sourceMappingURL=routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../../src/integrations/incidentio/routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAIpD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,8BAA8B,CAAC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AAE1E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAazD;;;GAGG;AACH,MAAM,WAAW,4BAA4B;IAC3C,oBAAoB,EAAE,OAAO,CAAC;IAC9B,kBAAkB,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,4BAA4B;IAC3C;;;OAGG;IACH,UAAU,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,2FAA2F;IAC3F,IAAI,EAAE,SAAS,CAAC;IAChB;;;OAGG;IACH,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,CAAC,KAAK,EAAE,sBAAsB,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAC3E;AAED;;;;;;;GAOG;AACH,wBAAsB,uBAAuB,CAAC,EAC5C,MAAM,EACN,KAAK,EACL,gBAAgB,EAChB,WAAW,GACZ,EAAE;IACD,MAAM,EAAE,aAAa,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CASlC;AAqED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,4BAA4B,GAAG,QAAQ,EAAE,CA8MvF"}