@shin1ohno/sage 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.
- package/LICENSE +21 -0
- package/README.md +168 -0
- package/dist/config/loader.d.ts +37 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +95 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/storage/file-storage.d.ts +35 -0
- package/dist/config/storage/file-storage.d.ts.map +1 -0
- package/dist/config/storage/file-storage.js +76 -0
- package/dist/config/storage/file-storage.js.map +1 -0
- package/dist/config/storage/index.d.ts +8 -0
- package/dist/config/storage/index.d.ts.map +1 -0
- package/dist/config/storage/index.js +8 -0
- package/dist/config/storage/index.js.map +1 -0
- package/dist/config/storage/session-storage.d.ts +35 -0
- package/dist/config/storage/session-storage.d.ts.map +1 -0
- package/dist/config/storage/session-storage.js +44 -0
- package/dist/config/storage/session-storage.js.map +1 -0
- package/dist/config/storage/storage-factory.d.ts +32 -0
- package/dist/config/storage/storage-factory.d.ts.map +1 -0
- package/dist/config/storage/storage-factory.js +78 -0
- package/dist/config/storage/storage-factory.js.map +1 -0
- package/dist/core/index.d.ts +6 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +6 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/sage-core.d.ts +80 -0
- package/dist/core/sage-core.d.ts.map +1 -0
- package/dist/core/sage-core.js +190 -0
- package/dist/core/sage-core.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +901 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/apple-reminders.d.ts +96 -0
- package/dist/integrations/apple-reminders.d.ts.map +1 -0
- package/dist/integrations/apple-reminders.js +250 -0
- package/dist/integrations/apple-reminders.js.map +1 -0
- package/dist/integrations/calendar-service.d.ts +126 -0
- package/dist/integrations/calendar-service.d.ts.map +1 -0
- package/dist/integrations/calendar-service.js +295 -0
- package/dist/integrations/calendar-service.js.map +1 -0
- package/dist/integrations/notion-mcp.d.ts +121 -0
- package/dist/integrations/notion-mcp.d.ts.map +1 -0
- package/dist/integrations/notion-mcp.js +281 -0
- package/dist/integrations/notion-mcp.js.map +1 -0
- package/dist/integrations/reminder-manager.d.ts +90 -0
- package/dist/integrations/reminder-manager.d.ts.map +1 -0
- package/dist/integrations/reminder-manager.js +182 -0
- package/dist/integrations/reminder-manager.js.map +1 -0
- package/dist/platform/adapter-factory.d.ts +22 -0
- package/dist/platform/adapter-factory.d.ts.map +1 -0
- package/dist/platform/adapter-factory.js +41 -0
- package/dist/platform/adapter-factory.js.map +1 -0
- package/dist/platform/adapters/mcp-adapter.d.ts +32 -0
- package/dist/platform/adapters/mcp-adapter.d.ts.map +1 -0
- package/dist/platform/adapters/mcp-adapter.js +52 -0
- package/dist/platform/adapters/mcp-adapter.js.map +1 -0
- package/dist/platform/adapters/skills-adapter-ios.d.ts +38 -0
- package/dist/platform/adapters/skills-adapter-ios.d.ts.map +1 -0
- package/dist/platform/adapters/skills-adapter-ios.js +59 -0
- package/dist/platform/adapters/skills-adapter-ios.js.map +1 -0
- package/dist/platform/adapters/skills-adapter-web.d.ts +36 -0
- package/dist/platform/adapters/skills-adapter-web.d.ts.map +1 -0
- package/dist/platform/adapters/skills-adapter-web.js +56 -0
- package/dist/platform/adapters/skills-adapter-web.js.map +1 -0
- package/dist/platform/detector.d.ts +60 -0
- package/dist/platform/detector.d.ts.map +1 -0
- package/dist/platform/detector.js +217 -0
- package/dist/platform/detector.js.map +1 -0
- package/dist/platform/index.d.ts +11 -0
- package/dist/platform/index.d.ts.map +1 -0
- package/dist/platform/index.js +11 -0
- package/dist/platform/index.js.map +1 -0
- package/dist/platform/types.d.ts +205 -0
- package/dist/platform/types.d.ts.map +1 -0
- package/dist/platform/types.js +33 -0
- package/dist/platform/types.js.map +1 -0
- package/dist/setup/questions.d.ts +15 -0
- package/dist/setup/questions.d.ts.map +1 -0
- package/dist/setup/questions.js +131 -0
- package/dist/setup/questions.js.map +1 -0
- package/dist/setup/wizard.d.ts +51 -0
- package/dist/setup/wizard.d.ts.map +1 -0
- package/dist/setup/wizard.js +210 -0
- package/dist/setup/wizard.js.map +1 -0
- package/dist/tools/analyze-tasks.d.ts +61 -0
- package/dist/tools/analyze-tasks.d.ts.map +1 -0
- package/dist/tools/analyze-tasks.js +258 -0
- package/dist/tools/analyze-tasks.js.map +1 -0
- package/dist/types/config.d.ts +126 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +118 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/errors.d.ts +39 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/errors.js +83 -0
- package/dist/types/errors.js.map +1 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +7 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/task.d.ts +69 -0
- package/dist/types/task.d.ts.map +1 -0
- package/dist/types/task.js +5 -0
- package/dist/types/task.js.map +1 -0
- package/dist/utils/estimation.d.ts +49 -0
- package/dist/utils/estimation.d.ts.map +1 -0
- package/dist/utils/estimation.js +244 -0
- package/dist/utils/estimation.js.map +1 -0
- package/dist/utils/priority.d.ts +68 -0
- package/dist/utils/priority.d.ts.map +1 -0
- package/dist/utils/priority.js +243 -0
- package/dist/utils/priority.js.map +1 -0
- package/dist/utils/retry.d.ts +62 -0
- package/dist/utils/retry.d.ts.map +1 -0
- package/dist/utils/retry.js +161 -0
- package/dist/utils/retry.js.map +1 -0
- package/dist/utils/stakeholders.d.ts +61 -0
- package/dist/utils/stakeholders.d.ts.map +1 -0
- package/dist/utils/stakeholders.js +301 -0
- package/dist/utils/stakeholders.js.map +1 -0
- package/dist/utils/task-splitter.d.ts +45 -0
- package/dist/utils/task-splitter.d.ts.map +1 -0
- package/dist/utils/task-splitter.js +321 -0
- package/dist/utils/task-splitter.js.map +1 -0
- package/package.json +66 -0
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Priority Engine
|
|
3
|
+
* Determines task priority based on rules and conditions
|
|
4
|
+
* Requirements: 2.1-2.5
|
|
5
|
+
*/
|
|
6
|
+
// Urgent keywords for P0
|
|
7
|
+
const URGENT_KEYWORDS = [
|
|
8
|
+
'urgent',
|
|
9
|
+
'emergency',
|
|
10
|
+
'critical',
|
|
11
|
+
'asap',
|
|
12
|
+
'immediately',
|
|
13
|
+
'緊急',
|
|
14
|
+
'至急',
|
|
15
|
+
'今すぐ',
|
|
16
|
+
'ブロッカー',
|
|
17
|
+
'blocker',
|
|
18
|
+
'blocking',
|
|
19
|
+
'障害',
|
|
20
|
+
'incident',
|
|
21
|
+
'outage',
|
|
22
|
+
];
|
|
23
|
+
// Important keywords for P1
|
|
24
|
+
const IMPORTANT_KEYWORDS = [
|
|
25
|
+
'important',
|
|
26
|
+
'high priority',
|
|
27
|
+
'重要',
|
|
28
|
+
'優先',
|
|
29
|
+
'deadline',
|
|
30
|
+
'期限',
|
|
31
|
+
'締め切り',
|
|
32
|
+
'due soon',
|
|
33
|
+
];
|
|
34
|
+
export class PriorityEngine {
|
|
35
|
+
/**
|
|
36
|
+
* Determine the priority of a task
|
|
37
|
+
* Requirement: 2.1, 2.2, 2.5
|
|
38
|
+
*/
|
|
39
|
+
static determinePriority(task, rules, teamConfig) {
|
|
40
|
+
// Check P0 conditions
|
|
41
|
+
const p0Match = this.evaluateConditions(task, rules.p0Conditions, teamConfig);
|
|
42
|
+
if (p0Match.matched) {
|
|
43
|
+
return {
|
|
44
|
+
priority: 'P0',
|
|
45
|
+
reason: this.buildReason('P0', p0Match.reasons),
|
|
46
|
+
conditions: p0Match.reasons,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
// Check P1 conditions
|
|
50
|
+
const p1Match = this.evaluateConditions(task, rules.p1Conditions, teamConfig);
|
|
51
|
+
if (p1Match.matched) {
|
|
52
|
+
return {
|
|
53
|
+
priority: 'P1',
|
|
54
|
+
reason: this.buildReason('P1', p1Match.reasons),
|
|
55
|
+
conditions: p1Match.reasons,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
// Check P2 conditions
|
|
59
|
+
const p2Match = this.evaluateConditions(task, rules.p2Conditions, teamConfig);
|
|
60
|
+
if (p2Match.matched) {
|
|
61
|
+
return {
|
|
62
|
+
priority: 'P2',
|
|
63
|
+
reason: this.buildReason('P2', p2Match.reasons),
|
|
64
|
+
conditions: p2Match.reasons,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
// Default priority
|
|
68
|
+
return {
|
|
69
|
+
priority: rules.defaultPriority,
|
|
70
|
+
reason: `デフォルト優先度 (${rules.defaultPriority})`,
|
|
71
|
+
conditions: [],
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Evaluate a set of conditions against a task
|
|
76
|
+
* Requirement: 2.2, 2.3, 2.4
|
|
77
|
+
*/
|
|
78
|
+
static evaluateConditions(task, conditions, teamConfig) {
|
|
79
|
+
const reasons = [];
|
|
80
|
+
for (const condition of conditions) {
|
|
81
|
+
if (this.evaluateSingleCondition(task, condition, teamConfig)) {
|
|
82
|
+
reasons.push(condition.description);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
matched: reasons.length > 0,
|
|
87
|
+
reasons,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Evaluate a single condition
|
|
92
|
+
*/
|
|
93
|
+
static evaluateSingleCondition(task, condition, teamConfig) {
|
|
94
|
+
const text = `${task.title} ${task.description ?? ''}`.toLowerCase();
|
|
95
|
+
switch (condition.type) {
|
|
96
|
+
case 'deadline':
|
|
97
|
+
return this.evaluateDeadlineCondition(task, condition);
|
|
98
|
+
case 'keyword':
|
|
99
|
+
return this.evaluateKeywordCondition(text, condition);
|
|
100
|
+
case 'stakeholder':
|
|
101
|
+
return this.evaluateStakeholderCondition(text, condition, teamConfig);
|
|
102
|
+
case 'blocking':
|
|
103
|
+
return this.evaluateBlockingCondition(text);
|
|
104
|
+
case 'custom':
|
|
105
|
+
return this.evaluateCustomCondition(text, condition);
|
|
106
|
+
default:
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Evaluate deadline-based conditions
|
|
112
|
+
* Requirement: 2.3
|
|
113
|
+
*/
|
|
114
|
+
static evaluateDeadlineCondition(task, condition) {
|
|
115
|
+
if (!task.deadline)
|
|
116
|
+
return false;
|
|
117
|
+
const deadline = new Date(task.deadline);
|
|
118
|
+
const now = new Date();
|
|
119
|
+
const diffMs = deadline.getTime() - now.getTime();
|
|
120
|
+
let thresholdMs;
|
|
121
|
+
const value = condition.value;
|
|
122
|
+
switch (condition.unit) {
|
|
123
|
+
case 'hours':
|
|
124
|
+
thresholdMs = value * 60 * 60 * 1000;
|
|
125
|
+
break;
|
|
126
|
+
case 'days':
|
|
127
|
+
thresholdMs = value * 24 * 60 * 60 * 1000;
|
|
128
|
+
break;
|
|
129
|
+
case 'weeks':
|
|
130
|
+
thresholdMs = value * 7 * 24 * 60 * 60 * 1000;
|
|
131
|
+
break;
|
|
132
|
+
default:
|
|
133
|
+
thresholdMs = value * 60 * 60 * 1000; // Default to hours
|
|
134
|
+
}
|
|
135
|
+
switch (condition.operator) {
|
|
136
|
+
case '<':
|
|
137
|
+
return diffMs < thresholdMs && diffMs > 0;
|
|
138
|
+
case '>':
|
|
139
|
+
return diffMs > thresholdMs;
|
|
140
|
+
case '=':
|
|
141
|
+
return Math.abs(diffMs - thresholdMs) < 60 * 60 * 1000; // Within 1 hour
|
|
142
|
+
default:
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Evaluate keyword-based conditions
|
|
148
|
+
* Requirement: 2.3
|
|
149
|
+
*/
|
|
150
|
+
static evaluateKeywordCondition(text, condition) {
|
|
151
|
+
const keywords = Array.isArray(condition.value) ? condition.value : [condition.value];
|
|
152
|
+
switch (condition.operator) {
|
|
153
|
+
case 'contains':
|
|
154
|
+
return keywords.some((keyword) => text.includes(keyword.toLowerCase()));
|
|
155
|
+
case 'matches':
|
|
156
|
+
return keywords.some((keyword) => {
|
|
157
|
+
const regex = new RegExp(keyword, 'i');
|
|
158
|
+
return regex.test(text);
|
|
159
|
+
});
|
|
160
|
+
default:
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Evaluate stakeholder-based conditions
|
|
166
|
+
* Requirement: 2.4
|
|
167
|
+
*/
|
|
168
|
+
static evaluateStakeholderCondition(text, condition, teamConfig) {
|
|
169
|
+
const value = condition.value;
|
|
170
|
+
if (value === 'manager' && teamConfig?.manager) {
|
|
171
|
+
const managerKeywords = [
|
|
172
|
+
teamConfig.manager.name.toLowerCase(),
|
|
173
|
+
'manager',
|
|
174
|
+
'マネージャー',
|
|
175
|
+
'上司',
|
|
176
|
+
'boss',
|
|
177
|
+
...teamConfig.manager.keywords.map((k) => k.toLowerCase()),
|
|
178
|
+
];
|
|
179
|
+
return managerKeywords.some((keyword) => text.includes(keyword));
|
|
180
|
+
}
|
|
181
|
+
if (value === 'lead' && teamConfig?.frequentCollaborators) {
|
|
182
|
+
const leads = teamConfig.frequentCollaborators.filter((c) => c.role === 'lead');
|
|
183
|
+
return leads.some((lead) => lead.keywords.some((keyword) => text.includes(keyword.toLowerCase())));
|
|
184
|
+
}
|
|
185
|
+
return false;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Evaluate blocking task conditions
|
|
189
|
+
*/
|
|
190
|
+
static evaluateBlockingCondition(text) {
|
|
191
|
+
const blockingKeywords = [
|
|
192
|
+
'blocking',
|
|
193
|
+
'blocker',
|
|
194
|
+
'blocks',
|
|
195
|
+
'ブロック',
|
|
196
|
+
'ブロッカー',
|
|
197
|
+
'障害',
|
|
198
|
+
'dependency',
|
|
199
|
+
'依存',
|
|
200
|
+
];
|
|
201
|
+
return blockingKeywords.some((keyword) => text.includes(keyword.toLowerCase()));
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Evaluate custom conditions
|
|
205
|
+
*/
|
|
206
|
+
static evaluateCustomCondition(text, condition) {
|
|
207
|
+
const value = condition.value;
|
|
208
|
+
switch (condition.operator) {
|
|
209
|
+
case 'contains':
|
|
210
|
+
return text.includes(value.toLowerCase());
|
|
211
|
+
case 'matches':
|
|
212
|
+
const regex = new RegExp(value, 'i');
|
|
213
|
+
return regex.test(text);
|
|
214
|
+
default:
|
|
215
|
+
return false;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Quick check for urgent keywords without full rules
|
|
220
|
+
*/
|
|
221
|
+
static hasUrgentKeywords(text) {
|
|
222
|
+
const lowerText = text.toLowerCase();
|
|
223
|
+
return URGENT_KEYWORDS.some((keyword) => lowerText.includes(keyword.toLowerCase()));
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Quick check for important keywords without full rules
|
|
227
|
+
*/
|
|
228
|
+
static hasImportantKeywords(text) {
|
|
229
|
+
const lowerText = text.toLowerCase();
|
|
230
|
+
return IMPORTANT_KEYWORDS.some((keyword) => lowerText.includes(keyword.toLowerCase()));
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Build a human-readable reason string
|
|
234
|
+
* Note: This is only called when conditions are matched
|
|
235
|
+
*/
|
|
236
|
+
static buildReason(priority, conditions) {
|
|
237
|
+
if (conditions.length === 1) {
|
|
238
|
+
return `${conditions[0]}のため${priority}に設定`;
|
|
239
|
+
}
|
|
240
|
+
return `${conditions.join('、')}のため${priority}に設定`;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
//# sourceMappingURL=priority.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"priority.js","sourceRoot":"","sources":["../../src/utils/priority.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retry Utility
|
|
3
|
+
* Provides retry mechanisms with exponential backoff
|
|
4
|
+
* Requirements: 5.6, 8.5, 15.2
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Retry options
|
|
8
|
+
*/
|
|
9
|
+
export interface RetryOptions {
|
|
10
|
+
/** Maximum number of attempts (default: 3) */
|
|
11
|
+
maxAttempts?: number;
|
|
12
|
+
/** Delay between retries in ms (default: 1000) */
|
|
13
|
+
delay?: number;
|
|
14
|
+
/** Callback called on each retry */
|
|
15
|
+
onRetry?: (error: Error, attempt: number) => void;
|
|
16
|
+
/** Function to determine if error is retryable */
|
|
17
|
+
shouldRetry?: (error: Error) => boolean;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Backoff options for exponential retry
|
|
21
|
+
*/
|
|
22
|
+
export interface BackoffOptions {
|
|
23
|
+
/** Maximum number of attempts (default: 3) */
|
|
24
|
+
maxAttempts?: number;
|
|
25
|
+
/** Initial delay in ms (default: 1000) */
|
|
26
|
+
initialDelay?: number;
|
|
27
|
+
/** Maximum delay in ms (default: 30000) */
|
|
28
|
+
maxDelay?: number;
|
|
29
|
+
/** Backoff multiplier (default: 2) */
|
|
30
|
+
multiplier?: number;
|
|
31
|
+
/** Add random jitter to delay (default: false) */
|
|
32
|
+
jitter?: boolean;
|
|
33
|
+
/** Callback called on each retry */
|
|
34
|
+
onRetry?: (error: Error, attempt: number, nextDelay: number) => void;
|
|
35
|
+
/** Function to determine if error is retryable */
|
|
36
|
+
shouldRetry?: (error: Error) => boolean;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Custom error for retry failures
|
|
40
|
+
*/
|
|
41
|
+
export declare class RetryError extends Error {
|
|
42
|
+
readonly lastError: Error;
|
|
43
|
+
readonly attempts: number;
|
|
44
|
+
constructor(message: string, lastError: Error, attempts: number);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Retry a function with fixed delay
|
|
48
|
+
*/
|
|
49
|
+
export declare function retry<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<T>;
|
|
50
|
+
/**
|
|
51
|
+
* Retry a function with exponential backoff
|
|
52
|
+
*/
|
|
53
|
+
export declare function retryWithBackoff<T>(fn: () => Promise<T>, options?: BackoffOptions): Promise<T>;
|
|
54
|
+
/**
|
|
55
|
+
* Determine if an error is retryable
|
|
56
|
+
*/
|
|
57
|
+
export declare function isRetryableError(error: Error): boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Create a retry wrapper for a service method
|
|
60
|
+
*/
|
|
61
|
+
export declare function withRetry<T extends (...args: unknown[]) => Promise<unknown>>(fn: T, options?: BackoffOptions): T;
|
|
62
|
+
//# sourceMappingURL=retry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/utils/retry.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,8CAA8C;IAC9C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kDAAkD;IAClD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oCAAoC;IACpC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD,kDAAkD;IAClD,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC;CACzC;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,8CAA8C;IAC9C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0CAA0C;IAC1C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sCAAsC;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kDAAkD;IAClD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,oCAAoC;IACpC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACrE,kDAAkD;IAClD,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC;CACzC;AAED;;GAEG;AACH,qBAAa,UAAW,SAAQ,KAAK;IACnC,SAAgB,SAAS,EAAE,KAAK,CAAC;IACjC,SAAgB,QAAQ,EAAE,MAAM,CAAC;gBAErB,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM;CAShE;AASD;;GAEG;AACH,wBAAsB,KAAK,CAAC,CAAC,EAC3B,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,CAAC,CAAC,CAoCZ;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,CAAC,EACtC,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,CAAC,CAAC,CAuDZ;AAsCD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAmBtD;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,EAC1E,EAAE,EAAE,CAAC,EACL,OAAO,GAAE,cAAmB,GAC3B,CAAC,CAUH"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retry Utility
|
|
3
|
+
* Provides retry mechanisms with exponential backoff
|
|
4
|
+
* Requirements: 5.6, 8.5, 15.2
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Custom error for retry failures
|
|
8
|
+
*/
|
|
9
|
+
export class RetryError extends Error {
|
|
10
|
+
lastError;
|
|
11
|
+
attempts;
|
|
12
|
+
constructor(message, lastError, attempts) {
|
|
13
|
+
super(message);
|
|
14
|
+
this.name = 'RetryError';
|
|
15
|
+
this.lastError = lastError;
|
|
16
|
+
this.attempts = attempts;
|
|
17
|
+
// Maintain proper prototype chain
|
|
18
|
+
Object.setPrototypeOf(this, RetryError.prototype);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Sleep for specified milliseconds
|
|
23
|
+
*/
|
|
24
|
+
function sleep(ms) {
|
|
25
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Retry a function with fixed delay
|
|
29
|
+
*/
|
|
30
|
+
export async function retry(fn, options = {}) {
|
|
31
|
+
const { maxAttempts = 3, delay = 1000, onRetry, shouldRetry } = options;
|
|
32
|
+
let lastError = new Error('No attempts made');
|
|
33
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
34
|
+
try {
|
|
35
|
+
return await fn();
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
39
|
+
// Check if we should retry this error
|
|
40
|
+
if (shouldRetry && !shouldRetry(lastError)) {
|
|
41
|
+
throw lastError;
|
|
42
|
+
}
|
|
43
|
+
// If this was the last attempt, don't retry
|
|
44
|
+
if (attempt >= maxAttempts) {
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
// Call onRetry callback
|
|
48
|
+
if (onRetry) {
|
|
49
|
+
onRetry(lastError, attempt);
|
|
50
|
+
}
|
|
51
|
+
// Wait before next attempt
|
|
52
|
+
await sleep(delay);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
throw new RetryError(`Failed after ${maxAttempts} attempts: ${lastError.message}`, lastError, maxAttempts);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Retry a function with exponential backoff
|
|
59
|
+
*/
|
|
60
|
+
export async function retryWithBackoff(fn, options = {}) {
|
|
61
|
+
const { maxAttempts = 3, initialDelay = 1000, maxDelay = 30000, multiplier = 2, jitter = false, onRetry, shouldRetry, } = options;
|
|
62
|
+
let lastError = new Error('No attempts made');
|
|
63
|
+
let currentDelay = initialDelay;
|
|
64
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
65
|
+
try {
|
|
66
|
+
return await fn();
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
70
|
+
// Check if we should retry this error
|
|
71
|
+
if (shouldRetry && !shouldRetry(lastError)) {
|
|
72
|
+
throw lastError;
|
|
73
|
+
}
|
|
74
|
+
// If this was the last attempt, don't retry
|
|
75
|
+
if (attempt >= maxAttempts) {
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
// Calculate delay with optional jitter
|
|
79
|
+
let delayMs = Math.min(currentDelay, maxDelay);
|
|
80
|
+
if (jitter) {
|
|
81
|
+
// Add random jitter between 0-25% of delay
|
|
82
|
+
delayMs = delayMs + Math.random() * delayMs * 0.25;
|
|
83
|
+
}
|
|
84
|
+
// Call onRetry callback
|
|
85
|
+
if (onRetry) {
|
|
86
|
+
onRetry(lastError, attempt, delayMs);
|
|
87
|
+
}
|
|
88
|
+
// Wait before next attempt
|
|
89
|
+
await sleep(delayMs);
|
|
90
|
+
// Increase delay for next attempt
|
|
91
|
+
currentDelay = currentDelay * multiplier;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
throw new RetryError(`Failed after ${maxAttempts} attempts: ${lastError.message}`, lastError, maxAttempts);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Patterns that indicate non-retryable errors
|
|
98
|
+
*/
|
|
99
|
+
const NON_RETRYABLE_PATTERNS = [
|
|
100
|
+
/permission denied/i,
|
|
101
|
+
/access denied/i,
|
|
102
|
+
/unauthorized/i,
|
|
103
|
+
/forbidden/i,
|
|
104
|
+
/invalid/i,
|
|
105
|
+
/validation/i,
|
|
106
|
+
/not found/i,
|
|
107
|
+
/does not exist/i,
|
|
108
|
+
/already exists/i,
|
|
109
|
+
/bad request/i,
|
|
110
|
+
];
|
|
111
|
+
/**
|
|
112
|
+
* Patterns that indicate retryable errors
|
|
113
|
+
*/
|
|
114
|
+
const RETRYABLE_PATTERNS = [
|
|
115
|
+
/ECONNRESET/i,
|
|
116
|
+
/ETIMEDOUT/i,
|
|
117
|
+
/ECONNREFUSED/i,
|
|
118
|
+
/ENETUNREACH/i,
|
|
119
|
+
/EHOSTUNREACH/i,
|
|
120
|
+
/network/i,
|
|
121
|
+
/timeout/i,
|
|
122
|
+
/temporary/i,
|
|
123
|
+
/unavailable/i,
|
|
124
|
+
/rate limit/i,
|
|
125
|
+
/too many requests/i,
|
|
126
|
+
/service busy/i,
|
|
127
|
+
/try again/i,
|
|
128
|
+
/retry/i,
|
|
129
|
+
];
|
|
130
|
+
/**
|
|
131
|
+
* Determine if an error is retryable
|
|
132
|
+
*/
|
|
133
|
+
export function isRetryableError(error) {
|
|
134
|
+
const message = error.message.toLowerCase();
|
|
135
|
+
// First check for non-retryable patterns
|
|
136
|
+
for (const pattern of NON_RETRYABLE_PATTERNS) {
|
|
137
|
+
if (pattern.test(message)) {
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
// Then check for retryable patterns
|
|
142
|
+
for (const pattern of RETRYABLE_PATTERNS) {
|
|
143
|
+
if (pattern.test(message)) {
|
|
144
|
+
return true;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
// Default to retryable for unknown errors
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Create a retry wrapper for a service method
|
|
152
|
+
*/
|
|
153
|
+
export function withRetry(fn, options = {}) {
|
|
154
|
+
return (async (...args) => {
|
|
155
|
+
return retryWithBackoff(() => fn(...args), {
|
|
156
|
+
...options,
|
|
157
|
+
shouldRetry: options.shouldRetry ?? isRetryableError,
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=retry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/utils/retry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stakeholder Extraction System
|
|
3
|
+
* Identifies and extracts stakeholders from task content
|
|
4
|
+
* Requirements: 4.1-4.5
|
|
5
|
+
*/
|
|
6
|
+
import type { Task, TeamConfig, TeamMember } from '../types/index.js';
|
|
7
|
+
interface StakeholderResult {
|
|
8
|
+
stakeholders: string[];
|
|
9
|
+
managerInvolved: boolean;
|
|
10
|
+
reason: string;
|
|
11
|
+
mentions: string[];
|
|
12
|
+
matchedTeamMembers: TeamMember[];
|
|
13
|
+
}
|
|
14
|
+
export declare class StakeholderExtractor {
|
|
15
|
+
/**
|
|
16
|
+
* Extract stakeholders from a task
|
|
17
|
+
* Requirement: 4.1, 4.5
|
|
18
|
+
*/
|
|
19
|
+
static extractStakeholders(task: Task, teamConfig?: TeamConfig): StakeholderResult;
|
|
20
|
+
/**
|
|
21
|
+
* Find @mentions in text
|
|
22
|
+
* Requirement: 4.3
|
|
23
|
+
*/
|
|
24
|
+
static findMentions(text: string): string[];
|
|
25
|
+
/**
|
|
26
|
+
* Match text against configured team members
|
|
27
|
+
* Requirement: 4.2
|
|
28
|
+
*/
|
|
29
|
+
static matchTeamMembers(text: string, teamConfig: TeamConfig): TeamMember[];
|
|
30
|
+
/**
|
|
31
|
+
* Check if a team member matches the text
|
|
32
|
+
*/
|
|
33
|
+
private static memberMatchesText;
|
|
34
|
+
/**
|
|
35
|
+
* Check if manager is involved in the task
|
|
36
|
+
* Requirement: 4.4
|
|
37
|
+
*/
|
|
38
|
+
static checkManagerInvolvement(text: string, teamConfig?: TeamConfig): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Check if a word is a common word (false positive)
|
|
41
|
+
*/
|
|
42
|
+
private static isCommonWord;
|
|
43
|
+
/**
|
|
44
|
+
* Build a human-readable reason
|
|
45
|
+
*/
|
|
46
|
+
private static buildReason;
|
|
47
|
+
/**
|
|
48
|
+
* Get priority boost for manager involvement
|
|
49
|
+
*/
|
|
50
|
+
static getManagerPriorityBoost(): number;
|
|
51
|
+
/**
|
|
52
|
+
* Extract all names from text (broader matching)
|
|
53
|
+
*/
|
|
54
|
+
static extractPotentialNames(text: string): string[];
|
|
55
|
+
/**
|
|
56
|
+
* Check if a capitalized word is commonly not a name
|
|
57
|
+
*/
|
|
58
|
+
private static isCommonCapitalizedWord;
|
|
59
|
+
}
|
|
60
|
+
export {};
|
|
61
|
+
//# sourceMappingURL=stakeholders.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stakeholders.d.ts","sourceRoot":"","sources":["../../src/utils/stakeholders.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEtE,UAAU,iBAAiB;IACzB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,eAAe,EAAE,OAAO,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,kBAAkB,EAAE,UAAU,EAAE,CAAC;CAClC;AA0BD,qBAAa,oBAAoB;IAC/B;;;OAGG;IACH,MAAM,CAAC,mBAAmB,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,CAAC,EAAE,UAAU,GAAG,iBAAiB;IAwClF;;;OAGG;IACH,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE;IAoB3C;;;OAGG;IACH,MAAM,CAAC,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,GAAG,UAAU,EAAE;IAqB3E;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAgBhC;;;OAGG;IACH,MAAM,CAAC,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,UAAU,GAAG,OAAO;IAwB9E;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,YAAY;IAuD3B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,WAAW;IA2B1B;;OAEG;IACH,MAAM,CAAC,uBAAuB,IAAI,MAAM;IAIxC;;OAEG;IACH,MAAM,CAAC,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE;IAuBpD;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,uBAAuB;CA+CvC"}
|