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,345 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Wogi Flow - Memory Entropy Monitor
|
|
5
|
+
*
|
|
6
|
+
* Monitors memory health and triggers automatic cleanup when needed.
|
|
7
|
+
*
|
|
8
|
+
* Commands:
|
|
9
|
+
* ./scripts/flow entropy - Show entropy stats
|
|
10
|
+
* ./scripts/flow entropy --auto - Auto-compact if entropy > threshold
|
|
11
|
+
* ./scripts/flow entropy --decay - Apply relevance decay
|
|
12
|
+
* ./scripts/flow entropy --history - Show entropy history
|
|
13
|
+
*
|
|
14
|
+
* Part of v1.8.0 - Automatic Memory Management
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
const fs = require('fs');
|
|
18
|
+
const path = require('path');
|
|
19
|
+
const memoryDb = require('./flow-memory-db');
|
|
20
|
+
|
|
21
|
+
// ============================================================
|
|
22
|
+
// Configuration
|
|
23
|
+
// ============================================================
|
|
24
|
+
|
|
25
|
+
const PROJECT_ROOT = process.env.WOGI_PROJECT_ROOT || process.cwd();
|
|
26
|
+
const CONFIG_PATH = path.join(PROJECT_ROOT, '.workflow', 'config.json');
|
|
27
|
+
|
|
28
|
+
function loadConfig() {
|
|
29
|
+
try {
|
|
30
|
+
if (fs.existsSync(CONFIG_PATH)) {
|
|
31
|
+
return JSON.parse(fs.readFileSync(CONFIG_PATH, 'utf-8'));
|
|
32
|
+
}
|
|
33
|
+
} catch {}
|
|
34
|
+
return {};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// ============================================================
|
|
38
|
+
// Output Formatting
|
|
39
|
+
// ============================================================
|
|
40
|
+
|
|
41
|
+
function color(c, text) {
|
|
42
|
+
const colors = {
|
|
43
|
+
red: '\x1b[31m',
|
|
44
|
+
green: '\x1b[32m',
|
|
45
|
+
yellow: '\x1b[33m',
|
|
46
|
+
blue: '\x1b[34m',
|
|
47
|
+
cyan: '\x1b[36m',
|
|
48
|
+
gray: '\x1b[90m',
|
|
49
|
+
reset: '\x1b[0m'
|
|
50
|
+
};
|
|
51
|
+
return `${colors[c] || ''}${text}${colors.reset}`;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function formatEntropy(entropy) {
|
|
55
|
+
if (entropy < 0.4) return color('green', `${entropy} (healthy)`);
|
|
56
|
+
if (entropy < 0.7) return color('yellow', `${entropy} (moderate)`);
|
|
57
|
+
return color('red', `${entropy} (needs cleanup)`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function formatStatus(status) {
|
|
61
|
+
switch (status) {
|
|
62
|
+
case 'healthy': return color('green', 'HEALTHY');
|
|
63
|
+
case 'moderate': return color('yellow', 'MODERATE');
|
|
64
|
+
case 'needs_cleanup': return color('red', 'NEEDS CLEANUP');
|
|
65
|
+
default: return status;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function formatPercent(value, max) {
|
|
70
|
+
const pct = max > 0 ? Math.round((value / max) * 100) : 0;
|
|
71
|
+
const bar = '█'.repeat(Math.floor(pct / 5)) + '░'.repeat(20 - Math.floor(pct / 5));
|
|
72
|
+
return `${bar} ${pct}%`;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// ============================================================
|
|
76
|
+
// Commands
|
|
77
|
+
// ============================================================
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Show entropy statistics
|
|
81
|
+
*/
|
|
82
|
+
async function showEntropy(config) {
|
|
83
|
+
const memoryConfig = {
|
|
84
|
+
maxLocalFacts: config.memory?.maxLocalFacts || 1000
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const stats = await memoryDb.getEntropyStats(memoryConfig);
|
|
88
|
+
|
|
89
|
+
console.log(color('cyan', '\nMemory Entropy Report'));
|
|
90
|
+
console.log('═'.repeat(50));
|
|
91
|
+
|
|
92
|
+
console.log(`\nStatus: ${formatStatus(stats.status)}`);
|
|
93
|
+
console.log(`Entropy Score: ${formatEntropy(stats.entropy)}`);
|
|
94
|
+
|
|
95
|
+
console.log(`\n${color('blue', 'Facts')}`);
|
|
96
|
+
console.log(` Active: ${stats.totalFacts}/${stats.maxFacts}`);
|
|
97
|
+
console.log(` Capacity: ${formatPercent(stats.totalFacts, stats.maxFacts)}`);
|
|
98
|
+
console.log(` Cold: ${stats.coldFacts} (archived)`);
|
|
99
|
+
|
|
100
|
+
console.log(`\n${color('blue', 'Health Metrics')}`);
|
|
101
|
+
console.log(` Avg Relevance: ${Math.round(stats.avgRelevance * 100)}%`);
|
|
102
|
+
console.log(` Never Accessed: ${stats.neverAccessed} (${Math.round((stats.neverAccessed / Math.max(1, stats.totalFacts)) * 100)}%)`);
|
|
103
|
+
console.log(` Low Relevance: ${stats.lowRelevanceCount} (<30%)`);
|
|
104
|
+
console.log(` Avg Age: ${stats.avgAgeDays} days`);
|
|
105
|
+
|
|
106
|
+
console.log(`\n${color('blue', 'Entropy Components')}`);
|
|
107
|
+
console.log(` Capacity (30%): ${Math.round(Math.min(1, stats.totalFacts / stats.maxFacts) * 100)}%`);
|
|
108
|
+
console.log(` Age (20%): ${Math.round(Math.min(1, stats.avgAgeDays / 30) * 100)}%`);
|
|
109
|
+
console.log(` Never Accessed (25%):${Math.round((stats.totalFacts > 0 ? stats.neverAccessed / stats.totalFacts : 0) * 100)}%`);
|
|
110
|
+
console.log(` Low Relevance (25%): ${Math.round((stats.totalFacts > 0 ? stats.lowRelevanceCount / stats.totalFacts : 0) * 100)}%`);
|
|
111
|
+
|
|
112
|
+
if (stats.needsCompaction) {
|
|
113
|
+
console.log(`\n${color('yellow', '⚠ Memory needs compaction')}`);
|
|
114
|
+
console.log(` Run: ${color('cyan', './scripts/flow compact-memory')}`);
|
|
115
|
+
console.log(` Or: ${color('cyan', './scripts/flow entropy --auto')}`);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
console.log('');
|
|
119
|
+
|
|
120
|
+
return stats;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Apply relevance decay to all facts
|
|
125
|
+
*/
|
|
126
|
+
async function applyDecay(config) {
|
|
127
|
+
const decayConfig = {
|
|
128
|
+
decayRate: config.automaticMemory?.relevanceDecay?.decayRate || 0.033,
|
|
129
|
+
neverAccessedPenalty: config.automaticMemory?.relevanceDecay?.neverAccessedPenalty || 0.1
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
console.log(color('cyan', '\nApplying Relevance Decay'));
|
|
133
|
+
console.log('═'.repeat(50));
|
|
134
|
+
|
|
135
|
+
const beforeStats = await memoryDb.getEntropyStats();
|
|
136
|
+
console.log(`Before: Avg Relevance = ${Math.round(beforeStats.avgRelevance * 100)}%`);
|
|
137
|
+
|
|
138
|
+
const result = await memoryDb.applyRelevanceDecay(decayConfig);
|
|
139
|
+
console.log(`Decayed ${result.decayed} facts`);
|
|
140
|
+
|
|
141
|
+
const afterStats = await memoryDb.getEntropyStats();
|
|
142
|
+
console.log(`After: Avg Relevance = ${Math.round(afterStats.avgRelevance * 100)}%`);
|
|
143
|
+
|
|
144
|
+
// Record metric
|
|
145
|
+
await memoryDb.recordMemoryMetric('decay');
|
|
146
|
+
|
|
147
|
+
console.log(color('green', '\n✓ Relevance decay applied'));
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Auto-compact memory if entropy exceeds threshold
|
|
152
|
+
*/
|
|
153
|
+
async function autoCompact(config) {
|
|
154
|
+
const threshold = config.automaticMemory?.entropyThreshold || 0.7;
|
|
155
|
+
const memoryConfig = {
|
|
156
|
+
maxLocalFacts: config.memory?.maxLocalFacts || 1000
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
console.log(color('cyan', '\nAuto-Compact Check'));
|
|
160
|
+
console.log('═'.repeat(50));
|
|
161
|
+
|
|
162
|
+
const stats = await memoryDb.getEntropyStats(memoryConfig);
|
|
163
|
+
console.log(`Current Entropy: ${formatEntropy(stats.entropy)}`);
|
|
164
|
+
console.log(`Threshold: ${threshold}`);
|
|
165
|
+
|
|
166
|
+
if (stats.entropy < threshold) {
|
|
167
|
+
console.log(color('green', '\n✓ Memory is healthy, no compaction needed'));
|
|
168
|
+
return { compacted: false, reason: 'below_threshold' };
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
console.log(color('yellow', '\n⚠ Entropy exceeds threshold, starting compaction...'));
|
|
172
|
+
|
|
173
|
+
const results = {
|
|
174
|
+
decay: null,
|
|
175
|
+
demotion: null,
|
|
176
|
+
merge: null,
|
|
177
|
+
purge: null
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
// 1. Apply relevance decay
|
|
181
|
+
console.log('\n1. Applying relevance decay...');
|
|
182
|
+
results.decay = await memoryDb.applyRelevanceDecay({
|
|
183
|
+
decayRate: config.automaticMemory?.relevanceDecay?.decayRate || 0.033,
|
|
184
|
+
neverAccessedPenalty: config.automaticMemory?.relevanceDecay?.neverAccessedPenalty || 0.1
|
|
185
|
+
});
|
|
186
|
+
console.log(` Decayed: ${results.decay.decayed} facts`);
|
|
187
|
+
|
|
188
|
+
// 2. Demote low-relevance facts
|
|
189
|
+
console.log('\n2. Demoting low-relevance facts...');
|
|
190
|
+
results.demotion = await memoryDb.demoteToColdStorage({
|
|
191
|
+
relevanceThreshold: config.automaticMemory?.demotion?.relevanceThreshold || 0.3
|
|
192
|
+
});
|
|
193
|
+
console.log(` Demoted: ${results.demotion.demoted} facts`);
|
|
194
|
+
|
|
195
|
+
// 3. Merge similar facts
|
|
196
|
+
console.log('\n3. Merging duplicate facts...');
|
|
197
|
+
results.merge = await memoryDb.mergeSimilarFacts({
|
|
198
|
+
mergeSimilarityThreshold: 0.95
|
|
199
|
+
});
|
|
200
|
+
console.log(` Merged: ${results.merge.merged} duplicates`);
|
|
201
|
+
|
|
202
|
+
// 4. Purge old cold facts
|
|
203
|
+
console.log('\n4. Purging old cold storage...');
|
|
204
|
+
results.purge = await memoryDb.purgeColdFacts({
|
|
205
|
+
coldRetentionDays: config.automaticMemory?.demotion?.coldRetentionDays || 90
|
|
206
|
+
});
|
|
207
|
+
console.log(` Purged: ${results.purge.purged} facts`);
|
|
208
|
+
|
|
209
|
+
// Record metric
|
|
210
|
+
await memoryDb.recordMemoryMetric('auto_compact');
|
|
211
|
+
|
|
212
|
+
// Show after stats
|
|
213
|
+
const afterStats = await memoryDb.getEntropyStats(memoryConfig);
|
|
214
|
+
|
|
215
|
+
console.log(color('cyan', '\nCompaction Results'));
|
|
216
|
+
console.log('═'.repeat(50));
|
|
217
|
+
console.log(`Entropy: ${formatEntropy(stats.entropy)} → ${formatEntropy(afterStats.entropy)}`);
|
|
218
|
+
console.log(`Facts: ${stats.totalFacts} → ${afterStats.totalFacts}`);
|
|
219
|
+
console.log(`Cold: ${stats.coldFacts} → ${afterStats.coldFacts}`);
|
|
220
|
+
|
|
221
|
+
console.log(color('green', '\n✓ Memory compaction complete'));
|
|
222
|
+
|
|
223
|
+
return {
|
|
224
|
+
compacted: true,
|
|
225
|
+
before: stats,
|
|
226
|
+
after: afterStats,
|
|
227
|
+
results
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Show entropy history
|
|
233
|
+
*/
|
|
234
|
+
async function showHistory(limit = 30) {
|
|
235
|
+
console.log(color('cyan', '\nEntropy History'));
|
|
236
|
+
console.log('═'.repeat(70));
|
|
237
|
+
|
|
238
|
+
const metrics = await memoryDb.getMemoryMetrics(limit);
|
|
239
|
+
|
|
240
|
+
if (metrics.length === 0) {
|
|
241
|
+
console.log(color('gray', 'No history available yet.'));
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
console.log(`${'Timestamp'.padEnd(20)} ${'Facts'.padEnd(8)} ${'Entropy'.padEnd(10)} ${'Action'}`);
|
|
246
|
+
console.log('-'.repeat(70));
|
|
247
|
+
|
|
248
|
+
for (const m of metrics) {
|
|
249
|
+
const ts = m.timestamp?.substring(0, 19) || 'N/A';
|
|
250
|
+
const facts = String(m.total_facts || 0).padEnd(8);
|
|
251
|
+
const entropy = String(m.entropy_score || 0).padEnd(10);
|
|
252
|
+
const action = m.action_taken || '-';
|
|
253
|
+
|
|
254
|
+
const entropyColor = m.entropy_score < 0.4 ? 'green' : m.entropy_score < 0.7 ? 'yellow' : 'red';
|
|
255
|
+
|
|
256
|
+
console.log(`${ts.padEnd(20)} ${facts} ${color(entropyColor, entropy)} ${action}`);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
console.log('');
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Show promotion candidates
|
|
264
|
+
*/
|
|
265
|
+
async function showPromotionCandidates(config) {
|
|
266
|
+
console.log(color('cyan', '\nPromotion Candidates'));
|
|
267
|
+
console.log('═'.repeat(70));
|
|
268
|
+
|
|
269
|
+
const candidates = await memoryDb.getPromotionCandidates({
|
|
270
|
+
minRelevance: config.automaticPromotion?.minRelevance || 0.8,
|
|
271
|
+
minAccessCount: config.automaticPromotion?.threshold || 3
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
if (candidates.length === 0) {
|
|
275
|
+
console.log(color('gray', 'No facts ready for promotion.'));
|
|
276
|
+
console.log('Facts need high relevance (80%+) and multiple accesses (3+).\n');
|
|
277
|
+
return [];
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
console.log(`Found ${color('green', candidates.length)} candidates:\n`);
|
|
281
|
+
|
|
282
|
+
for (const c of candidates.slice(0, 10)) {
|
|
283
|
+
const relevance = Math.round((c.relevance_score || 0) * 100);
|
|
284
|
+
console.log(` ${color('green', '●')} [${relevance}%] (${c.access_count}x) ${c.fact.substring(0, 60)}...`);
|
|
285
|
+
console.log(` Category: ${c.category || 'general'} | Scope: ${c.scope || 'local'}`);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
if (candidates.length > 10) {
|
|
289
|
+
console.log(color('gray', `\n ... and ${candidates.length - 10} more`));
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
console.log('');
|
|
293
|
+
return candidates;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// ============================================================
|
|
297
|
+
// Main
|
|
298
|
+
// ============================================================
|
|
299
|
+
|
|
300
|
+
async function main() {
|
|
301
|
+
const args = process.argv.slice(2);
|
|
302
|
+
const config = loadConfig();
|
|
303
|
+
|
|
304
|
+
try {
|
|
305
|
+
if (args.includes('--auto')) {
|
|
306
|
+
await autoCompact(config);
|
|
307
|
+
} else if (args.includes('--decay')) {
|
|
308
|
+
await applyDecay(config);
|
|
309
|
+
} else if (args.includes('--history')) {
|
|
310
|
+
const limit = parseInt(args[args.indexOf('--history') + 1]) || 30;
|
|
311
|
+
await showHistory(limit);
|
|
312
|
+
} else if (args.includes('--candidates')) {
|
|
313
|
+
await showPromotionCandidates(config);
|
|
314
|
+
} else if (args.includes('--help') || args.includes('-h')) {
|
|
315
|
+
console.log(`
|
|
316
|
+
${color('cyan', 'Memory Entropy Monitor')}
|
|
317
|
+
|
|
318
|
+
Usage: ./scripts/flow entropy [options]
|
|
319
|
+
|
|
320
|
+
Options:
|
|
321
|
+
(none) Show entropy statistics
|
|
322
|
+
--auto Auto-compact if entropy > threshold
|
|
323
|
+
--decay Apply relevance decay to all facts
|
|
324
|
+
--history [n] Show entropy history (last n entries, default 30)
|
|
325
|
+
--candidates Show facts ready for promotion
|
|
326
|
+
--help, -h Show this help
|
|
327
|
+
|
|
328
|
+
Examples:
|
|
329
|
+
./scripts/flow entropy # Show current status
|
|
330
|
+
./scripts/flow entropy --auto # Auto-compact if needed
|
|
331
|
+
./scripts/flow entropy --history 10 # Show last 10 metrics
|
|
332
|
+
`);
|
|
333
|
+
} else {
|
|
334
|
+
await showEntropy(config);
|
|
335
|
+
}
|
|
336
|
+
} catch (error) {
|
|
337
|
+
console.error(color('red', `Error: ${error.message}`));
|
|
338
|
+
if (process.env.DEBUG) console.error(error.stack);
|
|
339
|
+
process.exit(1);
|
|
340
|
+
} finally {
|
|
341
|
+
memoryDb.closeDatabase();
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
main();
|
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Wogi Flow - Export Profile
|
|
4
|
+
# Export workflow configuration for team sharing
|
|
5
|
+
# v2.1: Enhanced with rules, learnings, and templates
|
|
6
|
+
|
|
7
|
+
set -e
|
|
8
|
+
|
|
9
|
+
WORKFLOW_DIR=".workflow"
|
|
10
|
+
PROFILES_DIR="wogi-profiles"
|
|
11
|
+
|
|
12
|
+
# Colors
|
|
13
|
+
RED='\033[0;31m'
|
|
14
|
+
GREEN='\033[0;32m'
|
|
15
|
+
YELLOW='\033[1;33m'
|
|
16
|
+
CYAN='\033[0;36m'
|
|
17
|
+
DIM='\033[2m'
|
|
18
|
+
NC='\033[0m'
|
|
19
|
+
|
|
20
|
+
show_help() {
|
|
21
|
+
echo "Export Workflow Profile"
|
|
22
|
+
echo ""
|
|
23
|
+
echo "Usage: flow export-profile <profile-name> [options]"
|
|
24
|
+
echo ""
|
|
25
|
+
echo "Categories:"
|
|
26
|
+
echo " --rules Include .claude/rules/ and decisions.md"
|
|
27
|
+
echo " --learnings Include feedback-patterns.md and skill learnings"
|
|
28
|
+
echo " --templates Include sanitized project.md and roadmap templates"
|
|
29
|
+
echo " --full Include everything (all categories)"
|
|
30
|
+
echo ""
|
|
31
|
+
echo "Legacy options:"
|
|
32
|
+
echo " --include-decisions Include decisions.md only"
|
|
33
|
+
echo " --include-app-map Include app-map.md (component registry)"
|
|
34
|
+
echo ""
|
|
35
|
+
echo "Examples:"
|
|
36
|
+
echo " flow export-profile my-team --full"
|
|
37
|
+
echo " flow export-profile my-team --rules --learnings"
|
|
38
|
+
echo " flow export-profile my-team --include-decisions"
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if [ -z "$1" ] || [ "$1" = "--help" ] || [ "$1" = "-h" ]; then
|
|
42
|
+
show_help
|
|
43
|
+
exit 0
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
PROFILE_NAME="$1"
|
|
47
|
+
shift
|
|
48
|
+
|
|
49
|
+
# Parse options
|
|
50
|
+
INCLUDE_DECISIONS=false
|
|
51
|
+
INCLUDE_APP_MAP=false
|
|
52
|
+
INCLUDE_RULES=false
|
|
53
|
+
INCLUDE_LEARNINGS=false
|
|
54
|
+
INCLUDE_TEMPLATES=false
|
|
55
|
+
|
|
56
|
+
while [ $# -gt 0 ]; do
|
|
57
|
+
case "$1" in
|
|
58
|
+
--include-decisions)
|
|
59
|
+
INCLUDE_DECISIONS=true
|
|
60
|
+
;;
|
|
61
|
+
--include-app-map)
|
|
62
|
+
INCLUDE_APP_MAP=true
|
|
63
|
+
;;
|
|
64
|
+
--rules)
|
|
65
|
+
INCLUDE_RULES=true
|
|
66
|
+
INCLUDE_DECISIONS=true # Rules require decisions
|
|
67
|
+
;;
|
|
68
|
+
--learnings)
|
|
69
|
+
INCLUDE_LEARNINGS=true
|
|
70
|
+
;;
|
|
71
|
+
--templates)
|
|
72
|
+
INCLUDE_TEMPLATES=true
|
|
73
|
+
;;
|
|
74
|
+
--full)
|
|
75
|
+
INCLUDE_DECISIONS=true
|
|
76
|
+
INCLUDE_APP_MAP=true
|
|
77
|
+
INCLUDE_RULES=true
|
|
78
|
+
INCLUDE_LEARNINGS=true
|
|
79
|
+
INCLUDE_TEMPLATES=true
|
|
80
|
+
;;
|
|
81
|
+
*)
|
|
82
|
+
echo -e "${RED}Unknown option: $1${NC}"
|
|
83
|
+
exit 1
|
|
84
|
+
;;
|
|
85
|
+
esac
|
|
86
|
+
shift
|
|
87
|
+
done
|
|
88
|
+
|
|
89
|
+
# Create profiles directory
|
|
90
|
+
mkdir -p "$PROFILES_DIR"
|
|
91
|
+
|
|
92
|
+
# Create temp directory for profile
|
|
93
|
+
TEMP_DIR=$(mktemp -d)
|
|
94
|
+
PROFILE_DIR="$TEMP_DIR/$PROFILE_NAME"
|
|
95
|
+
mkdir -p "$PROFILE_DIR/agents"
|
|
96
|
+
mkdir -p "$PROFILE_DIR/.workflow"
|
|
97
|
+
|
|
98
|
+
echo -e "${CYAN}╔══════════════════════════════════════════════════════════╗${NC}"
|
|
99
|
+
echo -e "${CYAN}║ Exporting Profile: $PROFILE_NAME${NC}"
|
|
100
|
+
echo -e "${CYAN}╚══════════════════════════════════════════════════════════╝${NC}"
|
|
101
|
+
echo ""
|
|
102
|
+
|
|
103
|
+
# Track what's included for metadata
|
|
104
|
+
CONTENTS=""
|
|
105
|
+
|
|
106
|
+
# ==========================================
|
|
107
|
+
# CORE (always included)
|
|
108
|
+
# ==========================================
|
|
109
|
+
echo -e "${YELLOW}Core Files:${NC}"
|
|
110
|
+
|
|
111
|
+
echo -e " ${GREEN}✓${NC} CLAUDE.md"
|
|
112
|
+
cp CLAUDE.md "$PROFILE_DIR/"
|
|
113
|
+
CONTENTS="$CONTENTS\n- CLAUDE.md (core workflow instructions)"
|
|
114
|
+
|
|
115
|
+
echo -e " ${GREEN}✓${NC} agents/ ($(ls agents/*.md 2>/dev/null | wc -l | tr -d ' ') personas)"
|
|
116
|
+
cp agents/*.md "$PROFILE_DIR/agents/" 2>/dev/null || true
|
|
117
|
+
CONTENTS="$CONTENTS\n- agents/ (agent personas)"
|
|
118
|
+
|
|
119
|
+
echo -e " ${GREEN}✓${NC} config.json"
|
|
120
|
+
cp "$WORKFLOW_DIR/config.json" "$PROFILE_DIR/.workflow/"
|
|
121
|
+
CONTENTS="$CONTENTS\n- .workflow/config.json (configuration)"
|
|
122
|
+
|
|
123
|
+
# ==========================================
|
|
124
|
+
# RULES & DECISIONS
|
|
125
|
+
# ==========================================
|
|
126
|
+
if [ "$INCLUDE_DECISIONS" = true ] || [ "$INCLUDE_RULES" = true ]; then
|
|
127
|
+
echo ""
|
|
128
|
+
echo -e "${YELLOW}Rules & Decisions:${NC}"
|
|
129
|
+
|
|
130
|
+
# decisions.md
|
|
131
|
+
if [ -f "$WORKFLOW_DIR/state/decisions.md" ]; then
|
|
132
|
+
mkdir -p "$PROFILE_DIR/.workflow/state"
|
|
133
|
+
cp "$WORKFLOW_DIR/state/decisions.md" "$PROFILE_DIR/.workflow/state/"
|
|
134
|
+
echo -e " ${GREEN}✓${NC} decisions.md"
|
|
135
|
+
CONTENTS="$CONTENTS\n- .workflow/state/decisions.md (project rules)"
|
|
136
|
+
fi
|
|
137
|
+
|
|
138
|
+
# .claude/rules/
|
|
139
|
+
if [ "$INCLUDE_RULES" = true ] && [ -d ".claude/rules" ]; then
|
|
140
|
+
mkdir -p "$PROFILE_DIR/.claude/rules"
|
|
141
|
+
# Copy all rule files except README.md (auto-generated)
|
|
142
|
+
for file in .claude/rules/*.md; do
|
|
143
|
+
if [ -f "$file" ] && [ "$(basename "$file")" != "README.md" ]; then
|
|
144
|
+
cp "$file" "$PROFILE_DIR/.claude/rules/"
|
|
145
|
+
fi
|
|
146
|
+
done
|
|
147
|
+
RULE_COUNT=$(ls "$PROFILE_DIR/.claude/rules/"*.md 2>/dev/null | wc -l | tr -d ' ')
|
|
148
|
+
if [ "$RULE_COUNT" -gt 0 ]; then
|
|
149
|
+
echo -e " ${GREEN}✓${NC} .claude/rules/ ($RULE_COUNT rules)"
|
|
150
|
+
CONTENTS="$CONTENTS\n- .claude/rules/ (coding rules)"
|
|
151
|
+
fi
|
|
152
|
+
fi
|
|
153
|
+
fi
|
|
154
|
+
|
|
155
|
+
# ==========================================
|
|
156
|
+
# APP MAP (optional)
|
|
157
|
+
# ==========================================
|
|
158
|
+
if [ "$INCLUDE_APP_MAP" = true ] && [ -f "$WORKFLOW_DIR/state/app-map.md" ]; then
|
|
159
|
+
echo ""
|
|
160
|
+
echo -e "${YELLOW}Component Registry:${NC}"
|
|
161
|
+
mkdir -p "$PROFILE_DIR/.workflow/state"
|
|
162
|
+
cp "$WORKFLOW_DIR/state/app-map.md" "$PROFILE_DIR/.workflow/state/"
|
|
163
|
+
echo -e " ${GREEN}✓${NC} app-map.md"
|
|
164
|
+
CONTENTS="$CONTENTS\n- .workflow/state/app-map.md (component registry)"
|
|
165
|
+
fi
|
|
166
|
+
|
|
167
|
+
# ==========================================
|
|
168
|
+
# LEARNINGS
|
|
169
|
+
# ==========================================
|
|
170
|
+
if [ "$INCLUDE_LEARNINGS" = true ]; then
|
|
171
|
+
echo ""
|
|
172
|
+
echo -e "${YELLOW}Learnings:${NC}"
|
|
173
|
+
|
|
174
|
+
# feedback-patterns.md
|
|
175
|
+
if [ -f "$WORKFLOW_DIR/state/feedback-patterns.md" ]; then
|
|
176
|
+
mkdir -p "$PROFILE_DIR/.workflow/state"
|
|
177
|
+
cp "$WORKFLOW_DIR/state/feedback-patterns.md" "$PROFILE_DIR/.workflow/state/"
|
|
178
|
+
echo -e " ${GREEN}✓${NC} feedback-patterns.md"
|
|
179
|
+
CONTENTS="$CONTENTS\n- .workflow/state/feedback-patterns.md (team learnings)"
|
|
180
|
+
fi
|
|
181
|
+
|
|
182
|
+
# Skill learnings (patterns.md and learnings.md from each skill)
|
|
183
|
+
if [ -d ".claude/skills" ]; then
|
|
184
|
+
SKILL_COUNT=0
|
|
185
|
+
for skill_dir in .claude/skills/*/; do
|
|
186
|
+
if [ -d "$skill_dir/knowledge" ]; then
|
|
187
|
+
skill_name=$(basename "$skill_dir")
|
|
188
|
+
mkdir -p "$PROFILE_DIR/.claude/skills/$skill_name/knowledge"
|
|
189
|
+
|
|
190
|
+
# Copy patterns.md if exists
|
|
191
|
+
if [ -f "$skill_dir/knowledge/patterns.md" ]; then
|
|
192
|
+
cp "$skill_dir/knowledge/patterns.md" "$PROFILE_DIR/.claude/skills/$skill_name/knowledge/"
|
|
193
|
+
SKILL_COUNT=$((SKILL_COUNT + 1))
|
|
194
|
+
fi
|
|
195
|
+
|
|
196
|
+
# Copy learnings.md if exists
|
|
197
|
+
if [ -f "$skill_dir/knowledge/learnings.md" ]; then
|
|
198
|
+
cp "$skill_dir/knowledge/learnings.md" "$PROFILE_DIR/.claude/skills/$skill_name/knowledge/"
|
|
199
|
+
fi
|
|
200
|
+
fi
|
|
201
|
+
done
|
|
202
|
+
|
|
203
|
+
if [ "$SKILL_COUNT" -gt 0 ]; then
|
|
204
|
+
echo -e " ${GREEN}✓${NC} skill learnings ($SKILL_COUNT skills)"
|
|
205
|
+
CONTENTS="$CONTENTS\n- .claude/skills/*/knowledge/ (skill learnings)"
|
|
206
|
+
fi
|
|
207
|
+
fi
|
|
208
|
+
fi
|
|
209
|
+
|
|
210
|
+
# ==========================================
|
|
211
|
+
# TEMPLATES (sanitized)
|
|
212
|
+
# ==========================================
|
|
213
|
+
if [ "$INCLUDE_TEMPLATES" = true ]; then
|
|
214
|
+
echo ""
|
|
215
|
+
echo -e "${YELLOW}Templates:${NC}"
|
|
216
|
+
mkdir -p "$PROFILE_DIR/templates"
|
|
217
|
+
|
|
218
|
+
# Sanitize and export project.md as template
|
|
219
|
+
if [ -f "$WORKFLOW_DIR/specs/project.md" ]; then
|
|
220
|
+
# Create a sanitized template (remove project-specific content)
|
|
221
|
+
cat > "$PROFILE_DIR/templates/project-template.md" << 'TEMPLATE_EOF'
|
|
222
|
+
# Project Specification Template
|
|
223
|
+
|
|
224
|
+
## Overview
|
|
225
|
+
<!-- Fill in your project details -->
|
|
226
|
+
**Name**: [PROJECT_NAME]
|
|
227
|
+
**Description**: [PROJECT_DESCRIPTION]
|
|
228
|
+
|
|
229
|
+
## Tech Stack
|
|
230
|
+
<!-- Detected during onboarding -->
|
|
231
|
+
- **Language**:
|
|
232
|
+
- **Framework**:
|
|
233
|
+
- **Database**:
|
|
234
|
+
- **Package Manager**:
|
|
235
|
+
|
|
236
|
+
## Architecture
|
|
237
|
+
<!-- Document your architecture here -->
|
|
238
|
+
|
|
239
|
+
## Key Components
|
|
240
|
+
<!-- Auto-populated from codebase scan -->
|
|
241
|
+
|
|
242
|
+
## Conventions
|
|
243
|
+
<!-- Team conventions and standards -->
|
|
244
|
+
|
|
245
|
+
## Goals
|
|
246
|
+
<!-- Current project goals -->
|
|
247
|
+
TEMPLATE_EOF
|
|
248
|
+
echo -e " ${GREEN}✓${NC} project-template.md"
|
|
249
|
+
CONTENTS="$CONTENTS\n- templates/project-template.md"
|
|
250
|
+
fi
|
|
251
|
+
|
|
252
|
+
# Sanitize and export roadmap as template
|
|
253
|
+
if [ -f "$WORKFLOW_DIR/roadmap/roadmap.md" ]; then
|
|
254
|
+
cat > "$PROFILE_DIR/templates/roadmap-template.md" << 'ROADMAP_EOF'
|
|
255
|
+
# Project Roadmap Template
|
|
256
|
+
|
|
257
|
+
## Priority Levels
|
|
258
|
+
- **P0**: Critical - Drop everything
|
|
259
|
+
- **P1**: High - Do today
|
|
260
|
+
- **P2**: Medium - Do this week
|
|
261
|
+
- **P3**: Low - Do when possible
|
|
262
|
+
- **P4**: Backlog - Someday
|
|
263
|
+
|
|
264
|
+
## Current Sprint
|
|
265
|
+
<!-- Add current sprint items -->
|
|
266
|
+
|
|
267
|
+
## Upcoming
|
|
268
|
+
<!-- Add upcoming work -->
|
|
269
|
+
|
|
270
|
+
## Backlog
|
|
271
|
+
<!-- Add backlog items -->
|
|
272
|
+
|
|
273
|
+
## Completed
|
|
274
|
+
<!-- Move completed items here -->
|
|
275
|
+
ROADMAP_EOF
|
|
276
|
+
echo -e " ${GREEN}✓${NC} roadmap-template.md"
|
|
277
|
+
CONTENTS="$CONTENTS\n- templates/roadmap-template.md"
|
|
278
|
+
fi
|
|
279
|
+
fi
|
|
280
|
+
|
|
281
|
+
# ==========================================
|
|
282
|
+
# Create profile info file
|
|
283
|
+
# ==========================================
|
|
284
|
+
cat > "$PROFILE_DIR/PROFILE.md" << EOF
|
|
285
|
+
# Wogi Flow Profile: $PROFILE_NAME
|
|
286
|
+
|
|
287
|
+
Exported: $(date +%Y-%m-%d\ %H:%M)
|
|
288
|
+
Source: $(git remote get-url origin 2>/dev/null || echo "local")
|
|
289
|
+
Version: 2.1
|
|
290
|
+
|
|
291
|
+
## Contents
|
|
292
|
+
$(echo -e "$CONTENTS")
|
|
293
|
+
|
|
294
|
+
## Import Instructions
|
|
295
|
+
|
|
296
|
+
### New Project (during installation)
|
|
297
|
+
\`\`\`bash
|
|
298
|
+
./scripts/flow install
|
|
299
|
+
# Select option 2: "Import from existing profile"
|
|
300
|
+
# Enter path: $PROFILE_NAME.zip
|
|
301
|
+
\`\`\`
|
|
302
|
+
|
|
303
|
+
### Existing Project
|
|
304
|
+
\`\`\`bash
|
|
305
|
+
./scripts/flow import-profile $PROFILE_NAME.zip
|
|
306
|
+
\`\`\`
|
|
307
|
+
|
|
308
|
+
## Import Options
|
|
309
|
+
\`\`\`bash
|
|
310
|
+
# Preview what would be imported
|
|
311
|
+
./scripts/flow import-profile $PROFILE_NAME.zip --dry-run
|
|
312
|
+
|
|
313
|
+
# Create backup before importing
|
|
314
|
+
./scripts/flow import-profile $PROFILE_NAME.zip --backup
|
|
315
|
+
|
|
316
|
+
# Skip importing learnings
|
|
317
|
+
./scripts/flow import-profile $PROFILE_NAME.zip --skip-learnings
|
|
318
|
+
\`\`\`
|
|
319
|
+
|
|
320
|
+
## Configuration Summary
|
|
321
|
+
\`\`\`json
|
|
322
|
+
$(head -30 "$WORKFLOW_DIR/config.json")
|
|
323
|
+
...
|
|
324
|
+
\`\`\`
|
|
325
|
+
EOF
|
|
326
|
+
|
|
327
|
+
# ==========================================
|
|
328
|
+
# Create zip
|
|
329
|
+
# ==========================================
|
|
330
|
+
OUTPUT_FILE="$PROFILES_DIR/$PROFILE_NAME.zip"
|
|
331
|
+
(cd "$TEMP_DIR" && zip -r "$PROFILE_NAME.zip" "$PROFILE_NAME" > /dev/null)
|
|
332
|
+
mv "$TEMP_DIR/$PROFILE_NAME.zip" "$OUTPUT_FILE"
|
|
333
|
+
|
|
334
|
+
# Cleanup
|
|
335
|
+
rm -rf "$TEMP_DIR"
|
|
336
|
+
|
|
337
|
+
# Calculate size
|
|
338
|
+
SIZE=$(ls -lh "$OUTPUT_FILE" | awk '{print $5}')
|
|
339
|
+
|
|
340
|
+
echo ""
|
|
341
|
+
echo -e "${GREEN}╔══════════════════════════════════════════════════════════╗${NC}"
|
|
342
|
+
echo -e "${GREEN}║ ✓ Profile exported successfully ║${NC}"
|
|
343
|
+
echo -e "${GREEN}╚══════════════════════════════════════════════════════════╝${NC}"
|
|
344
|
+
echo ""
|
|
345
|
+
echo -e " ${CYAN}File:${NC} $OUTPUT_FILE"
|
|
346
|
+
echo -e " ${CYAN}Size:${NC} $SIZE"
|
|
347
|
+
echo ""
|
|
348
|
+
echo -e "${DIM}Share this file with team members.${NC}"
|
|
349
|
+
echo -e "${DIM}Import with: ./scripts/flow import-profile $OUTPUT_FILE${NC}"
|