digital-workers 0.1.1 → 2.0.2

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 (83) hide show
  1. package/.turbo/turbo-build.log +5 -0
  2. package/CHANGELOG.md +17 -0
  3. package/README.md +290 -106
  4. package/dist/actions.d.ts +95 -0
  5. package/dist/actions.d.ts.map +1 -0
  6. package/dist/actions.js +437 -0
  7. package/dist/actions.js.map +1 -0
  8. package/dist/approve.d.ts +49 -0
  9. package/dist/approve.d.ts.map +1 -0
  10. package/dist/approve.js +235 -0
  11. package/dist/approve.js.map +1 -0
  12. package/dist/ask.d.ts +42 -0
  13. package/dist/ask.d.ts.map +1 -0
  14. package/dist/ask.js +227 -0
  15. package/dist/ask.js.map +1 -0
  16. package/dist/decide.d.ts +62 -0
  17. package/dist/decide.d.ts.map +1 -0
  18. package/dist/decide.js +245 -0
  19. package/dist/decide.js.map +1 -0
  20. package/dist/do.d.ts +63 -0
  21. package/dist/do.d.ts.map +1 -0
  22. package/dist/do.js +228 -0
  23. package/dist/do.js.map +1 -0
  24. package/dist/generate.d.ts +61 -0
  25. package/dist/generate.d.ts.map +1 -0
  26. package/dist/generate.js +299 -0
  27. package/dist/generate.js.map +1 -0
  28. package/dist/goals.d.ts +89 -0
  29. package/dist/goals.d.ts.map +1 -0
  30. package/dist/goals.js +206 -0
  31. package/dist/goals.js.map +1 -0
  32. package/dist/index.d.ts +68 -0
  33. package/dist/index.d.ts.map +1 -0
  34. package/dist/index.js +69 -0
  35. package/dist/index.js.map +1 -0
  36. package/dist/is.d.ts +54 -0
  37. package/dist/is.d.ts.map +1 -0
  38. package/dist/is.js +318 -0
  39. package/dist/is.js.map +1 -0
  40. package/dist/kpis.d.ts +103 -0
  41. package/dist/kpis.d.ts.map +1 -0
  42. package/dist/kpis.js +271 -0
  43. package/dist/kpis.js.map +1 -0
  44. package/dist/notify.d.ts +47 -0
  45. package/dist/notify.d.ts.map +1 -0
  46. package/dist/notify.js +220 -0
  47. package/dist/notify.js.map +1 -0
  48. package/dist/role.d.ts +53 -0
  49. package/dist/role.d.ts.map +1 -0
  50. package/dist/role.js +111 -0
  51. package/dist/role.js.map +1 -0
  52. package/dist/team.d.ts +61 -0
  53. package/dist/team.d.ts.map +1 -0
  54. package/dist/team.js +131 -0
  55. package/dist/team.js.map +1 -0
  56. package/dist/transports.d.ts +164 -0
  57. package/dist/transports.d.ts.map +1 -0
  58. package/dist/transports.js +358 -0
  59. package/dist/transports.js.map +1 -0
  60. package/dist/types.d.ts +693 -0
  61. package/dist/types.d.ts.map +1 -0
  62. package/dist/types.js +72 -0
  63. package/dist/types.js.map +1 -0
  64. package/package.json +27 -61
  65. package/src/actions.ts +615 -0
  66. package/src/approve.ts +317 -0
  67. package/src/ask.ts +304 -0
  68. package/src/decide.ts +295 -0
  69. package/src/do.ts +275 -0
  70. package/src/generate.ts +364 -0
  71. package/src/goals.ts +220 -0
  72. package/src/index.ts +118 -0
  73. package/src/is.ts +372 -0
  74. package/src/kpis.ts +348 -0
  75. package/src/notify.ts +303 -0
  76. package/src/role.ts +116 -0
  77. package/src/team.ts +142 -0
  78. package/src/transports.ts +504 -0
  79. package/src/types.ts +843 -0
  80. package/test/actions.test.ts +546 -0
  81. package/test/standalone.test.ts +299 -0
  82. package/test/types.test.ts +460 -0
  83. package/tsconfig.json +9 -0
