wogiflow 1.0.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/.workflow/agents/reviewer.md +81 -0
- package/.workflow/agents/security.md +94 -0
- package/.workflow/agents/story-writer.md +58 -0
- package/.workflow/bridges/base-bridge.js +395 -0
- package/.workflow/bridges/claude-bridge.js +434 -0
- package/.workflow/bridges/index.js +130 -0
- package/.workflow/lib/assumption-detector.js +481 -0
- package/.workflow/lib/config-substitution.js +371 -0
- package/.workflow/lib/failure-categories.js +478 -0
- package/.workflow/state/app-map.md.template +15 -0
- package/.workflow/state/architecture.md.template +24 -0
- package/.workflow/state/component-index.json.template +5 -0
- package/.workflow/state/decisions.md.template +15 -0
- package/.workflow/state/feedback-patterns.md.template +9 -0
- package/.workflow/state/knowledge-sync.json.template +6 -0
- package/.workflow/state/progress.md.template +14 -0
- package/.workflow/state/ready.json.template +7 -0
- package/.workflow/state/request-log.md.template +14 -0
- package/.workflow/state/session-state.json.template +11 -0
- package/.workflow/state/stack.md.template +33 -0
- package/.workflow/state/testing.md.template +36 -0
- package/.workflow/templates/claude-md.hbs +257 -0
- package/.workflow/templates/correction-report.md +67 -0
- package/.workflow/templates/gemini-md.hbs +52 -0
- package/README.md +1802 -0
- package/bin/flow +205 -0
- package/lib/index.js +33 -0
- package/lib/installer.js +467 -0
- package/lib/release-channel.js +269 -0
- package/lib/skill-registry.js +526 -0
- package/lib/upgrader.js +401 -0
- package/lib/utils.js +305 -0
- package/package.json +64 -0
- package/scripts/flow +985 -0
- package/scripts/flow-adaptive-learning.js +1259 -0
- package/scripts/flow-aggregate.js +488 -0
- package/scripts/flow-archive +133 -0
- package/scripts/flow-auto-context.js +1015 -0
- package/scripts/flow-auto-learn.js +615 -0
- package/scripts/flow-bridge.js +223 -0
- package/scripts/flow-browser-suggest.js +316 -0
- package/scripts/flow-bug.js +247 -0
- package/scripts/flow-cascade.js +711 -0
- package/scripts/flow-changelog +85 -0
- package/scripts/flow-checkpoint.js +483 -0
- package/scripts/flow-cli.js +403 -0
- package/scripts/flow-code-intelligence.js +760 -0
- package/scripts/flow-complexity.js +502 -0
- package/scripts/flow-config-set.js +152 -0
- package/scripts/flow-constants.js +157 -0
- package/scripts/flow-context +152 -0
- package/scripts/flow-context-init.js +482 -0
- package/scripts/flow-context-monitor.js +384 -0
- package/scripts/flow-context-scoring.js +886 -0
- package/scripts/flow-correct.js +458 -0
- package/scripts/flow-damage-control.js +985 -0
- package/scripts/flow-deps +101 -0
- package/scripts/flow-diff.js +700 -0
- package/scripts/flow-done +151 -0
- package/scripts/flow-done.js +489 -0
- package/scripts/flow-durable-session.js +1541 -0
- package/scripts/flow-entropy-monitor.js +345 -0
- package/scripts/flow-export-profile +349 -0
- package/scripts/flow-export-scanner.js +1046 -0
- package/scripts/flow-figma-confirm.js +400 -0
- package/scripts/flow-figma-extract.js +496 -0
- package/scripts/flow-figma-generate.js +683 -0
- package/scripts/flow-figma-index.js +909 -0
- package/scripts/flow-figma-match.js +617 -0
- package/scripts/flow-figma-mcp-server.js +518 -0
- package/scripts/flow-figma-pipeline.js +414 -0
- package/scripts/flow-file-ops.js +301 -0
- package/scripts/flow-gate-confidence.js +825 -0
- package/scripts/flow-guided-edit.js +659 -0
- package/scripts/flow-health +185 -0
- package/scripts/flow-health.js +413 -0
- package/scripts/flow-hooks.js +556 -0
- package/scripts/flow-http-client.js +249 -0
- package/scripts/flow-hybrid-detect.js +167 -0
- package/scripts/flow-hybrid-interactive.js +591 -0
- package/scripts/flow-hybrid-test.js +152 -0
- package/scripts/flow-import-profile +439 -0
- package/scripts/flow-init +253 -0
- package/scripts/flow-instruction-richness.js +827 -0
- package/scripts/flow-jira-integration.js +579 -0
- package/scripts/flow-knowledge-router.js +522 -0
- package/scripts/flow-knowledge-sync.js +589 -0
- package/scripts/flow-linear-integration.js +631 -0
- package/scripts/flow-links.js +774 -0
- package/scripts/flow-log-manager.js +559 -0
- package/scripts/flow-loop-enforcer.js +1246 -0
- package/scripts/flow-loop-retry-learning.js +630 -0
- package/scripts/flow-lsp.js +923 -0
- package/scripts/flow-map-index +348 -0
- package/scripts/flow-map-sync +201 -0
- package/scripts/flow-memory-blocks.js +668 -0
- package/scripts/flow-memory-compactor.js +350 -0
- package/scripts/flow-memory-db.js +1110 -0
- package/scripts/flow-memory-sync.js +484 -0
- package/scripts/flow-metrics.js +353 -0
- package/scripts/flow-migrate-ids.js +370 -0
- package/scripts/flow-model-adapter.js +802 -0
- package/scripts/flow-model-router.js +884 -0
- package/scripts/flow-models.js +1231 -0
- package/scripts/flow-morning.js +517 -0
- package/scripts/flow-multi-approach.js +660 -0
- package/scripts/flow-new-feature +86 -0
- package/scripts/flow-onboard +1042 -0
- package/scripts/flow-orchestrate-llm.js +459 -0
- package/scripts/flow-orchestrate.js +3592 -0
- package/scripts/flow-output.js +123 -0
- package/scripts/flow-parallel-detector.js +399 -0
- package/scripts/flow-parallel-dispatch.js +987 -0
- package/scripts/flow-parallel.js +428 -0
- package/scripts/flow-pattern-enforcer.js +600 -0
- package/scripts/flow-prd-manager.js +282 -0
- package/scripts/flow-progress.js +323 -0
- package/scripts/flow-project-analyzer.js +975 -0
- package/scripts/flow-prompt-composer.js +487 -0
- package/scripts/flow-providers.js +1381 -0
- package/scripts/flow-queue.js +308 -0
- package/scripts/flow-ready +82 -0
- package/scripts/flow-ready.js +189 -0
- package/scripts/flow-regression.js +396 -0
- package/scripts/flow-response-parser.js +450 -0
- package/scripts/flow-resume.js +284 -0
- package/scripts/flow-rules-sync.js +439 -0
- package/scripts/flow-run-trace.js +718 -0
- package/scripts/flow-safety.js +587 -0
- package/scripts/flow-search +104 -0
- package/scripts/flow-security.js +481 -0
- package/scripts/flow-session-end +106 -0
- package/scripts/flow-session-end.js +437 -0
- package/scripts/flow-session-state.js +671 -0
- package/scripts/flow-setup-hooks +216 -0
- package/scripts/flow-setup-hooks.js +377 -0
- package/scripts/flow-skill-create.js +329 -0
- package/scripts/flow-skill-creator.js +572 -0
- package/scripts/flow-skill-generator.js +1046 -0
- package/scripts/flow-skill-learn.js +880 -0
- package/scripts/flow-skill-matcher.js +578 -0
- package/scripts/flow-spec-generator.js +820 -0
- package/scripts/flow-stack-wizard.js +895 -0
- package/scripts/flow-standup +162 -0
- package/scripts/flow-start +74 -0
- package/scripts/flow-start.js +235 -0
- package/scripts/flow-status +110 -0
- package/scripts/flow-status.js +301 -0
- package/scripts/flow-step-browser.js +83 -0
- package/scripts/flow-step-changelog.js +217 -0
- package/scripts/flow-step-comments.js +306 -0
- package/scripts/flow-step-complexity.js +234 -0
- package/scripts/flow-step-coverage.js +218 -0
- package/scripts/flow-step-knowledge.js +193 -0
- package/scripts/flow-step-pr-tests.js +364 -0
- package/scripts/flow-step-regression.js +89 -0
- package/scripts/flow-step-review.js +516 -0
- package/scripts/flow-step-security.js +162 -0
- package/scripts/flow-step-silent-failures.js +290 -0
- package/scripts/flow-step-simplifier.js +346 -0
- package/scripts/flow-story +105 -0
- package/scripts/flow-story.js +500 -0
- package/scripts/flow-suspend.js +252 -0
- package/scripts/flow-sync-daemon.js +654 -0
- package/scripts/flow-task-analyzer.js +606 -0
- package/scripts/flow-team-dashboard.js +748 -0
- package/scripts/flow-team-sync.js +752 -0
- package/scripts/flow-team.js +977 -0
- package/scripts/flow-tech-options.js +528 -0
- package/scripts/flow-templates.js +812 -0
- package/scripts/flow-tiered-learning.js +728 -0
- package/scripts/flow-trace +204 -0
- package/scripts/flow-transcript-chunking.js +1106 -0
- package/scripts/flow-transcript-digest.js +7918 -0
- package/scripts/flow-transcript-language.js +465 -0
- package/scripts/flow-transcript-parsing.js +1085 -0
- package/scripts/flow-transcript-stories.js +2194 -0
- package/scripts/flow-update-map +224 -0
- package/scripts/flow-utils.js +2242 -0
- package/scripts/flow-verification.js +644 -0
- package/scripts/flow-verify.js +1177 -0
- package/scripts/flow-voice-input.js +638 -0
- package/scripts/flow-watch +168 -0
- package/scripts/flow-workflow-steps.js +521 -0
- package/scripts/flow-workflow.js +1029 -0
- package/scripts/flow-worktree.js +489 -0
- package/scripts/hooks/adapters/base-adapter.js +102 -0
- package/scripts/hooks/adapters/claude-code.js +359 -0
- package/scripts/hooks/adapters/index.js +79 -0
- package/scripts/hooks/core/component-check.js +341 -0
- package/scripts/hooks/core/index.js +35 -0
- package/scripts/hooks/core/loop-check.js +241 -0
- package/scripts/hooks/core/session-context.js +294 -0
- package/scripts/hooks/core/task-gate.js +177 -0
- package/scripts/hooks/core/validation.js +230 -0
- package/scripts/hooks/entry/claude-code/post-tool-use.js +65 -0
- package/scripts/hooks/entry/claude-code/pre-tool-use.js +89 -0
- package/scripts/hooks/entry/claude-code/session-end.js +87 -0
- package/scripts/hooks/entry/claude-code/session-start.js +46 -0
- package/scripts/hooks/entry/claude-code/stop.js +43 -0
- package/scripts/postinstall.js +139 -0
- package/templates/browser-test-flow.json +56 -0
- package/templates/bug-report.md +43 -0
- package/templates/component-detail.md +42 -0
- package/templates/component.stories.tsx +49 -0
- package/templates/context/constraints.md +83 -0
- package/templates/context/conventions.md +177 -0
- package/templates/context/stack.md +60 -0
- package/templates/correction-report.md +90 -0
- package/templates/feature-proposal.md +35 -0
- package/templates/hybrid/_base.md +254 -0
- package/templates/hybrid/_patterns.md +45 -0
- package/templates/hybrid/create-component.md +127 -0
- package/templates/hybrid/create-file.md +56 -0
- package/templates/hybrid/create-hook.md +145 -0
- package/templates/hybrid/create-service.md +70 -0
- package/templates/hybrid/fix-bug.md +33 -0
- package/templates/hybrid/modify-file.md +55 -0
- package/templates/story.md +68 -0
- package/templates/task.json +56 -0
- package/templates/trace.md +69 -0
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Wogi Flow - Context Monitor
|
|
5
|
+
*
|
|
6
|
+
* Monitors estimated context usage and triggers warnings/prompts
|
|
7
|
+
* at configurable thresholds. Helps prevent context overflow.
|
|
8
|
+
*
|
|
9
|
+
* Part of v1.7.0 Context Memory Management
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const fs = require('fs');
|
|
13
|
+
const path = require('path');
|
|
14
|
+
const {
|
|
15
|
+
getConfig,
|
|
16
|
+
PATHS,
|
|
17
|
+
STATE_DIR,
|
|
18
|
+
PROJECT_ROOT,
|
|
19
|
+
colors,
|
|
20
|
+
color,
|
|
21
|
+
warn,
|
|
22
|
+
success,
|
|
23
|
+
readFile,
|
|
24
|
+
fileExists,
|
|
25
|
+
printHeader
|
|
26
|
+
} = require('./flow-utils');
|
|
27
|
+
|
|
28
|
+
// ============================================================
|
|
29
|
+
// Token Estimation
|
|
30
|
+
// ============================================================
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Estimate tokens from text
|
|
34
|
+
* Uses different ratios for prose vs code content:
|
|
35
|
+
* - Prose: ~4 chars = 1 token
|
|
36
|
+
* - Code: ~3 chars = 1 token (more token-dense)
|
|
37
|
+
*/
|
|
38
|
+
function estimateTokens(text, isCode = false) {
|
|
39
|
+
if (!text) return 0;
|
|
40
|
+
// Code is more token-dense due to keywords, punctuation, short variable names
|
|
41
|
+
const charsPerToken = isCode ? 3 : 4;
|
|
42
|
+
return Math.ceil(text.length / charsPerToken);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Detect if content is primarily code (for token estimation)
|
|
47
|
+
*/
|
|
48
|
+
function isCodeContent(content) {
|
|
49
|
+
if (!content || content.length < 100) return false;
|
|
50
|
+
// Simple heuristics: code has more brackets, semicolons, imports
|
|
51
|
+
const codeIndicators = (content.match(/[{}\[\]();=]/g) || []).length;
|
|
52
|
+
const ratio = codeIndicators / content.length;
|
|
53
|
+
return ratio > 0.03; // More than 3% is likely code
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Estimate tokens for a file
|
|
58
|
+
*/
|
|
59
|
+
function estimateFileTokens(filePath) {
|
|
60
|
+
try {
|
|
61
|
+
if (!fileExists(filePath)) return 0;
|
|
62
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
63
|
+
// Use code estimation for code files
|
|
64
|
+
const isCode = /\.(js|ts|jsx|tsx|json|css|scss)$/.test(filePath) || isCodeContent(content);
|
|
65
|
+
return estimateTokens(content, isCode);
|
|
66
|
+
} catch {
|
|
67
|
+
return 0;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// ============================================================
|
|
72
|
+
// Context Size Calculation
|
|
73
|
+
// ============================================================
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Get current context size from all state files
|
|
77
|
+
* Returns breakdown by file and total
|
|
78
|
+
*/
|
|
79
|
+
function getContextBreakdown() {
|
|
80
|
+
const files = {
|
|
81
|
+
'progress.md': PATHS.progress,
|
|
82
|
+
'request-log.md': PATHS.requestLog,
|
|
83
|
+
'decisions.md': PATHS.decisions,
|
|
84
|
+
'app-map.md': PATHS.appMap,
|
|
85
|
+
'feedback-patterns.md': PATHS.feedbackPatterns,
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const breakdown = {};
|
|
89
|
+
let total = 0;
|
|
90
|
+
|
|
91
|
+
for (const [name, filePath] of Object.entries(files)) {
|
|
92
|
+
const tokens = estimateFileTokens(filePath);
|
|
93
|
+
breakdown[name] = tokens;
|
|
94
|
+
total += tokens;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Also check component detail files
|
|
98
|
+
const componentsDir = PATHS.components;
|
|
99
|
+
let componentTokens = 0;
|
|
100
|
+
if (fs.existsSync(componentsDir)) {
|
|
101
|
+
try {
|
|
102
|
+
const componentFiles = fs.readdirSync(componentsDir)
|
|
103
|
+
.filter(f => f.endsWith('.md'));
|
|
104
|
+
for (const file of componentFiles) {
|
|
105
|
+
componentTokens += estimateFileTokens(path.join(componentsDir, file));
|
|
106
|
+
}
|
|
107
|
+
} catch {
|
|
108
|
+
// Ignore errors
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
breakdown['components/'] = componentTokens;
|
|
112
|
+
total += componentTokens;
|
|
113
|
+
|
|
114
|
+
return { breakdown, total };
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Get total current context size in tokens
|
|
119
|
+
*/
|
|
120
|
+
function getCurrentContextSize() {
|
|
121
|
+
return getContextBreakdown().total;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// ============================================================
|
|
125
|
+
// Health Check
|
|
126
|
+
// ============================================================
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Default configuration values
|
|
130
|
+
*/
|
|
131
|
+
const DEFAULTS = {
|
|
132
|
+
enabled: true,
|
|
133
|
+
warnAt: 0.7, // 70% - warning threshold
|
|
134
|
+
criticalAt: 0.85, // 85% - critical threshold
|
|
135
|
+
contextWindow: 200000, // Claude's context window
|
|
136
|
+
checkOnSessionStart: true,
|
|
137
|
+
checkAfterTask: true
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Get context monitor configuration
|
|
142
|
+
*/
|
|
143
|
+
function getContextMonitorConfig() {
|
|
144
|
+
const config = getConfig();
|
|
145
|
+
return {
|
|
146
|
+
...DEFAULTS,
|
|
147
|
+
...(config.contextMonitor || {})
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Check context health and return status
|
|
153
|
+
*/
|
|
154
|
+
function checkContextHealth() {
|
|
155
|
+
const config = getContextMonitorConfig();
|
|
156
|
+
|
|
157
|
+
if (!config.enabled) {
|
|
158
|
+
return {
|
|
159
|
+
status: 'disabled',
|
|
160
|
+
currentTokens: 0,
|
|
161
|
+
contextWindow: config.contextWindow,
|
|
162
|
+
usage: 0,
|
|
163
|
+
recommendation: null
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const { breakdown, total } = getContextBreakdown();
|
|
168
|
+
const usage = total / config.contextWindow;
|
|
169
|
+
|
|
170
|
+
let status, recommendation;
|
|
171
|
+
|
|
172
|
+
if (usage >= config.criticalAt) {
|
|
173
|
+
status = 'critical';
|
|
174
|
+
recommendation = 'Run /compact NOW to avoid context overflow';
|
|
175
|
+
} else if (usage >= config.warnAt) {
|
|
176
|
+
status = 'warning';
|
|
177
|
+
recommendation = 'Consider running /compact soon';
|
|
178
|
+
} else {
|
|
179
|
+
status = 'healthy';
|
|
180
|
+
recommendation = null;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return {
|
|
184
|
+
status,
|
|
185
|
+
currentTokens: total,
|
|
186
|
+
contextWindow: config.contextWindow,
|
|
187
|
+
usage,
|
|
188
|
+
usagePercent: Math.round(usage * 100),
|
|
189
|
+
recommendation,
|
|
190
|
+
breakdown,
|
|
191
|
+
thresholds: {
|
|
192
|
+
warn: config.warnAt,
|
|
193
|
+
critical: config.criticalAt
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// ============================================================
|
|
199
|
+
// Warning Display
|
|
200
|
+
// ============================================================
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Display context health warning if needed
|
|
204
|
+
* Returns true if critical warning was shown
|
|
205
|
+
*/
|
|
206
|
+
function warnIfContextHigh() {
|
|
207
|
+
const health = checkContextHealth();
|
|
208
|
+
|
|
209
|
+
if (health.status === 'disabled') {
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (health.status === 'critical') {
|
|
214
|
+
console.log('');
|
|
215
|
+
console.log(color('bgRed', color('white', ' CRITICAL ')));
|
|
216
|
+
console.log(color('red', `Context at ${health.usagePercent}% (${health.currentTokens.toLocaleString()} tokens)`));
|
|
217
|
+
console.log(color('red', health.recommendation));
|
|
218
|
+
console.log('');
|
|
219
|
+
return true;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
if (health.status === 'warning') {
|
|
223
|
+
console.log('');
|
|
224
|
+
console.log(color('yellow', `Context at ${health.usagePercent}% - ${health.recommendation}`));
|
|
225
|
+
console.log('');
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return false;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Display detailed context breakdown
|
|
233
|
+
*/
|
|
234
|
+
function showContextBreakdown() {
|
|
235
|
+
const health = checkContextHealth();
|
|
236
|
+
|
|
237
|
+
printHeader('Context Usage');
|
|
238
|
+
|
|
239
|
+
// Status indicator
|
|
240
|
+
const statusColors = {
|
|
241
|
+
healthy: 'green',
|
|
242
|
+
warning: 'yellow',
|
|
243
|
+
critical: 'red',
|
|
244
|
+
disabled: 'dim'
|
|
245
|
+
};
|
|
246
|
+
const statusColor = statusColors[health.status] || 'white';
|
|
247
|
+
console.log(`Status: ${color(statusColor, health.status.toUpperCase())}`);
|
|
248
|
+
console.log('');
|
|
249
|
+
|
|
250
|
+
// Progress bar
|
|
251
|
+
const barWidth = 40;
|
|
252
|
+
const filled = Math.min(Math.round(health.usage * barWidth), barWidth);
|
|
253
|
+
const bar = '█'.repeat(filled) + '░'.repeat(barWidth - filled);
|
|
254
|
+
console.log(`[${color(statusColor, bar)}] ${health.usagePercent}%`);
|
|
255
|
+
console.log(`${health.currentTokens.toLocaleString()} / ${health.contextWindow.toLocaleString()} tokens`);
|
|
256
|
+
console.log('');
|
|
257
|
+
|
|
258
|
+
// Breakdown
|
|
259
|
+
console.log(color('cyan', 'Breakdown:'));
|
|
260
|
+
const sortedBreakdown = Object.entries(health.breakdown)
|
|
261
|
+
.sort((a, b) => b[1] - a[1]);
|
|
262
|
+
|
|
263
|
+
for (const [file, tokens] of sortedBreakdown) {
|
|
264
|
+
if (tokens > 0) {
|
|
265
|
+
const percent = Math.round((tokens / health.currentTokens) * 100);
|
|
266
|
+
console.log(` ${file.padEnd(25)} ${tokens.toLocaleString().padStart(8)} tokens (${percent}%)`);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
console.log('');
|
|
270
|
+
|
|
271
|
+
// Thresholds
|
|
272
|
+
console.log(color('dim', `Thresholds: warn=${Math.round(health.thresholds.warn * 100)}%, critical=${Math.round(health.thresholds.critical * 100)}%`));
|
|
273
|
+
|
|
274
|
+
// Recommendation
|
|
275
|
+
if (health.recommendation) {
|
|
276
|
+
console.log('');
|
|
277
|
+
console.log(color(statusColor, health.recommendation));
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Get a brief status line for inline display
|
|
283
|
+
*/
|
|
284
|
+
function getStatusLine() {
|
|
285
|
+
const health = checkContextHealth();
|
|
286
|
+
|
|
287
|
+
if (health.status === 'disabled') {
|
|
288
|
+
return null;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
const icon = health.status === 'healthy' ? '●' :
|
|
292
|
+
health.status === 'warning' ? '◐' : '○';
|
|
293
|
+
const colorName = health.status === 'healthy' ? 'green' :
|
|
294
|
+
health.status === 'warning' ? 'yellow' : 'red';
|
|
295
|
+
|
|
296
|
+
return color(colorName, `${icon} Context: ${health.usagePercent}%`);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// ============================================================
|
|
300
|
+
// CLI Interface
|
|
301
|
+
// ============================================================
|
|
302
|
+
|
|
303
|
+
function printUsage() {
|
|
304
|
+
console.log(`
|
|
305
|
+
Usage: flow-context-monitor.js [command]
|
|
306
|
+
|
|
307
|
+
Commands:
|
|
308
|
+
check Check context health and show warnings
|
|
309
|
+
breakdown Show detailed context breakdown
|
|
310
|
+
status Show brief status line
|
|
311
|
+
--help Show this help
|
|
312
|
+
|
|
313
|
+
Examples:
|
|
314
|
+
node scripts/flow-context-monitor.js check
|
|
315
|
+
node scripts/flow-context-monitor.js breakdown
|
|
316
|
+
`);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// Main CLI handler
|
|
320
|
+
if (require.main === module) {
|
|
321
|
+
const args = process.argv.slice(2);
|
|
322
|
+
const command = args[0] || 'check';
|
|
323
|
+
|
|
324
|
+
switch (command) {
|
|
325
|
+
case 'check':
|
|
326
|
+
const critical = warnIfContextHigh();
|
|
327
|
+
if (!critical) {
|
|
328
|
+
const health = checkContextHealth();
|
|
329
|
+
if (health.status === 'healthy') {
|
|
330
|
+
success(`Context healthy (${health.usagePercent}%)`);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
break;
|
|
334
|
+
|
|
335
|
+
case 'breakdown':
|
|
336
|
+
showContextBreakdown();
|
|
337
|
+
break;
|
|
338
|
+
|
|
339
|
+
case 'status':
|
|
340
|
+
const line = getStatusLine();
|
|
341
|
+
if (line) {
|
|
342
|
+
console.log(line);
|
|
343
|
+
} else {
|
|
344
|
+
console.log('Context monitor disabled');
|
|
345
|
+
}
|
|
346
|
+
break;
|
|
347
|
+
|
|
348
|
+
case '--help':
|
|
349
|
+
case '-h':
|
|
350
|
+
printUsage();
|
|
351
|
+
break;
|
|
352
|
+
|
|
353
|
+
default:
|
|
354
|
+
console.error(`Unknown command: ${command}`);
|
|
355
|
+
printUsage();
|
|
356
|
+
process.exit(1);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
// ============================================================
|
|
361
|
+
// Exports
|
|
362
|
+
// ============================================================
|
|
363
|
+
|
|
364
|
+
module.exports = {
|
|
365
|
+
// Token estimation
|
|
366
|
+
estimateTokens,
|
|
367
|
+
estimateFileTokens,
|
|
368
|
+
|
|
369
|
+
// Context size
|
|
370
|
+
getContextBreakdown,
|
|
371
|
+
getCurrentContextSize,
|
|
372
|
+
|
|
373
|
+
// Health check
|
|
374
|
+
checkContextHealth,
|
|
375
|
+
getContextMonitorConfig,
|
|
376
|
+
|
|
377
|
+
// Warnings
|
|
378
|
+
warnIfContextHigh,
|
|
379
|
+
showContextBreakdown,
|
|
380
|
+
getStatusLine,
|
|
381
|
+
|
|
382
|
+
// Constants
|
|
383
|
+
DEFAULTS
|
|
384
|
+
};
|