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,350 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Wogi Flow - Memory Compactor
|
|
5
|
+
*
|
|
6
|
+
* Manages memory compaction: demotion, cold storage, merging, and purging.
|
|
7
|
+
*
|
|
8
|
+
* Commands:
|
|
9
|
+
* ./scripts/flow compact-memory - Full compaction
|
|
10
|
+
* ./scripts/flow compact-memory --demote - Only demote low-relevance facts
|
|
11
|
+
* ./scripts/flow compact-memory --merge - Only merge duplicates
|
|
12
|
+
* ./scripts/flow compact-memory --purge - Only purge old cold facts
|
|
13
|
+
* ./scripts/flow compact-memory --restore <id> - Restore from cold storage
|
|
14
|
+
* ./scripts/flow compact-memory --cold - List cold storage contents
|
|
15
|
+
*
|
|
16
|
+
* Part of v1.8.0 - Automatic Memory Management
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
const fs = require('fs');
|
|
20
|
+
const path = require('path');
|
|
21
|
+
const memoryDb = require('./flow-memory-db');
|
|
22
|
+
|
|
23
|
+
// ============================================================
|
|
24
|
+
// Configuration
|
|
25
|
+
// ============================================================
|
|
26
|
+
|
|
27
|
+
const PROJECT_ROOT = process.env.WOGI_PROJECT_ROOT || process.cwd();
|
|
28
|
+
const CONFIG_PATH = path.join(PROJECT_ROOT, '.workflow', 'config.json');
|
|
29
|
+
|
|
30
|
+
function loadConfig() {
|
|
31
|
+
try {
|
|
32
|
+
if (fs.existsSync(CONFIG_PATH)) {
|
|
33
|
+
return JSON.parse(fs.readFileSync(CONFIG_PATH, 'utf-8'));
|
|
34
|
+
}
|
|
35
|
+
} catch {}
|
|
36
|
+
return {};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// ============================================================
|
|
40
|
+
// Output Formatting
|
|
41
|
+
// ============================================================
|
|
42
|
+
|
|
43
|
+
function color(c, text) {
|
|
44
|
+
const colors = {
|
|
45
|
+
red: '\x1b[31m',
|
|
46
|
+
green: '\x1b[32m',
|
|
47
|
+
yellow: '\x1b[33m',
|
|
48
|
+
blue: '\x1b[34m',
|
|
49
|
+
cyan: '\x1b[36m',
|
|
50
|
+
gray: '\x1b[90m',
|
|
51
|
+
reset: '\x1b[0m'
|
|
52
|
+
};
|
|
53
|
+
return `${colors[c] || ''}${text}${colors.reset}`;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function formatEntropy(entropy) {
|
|
57
|
+
if (entropy < 0.4) return color('green', `${entropy}`);
|
|
58
|
+
if (entropy < 0.7) return color('yellow', `${entropy}`);
|
|
59
|
+
return color('red', `${entropy}`);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// ============================================================
|
|
63
|
+
// Commands
|
|
64
|
+
// ============================================================
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Full compaction - all operations
|
|
68
|
+
*/
|
|
69
|
+
async function fullCompaction(config) {
|
|
70
|
+
console.log(color('cyan', '\nMemory Compaction'));
|
|
71
|
+
console.log('═'.repeat(50));
|
|
72
|
+
|
|
73
|
+
const memoryConfig = { maxLocalFacts: config.memory?.maxLocalFacts || 1000 };
|
|
74
|
+
const beforeStats = await memoryDb.getEntropyStats(memoryConfig);
|
|
75
|
+
|
|
76
|
+
console.log(`\nBefore: ${beforeStats.totalFacts} facts | Entropy: ${formatEntropy(beforeStats.entropy)}`);
|
|
77
|
+
|
|
78
|
+
const results = {};
|
|
79
|
+
|
|
80
|
+
// 1. Apply relevance decay
|
|
81
|
+
console.log(`\n${color('blue', '1. Applying relevance decay...')}`);
|
|
82
|
+
results.decay = await memoryDb.applyRelevanceDecay({
|
|
83
|
+
decayRate: config.automaticMemory?.relevanceDecay?.decayRate || 0.033,
|
|
84
|
+
neverAccessedPenalty: config.automaticMemory?.relevanceDecay?.neverAccessedPenalty || 0.1
|
|
85
|
+
});
|
|
86
|
+
console.log(` ${color('green', '✓')} Updated ${results.decay.decayed} facts`);
|
|
87
|
+
|
|
88
|
+
// 2. Demote low-relevance facts
|
|
89
|
+
console.log(`\n${color('blue', '2. Demoting low-relevance facts...')}`);
|
|
90
|
+
results.demotion = await memoryDb.demoteToColdStorage({
|
|
91
|
+
relevanceThreshold: config.automaticMemory?.demotion?.relevanceThreshold || 0.3
|
|
92
|
+
});
|
|
93
|
+
console.log(` ${color('green', '✓')} Demoted ${results.demotion.demoted} facts to cold storage`);
|
|
94
|
+
|
|
95
|
+
// 3. Merge similar facts
|
|
96
|
+
console.log(`\n${color('blue', '3. Merging duplicate facts...')}`);
|
|
97
|
+
results.merge = await memoryDb.mergeSimilarFacts({
|
|
98
|
+
mergeSimilarityThreshold: 0.95
|
|
99
|
+
});
|
|
100
|
+
console.log(` ${color('green', '✓')} Merged ${results.merge.merged} duplicate pairs`);
|
|
101
|
+
|
|
102
|
+
// 4. Purge old cold facts
|
|
103
|
+
console.log(`\n${color('blue', '4. Purging old cold storage...')}`);
|
|
104
|
+
results.purge = await memoryDb.purgeColdFacts({
|
|
105
|
+
coldRetentionDays: config.automaticMemory?.demotion?.coldRetentionDays || 90
|
|
106
|
+
});
|
|
107
|
+
console.log(` ${color('green', '✓')} Purged ${results.purge.purged} old facts`);
|
|
108
|
+
|
|
109
|
+
// Record metric
|
|
110
|
+
await memoryDb.recordMemoryMetric('full_compact');
|
|
111
|
+
|
|
112
|
+
// Final stats
|
|
113
|
+
const afterStats = await memoryDb.getEntropyStats(memoryConfig);
|
|
114
|
+
|
|
115
|
+
console.log(color('cyan', '\n═══════════════════════════════════════════════════'));
|
|
116
|
+
console.log(color('cyan', 'Summary'));
|
|
117
|
+
console.log('═'.repeat(50));
|
|
118
|
+
|
|
119
|
+
console.log(`\nActive Facts: ${beforeStats.totalFacts} → ${afterStats.totalFacts}`);
|
|
120
|
+
console.log(`Cold Storage: ${beforeStats.coldFacts} → ${afterStats.coldFacts}`);
|
|
121
|
+
console.log(`Entropy: ${formatEntropy(beforeStats.entropy)} → ${formatEntropy(afterStats.entropy)}`);
|
|
122
|
+
console.log(`Avg Relevance: ${Math.round(beforeStats.avgRelevance * 100)}% → ${Math.round(afterStats.avgRelevance * 100)}%`);
|
|
123
|
+
|
|
124
|
+
console.log(color('green', '\n✓ Compaction complete\n'));
|
|
125
|
+
|
|
126
|
+
return { before: beforeStats, after: afterStats, results };
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Demote only
|
|
131
|
+
*/
|
|
132
|
+
async function demoteOnly(config) {
|
|
133
|
+
console.log(color('cyan', '\nDemoting Low-Relevance Facts'));
|
|
134
|
+
console.log('═'.repeat(50));
|
|
135
|
+
|
|
136
|
+
const threshold = config.automaticMemory?.demotion?.relevanceThreshold || 0.3;
|
|
137
|
+
console.log(`Threshold: ${Math.round(threshold * 100)}% relevance\n`);
|
|
138
|
+
|
|
139
|
+
const result = await memoryDb.demoteToColdStorage({ relevanceThreshold: threshold });
|
|
140
|
+
|
|
141
|
+
if (result.demoted === 0) {
|
|
142
|
+
console.log(color('green', '✓ No facts below threshold - nothing to demote\n'));
|
|
143
|
+
} else {
|
|
144
|
+
console.log(color('green', `✓ Demoted ${result.demoted} facts to cold storage\n`));
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
await memoryDb.recordMemoryMetric('demote');
|
|
148
|
+
|
|
149
|
+
return result;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Merge only
|
|
154
|
+
*/
|
|
155
|
+
async function mergeOnly() {
|
|
156
|
+
console.log(color('cyan', '\nMerging Duplicate Facts'));
|
|
157
|
+
console.log('═'.repeat(50));
|
|
158
|
+
|
|
159
|
+
console.log('Similarity threshold: 95%\n');
|
|
160
|
+
|
|
161
|
+
const result = await memoryDb.mergeSimilarFacts({ mergeSimilarityThreshold: 0.95 });
|
|
162
|
+
|
|
163
|
+
if (result.merged === 0) {
|
|
164
|
+
console.log(color('green', '✓ No duplicates found\n'));
|
|
165
|
+
} else {
|
|
166
|
+
console.log(color('green', `✓ Merged ${result.merged} duplicate pairs\n`));
|
|
167
|
+
|
|
168
|
+
if (result.details.length > 0 && result.details.length <= 10) {
|
|
169
|
+
console.log('Details:');
|
|
170
|
+
for (const d of result.details) {
|
|
171
|
+
console.log(` Kept: ${d.kept.substring(0, 20)}... | Deleted: ${d.deleted.substring(0, 20)}...`);
|
|
172
|
+
}
|
|
173
|
+
console.log('');
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
await memoryDb.recordMemoryMetric('merge');
|
|
178
|
+
|
|
179
|
+
return result;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Purge only
|
|
184
|
+
*/
|
|
185
|
+
async function purgeOnly(config) {
|
|
186
|
+
console.log(color('cyan', '\nPurging Old Cold Storage'));
|
|
187
|
+
console.log('═'.repeat(50));
|
|
188
|
+
|
|
189
|
+
const retentionDays = config.automaticMemory?.demotion?.coldRetentionDays || 90;
|
|
190
|
+
console.log(`Retention: ${retentionDays} days\n`);
|
|
191
|
+
|
|
192
|
+
const result = await memoryDb.purgeColdFacts({ coldRetentionDays: retentionDays });
|
|
193
|
+
|
|
194
|
+
if (result.purged === 0) {
|
|
195
|
+
console.log(color('green', '✓ No facts older than retention period\n'));
|
|
196
|
+
} else {
|
|
197
|
+
console.log(color('green', `✓ Purged ${result.purged} old facts\n`));
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
await memoryDb.recordMemoryMetric('purge');
|
|
201
|
+
|
|
202
|
+
return result;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* List cold storage contents
|
|
207
|
+
*/
|
|
208
|
+
async function listColdStorage() {
|
|
209
|
+
console.log(color('cyan', '\nCold Storage Contents'));
|
|
210
|
+
console.log('═'.repeat(70));
|
|
211
|
+
|
|
212
|
+
await memoryDb.initDatabase();
|
|
213
|
+
|
|
214
|
+
// Direct query for cold storage
|
|
215
|
+
const SQL = require('sql.js');
|
|
216
|
+
const db = await memoryDb.initDatabase();
|
|
217
|
+
|
|
218
|
+
// This is a workaround since we don't expose direct query in the module
|
|
219
|
+
// We'll use getEntropyStats to show cold count
|
|
220
|
+
const stats = await memoryDb.getEntropyStats();
|
|
221
|
+
|
|
222
|
+
console.log(`\nTotal cold facts: ${stats.coldFacts}`);
|
|
223
|
+
|
|
224
|
+
if (stats.coldFacts === 0) {
|
|
225
|
+
console.log(color('gray', '\nNo facts in cold storage.\n'));
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Since we can't directly query cold storage through the module,
|
|
230
|
+
// inform user how to restore if needed
|
|
231
|
+
console.log(`
|
|
232
|
+
${color('yellow', 'Note:')} To restore a fact from cold storage:
|
|
233
|
+
./scripts/flow compact-memory --restore <fact_id>
|
|
234
|
+
|
|
235
|
+
To see fact IDs, check the database directly:
|
|
236
|
+
sqlite3 .workflow/memory/local.db "SELECT id, substr(fact,1,50) FROM facts_cold"
|
|
237
|
+
`);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Restore from cold storage
|
|
242
|
+
*/
|
|
243
|
+
async function restoreFromCold(factId) {
|
|
244
|
+
console.log(color('cyan', '\nRestoring from Cold Storage'));
|
|
245
|
+
console.log('═'.repeat(50));
|
|
246
|
+
|
|
247
|
+
console.log(`Fact ID: ${factId}\n`);
|
|
248
|
+
|
|
249
|
+
const result = await memoryDb.restoreFromColdStorage(factId);
|
|
250
|
+
|
|
251
|
+
if (result.restored) {
|
|
252
|
+
console.log(color('green', '✓ Fact restored successfully'));
|
|
253
|
+
console.log('Relevance has been reset to 50%\n');
|
|
254
|
+
} else {
|
|
255
|
+
console.log(color('red', `✗ ${result.error || 'Failed to restore'}\n`));
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
return result;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Show compaction stats/preview
|
|
263
|
+
*/
|
|
264
|
+
async function showPreview(config) {
|
|
265
|
+
console.log(color('cyan', '\nCompaction Preview'));
|
|
266
|
+
console.log('═'.repeat(50));
|
|
267
|
+
|
|
268
|
+
const memoryConfig = { maxLocalFacts: config.memory?.maxLocalFacts || 1000 };
|
|
269
|
+
const stats = await memoryDb.getEntropyStats(memoryConfig);
|
|
270
|
+
|
|
271
|
+
console.log(`\nCurrent State:`);
|
|
272
|
+
console.log(` Active Facts: ${stats.totalFacts}`);
|
|
273
|
+
console.log(` Cold Facts: ${stats.coldFacts}`);
|
|
274
|
+
console.log(` Entropy: ${formatEntropy(stats.entropy)}`);
|
|
275
|
+
|
|
276
|
+
console.log(`\n${color('blue', 'Would Affect:')}`);
|
|
277
|
+
|
|
278
|
+
const threshold = config.automaticMemory?.demotion?.relevanceThreshold || 0.3;
|
|
279
|
+
console.log(` Low Relevance (<${Math.round(threshold * 100)}%): ${stats.lowRelevanceCount} facts → would be demoted`);
|
|
280
|
+
console.log(` Never Accessed: ${stats.neverAccessed} facts → accelerated decay`);
|
|
281
|
+
|
|
282
|
+
// Estimate merged (can't know without running)
|
|
283
|
+
console.log(` Duplicates: Unknown (run --merge to detect)`);
|
|
284
|
+
|
|
285
|
+
console.log(`\n${color('yellow', 'Run ./scripts/flow compact-memory to execute')}\n`);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// ============================================================
|
|
289
|
+
// Main
|
|
290
|
+
// ============================================================
|
|
291
|
+
|
|
292
|
+
async function main() {
|
|
293
|
+
const args = process.argv.slice(2);
|
|
294
|
+
const config = loadConfig();
|
|
295
|
+
|
|
296
|
+
try {
|
|
297
|
+
if (args.includes('--demote')) {
|
|
298
|
+
await demoteOnly(config);
|
|
299
|
+
} else if (args.includes('--merge')) {
|
|
300
|
+
await mergeOnly();
|
|
301
|
+
} else if (args.includes('--purge')) {
|
|
302
|
+
await purgeOnly(config);
|
|
303
|
+
} else if (args.includes('--cold') || args.includes('--list')) {
|
|
304
|
+
await listColdStorage();
|
|
305
|
+
} else if (args.includes('--restore')) {
|
|
306
|
+
const idx = args.indexOf('--restore');
|
|
307
|
+
const factId = args[idx + 1];
|
|
308
|
+
if (!factId) {
|
|
309
|
+
console.error(color('red', 'Error: Missing fact ID'));
|
|
310
|
+
console.log('Usage: ./scripts/flow compact-memory --restore <fact_id>');
|
|
311
|
+
process.exit(1);
|
|
312
|
+
}
|
|
313
|
+
await restoreFromCold(factId);
|
|
314
|
+
} else if (args.includes('--preview')) {
|
|
315
|
+
await showPreview(config);
|
|
316
|
+
} else if (args.includes('--help') || args.includes('-h')) {
|
|
317
|
+
console.log(`
|
|
318
|
+
${color('cyan', 'Memory Compactor')}
|
|
319
|
+
|
|
320
|
+
Usage: ./scripts/flow compact-memory [options]
|
|
321
|
+
|
|
322
|
+
Options:
|
|
323
|
+
(none) Full compaction (all operations)
|
|
324
|
+
--preview Show what would be affected without changing
|
|
325
|
+
--demote Only demote low-relevance facts to cold storage
|
|
326
|
+
--merge Only merge duplicate facts (>95% similar)
|
|
327
|
+
--purge Only purge old facts from cold storage
|
|
328
|
+
--cold, --list Show cold storage contents
|
|
329
|
+
--restore <id> Restore a fact from cold storage
|
|
330
|
+
--help, -h Show this help
|
|
331
|
+
|
|
332
|
+
Examples:
|
|
333
|
+
./scripts/flow compact-memory # Full compaction
|
|
334
|
+
./scripts/flow compact-memory --preview # Preview changes
|
|
335
|
+
./scripts/flow compact-memory --demote # Just demote low relevance
|
|
336
|
+
./scripts/flow compact-memory --restore fact_12345_abc
|
|
337
|
+
`);
|
|
338
|
+
} else {
|
|
339
|
+
await fullCompaction(config);
|
|
340
|
+
}
|
|
341
|
+
} catch (error) {
|
|
342
|
+
console.error(color('red', `Error: ${error.message}`));
|
|
343
|
+
if (process.env.DEBUG) console.error(error.stack);
|
|
344
|
+
process.exit(1);
|
|
345
|
+
} finally {
|
|
346
|
+
memoryDb.closeDatabase();
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
main();
|