@ginkoai/cli 1.4.13 → 1.6.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/dist/commands/graph/api-client.d.ts +16 -1
- package/dist/commands/graph/api-client.d.ts.map +1 -1
- package/dist/commands/graph/api-client.js +79 -4
- package/dist/commands/graph/api-client.js.map +1 -1
- package/dist/commands/graph/health.d.ts +22 -0
- package/dist/commands/graph/health.d.ts.map +1 -0
- package/dist/commands/graph/health.js +37 -0
- package/dist/commands/graph/health.js.map +1 -0
- package/dist/commands/graph/index.d.ts.map +1 -1
- package/dist/commands/graph/index.js +8 -0
- package/dist/commands/graph/index.js.map +1 -1
- package/dist/commands/handoff.d.ts +7 -1
- package/dist/commands/handoff.d.ts.map +1 -1
- package/dist/commands/handoff.js +8 -0
- package/dist/commands/handoff.js.map +1 -1
- package/dist/commands/log.d.ts +5 -4
- package/dist/commands/log.d.ts.map +1 -1
- package/dist/commands/log.js +197 -216
- package/dist/commands/log.js.map +1 -1
- package/dist/commands/start/start-reflection.d.ts +22 -0
- package/dist/commands/start/start-reflection.d.ts.map +1 -1
- package/dist/commands/start/start-reflection.js +249 -30
- package/dist/commands/start/start-reflection.js.map +1 -1
- package/dist/index.js +7 -6
- package/dist/index.js.map +1 -1
- package/dist/lib/charter-loader.d.ts +74 -0
- package/dist/lib/charter-loader.d.ts.map +1 -0
- package/dist/lib/charter-loader.js +328 -0
- package/dist/lib/charter-loader.js.map +1 -0
- package/dist/lib/context-loader-events.d.ts +49 -0
- package/dist/lib/context-loader-events.d.ts.map +1 -1
- package/dist/lib/context-loader-events.js +280 -34
- package/dist/lib/context-loader-events.js.map +1 -1
- package/dist/lib/event-logger.d.ts +8 -5
- package/dist/lib/event-logger.d.ts.map +1 -1
- package/dist/lib/event-logger.js +54 -14
- package/dist/lib/event-logger.js.map +1 -1
- package/dist/lib/event-task-linker.d.ts +81 -0
- package/dist/lib/event-task-linker.d.ts.map +1 -0
- package/dist/lib/event-task-linker.js +132 -0
- package/dist/lib/event-task-linker.js.map +1 -0
- package/dist/lib/output-formatter.d.ts +172 -0
- package/dist/lib/output-formatter.d.ts.map +1 -0
- package/dist/lib/output-formatter.js +219 -0
- package/dist/lib/output-formatter.js.map +1 -0
- package/dist/lib/session-cursor.d.ts +12 -5
- package/dist/lib/session-cursor.d.ts.map +1 -1
- package/dist/lib/session-cursor.js +12 -5
- package/dist/lib/session-cursor.js.map +1 -1
- package/dist/lib/sprint-loader.d.ts +91 -0
- package/dist/lib/sprint-loader.d.ts.map +1 -0
- package/dist/lib/sprint-loader.js +296 -0
- package/dist/lib/sprint-loader.js.map +1 -0
- package/dist/lib/sprint-parser.d.ts +79 -0
- package/dist/lib/sprint-parser.d.ts.map +1 -0
- package/dist/lib/sprint-parser.js +346 -0
- package/dist/lib/sprint-parser.js.map +1 -0
- package/dist/lib/write-dispatcher/adapters/local-adapter.d.ts.map +1 -1
- package/dist/lib/write-dispatcher/adapters/local-adapter.js +8 -2
- package/dist/lib/write-dispatcher/adapters/local-adapter.js.map +1 -1
- package/dist/utils/command-helpers.d.ts +76 -0
- package/dist/utils/command-helpers.d.ts.map +1 -0
- package/dist/utils/command-helpers.js +314 -0
- package/dist/utils/command-helpers.js.map +1 -0
- package/dist/utils/graph-health-monitor.d.ts +75 -0
- package/dist/utils/graph-health-monitor.d.ts.map +1 -0
- package/dist/utils/graph-health-monitor.js +108 -0
- package/dist/utils/graph-health-monitor.js.map +1 -0
- package/dist/utils/synthesis.d.ts.map +1 -1
- package/dist/utils/synthesis.js +17 -9
- package/dist/utils/synthesis.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileType: utility
|
|
3
|
+
* @status: current
|
|
4
|
+
* @updated: 2025-11-18
|
|
5
|
+
* @pattern: utility
|
|
6
|
+
* @tags: [command-patterns, ai-first-ux, smart-defaults, adr-046, utility-command]
|
|
7
|
+
* @related: [log-quality.ts, ../commands/log.ts, ADR-046-command-patterns-reflection-vs-utility.md]
|
|
8
|
+
* @priority: high
|
|
9
|
+
* @complexity: medium
|
|
10
|
+
* @dependencies: [chalk, log-quality]
|
|
11
|
+
*/
|
|
12
|
+
import chalk from 'chalk';
|
|
13
|
+
import { detectGitContext, validateEntry } from './log-quality.js';
|
|
14
|
+
/**
|
|
15
|
+
* Category detection keywords and patterns
|
|
16
|
+
*/
|
|
17
|
+
const CATEGORY_PATTERNS = {
|
|
18
|
+
fix: [
|
|
19
|
+
/\b(fixed|fix|bug|error|issue|resolved|patched|repaired)\b/i,
|
|
20
|
+
/\b(root cause|caused by|breaking)\b/i,
|
|
21
|
+
/\b(corrected|debugged|troubleshot)\b/i,
|
|
22
|
+
],
|
|
23
|
+
feature: [
|
|
24
|
+
/\b(implemented|added|created|built|developed)\b/i,
|
|
25
|
+
/\b(new feature|enhancement|capability)\b/i,
|
|
26
|
+
/\b(introducing|rolled out)\b/i,
|
|
27
|
+
],
|
|
28
|
+
decision: [
|
|
29
|
+
/\b(decided|chose|selected|opted for)\b/i,
|
|
30
|
+
/\b(vs|versus|instead of|rather than|over)\b/i,
|
|
31
|
+
/\b(alternative|option|choice|approach)\b/i,
|
|
32
|
+
/\b(rationale|reasoning|considered)\b/i,
|
|
33
|
+
],
|
|
34
|
+
insight: [
|
|
35
|
+
/\b(discovered|learned|realized|found that)\b/i,
|
|
36
|
+
/\b(insight|pattern|observation|gotcha)\b/i,
|
|
37
|
+
/\b(breakthrough|understanding|key finding)\b/i,
|
|
38
|
+
],
|
|
39
|
+
achievement: [
|
|
40
|
+
/\b(completed|finished|delivered|shipped)\b/i,
|
|
41
|
+
/\b(milestone|achievement|success)\b/i,
|
|
42
|
+
/\b(100%|all tests|fully working)\b/i,
|
|
43
|
+
],
|
|
44
|
+
git: [
|
|
45
|
+
/\b(commit(ted)?|push(ed)?|merg(e|ed|ing)|rebas(e|ed|ing)|cherry-pick(ed)?)\b/i,
|
|
46
|
+
/\b(pull request|pr)\b/i,
|
|
47
|
+
/\b(git|version control)\b/i,
|
|
48
|
+
/\b(created?|made|new)\s+(feature\s+)?branch\b/i, // Branch operations
|
|
49
|
+
/\bbranch\b.*\b(created?|new|made)\b/i, // Branch creation
|
|
50
|
+
],
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Impact indicators - metrics and language intensity
|
|
54
|
+
*/
|
|
55
|
+
const IMPACT_INDICATORS = {
|
|
56
|
+
high: {
|
|
57
|
+
metrics: [
|
|
58
|
+
/\b\d+%\s*(reduction|improvement|faster|increase)\b/i,
|
|
59
|
+
/\b(by|improved|reduced).*\d+%/i,
|
|
60
|
+
/\b(\d+x|10x|100x)\b/i,
|
|
61
|
+
/\b(critical|severe|major|significant)\b/i,
|
|
62
|
+
/\b(production|blocker|urgent|emergency)\b/i,
|
|
63
|
+
],
|
|
64
|
+
quantitative: [
|
|
65
|
+
/\b\d+\s*(ms|s|sec|seconds?|minutes?|hours?)\s*[→>-]+\s*\d+/i, // Performance changes
|
|
66
|
+
/\bfrom\s+\d+\s*(ms|s|sec|seconds?)\s+to\s+\d+/i, // "from X to Y" pattern
|
|
67
|
+
/\b(90|95|98|99|100)%/i, // High percentages
|
|
68
|
+
/\b[5-9]\d{1,2}\s*tokens?\b/i, // Large token counts
|
|
69
|
+
],
|
|
70
|
+
},
|
|
71
|
+
medium: {
|
|
72
|
+
keywords: [
|
|
73
|
+
/\b(updated|modified|refactored|improved)\b/i,
|
|
74
|
+
/\b(moderate|reasonable|noticeable)\b/i,
|
|
75
|
+
],
|
|
76
|
+
},
|
|
77
|
+
low: {
|
|
78
|
+
keywords: [
|
|
79
|
+
/\b(minor|small|trivial|cosmetic)\b/i,
|
|
80
|
+
/\b(typo|formatting|cleanup|documentation)\b/i,
|
|
81
|
+
],
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* Detect category from description keywords
|
|
86
|
+
* Returns null if no clear category detected (caller should use default)
|
|
87
|
+
*/
|
|
88
|
+
export function detectCategory(description) {
|
|
89
|
+
// Handle edge cases: null, undefined, empty, whitespace-only
|
|
90
|
+
if (!description || typeof description !== 'string' || !description.trim()) {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
const scores = {
|
|
94
|
+
fix: 0,
|
|
95
|
+
feature: 0,
|
|
96
|
+
decision: 0,
|
|
97
|
+
insight: 0,
|
|
98
|
+
achievement: 0,
|
|
99
|
+
git: 0,
|
|
100
|
+
};
|
|
101
|
+
// Check for low-confidence cases (very short descriptions)
|
|
102
|
+
const wordCount = description.trim().split(/\s+/).length;
|
|
103
|
+
const isTerse = wordCount < 3;
|
|
104
|
+
// Score each category based on pattern matches
|
|
105
|
+
for (const [category, patterns] of Object.entries(CATEGORY_PATTERNS)) {
|
|
106
|
+
for (const pattern of patterns) {
|
|
107
|
+
if (pattern.test(description)) {
|
|
108
|
+
scores[category] += 1;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
// Find highest scoring category
|
|
113
|
+
let maxScore = 0;
|
|
114
|
+
let detectedCategory = null;
|
|
115
|
+
for (const [category, score] of Object.entries(scores)) {
|
|
116
|
+
if (score > maxScore) {
|
|
117
|
+
maxScore = score;
|
|
118
|
+
detectedCategory = category;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// Require higher confidence for terse descriptions
|
|
122
|
+
const minScore = isTerse ? 2 : 1;
|
|
123
|
+
return maxScore >= minScore ? detectedCategory : null;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Detect impact level from metrics and language intensity
|
|
127
|
+
* Always returns a value (defaults to medium)
|
|
128
|
+
*/
|
|
129
|
+
export function detectImpact(description) {
|
|
130
|
+
// Handle edge cases: null, undefined, empty, whitespace-only
|
|
131
|
+
if (!description || typeof description !== 'string' || !description.trim()) {
|
|
132
|
+
return 'medium'; // Safe default
|
|
133
|
+
}
|
|
134
|
+
// Check for high impact indicators first
|
|
135
|
+
for (const pattern of IMPACT_INDICATORS.high.metrics) {
|
|
136
|
+
if (pattern.test(description)) {
|
|
137
|
+
return 'high';
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
for (const pattern of IMPACT_INDICATORS.high.quantitative) {
|
|
141
|
+
if (pattern.test(description)) {
|
|
142
|
+
return 'high';
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// Check for low impact indicators
|
|
146
|
+
for (const pattern of IMPACT_INDICATORS.low.keywords) {
|
|
147
|
+
if (pattern.test(description)) {
|
|
148
|
+
return 'low';
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
// Check for medium impact indicators (explicit)
|
|
152
|
+
for (const pattern of IMPACT_INDICATORS.medium.keywords) {
|
|
153
|
+
if (pattern.test(description)) {
|
|
154
|
+
return 'medium';
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
// Default to medium if no clear signals
|
|
158
|
+
return 'medium';
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Determine if context module should be auto-created
|
|
162
|
+
* High-value entries: high impact + specific categories
|
|
163
|
+
*/
|
|
164
|
+
export function shouldCreateContextModule(category, impact) {
|
|
165
|
+
const eligibleCategories = ['fix', 'feature', 'decision', 'insight'];
|
|
166
|
+
return impact === 'high' && eligibleCategories.includes(category);
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Gather git context for smart defaults
|
|
170
|
+
* Wrapper around log-quality detectGitContext for convenience
|
|
171
|
+
*/
|
|
172
|
+
export async function gatherGitContext() {
|
|
173
|
+
return await detectGitContext();
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Format quality description for educational feedback
|
|
177
|
+
*/
|
|
178
|
+
export function getQualityDescription(validation) {
|
|
179
|
+
if (validation.score >= 90) {
|
|
180
|
+
return chalk.green('Excellent ') + chalk.dim('(WHAT+WHY+HOW present)');
|
|
181
|
+
}
|
|
182
|
+
else if (validation.score >= 70) {
|
|
183
|
+
return chalk.cyan('Good ') + chalk.dim('(meets quality threshold)');
|
|
184
|
+
}
|
|
185
|
+
else if (validation.score >= 50) {
|
|
186
|
+
return chalk.yellow('Fair ') + chalk.dim('(could use more context)');
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
return chalk.red('Needs improvement ') + chalk.dim('(add WHAT+WHY+HOW)');
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Extract WHAT/WHY/HOW breakdown from description
|
|
194
|
+
* Returns formatted breakdown string if patterns detected
|
|
195
|
+
*/
|
|
196
|
+
export function getQualityBreakdown(description) {
|
|
197
|
+
const lines = [];
|
|
198
|
+
// WHAT detection - action taken
|
|
199
|
+
const whatMatch = description.match(/\b(fixed|implemented|added|created|chose|discovered|optimized|improved|refactored|updated|built|developed)\s+([^.!?]+)/i);
|
|
200
|
+
if (whatMatch) {
|
|
201
|
+
lines.push(`WHAT: "${whatMatch[0].trim()}"`);
|
|
202
|
+
}
|
|
203
|
+
// WHY detection - root cause or reason
|
|
204
|
+
const whyPatterns = [
|
|
205
|
+
/root cause:\s*([^.!?]+)/i,
|
|
206
|
+
/because\s+([^.!?]+)/i,
|
|
207
|
+
/caused by\s+([^.!?]+)/i,
|
|
208
|
+
/problem:\s*([^.!?]+)/i,
|
|
209
|
+
];
|
|
210
|
+
for (const pattern of whyPatterns) {
|
|
211
|
+
const match = description.match(pattern);
|
|
212
|
+
if (match) {
|
|
213
|
+
lines.push(`WHY: "${match[0].trim()}"`);
|
|
214
|
+
break;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
// HOW detection - solution or approach
|
|
218
|
+
const howPatterns = [
|
|
219
|
+
/solution:\s*([^.!?]+)/i,
|
|
220
|
+
/implemented\s+([^.!?]+)/i,
|
|
221
|
+
/by\s+(adding|removing|changing|using)\s+([^.!?]+)/i,
|
|
222
|
+
];
|
|
223
|
+
for (const pattern of howPatterns) {
|
|
224
|
+
const match = description.match(pattern);
|
|
225
|
+
if (match) {
|
|
226
|
+
lines.push(`HOW: "${match[0].trim()}"`);
|
|
227
|
+
break;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
// IMPACT detection - metrics or results
|
|
231
|
+
const impactPatterns = [
|
|
232
|
+
/(\d+%|\d+x|\d+\s*(ms|s|sec|tokens?))\s*[→>-]+\s*(\d+%|\d+x|\d+\s*(ms|s|sec|tokens?))/i,
|
|
233
|
+
/from\s+(\d+\s*(ms|s|sec|seconds?|minutes?))\s+to\s+(\d+\s*(ms|s|sec|seconds?|minutes?))/i,
|
|
234
|
+
];
|
|
235
|
+
for (const pattern of impactPatterns) {
|
|
236
|
+
const match = description.match(pattern);
|
|
237
|
+
if (match) {
|
|
238
|
+
lines.push(`IMPACT: "${match[0].trim()}"`);
|
|
239
|
+
break;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return lines.length >= 2 ? lines.join('\n - ') : null;
|
|
243
|
+
}
|
|
244
|
+
export function formatFeedback(options) {
|
|
245
|
+
const lines = [];
|
|
246
|
+
// Header - success message
|
|
247
|
+
const autoLabel = options.autoDetected?.category || options.autoDetected?.impact
|
|
248
|
+
? chalk.dim(' (auto-detected)')
|
|
249
|
+
: '';
|
|
250
|
+
lines.push(chalk.green(`\n✓ Event logged: ${options.category} (${options.impact} impact)`) + autoLabel);
|
|
251
|
+
// Quality analysis (if provided)
|
|
252
|
+
if (options.quality) {
|
|
253
|
+
lines.push('');
|
|
254
|
+
lines.push(chalk.cyan('Quality: ') + getQualityDescription(options.quality));
|
|
255
|
+
}
|
|
256
|
+
// Auto-detection details (transparency)
|
|
257
|
+
if (options.autoDetected?.category || options.autoDetected?.impact) {
|
|
258
|
+
const detected = [];
|
|
259
|
+
if (options.autoDetected.category)
|
|
260
|
+
detected.push(`category=${options.category}`);
|
|
261
|
+
if (options.autoDetected.impact)
|
|
262
|
+
detected.push(`impact=${options.impact}`);
|
|
263
|
+
lines.push(chalk.dim(` Auto-detected: ${detected.join(', ')}`));
|
|
264
|
+
}
|
|
265
|
+
// Files included
|
|
266
|
+
if (options.files && options.files.length > 0) {
|
|
267
|
+
lines.push('');
|
|
268
|
+
lines.push(chalk.cyan('Files: ') + chalk.dim(`${options.files.length} auto-included`));
|
|
269
|
+
for (const file of options.files.slice(0, 3)) {
|
|
270
|
+
lines.push(chalk.dim(` - ${file}`));
|
|
271
|
+
}
|
|
272
|
+
if (options.files.length > 3) {
|
|
273
|
+
lines.push(chalk.dim(` ... and ${options.files.length - 3} more`));
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
// References detected
|
|
277
|
+
if (options.references && options.references.length > 0) {
|
|
278
|
+
lines.push('');
|
|
279
|
+
lines.push(chalk.cyan('References: ') + chalk.dim(`${options.references.length} detected`));
|
|
280
|
+
for (const ref of options.references.slice(0, 3)) {
|
|
281
|
+
lines.push(chalk.dim(` - ${ref.rawText}`));
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
// Context module creation
|
|
285
|
+
if (options.moduleCreated) {
|
|
286
|
+
lines.push('');
|
|
287
|
+
lines.push(chalk.green('Context module: ') + chalk.dim('Created (high-impact pattern)'));
|
|
288
|
+
}
|
|
289
|
+
// Quality coaching (if warnings present)
|
|
290
|
+
if (options.quality && options.quality.warnings.length > 0) {
|
|
291
|
+
lines.push('');
|
|
292
|
+
lines.push(chalk.yellow('💡 Quality Tips:'));
|
|
293
|
+
for (const warning of options.quality.warnings) {
|
|
294
|
+
lines.push(chalk.dim(` ${warning}`));
|
|
295
|
+
}
|
|
296
|
+
lines.push(chalk.dim('\n Next entry: Include WHAT+WHY+HOW for richer context'));
|
|
297
|
+
lines.push(chalk.dim(' Example: "Fixed X. Root cause: Y. Solution: Z. Impact: A→B"'));
|
|
298
|
+
}
|
|
299
|
+
lines.push(''); // Blank line for spacing
|
|
300
|
+
return lines.join('\n');
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Analyze entry quality and return scoring
|
|
304
|
+
* Wrapper around validateEntry for consistency
|
|
305
|
+
*/
|
|
306
|
+
export function analyzeQuality(entry) {
|
|
307
|
+
const validation = validateEntry(entry);
|
|
308
|
+
const score = validation.warnings.length === 0 ? 100 : Math.max(50, 100 - validation.warnings.length * 20);
|
|
309
|
+
return {
|
|
310
|
+
score,
|
|
311
|
+
warnings: validation.warnings,
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
//# sourceMappingURL=command-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-helpers.js","sourceRoot":"","sources":["../../src/utils/command-helpers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileType: utility
|
|
3
|
+
* @status: current
|
|
4
|
+
* @updated: 2025-11-21
|
|
5
|
+
* @tags: [monitoring, health-check, graph, reliability, task-013]
|
|
6
|
+
* @related: [../commands/graph/api-client.ts, event-logger.ts]
|
|
7
|
+
* @priority: high
|
|
8
|
+
* @complexity: low
|
|
9
|
+
* @dependencies: []
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Graph Health Monitor (TASK-013)
|
|
13
|
+
*
|
|
14
|
+
* Tracks graph operation metrics for reliability monitoring.
|
|
15
|
+
* Provides simple in-memory metrics for:
|
|
16
|
+
* - Event creation success/failure rates
|
|
17
|
+
* - Request latencies
|
|
18
|
+
* - Retry counts
|
|
19
|
+
*
|
|
20
|
+
* Future: Export to external monitoring (Datadog, New Relic, etc.)
|
|
21
|
+
*/
|
|
22
|
+
export interface GraphMetrics {
|
|
23
|
+
totalRequests: number;
|
|
24
|
+
successfulRequests: number;
|
|
25
|
+
failedRequests: number;
|
|
26
|
+
retryCount: number;
|
|
27
|
+
totalLatencyMs: number;
|
|
28
|
+
lastError?: {
|
|
29
|
+
timestamp: Date;
|
|
30
|
+
message: string;
|
|
31
|
+
operation: string;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
declare class GraphHealthMonitor {
|
|
35
|
+
private metrics;
|
|
36
|
+
/**
|
|
37
|
+
* Record a successful graph operation
|
|
38
|
+
*/
|
|
39
|
+
recordSuccess(latencyMs: number): void;
|
|
40
|
+
/**
|
|
41
|
+
* Record a failed graph operation
|
|
42
|
+
*/
|
|
43
|
+
recordFailure(operation: string, errorMessage: string): void;
|
|
44
|
+
/**
|
|
45
|
+
* Record a retry attempt
|
|
46
|
+
*/
|
|
47
|
+
recordRetry(): void;
|
|
48
|
+
/**
|
|
49
|
+
* Get current metrics
|
|
50
|
+
*/
|
|
51
|
+
getMetrics(): GraphMetrics;
|
|
52
|
+
/**
|
|
53
|
+
* Get success rate percentage
|
|
54
|
+
*/
|
|
55
|
+
getSuccessRate(): number;
|
|
56
|
+
/**
|
|
57
|
+
* Get average latency
|
|
58
|
+
*/
|
|
59
|
+
getAverageLatency(): number;
|
|
60
|
+
/**
|
|
61
|
+
* Check if graph health is good (target: 99.9% uptime)
|
|
62
|
+
*/
|
|
63
|
+
isHealthy(): boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Get health status summary
|
|
66
|
+
*/
|
|
67
|
+
getHealthSummary(): string;
|
|
68
|
+
/**
|
|
69
|
+
* Reset metrics (for testing)
|
|
70
|
+
*/
|
|
71
|
+
reset(): void;
|
|
72
|
+
}
|
|
73
|
+
export declare const graphHealthMonitor: GraphHealthMonitor;
|
|
74
|
+
export {};
|
|
75
|
+
//# sourceMappingURL=graph-health-monitor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph-health-monitor.d.ts","sourceRoot":"","sources":["../../src/utils/graph-health-monitor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;;;;;;;;GAUG;AAEH,MAAM,WAAW,YAAY;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE;QACV,SAAS,EAAE,IAAI,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED,cAAM,kBAAkB;IACtB,OAAO,CAAC,OAAO,CAMb;IAEF;;OAEG;IACH,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAMtC;;OAEG;IACH,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI;IAU5D;;OAEG;IACH,WAAW,IAAI,IAAI;IAInB;;OAEG;IACH,UAAU,IAAI,YAAY;IAI1B;;OAEG;IACH,cAAc,IAAI,MAAM;IAKxB;;OAEG;IACH,iBAAiB,IAAI,MAAM;IAK3B;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;OAEG;IACH,gBAAgB,IAAI,MAAM;IAmB1B;;OAEG;IACH,KAAK,IAAI,IAAI;CASd;AAGD,eAAO,MAAM,kBAAkB,oBAA2B,CAAC"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileType: utility
|
|
3
|
+
* @status: current
|
|
4
|
+
* @updated: 2025-11-21
|
|
5
|
+
* @tags: [monitoring, health-check, graph, reliability, task-013]
|
|
6
|
+
* @related: [../commands/graph/api-client.ts, event-logger.ts]
|
|
7
|
+
* @priority: high
|
|
8
|
+
* @complexity: low
|
|
9
|
+
* @dependencies: []
|
|
10
|
+
*/
|
|
11
|
+
class GraphHealthMonitor {
|
|
12
|
+
metrics = {
|
|
13
|
+
totalRequests: 0,
|
|
14
|
+
successfulRequests: 0,
|
|
15
|
+
failedRequests: 0,
|
|
16
|
+
retryCount: 0,
|
|
17
|
+
totalLatencyMs: 0,
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Record a successful graph operation
|
|
21
|
+
*/
|
|
22
|
+
recordSuccess(latencyMs) {
|
|
23
|
+
this.metrics.totalRequests++;
|
|
24
|
+
this.metrics.successfulRequests++;
|
|
25
|
+
this.metrics.totalLatencyMs += latencyMs;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Record a failed graph operation
|
|
29
|
+
*/
|
|
30
|
+
recordFailure(operation, errorMessage) {
|
|
31
|
+
this.metrics.totalRequests++;
|
|
32
|
+
this.metrics.failedRequests++;
|
|
33
|
+
this.metrics.lastError = {
|
|
34
|
+
timestamp: new Date(),
|
|
35
|
+
message: errorMessage,
|
|
36
|
+
operation,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Record a retry attempt
|
|
41
|
+
*/
|
|
42
|
+
recordRetry() {
|
|
43
|
+
this.metrics.retryCount++;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Get current metrics
|
|
47
|
+
*/
|
|
48
|
+
getMetrics() {
|
|
49
|
+
return { ...this.metrics };
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Get success rate percentage
|
|
53
|
+
*/
|
|
54
|
+
getSuccessRate() {
|
|
55
|
+
if (this.metrics.totalRequests === 0)
|
|
56
|
+
return 100;
|
|
57
|
+
return (this.metrics.successfulRequests / this.metrics.totalRequests) * 100;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Get average latency
|
|
61
|
+
*/
|
|
62
|
+
getAverageLatency() {
|
|
63
|
+
if (this.metrics.successfulRequests === 0)
|
|
64
|
+
return 0;
|
|
65
|
+
return this.metrics.totalLatencyMs / this.metrics.successfulRequests;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Check if graph health is good (target: 99.9% uptime)
|
|
69
|
+
*/
|
|
70
|
+
isHealthy() {
|
|
71
|
+
return this.getSuccessRate() >= 99.9;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Get health status summary
|
|
75
|
+
*/
|
|
76
|
+
getHealthSummary() {
|
|
77
|
+
const successRate = this.getSuccessRate();
|
|
78
|
+
const avgLatency = this.getAverageLatency();
|
|
79
|
+
const health = this.isHealthy() ? '✅ Healthy' : '⚠️ Degraded';
|
|
80
|
+
return `
|
|
81
|
+
Graph Health: ${health}
|
|
82
|
+
──────────────────────────────────────
|
|
83
|
+
Total Requests: ${this.metrics.totalRequests}
|
|
84
|
+
Successful: ${this.metrics.successfulRequests} (${successRate.toFixed(2)}%)
|
|
85
|
+
Failed: ${this.metrics.failedRequests}
|
|
86
|
+
Retries: ${this.metrics.retryCount}
|
|
87
|
+
Avg Latency: ${avgLatency.toFixed(0)}ms
|
|
88
|
+
──────────────────────────────────────
|
|
89
|
+
Target: 99.9% success rate
|
|
90
|
+
Status: ${successRate >= 99.9 ? '✅ Meeting target' : '⚠️ Below target'}
|
|
91
|
+
`;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Reset metrics (for testing)
|
|
95
|
+
*/
|
|
96
|
+
reset() {
|
|
97
|
+
this.metrics = {
|
|
98
|
+
totalRequests: 0,
|
|
99
|
+
successfulRequests: 0,
|
|
100
|
+
failedRequests: 0,
|
|
101
|
+
retryCount: 0,
|
|
102
|
+
totalLatencyMs: 0,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// Singleton instance
|
|
107
|
+
export const graphHealthMonitor = new GraphHealthMonitor();
|
|
108
|
+
//# sourceMappingURL=graph-health-monitor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph-health-monitor.js","sourceRoot":"","sources":["../../src/utils/graph-health-monitor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AA2BH,MAAM,kBAAkB;IACd,OAAO,GAAiB;QAC9B,aAAa,EAAE,CAAC;QAChB,kBAAkB,EAAE,CAAC;QACrB,cAAc,EAAE,CAAC;QACjB,UAAU,EAAE,CAAC;QACb,cAAc,EAAE,CAAC;KAClB,CAAC;IAEF;;OAEG;IACH,aAAa,CAAC,SAAiB;QAC7B,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;QAC7B,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,CAAC;QAClC,IAAI,CAAC,OAAO,CAAC,cAAc,IAAI,SAAS,CAAC;IAC3C,CAAC;IAED;;OAEG;IACH,aAAa,CAAC,SAAiB,EAAE,YAAoB;QACnD,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;QAC7B,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC;QAC9B,IAAI,CAAC,OAAO,CAAC,SAAS,GAAG;YACvB,SAAS,EAAE,IAAI,IAAI,EAAE;YACrB,OAAO,EAAE,YAAY;YACrB,SAAS;SACV,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,WAAW;QACT,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;IAC5B,CAAC;IAED;;OAEG;IACH,UAAU;QACR,OAAO,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,cAAc;QACZ,IAAI,IAAI,CAAC,OAAO,CAAC,aAAa,KAAK,CAAC;YAAE,OAAO,GAAG,CAAC;QACjD,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG,GAAG,CAAC;IAC9E,CAAC;IAED;;OAEG;IACH,iBAAiB;QACf,IAAI,IAAI,CAAC,OAAO,CAAC,kBAAkB,KAAK,CAAC;YAAE,OAAO,CAAC,CAAC;QACpD,OAAO,IAAI,CAAC,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC;IACvE,CAAC;IAED;;OAEG;IACH,SAAS;QACP,OAAO,IAAI,CAAC,cAAc,EAAE,IAAI,IAAI,CAAC;IACvC,CAAC;IAED;;OAEG;IACH,gBAAgB;QACd,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;QAC1C,MAAM,UAAU,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,cAAc,CAAC;QAE/D,OAAO;gBACK,MAAM;;qBAED,IAAI,CAAC,OAAO,CAAC,aAAa;qBAC1B,IAAI,CAAC,OAAO,CAAC,kBAAkB,KAAK,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;qBAC1D,IAAI,CAAC,OAAO,CAAC,cAAc;qBAC3B,IAAI,CAAC,OAAO,CAAC,UAAU;qBACvB,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;;;qBAGrB,WAAW,IAAI,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,kBAAkB;CACjF,CAAC;IACA,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,OAAO,GAAG;YACb,aAAa,EAAE,CAAC;YAChB,kBAAkB,EAAE,CAAC;YACrB,cAAc,EAAE,CAAC;YACjB,UAAU,EAAE,CAAC;YACb,cAAc,EAAE,CAAC;SAClB,CAAC;IACJ,CAAC;CACF;AAED,qBAAqB;AACrB,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,kBAAkB,EAAE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"synthesis.d.ts","sourceRoot":"","sources":["../../src/utils/synthesis.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,EAAqB,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAE7E;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;AAElE;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE;QACV,QAAQ,EAAE,MAAM,EAAE,CAAC;QACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;KACpB,CAAC;IACF,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,QAAQ,EAAE,QAAQ,EAAE,CAAC;IACrB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,WAAW,CAAC;IACzB,aAAa,EAAE,WAAW,CAAC;IAC3B,WAAW,EAAE,WAAW,CAAC;IACzB,aAAa,EAAE,aAAa,GAAG,IAAI,CAAC;IACpC,SAAS,EAAE,SAAS,CAAC;IACrB,WAAW,EAAE,WAAW,CAAC;IACzB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;;GAKG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,GAAG,CAAY;IACvB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,WAAW,CAAS;gBAEhB,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;IAMnD;;;;;;;;;OASG;WACU,oBAAoB,CAC/B,YAAY,EAAE,GAAG,EAAE,8CAA8C;IACjE,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,eAAe,CAAC;IA8D3B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,oBAAoB;
|
|
1
|
+
{"version":3,"file":"synthesis.d.ts","sourceRoot":"","sources":["../../src/utils/synthesis.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/synthesis.js
CHANGED
|
@@ -98,17 +98,24 @@ export class SessionSynthesizer {
|
|
|
98
98
|
const inProgress = [];
|
|
99
99
|
const blocked = [];
|
|
100
100
|
for (const entry of timeline) {
|
|
101
|
+
let categorized = false;
|
|
101
102
|
if (entry.category === 'achievement' || entry.category === 'fix') {
|
|
102
103
|
completed.push(entry.description);
|
|
104
|
+
categorized = true;
|
|
103
105
|
}
|
|
104
106
|
else if (entry.category === 'feature') {
|
|
105
107
|
inProgress.push(entry.description);
|
|
108
|
+
categorized = true;
|
|
106
109
|
}
|
|
107
|
-
// Check for blocked indicators
|
|
108
|
-
if
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
110
|
+
// Check for blocked indicators (smart detection)
|
|
111
|
+
// Skip if already categorized as completed/in-progress to avoid duplicates
|
|
112
|
+
if (!categorized) {
|
|
113
|
+
const blockingWords = /\b(block(s|ed|ing)?|stuck|waiting|can'?t proceed|impediment)\b/i;
|
|
114
|
+
const unblockingWords = /\b(unblock(s|ed|ing)?|resolv(e|ed|ing)?|fixed|completed?|solved?)\b/i;
|
|
115
|
+
if (blockingWords.test(entry.description) &&
|
|
116
|
+
!unblockingWords.test(entry.description)) {
|
|
117
|
+
blocked.push(entry.description);
|
|
118
|
+
}
|
|
112
119
|
}
|
|
113
120
|
}
|
|
114
121
|
return { completed, inProgress, blocked };
|
|
@@ -465,11 +472,12 @@ export class SessionSynthesizer {
|
|
|
465
472
|
}
|
|
466
473
|
}
|
|
467
474
|
}
|
|
468
|
-
// Extract blocked items (
|
|
475
|
+
// Extract blocked items (smart detection with word boundaries)
|
|
476
|
+
const blockingWords = /\b(block(s|ed|ing)?|stuck|waiting|can'?t proceed|impediment)\b/i;
|
|
477
|
+
const unblockingWords = /\b(unblock(s|ed|ing)?|resolv(e|ed|ing)?|fixed|completed?|solved?)\b/i;
|
|
469
478
|
for (const entry of timeline) {
|
|
470
|
-
if (entry.description
|
|
471
|
-
entry.description
|
|
472
|
-
entry.description.toLowerCase().includes('stuck')) {
|
|
479
|
+
if (blockingWords.test(entry.description) &&
|
|
480
|
+
!unblockingWords.test(entry.description)) {
|
|
473
481
|
blocked.push(entry.description);
|
|
474
482
|
}
|
|
475
483
|
}
|