@ai-sdlc/orchestrator 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (203) hide show
  1. package/dist/adapters.d.ts +60 -0
  2. package/dist/adapters.js +160 -0
  3. package/dist/admission.d.ts +49 -0
  4. package/dist/admission.js +90 -0
  5. package/dist/analysis/analyzer.d.ts +10 -0
  6. package/dist/analysis/analyzer.js +67 -0
  7. package/dist/analysis/complexity-scorer.d.ts +24 -0
  8. package/dist/analysis/complexity-scorer.js +39 -0
  9. package/dist/analysis/context-builder.d.ts +14 -0
  10. package/dist/analysis/context-builder.js +79 -0
  11. package/dist/analysis/convention-detector.d.ts +9 -0
  12. package/dist/analysis/convention-detector.js +177 -0
  13. package/dist/analysis/dependency-parser.d.ts +17 -0
  14. package/dist/analysis/dependency-parser.js +167 -0
  15. package/dist/analysis/file-walker.d.ts +18 -0
  16. package/dist/analysis/file-walker.js +158 -0
  17. package/dist/analysis/hotspot-analyzer.d.ts +28 -0
  18. package/dist/analysis/hotspot-analyzer.js +85 -0
  19. package/dist/analysis/index.d.ts +13 -0
  20. package/dist/analysis/index.js +12 -0
  21. package/dist/analysis/pattern-detector.d.ts +10 -0
  22. package/dist/analysis/pattern-detector.js +86 -0
  23. package/dist/analysis/types.d.ts +94 -0
  24. package/dist/analysis/types.js +5 -0
  25. package/dist/audit-archival.d.ts +48 -0
  26. package/dist/audit-archival.js +72 -0
  27. package/dist/audit-export.d.ts +45 -0
  28. package/dist/audit-export.js +100 -0
  29. package/dist/audit-extended.d.ts +28 -0
  30. package/dist/audit-extended.js +38 -0
  31. package/dist/audit-scheduler.d.ts +32 -0
  32. package/dist/audit-scheduler.js +52 -0
  33. package/dist/audit-sqlite-sink.d.ts +11 -0
  34. package/dist/audit-sqlite-sink.js +51 -0
  35. package/dist/autonomy-tracker.d.ts +76 -0
  36. package/dist/autonomy-tracker.js +277 -0
  37. package/dist/check-runs.d.ts +37 -0
  38. package/dist/check-runs.js +72 -0
  39. package/dist/cli/commands/agents.d.ts +6 -0
  40. package/dist/cli/commands/agents.js +33 -0
  41. package/dist/cli/commands/complexity.d.ts +6 -0
  42. package/dist/cli/commands/complexity.js +35 -0
  43. package/dist/cli/commands/cost.d.ts +6 -0
  44. package/dist/cli/commands/cost.js +53 -0
  45. package/dist/cli/commands/dashboard.d.ts +9 -0
  46. package/dist/cli/commands/dashboard.js +50 -0
  47. package/dist/cli/commands/health.d.ts +6 -0
  48. package/dist/cli/commands/health.js +33 -0
  49. package/dist/cli/commands/init.d.ts +6 -0
  50. package/dist/cli/commands/init.js +127 -0
  51. package/dist/cli/commands/routing.d.ts +6 -0
  52. package/dist/cli/commands/routing.js +46 -0
  53. package/dist/cli/commands/run.d.ts +6 -0
  54. package/dist/cli/commands/run.js +36 -0
  55. package/dist/cli/commands/start.d.ts +6 -0
  56. package/dist/cli/commands/start.js +26 -0
  57. package/dist/cli/commands/status.d.ts +6 -0
  58. package/dist/cli/commands/status.js +34 -0
  59. package/dist/cli/dashboard-renderer.d.ts +24 -0
  60. package/dist/cli/dashboard-renderer.js +129 -0
  61. package/dist/cli/formatters/index.d.ts +6 -0
  62. package/dist/cli/formatters/index.js +18 -0
  63. package/dist/cli/formatters/json.d.ts +5 -0
  64. package/dist/cli/formatters/json.js +7 -0
  65. package/dist/cli/formatters/minimal.d.ts +5 -0
  66. package/dist/cli/formatters/minimal.js +36 -0
  67. package/dist/cli/formatters/table.d.ts +5 -0
  68. package/dist/cli/formatters/table.js +184 -0
  69. package/dist/cli/index.d.ts +6 -0
  70. package/dist/cli/index.js +35 -0
  71. package/dist/compliance-extended.d.ts +41 -0
  72. package/dist/compliance-extended.js +58 -0
  73. package/dist/config.d.ts +26 -0
  74. package/dist/config.js +66 -0
  75. package/dist/context-enrichment.d.ts +33 -0
  76. package/dist/context-enrichment.js +125 -0
  77. package/dist/cost-governance.d.ts +22 -0
  78. package/dist/cost-governance.js +106 -0
  79. package/dist/cost-tracker.d.ts +75 -0
  80. package/dist/cost-tracker.js +177 -0
  81. package/dist/defaults.d.ts +140 -0
  82. package/dist/defaults.js +218 -0
  83. package/dist/deploy/flyio-target.d.ts +19 -0
  84. package/dist/deploy/flyio-target.js +114 -0
  85. package/dist/deploy/index.d.ts +15 -0
  86. package/dist/deploy/index.js +11 -0
  87. package/dist/deploy/kubernetes-target.d.ts +25 -0
  88. package/dist/deploy/kubernetes-target.js +124 -0
  89. package/dist/deploy/metrics-collector.d.ts +31 -0
  90. package/dist/deploy/metrics-collector.js +75 -0
  91. package/dist/deploy/rollout-controller.d.ts +42 -0
  92. package/dist/deploy/rollout-controller.js +192 -0
  93. package/dist/deploy/rollout-types.d.ts +86 -0
  94. package/dist/deploy/rollout-types.js +5 -0
  95. package/dist/deploy/types.d.ts +47 -0
  96. package/dist/deploy/types.js +5 -0
  97. package/dist/deploy/vercel-target.d.ts +16 -0
  98. package/dist/deploy/vercel-target.js +115 -0
  99. package/dist/discovery.d.ts +26 -0
  100. package/dist/discovery.js +46 -0
  101. package/dist/episodic-enhanced.d.ts +88 -0
  102. package/dist/episodic-enhanced.js +212 -0
  103. package/dist/execute.d.ts +81 -0
  104. package/dist/execute.js +703 -0
  105. package/dist/fix-ci.d.ts +61 -0
  106. package/dist/fix-ci.js +380 -0
  107. package/dist/handoff-executor.d.ts +61 -0
  108. package/dist/handoff-executor.js +119 -0
  109. package/dist/index.d.ts +70 -0
  110. package/dist/index.js +87 -0
  111. package/dist/instrumented.d.ts +27 -0
  112. package/dist/instrumented.js +34 -0
  113. package/dist/logger.d.ts +17 -0
  114. package/dist/logger.js +37 -0
  115. package/dist/multi-repo/impact-analyzer.d.ts +22 -0
  116. package/dist/multi-repo/impact-analyzer.js +95 -0
  117. package/dist/multi-repo/index.d.ts +5 -0
  118. package/dist/multi-repo/index.js +4 -0
  119. package/dist/multi-repo/monorepo-detector.d.ts +16 -0
  120. package/dist/multi-repo/monorepo-detector.js +246 -0
  121. package/dist/multi-repo/service-map-builder.d.ts +24 -0
  122. package/dist/multi-repo/service-map-builder.js +235 -0
  123. package/dist/multi-repo/types.d.ts +54 -0
  124. package/dist/multi-repo/types.js +5 -0
  125. package/dist/notifications/index.d.ts +4 -0
  126. package/dist/notifications/index.js +4 -0
  127. package/dist/notifications/notification-router.d.ts +62 -0
  128. package/dist/notifications/notification-router.js +206 -0
  129. package/dist/notifications/slack-messenger.d.ts +26 -0
  130. package/dist/notifications/slack-messenger.js +69 -0
  131. package/dist/notifications/teams-messenger.d.ts +21 -0
  132. package/dist/notifications/teams-messenger.js +85 -0
  133. package/dist/notifications.d.ts +13 -0
  134. package/dist/notifications.js +15 -0
  135. package/dist/orchestration.d.ts +20 -0
  136. package/dist/orchestration.js +53 -0
  137. package/dist/orchestrator.d.ts +160 -0
  138. package/dist/orchestrator.js +372 -0
  139. package/dist/otel-exporter.d.ts +37 -0
  140. package/dist/otel-exporter.js +128 -0
  141. package/dist/plugin.d.ts +45 -0
  142. package/dist/plugin.js +8 -0
  143. package/dist/policy-evaluators.d.ts +40 -0
  144. package/dist/policy-evaluators.js +57 -0
  145. package/dist/process-escalation.d.ts +38 -0
  146. package/dist/process-escalation.js +129 -0
  147. package/dist/progressive-gates.d.ts +54 -0
  148. package/dist/progressive-gates.js +135 -0
  149. package/dist/provenance.d.ts +29 -0
  150. package/dist/provenance.js +61 -0
  151. package/dist/reconcilers.d.ts +28 -0
  152. package/dist/reconcilers.js +37 -0
  153. package/dist/runners/claude-code.d.ts +17 -0
  154. package/dist/runners/claude-code.js +200 -0
  155. package/dist/runners/codex.d.ts +19 -0
  156. package/dist/runners/codex.js +153 -0
  157. package/dist/runners/copilot-stub.d.ts +9 -0
  158. package/dist/runners/copilot-stub.js +15 -0
  159. package/dist/runners/copilot.d.ts +15 -0
  160. package/dist/runners/copilot.js +119 -0
  161. package/dist/runners/cursor-stub.d.ts +9 -0
  162. package/dist/runners/cursor-stub.js +15 -0
  163. package/dist/runners/cursor.d.ts +20 -0
  164. package/dist/runners/cursor.js +140 -0
  165. package/dist/runners/devin-stub.d.ts +9 -0
  166. package/dist/runners/devin-stub.js +15 -0
  167. package/dist/runners/generic-llm.d.ts +51 -0
  168. package/dist/runners/generic-llm.js +125 -0
  169. package/dist/runners/index.d.ts +8 -0
  170. package/dist/runners/index.js +7 -0
  171. package/dist/runners/runner-registry.d.ts +50 -0
  172. package/dist/runners/runner-registry.js +156 -0
  173. package/dist/runners/types.d.ts +59 -0
  174. package/dist/runners/types.js +7 -0
  175. package/dist/security.d.ts +51 -0
  176. package/dist/security.js +70 -0
  177. package/dist/shared.d.ts +134 -0
  178. package/dist/shared.js +284 -0
  179. package/dist/state/index.d.ts +4 -0
  180. package/dist/state/index.js +3 -0
  181. package/dist/state/schema.d.ts +16 -0
  182. package/dist/state/schema.js +264 -0
  183. package/dist/state/store.d.ts +109 -0
  184. package/dist/state/store.js +644 -0
  185. package/dist/state/types.d.ts +190 -0
  186. package/dist/state/types.js +5 -0
  187. package/dist/structured-logger.d.ts +20 -0
  188. package/dist/structured-logger.js +64 -0
  189. package/dist/task-decomposer.d.ts +61 -0
  190. package/dist/task-decomposer.js +265 -0
  191. package/dist/telemetry-extended.d.ts +24 -0
  192. package/dist/telemetry-extended.js +31 -0
  193. package/dist/types.d.ts +9 -0
  194. package/dist/types.js +7 -0
  195. package/dist/validate-agent-output.d.ts +30 -0
  196. package/dist/validate-agent-output.js +81 -0
  197. package/dist/validate-issue.d.ts +25 -0
  198. package/dist/validate-issue.js +102 -0
  199. package/dist/watch.d.ts +43 -0
  200. package/dist/watch.js +99 -0
  201. package/dist/webhook-manager.d.ts +38 -0
  202. package/dist/webhook-manager.js +66 -0
  203. package/package.json +59 -0