package/dist/kpis.js ADDED
@@ -0,0 +1,271 @@
1
+ /**
2
+ * KPI and OKR tracking functionality for digital workers
3
+ */
4
+ export function kpis(definition) {
5
+ return definition;
6
+ }
7
+ /**
8
+ * Update a KPI's current value
9
+ *
10
+ * @param kpi - The KPI to update
11
+ * @param current - New current value
12
+ * @returns Updated KPI
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * const updated = kpis.update(deploymentFrequency, 8)
17
+ * console.log(updated.current) // 8
18
+ * console.log(updated.trend) // 'up' (automatically determined)
19
+ * ```
20
+ */
21
+ kpis.update = (kpi, current) => {
22
+ // Determine trend
23
+ let trend = 'stable';
24
+ if (current > kpi.current) {
25
+ trend = 'up';
26
+ }
27
+ else if (current < kpi.current) {
28
+ trend = 'down';
29
+ }
30
+ return {
31
+ ...kpi,
32
+ current,
33
+ trend,
34
+ };
35
+ };
36
+ /**
37
+ * Calculate progress towards target (0-1)
38
+ *
39
+ * @param kpi - The KPI
40
+ * @returns Progress as a decimal (0-1)
41
+ *
42
+ * @example
43
+ * ```ts
44
+ * const kpi = { current: 75, target: 100 }
45
+ * const progress = kpis.progress(kpi) // 0.75
46
+ * ```
47
+ */
48
+ kpis.progress = (kpi) => {
49
+ if (kpi.target === 0)
50
+ return 0;
51
+ return Math.min(1, Math.max(0, kpi.current / kpi.target));
52
+ };
53
+ /**
54
+ * Check if a KPI is on track
55
+ *
56
+ * @param kpi - The KPI
57
+ * @param threshold - Minimum progress to be "on track" (default: 0.8)
58
+ * @returns Whether the KPI is on track
59
+ *
60
+ * @example
61
+ * ```ts
62
+ * const kpi = { current: 85, target: 100 }
63
+ * const onTrack = kpis.onTrack(kpi) // true (85% >= 80%)
64
+ * ```
65
+ */
66
+ kpis.onTrack = (kpi, threshold = 0.8) => {
67
+ return kpis.progress(kpi) >= threshold;
68
+ };
69
+ /**
70
+ * Get the gap to target
71
+ *
72
+ * @param kpi - The KPI
73
+ * @returns Difference between target and current
74
+ *
75
+ * @example
76
+ * ```ts
77
+ * const kpi = { current: 75, target: 100 }
78
+ * const gap = kpis.gap(kpi) // 25
79
+ * ```
80
+ */
81
+ kpis.gap = (kpi) => {
82
+ return kpi.target - kpi.current;
83
+ };
84
+ /**
85
+ * Format a KPI for display
86
+ *
87
+ * @param kpi - The KPI
88
+ * @returns Formatted string
89
+ *
90
+ * @example
91
+ * ```ts
92
+ * const kpi = {
93
+ * name: 'Deployment Frequency',
94
+ * current: 5,
95
+ * target: 10,
96
+ * unit: 'deploys/week',
97
+ * trend: 'up',
98
+ * }
99
+ * const formatted = kpis.format(kpi)
100
+ * // "Deployment Frequency: 5/10 deploys/week (50%, trending up)"
101
+ * ```
102
+ */
103
+ kpis.format = (kpi) => {
104
+ const progress = kpis.progress(kpi);
105
+ const progressPercent = Math.round(progress * 100);
106
+ const trendEmoji = kpi.trend === 'up' ? '↑' : kpi.trend === 'down' ? '↓' : '→';
107
+ return `${kpi.name}: ${kpi.current}/${kpi.target} ${kpi.unit} (${progressPercent}%, trending ${kpi.trend} ${trendEmoji})`;
108
+ };
109
+ /**
110
+ * Compare two KPI snapshots to see change over time
111
+ *
112
+ * @param previous - Previous KPI state
113
+ * @param current - Current KPI state
114
+ * @returns Change analysis
115
+ *
116
+ * @example
117
+ * ```ts
118
+ * const change = kpis.compare(previousKPI, currentKPI)
119
+ * console.log(change.delta) // 5
120
+ * console.log(change.percentChange) // 10
121
+ * console.log(change.improved) // true
122
+ * ```
123
+ */
124
+ kpis.compare = (previous, current) => {
125
+ const delta = current.current - previous.current;
126
+ const percentChange = previous.current !== 0
127
+ ? (delta / previous.current) * 100
128
+ : 0;
129
+ // Improved if we got closer to the target
130
+ const previousGap = Math.abs(previous.target - previous.current);
131
+ const currentGap = Math.abs(current.target - current.current);
132
+ const improved = currentGap < previousGap;
133
+ return {
134
+ delta,
135
+ percentChange,
136
+ improved,
137
+ };
138
+ };
139
+ /**
140
+ * Define OKRs (Objectives and Key Results)
141
+ *
142
+ * @param definition - OKR definition
143
+ * @returns The defined OKR
144
+ *
145
+ * @example
146
+ * ```ts
147
+ * const engineeringOKR = okrs({
148
+ * objective: 'Improve development velocity',
149
+ * keyResults: [
150
+ * {
151
+ * name: 'Deployment Frequency',
152
+ * current: 5,
153
+ * target: 10,
154
+ * unit: 'deploys/week',
155
+ * },
156
+ * {
157
+ * name: 'Lead Time',
158
+ * current: 48,
159
+ * target: 24,
160
+ * unit: 'hours',
161
+ * },
162
+ * {
163
+ * name: 'Change Failure Rate',
164
+ * current: 15,
165
+ * target: 5,
166
+ * unit: '%',
167
+ * },
168
+ * ],
169
+ * owner: 'engineering-team',
170
+ * dueDate: new Date('2024-03-31'),
171
+ * })
172
+ * ```
173
+ */
174
+ export function okrs(definition) {
175
+ return definition;
176
+ }
177
+ /**
178
+ * Calculate overall OKR progress
179
+ *
180
+ * @param okr - The OKR
181
+ * @returns Average progress across all key results (0-1)
182
+ *
183
+ * @example
184
+ * ```ts
185
+ * const progress = okrs.progress(engineeringOKR)
186
+ * console.log(progress) // 0.67 (67% complete)
187
+ * ```
188
+ */
189
+ okrs.progress = (okr) => {
190
+ if (okr.keyResults.length === 0)
191
+ return 0;
192
+ const totalProgress = okr.keyResults.reduce((sum, kr) => {
193
+ return sum + kpis.progress(kr);
194
+ }, 0);
195
+ return totalProgress / okr.keyResults.length;
196
+ };
197
+ /**
198
+ * Update a key result in an OKR
199
+ *
200
+ * @param okr - The OKR
201
+ * @param keyResultName - Name of key result to update
202
+ * @param current - New current value
203
+ * @returns Updated OKR
204
+ *
205
+ * @example
206
+ * ```ts
207
+ * const updated = okrs.updateKeyResult(
208
+ * engineeringOKR,
209
+ * 'Deployment Frequency',
210
+ * 8
211
+ * )
212
+ * ```
213
+ */
214
+ okrs.updateKeyResult = (okr, keyResultName, current) => {
215
+ return {
216
+ ...okr,
217
+ keyResults: okr.keyResults.map((kr) => kr.name === keyResultName ? { ...kr, current } : kr),
218
+ progress: undefined, // Will be recalculated
219
+ };
220
+ };
221
+ /**
222
+ * Check if OKR is on track
223
+ *
224
+ * @param okr - The OKR
225
+ * @param threshold - Minimum progress to be "on track" (default: 0.7)
226
+ * @returns Whether the OKR is on track
227
+ *
228
+ * @example
229
+ * ```ts
230
+ * const onTrack = okrs.onTrack(engineeringOKR)
231
+ * ```
232
+ */
233
+ okrs.onTrack = (okr, threshold = 0.7) => {
234
+ return okrs.progress(okr) >= threshold;
235
+ };
236
+ /**
237
+ * Format OKR for display
238
+ *
239
+ * @param okr - The OKR
240
+ * @returns Formatted string
241
+ *
242
+ * @example
243
+ * ```ts
244
+ * const formatted = okrs.format(engineeringOKR)
245
+ * console.log(formatted)
246
+ * // Improve development velocity (67% complete)
247
+ * // • Deployment Frequency: 5/10 deploys/week (50%)
248
+ * // • Lead Time: 48/24 hours (200%)
249
+ * // • Change Failure Rate: 15/5 % (300%)
250
+ * ```
251
+ */
252
+ okrs.format = (okr) => {
253
+ const progress = okrs.progress(okr);
254
+ const progressPercent = Math.round(progress * 100);
255
+ const lines = [
256
+ `${okr.objective} (${progressPercent}% complete)`,
257
+ ...okr.keyResults.map((kr) => {
258
+ const krProgress = kpis.progress(kr);
259
+ const krPercent = Math.round(krProgress * 100);
260
+ return ` • ${kr.name}: ${kr.current}/${kr.target} ${kr.unit} (${krPercent}%)`;
261
+ }),
262
+ ];
263
+ if (okr.owner) {
264
+ lines.push(` Owner: ${okr.owner}`);
265
+ }
266
+ if (okr.dueDate) {
267
+ lines.push(` Due: ${okr.dueDate.toLocaleDateString()}`);
268
+ }
269
+ return lines.join('\n');
270
+ };
271
+ //# sourceMappingURL=kpis.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kpis.js","sourceRoot":"","sources":["../src/kpis.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Notification functionality for digital workers
3
+ */
4
+ import type { ActionTarget, NotifyResult, NotifyOptions } from './types.js';
5
+ /**
6
+ * Send a notification to a worker or team
7
+ *
8
+ * Routes notifications through the specified channel(s), falling back
9
+ * to the target's preferred channel if not specified.
10
+ *
11
+ * @param target - The worker or team to notify
12
+ * @param message - The notification message
13
+ * @param options - Notification options
14
+ * @returns Promise resolving to notification result
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * // Notify a worker via their preferred channel
19
+ * await notify(alice, 'Deployment completed successfully')
20
+ *
21
+ * // Notify via specific channel
22
+ * await notify(alice, 'Urgent: Server down!', { via: 'slack' })
23
+ *
24
+ * // Notify via multiple channels
25
+ * await notify(alice, 'Critical alert', { via: ['slack', 'sms'] })
26
+ *
27
+ * // Notify a team
28
+ * await notify(engineering, 'Sprint planning tomorrow', { via: 'slack' })
29
+ * ```
30
+ */
31
+ export declare function notify(target: ActionTarget, message: string, options?: NotifyOptions): Promise<NotifyResult>;
32
+ export declare namespace notify {
33
+ var alert: (target: ActionTarget, message: string, options?: NotifyOptions) => Promise<NotifyResult>;
34
+ var info: (target: ActionTarget, message: string, options?: NotifyOptions) => Promise<NotifyResult>;
35
+ var rich: (target: ActionTarget, title: string, body: string, options?: NotifyOptions) => Promise<NotifyResult>;
36
+ var batch: (notifications: Array<{
37
+ target: ActionTarget;
38
+ message: string;
39
+ options?: NotifyOptions;
40
+ }>) => Promise<NotifyResult[]>;
41
+ var schedule: (target: ActionTarget, message: string, when: Date | number, options?: NotifyOptions) => Promise<{
42
+ scheduled: true;
43
+ scheduledFor: Date;
44
+ messageId: string;
45
+ }>;
46
+ }
47
+ //# sourceMappingURL=notify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notify.d.ts","sourceRoot":"","sources":["../src/notify.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAIV,YAAY,EAEZ,YAAY,EACZ,aAAa,EAEd,MAAM,YAAY,CAAA;AAEnB;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,MAAM,CAC1B,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,YAAY,CAAC,CA6CvB;yBAjDqB,MAAM;wBA4DlB,YAAY,WACX,MAAM,YACN,aAAa,KACrB,OAAO,CAAC,YAAY,CAAC;uBAad,YAAY,WACX,MAAM,YACN,aAAa,KACrB,OAAO,CAAC,YAAY,CAAC;uBAgBd,YAAY,SACb,MAAM,QACP,MAAM,YACH,aAAa,KACrB,OAAO,CAAC,YAAY,CAAC;+BAkBP,KAAK,CAAC;QACnB,MAAM,EAAE,YAAY,CAAA;QACpB,OAAO,EAAE,MAAM,CAAA;QACf,OAAO,CAAC,EAAE,aAAa,CAAA;KACxB,CAAC,KACD,OAAO,CAAC,YAAY,EAAE,CAAC;2BAmBhB,YAAY,WACX,MAAM,QACT,IAAI,GAAG,MAAM,YACV,aAAa,KACrB,OAAO,CAAC;QAAE,SAAS,EAAE,IAAI,CAAC;QAAC,YAAY,EAAE,IAAI,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC"}
package/dist/notify.js ADDED
@@ -0,0 +1,220 @@
1
+ /**
2
+ * Notification functionality for digital workers
3
+ */
4
+ /**
5
+ * Send a notification to a worker or team
6
+ *
7
+ * Routes notifications through the specified channel(s), falling back
8
+ * to the target's preferred channel if not specified.
9
+ *
10
+ * @param target - The worker or team to notify
11
+ * @param message - The notification message
12
+ * @param options - Notification options
13
+ * @returns Promise resolving to notification result
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * // Notify a worker via their preferred channel
18
+ * await notify(alice, 'Deployment completed successfully')
19
+ *
20
+ * // Notify via specific channel
21
+ * await notify(alice, 'Urgent: Server down!', { via: 'slack' })
22
+ *
23
+ * // Notify via multiple channels
24
+ * await notify(alice, 'Critical alert', { via: ['slack', 'sms'] })
25
+ *
26
+ * // Notify a team
27
+ * await notify(engineering, 'Sprint planning tomorrow', { via: 'slack' })
28
+ * ```
29
+ */
30
+ export async function notify(target, message, options = {}) {
31
+ const { via, priority = 'normal', fallback = false, timeout, context, metadata } = options;
32
+ // Resolve target to get contacts
33
+ const { contacts, recipients } = resolveTarget(target);
34
+ // Determine which channels to use
35
+ const channels = resolveChannels(via, contacts, priority);
36
+ if (channels.length === 0) {
37
+ return {
38
+ sent: false,
39
+ via: [],
40
+ sentAt: new Date(),
41
+ messageId: generateMessageId(),
42
+ delivery: [],
43
+ };
44
+ }
45
+ // Send to each channel
46
+ const delivery = await Promise.all(channels.map(async (channel) => {
47
+ try {
48
+ await sendToChannel(channel, message, contacts, { priority, metadata });
49
+ return { channel, status: 'sent' };
50
+ }
51
+ catch (error) {
52
+ return {
53
+ channel,
54
+ status: 'failed',
55
+ error: error instanceof Error ? error.message : 'Unknown error',
56
+ };
57
+ }
58
+ }));
59
+ const sent = delivery.some((d) => d.status === 'sent');
60
+ return {
61
+ sent,
62
+ via: channels,
63
+ recipients,
64
+ sentAt: new Date(),
65
+ messageId: generateMessageId(),
66
+ delivery,
67
+ };
68
+ }
69
+ /**
70
+ * Send a high-priority alert notification
71
+ *
72
+ * @example
73
+ * ```ts
74
+ * await notify.alert(oncallEngineer, 'Production is down!')
75
+ * ```
76
+ */
77
+ notify.alert = async (target, message, options = {}) => {
78
+ return notify(target, message, { ...options, priority: 'urgent' });
79
+ };
80
+ /**
81
+ * Send a low-priority info notification
82
+ *
83
+ * @example
84
+ * ```ts
85
+ * await notify.info(team, 'Weekly sync notes posted')
86
+ * ```
87
+ */
88
+ notify.info = async (target, message, options = {}) => {
89
+ return notify(target, message, { ...options, priority: 'low' });
90
+ };
91
+ /**
92
+ * Send a rich notification with title and body
93
+ *
94
+ * @example
95
+ * ```ts
96
+ * await notify.rich(alice, 'Deployment Complete', 'Version 2.1.0 deployed to production', {
97
+ * via: 'slack',
98
+ * metadata: { version: '2.1.0', environment: 'production' },
99
+ * })
100
+ * ```
101
+ */
102
+ notify.rich = async (target, title, body, options = {}) => {
103
+ const message = `**${title}**\n\n${body}`;
104
+ return notify(target, message, options);
105
+ };
106
+ /**
107
+ * Send notifications in batch
108
+ *
109
+ * @example
110
+ * ```ts
111
+ * await notify.batch([
112
+ * { target: alice, message: 'Task 1 complete' },
113
+ * { target: bob, message: 'Task 2 complete' },
114
+ * { target: team, message: 'All tasks done', options: { via: 'slack' } },
115
+ * ])
116
+ * ```
117
+ */
118
+ notify.batch = async (notifications) => {
119
+ return Promise.all(notifications.map(({ target, message, options }) => notify(target, message, options)));
120
+ };
121
+ /**
122
+ * Schedule a notification for later
123
+ *
124
+ * @example
125
+ * ```ts
126
+ * // Schedule for specific time
127
+ * await notify.schedule(alice, 'Meeting in 15 minutes', new Date('2024-01-15T14:45:00Z'))
128
+ *
129
+ * // Schedule with delay
130
+ * await notify.schedule(alice, 'Reminder', 60000) // 1 minute
131
+ * ```
132
+ */
133
+ notify.schedule = async (target, message, when, options = {}) => {
134
+ const scheduledFor = when instanceof Date ? when : new Date(Date.now() + when);
135
+ // In a real implementation, this would store the scheduled notification
136
+ return {
137
+ scheduled: true,
138
+ scheduledFor,
139
+ messageId: generateMessageId('scheduled'),
140
+ };
141
+ };
142
+ // ============================================================================
143
+ // Internal Helpers
144
+ // ============================================================================
145
+ /**
146
+ * Resolve an action target to contacts and recipients
147
+ */
148
+ function resolveTarget(target) {
149
+ if (typeof target === 'string') {
150
+ // Just an ID - return empty contacts, would need to look up
151
+ return {
152
+ contacts: {},
153
+ recipients: [{ id: target }],
154
+ };
155
+ }
156
+ if ('contacts' in target) {
157
+ // Worker or Team
158
+ const recipients = 'members' in target
159
+ ? target.members // Team
160
+ : [{ id: target.id, type: target.type, name: target.name }]; // Worker
161
+ return {
162
+ contacts: target.contacts,
163
+ recipients,
164
+ };
165
+ }
166
+ // WorkerRef - no contacts available
167
+ return {
168
+ contacts: {},
169
+ recipients: [target],
170
+ };
171
+ }
172
+ /**
173
+ * Determine which channels to use based on options and contacts
174
+ */
175
+ function resolveChannels(via, contacts, priority) {
176
+ // If specific channels requested, use those
177
+ if (via) {
178
+ const requested = Array.isArray(via) ? via : [via];
179
+ // Filter to only channels that exist in contacts
180
+ return requested.filter((channel) => contacts[channel] !== undefined);
181
+ }
182
+ // Otherwise, use available channels based on priority
183
+ const available = Object.keys(contacts);
184
+ if (available.length === 0) {
185
+ return [];
186
+ }
187
+ const firstChannel = available[0];
188
+ if (!firstChannel) {
189
+ return [];
190
+ }
191
+ // For urgent, try multiple channels
192
+ if (priority === 'urgent') {
193
+ const urgentChannels = ['slack', 'sms', 'phone'];
194
+ return available.filter((c) => urgentChannels.includes(c));
195
+ }
196
+ // Default to first available
197
+ return [firstChannel];
198
+ }
199
+ /**
200
+ * Send a notification to a specific channel
201
+ */
202
+ async function sendToChannel(channel, message, contacts, options) {
203
+ const contact = contacts[channel];
204
+ if (!contact) {
205
+ throw new Error(`No ${channel} contact configured`);
206
+ }
207
+ // In a real implementation, this would:
208
+ // 1. Format the message for the channel
209
+ // 2. Send via the appropriate API (Slack, SendGrid, Twilio, etc.)
210
+ // 3. Handle delivery confirmation
211
+ // For now, simulate success
212
+ await new Promise((resolve) => setTimeout(resolve, 10));
213
+ }
214
+ /**
215
+ * Generate a unique message ID
216
+ */
217
+ function generateMessageId(prefix = 'msg') {
218
+ return `${prefix}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
219
+ }
220
+ //# sourceMappingURL=notify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notify.js","sourceRoot":"","sources":["../src/notify.ts"],"names":[],"mappings":"AAAA;;GAEG;AAaH;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAC1B,MAAoB,EACpB,OAAe,EACf,UAAyB,EAAE;IAE3B,MAAM,EAAE,GAAG,EAAE,QAAQ,GAAG,QAAQ,EAAE,QAAQ,GAAG,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAA;IAE1F,iCAAiC;IACjC,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,aAAa,CAAC,MAAM,CAAC,CAAA;IAEtD,kCAAkC;IAClC,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAA;IAEzD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO;YACL,IAAI,EAAE,KAAK;YACX,GAAG,EAAE,EAAE;YACP,MAAM,EAAE,IAAI,IAAI,EAAE;YAClB,SAAS,EAAE,iBAAiB,EAAE;YAC9B,QAAQ,EAAE,EAAE;SACb,CAAA;IACH,CAAC;IAED,uBAAuB;IACvB,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CAChC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;QAC7B,IAAI,CAAC;YACH,MAAM,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAA;YACvE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAe,EAAE,CAAA;QAC7C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,OAAO;gBACP,MAAM,EAAE,QAAiB;gBACzB,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;aAChE,CAAA;QACH,CAAC;IACH,CAAC,CAAC,CACH,CAAA;IAED,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAA;IAEtD,OAAO;QACL,IAAI;QACJ,GAAG,EAAE,QAAQ;QACb,UAAU;QACV,MAAM,EAAE,IAAI,IAAI,EAAE;QAClB,SAAS,EAAE,iBAAiB,EAAE;QAC9B,QAAQ;KACT,CAAA;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,GAAG,KAAK,EAClB,MAAoB,EACpB,OAAe,EACf,UAAyB,EAAE,EACJ,EAAE;IACzB,OAAO,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,GAAG,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAA;AACpE,CAAC,CAAA;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,IAAI,GAAG,KAAK,EACjB,MAAoB,EACpB,OAAe,EACf,UAAyB,EAAE,EACJ,EAAE;IACzB,OAAO,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,GAAG,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAA;AACjE,CAAC,CAAA;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,IAAI,GAAG,KAAK,EACjB,MAAoB,EACpB,KAAa,EACb,IAAY,EACZ,UAAyB,EAAE,EACJ,EAAE;IACzB,MAAM,OAAO,GAAG,KAAK,KAAK,SAAS,IAAI,EAAE,CAAA;IACzC,OAAO,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;AACzC,CAAC,CAAA;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,GAAG,KAAK,EAClB,aAIE,EACuB,EAAE;IAC3B,OAAO,OAAO,CAAC,GAAG,CAChB,aAAa,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CACtF,CAAA;AACH,CAAC,CAAA;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,QAAQ,GAAG,KAAK,EACrB,MAAoB,EACpB,OAAe,EACf,IAAmB,EACnB,UAAyB,EAAE,EAC0C,EAAE;IACvE,MAAM,YAAY,GAAG,IAAI,YAAY,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAA;IAE9E,wEAAwE;IACxE,OAAO;QACL,SAAS,EAAE,IAAI;QACf,YAAY;QACZ,SAAS,EAAE,iBAAiB,CAAC,WAAW,CAAC;KAC1C,CAAA;AACH,CAAC,CAAA;AAED,+EAA+E;AAC/E,mBAAmB;AACnB,+EAA+E;AAE/E;;GAEG;AACH,SAAS,aAAa,CAAC,MAAoB;IAIzC,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,4DAA4D;QAC5D,OAAO;YACL,QAAQ,EAAE,EAAE;YACZ,UAAU,EAAE,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC;SAC7B,CAAA;IACH,CAAC;IAED,IAAI,UAAU,IAAI,MAAM,EAAE,CAAC;QACzB,iBAAiB;QACjB,MAAM,UAAU,GACd,SAAS,IAAI,MAAM;YACjB,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO;YACxB,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAA,CAAC,SAAS;QAEzE,OAAO;YACL,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,UAAU;SACX,CAAA;IACH,CAAC;IAED,oCAAoC;IACpC,OAAO;QACL,QAAQ,EAAE,EAAE;QACZ,UAAU,EAAE,CAAC,MAAM,CAAC;KACrB,CAAA;AACH,CAAC;AAED;;GAEG;AACH,SAAS,eAAe,CACtB,GAAkD,EAClD,QAAkB,EAClB,QAAgB;IAEhB,4CAA4C;IAC5C,IAAI,GAAG,EAAE,CAAC;QACR,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;QAClD,iDAAiD;QACjD,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,SAAS,CAAC,CAAA;IACvE,CAAC;IAED,sDAAsD;IACtD,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAqB,CAAA;IAE3D,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,EAAE,CAAA;IACX,CAAC;IAED,MAAM,YAAY,GAAG,SAAS,CAAC,CAAC,CAAC,CAAA;IACjC,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO,EAAE,CAAA;IACX,CAAC;IAED,oCAAoC;IACpC,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC1B,MAAM,cAAc,GAAqB,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,CAAA;QAClE,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;IAC5D,CAAC;IAED,6BAA6B;IAC7B,OAAO,CAAC,YAAY,CAAC,CAAA;AACvB,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,aAAa,CAC1B,OAAuB,EACvB,OAAe,EACf,QAAkB,EAClB,OAAkE;IAElE,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAA;IAEjC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,MAAM,OAAO,qBAAqB,CAAC,CAAA;IACrD,CAAC;IAED,wCAAwC;IACxC,wCAAwC;IACxC,kEAAkE;IAClE,kCAAkC;IAElC,4BAA4B;IAC5B,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAA;AACzD,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB,CAAC,MAAM,GAAG,KAAK;IACvC,OAAO,GAAG,MAAM,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAA;AAC7E,CAAC"}
package/dist/role.d.ts ADDED
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Role definition for digital workers
3
+ */
4
+ import type { WorkerRole } from './types.js';
5
+ /**
6
+ * Define a worker role
7
+ *
8
+ * Roles define responsibilities, skills, and permissions for workers
9
+ * (both AI agents and humans) within an organization.
10
+ *
11
+ * @param definition - Role definition
12
+ * @returns The defined role
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * const engineer = Role({
17
+ * name: 'Software Engineer',
18
+ * description: 'Builds and maintains software systems',
19
+ * responsibilities: [
20
+ * 'Write clean, maintainable code',
21
+ * 'Review pull requests',
22
+ * 'Fix bugs and issues',
23
+ * 'Participate in architecture decisions',
24
+ * ],
25
+ * skills: ['TypeScript', 'React', 'Node.js'],
26
+ * type: 'hybrid', // Can be filled by AI or human
27
+ * })
28
+ * ```
29
+ *
30
+ * @example
31
+ * ```ts
32
+ * const supportAgent = Role({
33
+ * name: 'Customer Support Agent',
34
+ * description: 'Assists customers with inquiries and issues',
35
+ * responsibilities: [
36
+ * 'Respond to customer inquiries',
37
+ * 'Troubleshoot issues',
38
+ * 'Escalate complex problems',
39
+ * 'Maintain customer satisfaction',
40
+ * ],
41
+ * type: 'ai', // AI-first role
42
+ * })
43
+ * ```
44
+ */
45
+ export declare function Role(definition: Omit<WorkerRole, 'type'> & {
46
+ type?: WorkerRole['type'];
47
+ }): WorkerRole;
48
+ export declare namespace Role {
49
+ var ai: (definition: Omit<WorkerRole, "type">) => WorkerRole;
50
+ var human: (definition: Omit<WorkerRole, "type">) => WorkerRole;
51
+ var hybrid: (definition: Omit<WorkerRole, "type">) => WorkerRole;
52
+ }
53
+ //# sourceMappingURL=role.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"role.d.ts","sourceRoot":"","sources":["../src/role.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAE5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,wBAAgB,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,GAAG;IAAE,IAAI,CAAC,EAAE,UAAU,CAAC,MAAM,CAAC,CAAA;CAAE,GAAG,UAAU,CAKrG;yBALe,IAAI;yBAuBG,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,KAAG,UAAU;4BAsBlC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,KAAG,UAAU;6BAqBpC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,KAAG,UAAU"}