@@ -0,0 +1,206 @@
1
+ /**
2
+ * Notification router — dispatches pipeline events to configured messengers.
3
+ *
4
+ * Routes events like pipeline-start, gate-failure, agent-complete, pr-created
5
+ * to one or more Messenger implementations with filtering and template rendering.
6
+ */
7
+ // ── Default Templates ────────────────────────────────────────────────
8
+ const DEFAULT_TEMPLATES = {
9
+ 'pipeline-start': {
10
+ title: 'Pipeline Started',
11
+ body: 'Pipeline run {runId} started for issue #{issueNumber}',
12
+ },
13
+ 'pipeline-complete': {
14
+ title: 'Pipeline Completed',
15
+ body: 'Pipeline run {runId} completed successfully. PR: {prUrl}',
16
+ },
17
+ 'pipeline-failed': {
18
+ title: 'Pipeline Failed',
19
+ body: 'Pipeline run {runId} failed: {error}',
20
+ },
21
+ 'gate-pass': {
22
+ title: 'Gate Passed',
23
+ body: 'Quality gate "{gateName}" passed for issue #{issueNumber}',
24
+ },
25
+ 'gate-failure': {
26
+ title: 'Gate Failed',
27
+ body: 'Quality gate "{gateName}" failed: {details}',
28
+ },
29
+ 'agent-start': {
30
+ title: 'Agent Started',
31
+ body: 'Agent {agentName} started working on issue #{issueNumber}',
32
+ },
33
+ 'agent-complete': {
34
+ title: 'Agent Completed',
35
+ body: 'Agent {agentName} completed. Files changed: {filesChanged}',
36
+ },
37
+ 'agent-failed': {
38
+ title: 'Agent Failed',
39
+ body: 'Agent {agentName} failed: {error}',
40
+ },
41
+ 'pr-created': {
42
+ title: 'PR Created',
43
+ body: 'Pull request created: {prUrl}',
44
+ },
45
+ 'approval-required': {
46
+ title: 'Approval Required',
47
+ body: 'Issue #{issueNumber} requires approval (tier: {tier})',
48
+ },
49
+ promotion: {
50
+ title: 'Agent Promoted',
51
+ body: 'Agent {agentName} promoted from level {fromLevel} to {toLevel}',
52
+ },
53
+ demotion: {
54
+ title: 'Agent Demoted',
55
+ body: 'Agent {agentName} demoted from level {fromLevel} to {toLevel}: {reason}',
56
+ },
57
+ 'cost-alert': {
58
+ title: 'Cost Alert',
59
+ body: 'Budget utilization at {utilization}% ({spent}/{budget} USD)',
60
+ },
61
+ 'deploy-start': {
62
+ title: 'Deployment Started',
63
+ body: 'Deploying {version} to {environment} via {target}',
64
+ },
65
+ 'deploy-complete': {
66
+ title: 'Deployment Complete',
67
+ body: 'Version {version} deployed to {environment}. URL: {url}',
68
+ },
69
+ 'deploy-failed': {
70
+ title: 'Deployment Failed',
71
+ body: 'Deployment of {version} to {environment} failed: {error}',
72
+ },
73
+ 'rollout-progressing': {
74
+ title: 'Rollout Progressing',
75
+ body: 'Rollout at {weightPercent}% (step {step}). Error rate: {errorRate}%, P95: {latencyP95}ms',
76
+ },
77
+ 'rollout-complete': {
78
+ title: 'Rollout Complete',
79
+ body: 'Rollout of {version} to {environment} completed at 100%',
80
+ },
81
+ 'rollout-rollback': {
82
+ title: 'Rollout Rolled Back',
83
+ body: 'Rollout of {version} to {environment} rolled back: {reason}',
84
+ },
85
+ };
86
+ // ── Router ───────────────────────────────────────────────────────────
87
+ export class NotificationRouter {
88
+ routes = [];
89
+ templates = new Map();
90
+ activeThreads = new Map(); // route+issue -> threadId
91
+ constructor(customTemplates) {
92
+ // Initialize with default templates
93
+ for (const [key, value] of Object.entries(DEFAULT_TEMPLATES)) {
94
+ this.templates.set(key, value);
95
+ }
96
+ // Override with custom templates
97
+ if (customTemplates) {
98
+ for (const [key, value] of Object.entries(customTemplates)) {
99
+ if (value)
100
+ this.templates.set(key, value);
101
+ }
102
+ }
103
+ }
104
+ /**
105
+ * Add a notification route.
106
+ */
107
+ addRoute(route) {
108
+ this.routes.push(route);
109
+ }
110
+ /**
111
+ * Remove a route by name.
112
+ */
113
+ removeRoute(name) {
114
+ this.routes = this.routes.filter((r) => r.name !== name);
115
+ }
116
+ /**
117
+ * Dispatch a pipeline event to all matching routes.
118
+ */
119
+ async dispatch(event) {
120
+ const matchingRoutes = this.routes.filter((route) => this.matchesRoute(route, event));
121
+ const promises = matchingRoutes.map((route) => this.sendToRoute(route, event).catch((err) => {
122
+ // Non-blocking: log but don't fail the pipeline
123
+ console.error(`Notification route "${route.name}" failed:`, err);
124
+ }));
125
+ await Promise.all(promises);
126
+ }
127
+ /**
128
+ * Get the count of configured routes.
129
+ */
130
+ get routeCount() {
131
+ return this.routes.length;
132
+ }
133
+ // ── Internal ─────────────────────────────────────────────────────
134
+ matchesRoute(route, event) {
135
+ // Check event type filter
136
+ if (route.events && route.events.length > 0 && !route.events.includes(event.type)) {
137
+ return false;
138
+ }
139
+ // Check minimum severity
140
+ if (route.minSeverity) {
141
+ const severityOrder = { info: 0, warning: 1, error: 2 };
142
+ const eventSeverity = event.severity ?? this.defaultSeverity(event.type);
143
+ if (severityOrder[eventSeverity] < severityOrder[route.minSeverity]) {
144
+ return false;
145
+ }
146
+ }
147
+ return true;
148
+ }
149
+ async sendToRoute(route, event) {
150
+ const template = this.templates.get(event.type) ?? {
151
+ title: event.type,
152
+ body: JSON.stringify(event.data),
153
+ };
154
+ const rendered = this.renderTemplate(template, event.data);
155
+ const severity = event.severity ?? this.defaultSeverity(event.type);
156
+ if (route.useThreads) {
157
+ const threadKey = `${route.name}:${event.data.issueNumber ?? 'global'}`;
158
+ const existingThread = this.activeThreads.get(threadKey);
159
+ if (existingThread) {
160
+ await route.messenger.postUpdate(existingThread, `**${rendered.title}**\n${rendered.body}`);
161
+ }
162
+ else {
163
+ const thread = await route.messenger.createThread({
164
+ channel: route.channel,
165
+ title: rendered.title,
166
+ message: rendered.body,
167
+ });
168
+ this.activeThreads.set(threadKey, thread.id);
169
+ }
170
+ }
171
+ else {
172
+ await route.messenger.sendNotification({
173
+ channel: route.channel,
174
+ message: `**${rendered.title}**\n${rendered.body}`,
175
+ severity,
176
+ });
177
+ }
178
+ }
179
+ renderTemplate(template, data) {
180
+ let title = template.title;
181
+ let body = template.body;
182
+ for (const [key, value] of Object.entries(data)) {
183
+ const placeholder = `{${key}}`;
184
+ title = title.replaceAll(placeholder, String(value));
185
+ body = body.replaceAll(placeholder, String(value));
186
+ }
187
+ return { title, body };
188
+ }
189
+ defaultSeverity(type) {
190
+ switch (type) {
191
+ case 'pipeline-failed':
192
+ case 'agent-failed':
193
+ case 'gate-failure':
194
+ case 'deploy-failed':
195
+ return 'error';
196
+ case 'approval-required':
197
+ case 'demotion':
198
+ case 'cost-alert':
199
+ case 'rollout-rollback':
200
+ return 'warning';
201
+ default:
202
+ return 'info';
203
+ }
204
+ }
205
+ }
206
+ //# sourceMappingURL=notification-router.js.map
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Slack Messenger — implements the Messenger interface using Slack Web API.
3
+ *
4
+ * Design decision D5: Uses chat.postMessage via Web API.
5
+ */
6
+ import type { Messenger, NotificationInput, ThreadInput, Thread } from '@ai-sdlc/reference';
7
+ export interface SlackConfig {
8
+ /** Slack Bot OAuth token (xoxb-...). */
9
+ token: string;
10
+ /** Base URL for Slack API. Defaults to https://slack.com/api. */
11
+ apiUrl?: string;
12
+ /** Default channel for notifications (can be overridden per message). */
13
+ defaultChannel?: string;
14
+ }
15
+ export declare class SlackMessenger implements Messenger {
16
+ private config;
17
+ private apiUrl;
18
+ constructor(config: SlackConfig);
19
+ sendNotification(input: NotificationInput): Promise<void>;
20
+ createThread(input: ThreadInput): Promise<Thread>;
21
+ postUpdate(threadId: string, message: string): Promise<void>;
22
+ private postMessage;
23
+ private callAPI;
24
+ private severityIcon;
25
+ }
26
+ //# sourceMappingURL=slack-messenger.d.ts.map
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Slack Messenger — implements the Messenger interface using Slack Web API.
3
+ *
4
+ * Design decision D5: Uses chat.postMessage via Web API.
5
+ */
6
+ export class SlackMessenger {
7
+ config;
8
+ apiUrl;
9
+ constructor(config) {
10
+ this.config = config;
11
+ this.apiUrl = config.apiUrl ?? 'https://slack.com/api';
12
+ }
13
+ async sendNotification(input) {
14
+ const channel = input.channel || this.config.defaultChannel;
15
+ if (!channel)
16
+ throw new Error('No channel specified for Slack notification');
17
+ const icon = this.severityIcon(input.severity);
18
+ await this.postMessage(channel, `${icon} ${input.message}`);
19
+ }
20
+ async createThread(input) {
21
+ const channel = input.channel || this.config.defaultChannel;
22
+ if (!channel)
23
+ throw new Error('No channel specified for Slack thread');
24
+ const response = await this.postMessage(channel, `*${input.title}*\n\n${input.message}`);
25
+ return {
26
+ id: response.ts ?? '',
27
+ url: `https://slack.com/archives/${response.channel}/p${response.ts?.replace('.', '')}`,
28
+ };
29
+ }
30
+ async postUpdate(threadId, message) {
31
+ const channel = this.config.defaultChannel;
32
+ if (!channel)
33
+ throw new Error('No default channel for thread update');
34
+ await this.callAPI('chat.postMessage', {
35
+ channel,
36
+ text: message,
37
+ thread_ts: threadId,
38
+ });
39
+ }
40
+ async postMessage(channel, text) {
41
+ return this.callAPI('chat.postMessage', { channel, text });
42
+ }
43
+ async callAPI(method, body) {
44
+ const res = await fetch(`${this.apiUrl}/${method}`, {
45
+ method: 'POST',
46
+ headers: {
47
+ 'Content-Type': 'application/json; charset=utf-8',
48
+ Authorization: `Bearer ${this.config.token}`,
49
+ },
50
+ body: JSON.stringify(body),
51
+ });
52
+ const data = (await res.json());
53
+ if (!data.ok) {
54
+ throw new Error(`Slack API error: ${data.error ?? 'unknown'}`);
55
+ }
56
+ return data;
57
+ }
58
+ severityIcon(severity) {
59
+ switch (severity) {
60
+ case 'error':
61
+ return ':red_circle:';
62
+ case 'warning':
63
+ return ':warning:';
64
+ default:
65
+ return ':information_source:';
66
+ }
67
+ }
68
+ }
69
+ //# sourceMappingURL=slack-messenger.js.map
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Microsoft Teams Messenger — implements the Messenger interface using incoming webhooks.
3
+ *
4
+ * Design decision D5: Uses incoming webhook URLs for simplicity.
5
+ */
6
+ import type { Messenger, NotificationInput, ThreadInput, Thread } from '@ai-sdlc/reference';
7
+ export interface TeamsConfig {
8
+ /** Incoming webhook URL. */
9
+ webhookUrl: string;
10
+ }
11
+ export declare class TeamsMessenger implements Messenger {
12
+ private config;
13
+ constructor(config: TeamsConfig);
14
+ sendNotification(input: NotificationInput): Promise<void>;
15
+ createThread(input: ThreadInput): Promise<Thread>;
16
+ postUpdate(threadId: string, message: string): Promise<void>;
17
+ private buildCard;
18
+ private postWebhook;
19
+ private severityIcon;
20
+ }
21
+ //# sourceMappingURL=teams-messenger.d.ts.map
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Microsoft Teams Messenger — implements the Messenger interface using incoming webhooks.
3
+ *
4
+ * Design decision D5: Uses incoming webhook URLs for simplicity.
5
+ */
6
+ export class TeamsMessenger {
7
+ config;
8
+ constructor(config) {
9
+ this.config = config;
10
+ }
11
+ async sendNotification(input) {
12
+ const icon = this.severityIcon(input.severity);
13
+ const card = this.buildCard(`${icon} ${input.message}`);
14
+ await this.postWebhook(card);
15
+ }
16
+ async createThread(input) {
17
+ const card = this.buildCard(input.message, input.title);
18
+ await this.postWebhook(card);
19
+ // Teams webhooks don't return thread IDs, so generate a correlation ID
20
+ const threadId = `teams-${Date.now()}`;
21
+ return {
22
+ id: threadId,
23
+ url: this.config.webhookUrl,
24
+ };
25
+ }
26
+ async postUpdate(threadId, message) {
27
+ // Teams webhooks are fire-and-forget — no thread reply support
28
+ // Send as a new message referencing the thread
29
+ const card = this.buildCard(`[Thread: ${threadId}] ${message}`);
30
+ await this.postWebhook(card);
31
+ }
32
+ buildCard(message, title) {
33
+ const body = [];
34
+ if (title) {
35
+ body.push({
36
+ type: 'TextBlock',
37
+ text: title,
38
+ weight: 'Bolder',
39
+ size: 'Medium',
40
+ wrap: true,
41
+ });
42
+ }
43
+ body.push({
44
+ type: 'TextBlock',
45
+ text: message,
46
+ wrap: true,
47
+ });
48
+ return {
49
+ type: 'message',
50
+ attachments: [
51
+ {
52
+ contentType: 'application/vnd.microsoft.card.adaptive',
53
+ content: {
54
+ $schema: 'http://adaptivecards.io/schemas/adaptive-card.json',
55
+ type: 'AdaptiveCard',
56
+ version: '1.4',
57
+ body,
58
+ },
59
+ },
60
+ ],
61
+ };
62
+ }
63
+ async postWebhook(card) {
64
+ const res = await fetch(this.config.webhookUrl, {
65
+ method: 'POST',
66
+ headers: { 'Content-Type': 'application/json' },
67
+ body: JSON.stringify(card),
68
+ });
69
+ if (!res.ok) {
70
+ const text = await res.text().catch(() => '');
71
+ throw new Error(`Teams webhook error ${res.status}: ${text.slice(0, 200)}`);
72
+ }
73
+ }
74
+ severityIcon(severity) {
75
+ switch (severity) {
76
+ case 'error':
77
+ return '🔴';
78
+ case 'warning':
79
+ return '⚠️';
80
+ default:
81
+ return 'ℹ️';
82
+ }
83
+ }
84
+ }
85
+ //# sourceMappingURL=teams-messenger.js.map
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Notification template rendering utility.
3
+ * Replaces {key} placeholders in title and body with provided variable values.
4
+ */
5
+ import type { NotificationTemplate } from '@ai-sdlc/reference';
6
+ /**
7
+ * Render a notification template by replacing {key} placeholders with values.
8
+ */
9
+ export declare function renderTemplate(template: NotificationTemplate, vars: Record<string, string>): {
10
+ title: string;
11
+ body: string;
12
+ };
13
+ //# sourceMappingURL=notifications.d.ts.map
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Notification template rendering utility.
3
+ * Replaces {key} placeholders in title and body with provided variable values.
4
+ */
5
+ import { interpolate } from './shared.js';
6
+ /**
7
+ * Render a notification template by replacing {key} placeholders with values.
8
+ */
9
+ export function renderTemplate(template, vars) {
10
+ return {
11
+ title: interpolate(template.title, vars),
12
+ body: interpolate(template.body ?? '', vars),
13
+ };
14
+ }
15
+ //# sourceMappingURL=notifications.js.map
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Agent orchestration integration — wraps multi-agent orchestration patterns,
3
+ * execution engine, and handoff validation for pipeline stages.
4
+ */
5
+ import { sequential, parallel, hybrid, hierarchical, swarm, router, collaborative, executeOrchestration, validateHandoff, validateHandoffContract, simpleSchemaValidate, type OrchestrationPattern, type OrchestrationPlan, type OrchestrationStep, type OrchestrationResult, type StepResult, type TaskFn, type ExecutionOptions, type AgentRole } from '@ai-sdlc/reference';
6
+ /**
7
+ * Create an orchestration plan appropriate for the given agent count and pattern.
8
+ */
9
+ export declare function createPipelineOrchestration(agents: AgentRole[], pattern?: OrchestrationPattern): OrchestrationPlan;
10
+ /**
11
+ * Execute an orchestration plan with a task function for each agent.
12
+ */
13
+ export declare function executePipelineOrchestration(plan: OrchestrationPlan, agents: AgentRole[], taskFn: TaskFn, options?: ExecutionOptions): Promise<OrchestrationResult>;
14
+ /**
15
+ * Validate that all handoff targets in an agent's handoff declarations exist.
16
+ */
17
+ export declare function validatePipelineHandoffs(agents: AgentRole[]): string[];
18
+ export { sequential, parallel, hybrid, hierarchical, swarm, router, collaborative, executeOrchestration, validateHandoff, validateHandoffContract, simpleSchemaValidate, };
19
+ export type { OrchestrationPattern, OrchestrationPlan, OrchestrationStep, OrchestrationResult, StepResult, TaskFn, ExecutionOptions, };
20
+ //# sourceMappingURL=orchestration.d.ts.map
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Agent orchestration integration — wraps multi-agent orchestration patterns,
3
+ * execution engine, and handoff validation for pipeline stages.
4
+ */
5
+ import { sequential, parallel, hybrid, hierarchical, swarm, router, collaborative, executeOrchestration, validateHandoff, validateHandoffContract, simpleSchemaValidate, } from '@ai-sdlc/reference';
6
+ /**
7
+ * Create an orchestration plan appropriate for the given agent count and pattern.
8
+ */
9
+ export function createPipelineOrchestration(agents, pattern = 'sequential') {
10
+ switch (pattern) {
11
+ case 'sequential':
12
+ return sequential(agents);
13
+ case 'parallel':
14
+ return parallel(agents);
15
+ case 'hybrid':
16
+ return hybrid(agents[0], agents.slice(1));
17
+ case 'hierarchical':
18
+ return hierarchical(agents[0], agents.slice(1));
19
+ case 'swarm':
20
+ return swarm(agents);
21
+ default:
22
+ return sequential(agents);
23
+ }
24
+ }
25
+ /**
26
+ * Execute an orchestration plan with a task function for each agent.
27
+ */
28
+ export async function executePipelineOrchestration(plan, agents, taskFn, options) {
29
+ const agentMap = new Map();
30
+ for (const agent of agents) {
31
+ agentMap.set(agent.metadata.name, agent);
32
+ }
33
+ return executeOrchestration(plan, agentMap, taskFn, options);
34
+ }
35
+ /**
36
+ * Validate that all handoff targets in an agent's handoff declarations exist.
37
+ */
38
+ export function validatePipelineHandoffs(agents) {
39
+ const errors = [];
40
+ const agentNames = new Set(agents.map((a) => a.metadata.name));
41
+ for (const agent of agents) {
42
+ if (!agent.spec.handoffs)
43
+ continue;
44
+ for (const handoff of agent.spec.handoffs) {
45
+ if (!agentNames.has(handoff.target)) {
46
+ errors.push(`Agent "${agent.metadata.name}" has handoff to unknown target "${handoff.target}"`);
47
+ }
48
+ }
49
+ }
50
+ return errors;
51
+ }
52
+ export { sequential, parallel, hybrid, hierarchical, swarm, router, collaborative, executeOrchestration, validateHandoff, validateHandoffContract, simpleSchemaValidate, };
53
+ //# sourceMappingURL=orchestration.js.map
@@ -0,0 +1,160 @@
1
+ /**
2
+ * Orchestrator class — central entry point wrapping executePipeline,
3
+ * startWatch, executeFixCI, and the state store.
4
+ */
5
+ import { type ExecuteOptions, type PipelineResult } from './execute.js';
6
+ import { type WatchOptions, type WatchHandle } from './watch.js';
7
+ import { type FixCIOptions } from './fix-ci.js';
8
+ import { type AiSdlcConfig } from './config.js';
9
+ import { StateStore } from './state/index.js';
10
+ import { type Logger } from './logger.js';
11
+ import type { SecurityContext } from './security.js';
12
+ import type { AgentRunner } from './runners/types.js';
13
+ import type { CodebaseProfile, CodebaseContext } from './analysis/types.js';
14
+ import type { AutonomyLedgerEntry, RoutingDecision } from './state/types.js';
15
+ import { AutonomyTracker } from './autonomy-tracker.js';
16
+ import { CostTracker, type CostSummary, type BudgetStatus } from './cost-tracker.js';
17
+ import type { OrchestratorPlugin } from './plugin.js';
18
+ export interface WebhookConfig {
19
+ /** Port to listen on for webhooks. */
20
+ port: number;
21
+ /** Host to bind to (defaults to '0.0.0.0'). */
22
+ host?: string;
23
+ /** GitHub webhook secret. */
24
+ githubSecret?: string;
25
+ /** GitLab webhook secret token. */
26
+ gitlabSecretToken?: string;
27
+ /** Jira webhook secret. */
28
+ jiraSecret?: string;
29
+ /** Linear webhook signing secret. */
30
+ linearSigningSecret?: string;
31
+ }
32
+ export interface OrchestratorConfig {
33
+ /** Path to the .ai-sdlc config directory. */
34
+ configDir?: string;
35
+ /** Working directory (defaults to process.cwd()). */
36
+ workDir?: string;
37
+ /** Path to the SQLite state database. Omit to disable persistence. */
38
+ statePath?: string;
39
+ /** Security context for enterprise features. */
40
+ security?: SecurityContext;
41
+ /** Custom agent runner override. */
42
+ runner?: AgentRunner;
43
+ /** Custom logger. */
44
+ logger?: Logger;
45
+ /** Webhook server configuration. */
46
+ webhooks?: WebhookConfig;
47
+ /** Plugins to hook into the pipeline lifecycle. */
48
+ plugins?: OrchestratorPlugin[];
49
+ }
50
+ export interface StatusResult {
51
+ config: AiSdlcConfig;
52
+ recentRuns: Array<{
53
+ runId: string;
54
+ issueNumber?: number;
55
+ status: string;
56
+ startedAt?: string;
57
+ }>;
58
+ }
59
+ export interface HealthResult {
60
+ configValid: boolean;
61
+ stateStoreConnected: boolean;
62
+ errors: string[];
63
+ }
64
+ export declare class Orchestrator {
65
+ private config;
66
+ private _state?;
67
+ private log;
68
+ private _autonomyTracker?;
69
+ private _costTracker?;
70
+ private plugins;
71
+ private _pluginsInitialized;
72
+ constructor(config: OrchestratorConfig);
73
+ private _initPlugins;
74
+ /**
75
+ * Run the full pipeline for a single issue.
76
+ */
77
+ run(issueNumber: number, overrides?: Partial<ExecuteOptions>): Promise<PipelineResult>;
78
+ /**
79
+ * Start watch mode — continuous reconciliation loop.
80
+ */
81
+ start(options?: Partial<WatchOptions>): Promise<WatchHandle>;
82
+ /**
83
+ * Fix a failing CI run on an agent-created PR.
84
+ */
85
+ fixCI(prNumber: number, runId: number, overrides?: Partial<FixCIOptions>): Promise<void>;
86
+ /**
87
+ * Get pipeline status, optionally filtered by issue number.
88
+ */
89
+ status(issueNumber?: number): Promise<StatusResult>;
90
+ /**
91
+ * Health check — validates config, state store, and adapter connectivity.
92
+ */
93
+ health(): Promise<HealthResult>;
94
+ /**
95
+ * Analyze the codebase and return a CodebaseProfile.
96
+ * Caches the result in the state store if available.
97
+ */
98
+ analyze(options?: {
99
+ force?: boolean;
100
+ }): Promise<CodebaseProfile>;
101
+ /**
102
+ * Get agent roster with autonomy levels and performance.
103
+ */
104
+ agents(): Promise<AutonomyLedgerEntry[]>;
105
+ /**
106
+ * Get routing decision history.
107
+ */
108
+ routing(options?: {
109
+ limit?: number;
110
+ }): Promise<RoutingDecision[]>;
111
+ /**
112
+ * Get codebase complexity profile as CodebaseContext.
113
+ */
114
+ complexity(options?: {
115
+ analyze?: boolean;
116
+ }): Promise<{
117
+ profile: CodebaseProfile;
118
+ context: CodebaseContext;
119
+ }>;
120
+ /**
121
+ * Get cost summary and budget status.
122
+ */
123
+ cost(opts?: {
124
+ since?: string;
125
+ budget?: number;
126
+ }): Promise<{
127
+ summary: CostSummary;
128
+ budget: BudgetStatus;
129
+ }>;
130
+ /**
131
+ * Get dashboard data snapshot for TUI rendering.
132
+ */
133
+ dashboard(): Promise<{
134
+ runs: Array<{
135
+ runId: string;
136
+ status: string;
137
+ startedAt?: string;
138
+ }>;
139
+ agents: AutonomyLedgerEntry[];
140
+ costSummary: CostSummary;
141
+ budgetStatus: BudgetStatus;
142
+ }>;
143
+ /**
144
+ * Access the autonomy tracker.
145
+ */
146
+ get autonomyTracker(): AutonomyTracker | undefined;
147
+ /**
148
+ * Access the cost tracker.
149
+ */
150
+ get costTracker(): CostTracker | undefined;
151
+ /**
152
+ * Access the state store directly.
153
+ */
154
+ get state(): StateStore | undefined;
155
+ /**
156
+ * Clean up resources. Calls shutdown() on all plugins.
157
+ */
158
+ close(): Promise<void>;
159
+ }
160
+ //# sourceMappingURL=orchestrator.d.ts.map