@cloudstreamsoftware/claude-tools 1.0.0 → 1.2.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/README.md +152 -37
- package/agents/INDEX.md +183 -0
- package/agents/architect.md +247 -0
- package/agents/build-error-resolver.md +555 -0
- package/agents/catalyst-deployer.md +132 -0
- package/agents/code-reviewer.md +121 -0
- package/agents/compliance-auditor.md +148 -0
- package/agents/creator-architect.md +395 -0
- package/agents/deluge-reviewer.md +98 -0
- package/agents/doc-updater.md +471 -0
- package/agents/e2e-runner.md +711 -0
- package/agents/planner.md +122 -0
- package/agents/refactor-cleaner.md +309 -0
- package/agents/security-reviewer.md +582 -0
- package/agents/tdd-guide.md +302 -0
- package/bin/cloudstream-setup.js +16 -6
- package/config/versions.json +63 -0
- package/dist/hooks/hooks.json +209 -0
- package/dist/index.js +47 -0
- package/dist/lib/asset-value.js +609 -0
- package/dist/lib/client-manager.js +300 -0
- package/dist/lib/command-matcher.js +242 -0
- package/dist/lib/cross-session-patterns.js +754 -0
- package/dist/lib/intent-classifier.js +1075 -0
- package/dist/lib/package-manager.js +374 -0
- package/dist/lib/recommendation-engine.js +597 -0
- package/dist/lib/session-memory.js +489 -0
- package/dist/lib/skill-effectiveness.js +486 -0
- package/dist/lib/skill-matcher.js +595 -0
- package/dist/lib/tutorial-metrics.js +242 -0
- package/dist/lib/tutorial-progress.js +209 -0
- package/dist/lib/tutorial-renderer.js +431 -0
- package/dist/lib/utils.js +380 -0
- package/dist/lib/verify-formatter.js +143 -0
- package/dist/lib/workflow-state.js +249 -0
- package/hooks/hooks.json +209 -0
- package/package.json +5 -1
- package/scripts/aggregate-sessions.js +290 -0
- package/scripts/branch-name-validator.js +291 -0
- package/scripts/build.js +101 -0
- package/scripts/commands/client-switch.js +231 -0
- package/scripts/deprecate-skill.js +610 -0
- package/scripts/diagnose.js +324 -0
- package/scripts/doc-freshness.js +168 -0
- package/scripts/generate-weekly-digest.js +393 -0
- package/scripts/health-check.js +270 -0
- package/scripts/hooks/credential-check.js +101 -0
- package/scripts/hooks/evaluate-session.js +81 -0
- package/scripts/hooks/pre-compact.js +66 -0
- package/scripts/hooks/prompt-analyzer.js +276 -0
- package/scripts/hooks/prompt-router.js +422 -0
- package/scripts/hooks/quality-gate-enforcer.js +371 -0
- package/scripts/hooks/session-end.js +156 -0
- package/scripts/hooks/session-start.js +195 -0
- package/scripts/hooks/skill-injector.js +333 -0
- package/scripts/hooks/suggest-compact.js +58 -0
- package/scripts/lib/asset-value.js +609 -0
- package/scripts/lib/client-manager.js +300 -0
- package/scripts/lib/command-matcher.js +242 -0
- package/scripts/lib/cross-session-patterns.js +754 -0
- package/scripts/lib/intent-classifier.js +1075 -0
- package/scripts/lib/package-manager.js +374 -0
- package/scripts/lib/recommendation-engine.js +597 -0
- package/scripts/lib/session-memory.js +489 -0
- package/scripts/lib/skill-effectiveness.js +486 -0
- package/scripts/lib/skill-matcher.js +595 -0
- package/scripts/lib/tutorial-metrics.js +242 -0
- package/scripts/lib/tutorial-progress.js +209 -0
- package/scripts/lib/tutorial-renderer.js +431 -0
- package/scripts/lib/utils.js +380 -0
- package/scripts/lib/verify-formatter.js +143 -0
- package/scripts/lib/workflow-state.js +249 -0
- package/scripts/onboard.js +363 -0
- package/scripts/quarterly-report.js +692 -0
- package/scripts/setup-package-manager.js +204 -0
- package/scripts/sync-upstream.js +391 -0
- package/scripts/test.js +108 -0
- package/scripts/tutorial-runner.js +351 -0
- package/scripts/validate-all.js +201 -0
- package/scripts/verifiers/agents.js +245 -0
- package/scripts/verifiers/config.js +186 -0
- package/scripts/verifiers/environment.js +123 -0
- package/scripts/verifiers/hooks.js +188 -0
- package/scripts/verifiers/index.js +38 -0
- package/scripts/verifiers/persistence.js +140 -0
- package/scripts/verifiers/plugin.js +215 -0
- package/scripts/verifiers/skills.js +209 -0
- package/scripts/verify-setup.js +164 -0
- package/skills/INDEX.md +157 -0
- package/skills/backend-patterns/SKILL.md +586 -0
- package/skills/backend-patterns/catalyst-patterns.md +128 -0
- package/skills/bigquery-patterns/SKILL.md +27 -0
- package/skills/bigquery-patterns/performance-optimization.md +518 -0
- package/skills/bigquery-patterns/query-patterns.md +372 -0
- package/skills/bigquery-patterns/schema-design.md +78 -0
- package/skills/cloudstream-project-template/SKILL.md +20 -0
- package/skills/cloudstream-project-template/structure.md +65 -0
- package/skills/coding-standards/SKILL.md +524 -0
- package/skills/coding-standards/deluge-standards.md +83 -0
- package/skills/compliance-patterns/SKILL.md +28 -0
- package/skills/compliance-patterns/hipaa/audit-requirements.md +251 -0
- package/skills/compliance-patterns/hipaa/baa-process.md +298 -0
- package/skills/compliance-patterns/hipaa/data-archival-strategy.md +387 -0
- package/skills/compliance-patterns/hipaa/phi-handling.md +52 -0
- package/skills/compliance-patterns/pci-dss/saq-a-requirements.md +307 -0
- package/skills/compliance-patterns/pci-dss/tokenization-patterns.md +382 -0
- package/skills/compliance-patterns/pci-dss/zoho-checkout-patterns.md +56 -0
- package/skills/compliance-patterns/soc2/access-controls.md +344 -0
- package/skills/compliance-patterns/soc2/audit-logging.md +458 -0
- package/skills/compliance-patterns/soc2/change-management.md +403 -0
- package/skills/compliance-patterns/soc2/deluge-execution-logging.md +407 -0
- package/skills/consultancy-workflows/SKILL.md +19 -0
- package/skills/consultancy-workflows/client-isolation.md +21 -0
- package/skills/consultancy-workflows/documentation-automation.md +454 -0
- package/skills/consultancy-workflows/handoff-procedures.md +257 -0
- package/skills/consultancy-workflows/knowledge-capture.md +513 -0
- package/skills/consultancy-workflows/time-tracking.md +26 -0
- package/skills/continuous-learning/SKILL.md +84 -0
- package/skills/continuous-learning/config.json +18 -0
- package/skills/continuous-learning/evaluate-session.sh +60 -0
- package/skills/continuous-learning-v2/SKILL.md +126 -0
- package/skills/continuous-learning-v2/config.json +61 -0
- package/skills/frontend-patterns/SKILL.md +635 -0
- package/skills/frontend-patterns/zoho-widget-patterns.md +103 -0
- package/skills/gcp-data-engineering/SKILL.md +36 -0
- package/skills/gcp-data-engineering/bigquery/performance-optimization.md +337 -0
- package/skills/gcp-data-engineering/dataflow/error-handling.md +496 -0
- package/skills/gcp-data-engineering/dataflow/pipeline-patterns.md +444 -0
- package/skills/gcp-data-engineering/dbt/model-organization.md +63 -0
- package/skills/gcp-data-engineering/dbt/testing-patterns.md +503 -0
- package/skills/gcp-data-engineering/medallion-architecture/bronze-layer.md +60 -0
- package/skills/gcp-data-engineering/medallion-architecture/gold-layer.md +311 -0
- package/skills/gcp-data-engineering/medallion-architecture/layer-transitions.md +517 -0
- package/skills/gcp-data-engineering/medallion-architecture/silver-layer.md +305 -0
- package/skills/gcp-data-engineering/zoho-to-gcp/data-extraction.md +543 -0
- package/skills/gcp-data-engineering/zoho-to-gcp/real-time-vs-batch.md +337 -0
- package/skills/security-review/SKILL.md +498 -0
- package/skills/security-review/compliance-checklist.md +53 -0
- package/skills/strategic-compact/SKILL.md +67 -0
- package/skills/tdd-workflow/SKILL.md +413 -0
- package/skills/tdd-workflow/zoho-testing.md +124 -0
- package/skills/tutorial/SKILL.md +249 -0
- package/skills/tutorial/docs/ACCESSIBILITY.md +169 -0
- package/skills/tutorial/lessons/00-philosophy-and-workflow.md +198 -0
- package/skills/tutorial/lessons/01-basics.md +81 -0
- package/skills/tutorial/lessons/02-training.md +86 -0
- package/skills/tutorial/lessons/03-commands.md +109 -0
- package/skills/tutorial/lessons/04-workflows.md +115 -0
- package/skills/tutorial/lessons/05-compliance.md +116 -0
- package/skills/tutorial/lessons/06-zoho.md +121 -0
- package/skills/tutorial/lessons/07-hooks-system.md +277 -0
- package/skills/tutorial/lessons/08-mcp-servers.md +316 -0
- package/skills/tutorial/lessons/09-client-management.md +215 -0
- package/skills/tutorial/lessons/10-testing-e2e.md +260 -0
- package/skills/tutorial/lessons/11-skills-deep-dive.md +272 -0
- package/skills/tutorial/lessons/12-rules-system.md +326 -0
- package/skills/tutorial/lessons/13-golden-standard-graduation.md +213 -0
- package/skills/tutorial/lessons/14-fork-setup-and-sync.md +312 -0
- package/skills/tutorial/lessons/15-living-examples-system.md +221 -0
- package/skills/tutorial/tracks/accelerated/README.md +134 -0
- package/skills/tutorial/tracks/accelerated/assessment/checkpoint-1.md +161 -0
- package/skills/tutorial/tracks/accelerated/assessment/checkpoint-2.md +175 -0
- package/skills/tutorial/tracks/accelerated/day-1-core-concepts.md +234 -0
- package/skills/tutorial/tracks/accelerated/day-2-essential-commands.md +270 -0
- package/skills/tutorial/tracks/accelerated/day-3-workflow-mastery.md +305 -0
- package/skills/tutorial/tracks/accelerated/day-4-compliance-zoho.md +304 -0
- package/skills/tutorial/tracks/accelerated/day-5-hooks-skills.md +344 -0
- package/skills/tutorial/tracks/accelerated/day-6-client-testing.md +386 -0
- package/skills/tutorial/tracks/accelerated/day-7-graduation.md +369 -0
- package/skills/zoho-patterns/CHANGELOG.md +108 -0
- package/skills/zoho-patterns/SKILL.md +446 -0
- package/skills/zoho-patterns/analytics/dashboard-patterns.md +352 -0
- package/skills/zoho-patterns/analytics/zoho-to-bigquery-pipeline.md +427 -0
- package/skills/zoho-patterns/catalyst/appsail-deployment.md +349 -0
- package/skills/zoho-patterns/catalyst/context-close-patterns.md +354 -0
- package/skills/zoho-patterns/catalyst/cron-batch-processing.md +374 -0
- package/skills/zoho-patterns/catalyst/function-patterns.md +439 -0
- package/skills/zoho-patterns/creator/form-design.md +304 -0
- package/skills/zoho-patterns/creator/publish-api-patterns.md +313 -0
- package/skills/zoho-patterns/creator/widget-integration.md +306 -0
- package/skills/zoho-patterns/creator/workflow-automation.md +253 -0
- package/skills/zoho-patterns/deluge/api-patterns.md +468 -0
- package/skills/zoho-patterns/deluge/batch-processing.md +403 -0
- package/skills/zoho-patterns/deluge/cross-app-integration.md +356 -0
- package/skills/zoho-patterns/deluge/error-handling.md +423 -0
- package/skills/zoho-patterns/deluge/syntax-reference.md +65 -0
- package/skills/zoho-patterns/integration/cors-proxy-architecture.md +426 -0
- package/skills/zoho-patterns/integration/crm-books-native-sync.md +277 -0
- package/skills/zoho-patterns/integration/oauth-token-management.md +461 -0
- package/skills/zoho-patterns/integration/zoho-flow-patterns.md +334 -0
|
@@ -0,0 +1,609 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Knowledge Asset Value Calculator
|
|
3
|
+
*
|
|
4
|
+
* Calculates the monetary value of knowledge assets (skills, agents, patterns).
|
|
5
|
+
* Integrates with skill-effectiveness.js and versions.json for comprehensive
|
|
6
|
+
* asset valuation.
|
|
7
|
+
*
|
|
8
|
+
* Formula: Value = usageCount * avgTimeSavedMinutes * (hourlyRate / 60)
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const fs = require('fs');
|
|
12
|
+
const path = require('path');
|
|
13
|
+
const { ensureDir, getDateTimeString, getClaudeDir, readFile, findFiles } = require('./utils');
|
|
14
|
+
|
|
15
|
+
// File paths
|
|
16
|
+
const CONFIG_PATH = path.join(__dirname, '..', '..', 'config', 'asset-value.json');
|
|
17
|
+
const VERSIONS_PATH = path.join(__dirname, '..', '..', 'config', 'versions.json');
|
|
18
|
+
const KNOWLEDGE_DIR = path.join(getClaudeDir(), 'knowledge');
|
|
19
|
+
const EFFECTIVENESS_FILE = path.join(KNOWLEDGE_DIR, 'skill-effectiveness.json');
|
|
20
|
+
const ANTI_PATTERNS_FILE = path.join(KNOWLEDGE_DIR, 'anti-patterns.json');
|
|
21
|
+
const ASSET_CACHE_FILE = path.join(KNOWLEDGE_DIR, 'asset-summary.json');
|
|
22
|
+
|
|
23
|
+
// Asset categories
|
|
24
|
+
const ASSET_CATEGORIES = {
|
|
25
|
+
BUNDLED: 'bundled',
|
|
26
|
+
AGENT: 'agent',
|
|
27
|
+
LEARNED: 'learned',
|
|
28
|
+
SHARED: 'shared',
|
|
29
|
+
PATTERN: 'pattern',
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Load asset value configuration
|
|
34
|
+
*/
|
|
35
|
+
function loadConfig() {
|
|
36
|
+
try {
|
|
37
|
+
if (fs.existsSync(CONFIG_PATH)) {
|
|
38
|
+
const content = fs.readFileSync(CONFIG_PATH, 'utf8');
|
|
39
|
+
return JSON.parse(content);
|
|
40
|
+
}
|
|
41
|
+
} catch (err) {
|
|
42
|
+
console.error(`[AssetValue] Error loading config: ${err.message}`);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Default configuration
|
|
46
|
+
return {
|
|
47
|
+
valueCalculation: {
|
|
48
|
+
hourlyRate: 150,
|
|
49
|
+
currency: 'USD',
|
|
50
|
+
avgTimeSavedMinutes: {
|
|
51
|
+
bundled: 15,
|
|
52
|
+
agent: 30,
|
|
53
|
+
learned: 20,
|
|
54
|
+
shared: 25,
|
|
55
|
+
pattern: 10,
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
confidence: {
|
|
59
|
+
lowThreshold: 5,
|
|
60
|
+
mediumThreshold: 15,
|
|
61
|
+
highThreshold: 30,
|
|
62
|
+
},
|
|
63
|
+
decay: {
|
|
64
|
+
enabled: true,
|
|
65
|
+
ratePerQuarter: 0.05,
|
|
66
|
+
minimumValueMultiplier: 0.1,
|
|
67
|
+
},
|
|
68
|
+
reporting: {
|
|
69
|
+
topAssetsCount: 10,
|
|
70
|
+
deprecationThreshold: 0.4,
|
|
71
|
+
promotionThreshold: 0.9,
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Load version registry for asset metadata
|
|
78
|
+
*/
|
|
79
|
+
function loadVersionRegistry() {
|
|
80
|
+
try {
|
|
81
|
+
if (fs.existsSync(VERSIONS_PATH)) {
|
|
82
|
+
const content = fs.readFileSync(VERSIONS_PATH, 'utf8');
|
|
83
|
+
return JSON.parse(content);
|
|
84
|
+
}
|
|
85
|
+
} catch (err) {
|
|
86
|
+
console.error(`[AssetValue] Error loading versions: ${err.message}`);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return { skills: {}, agents: {} };
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Load skill effectiveness data
|
|
94
|
+
*/
|
|
95
|
+
function loadSkillEffectiveness() {
|
|
96
|
+
try {
|
|
97
|
+
if (fs.existsSync(EFFECTIVENESS_FILE)) {
|
|
98
|
+
const content = fs.readFileSync(EFFECTIVENESS_FILE, 'utf8');
|
|
99
|
+
return JSON.parse(content);
|
|
100
|
+
}
|
|
101
|
+
} catch (err) {
|
|
102
|
+
console.error(`[AssetValue] Error loading effectiveness: ${err.message}`);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return { skills: {}, summary: { totalApplications: 0 } };
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Load anti-patterns data
|
|
110
|
+
*/
|
|
111
|
+
function loadAntiPatterns() {
|
|
112
|
+
try {
|
|
113
|
+
if (fs.existsSync(ANTI_PATTERNS_FILE)) {
|
|
114
|
+
const content = fs.readFileSync(ANTI_PATTERNS_FILE, 'utf8');
|
|
115
|
+
return JSON.parse(content);
|
|
116
|
+
}
|
|
117
|
+
} catch (err) {
|
|
118
|
+
// Anti-patterns file may not exist yet
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return { patterns: [] };
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Count learned skills in user directory
|
|
126
|
+
*/
|
|
127
|
+
function countLearnedSkills() {
|
|
128
|
+
const learnedDir = path.join(getClaudeDir(), 'skills', 'learned');
|
|
129
|
+
|
|
130
|
+
if (!fs.existsSync(learnedDir)) {
|
|
131
|
+
return { count: 0, skills: [] };
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
try {
|
|
135
|
+
const files = fs.readdirSync(learnedDir).filter((f) => f.endsWith('.md'));
|
|
136
|
+
return {
|
|
137
|
+
count: files.length,
|
|
138
|
+
skills: files.map((f) => f.replace('.md', '')),
|
|
139
|
+
};
|
|
140
|
+
} catch (err) {
|
|
141
|
+
return { count: 0, skills: [] };
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Count shared skills in user directory
|
|
147
|
+
*/
|
|
148
|
+
function countSharedSkills() {
|
|
149
|
+
const sharedDir = path.join(getClaudeDir(), 'skills', 'shared');
|
|
150
|
+
|
|
151
|
+
if (!fs.existsSync(sharedDir)) {
|
|
152
|
+
return { count: 0, skills: [] };
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
try {
|
|
156
|
+
const files = findFiles(sharedDir, '*.md', { recursive: true });
|
|
157
|
+
return {
|
|
158
|
+
count: files.length,
|
|
159
|
+
skills: files.map((f) => path.basename(f.path, '.md')),
|
|
160
|
+
};
|
|
161
|
+
} catch (err) {
|
|
162
|
+
return { count: 0, skills: [] };
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Calculate the value of a single asset
|
|
168
|
+
* @param {object} asset - Asset data with usageCount, effectiveness, category
|
|
169
|
+
* @param {object} config - Configuration object
|
|
170
|
+
*/
|
|
171
|
+
function calculateAssetValue(asset, config) {
|
|
172
|
+
const { valueCalculation, confidence, decay } = config;
|
|
173
|
+
const { hourlyRate, avgTimeSavedMinutes } = valueCalculation;
|
|
174
|
+
|
|
175
|
+
// Get time saved based on category
|
|
176
|
+
const timeSaved = avgTimeSavedMinutes[asset.category] || avgTimeSavedMinutes.bundled;
|
|
177
|
+
|
|
178
|
+
// Base value calculation: uses * minutes_saved * (hourly_rate / 60)
|
|
179
|
+
const baseValue = asset.usageCount * timeSaved * (hourlyRate / 60);
|
|
180
|
+
|
|
181
|
+
// Apply effectiveness multiplier (0.5 to 1.5 range)
|
|
182
|
+
const effectivenessMultiplier = 0.5 + (asset.effectiveness || 0.5);
|
|
183
|
+
|
|
184
|
+
// Calculate raw value
|
|
185
|
+
let value = baseValue * effectivenessMultiplier;
|
|
186
|
+
|
|
187
|
+
// Apply decay if enabled and asset hasn't been used recently
|
|
188
|
+
if (decay.enabled && asset.daysSinceLastUse) {
|
|
189
|
+
const quartersUnused = asset.daysSinceLastUse / 90;
|
|
190
|
+
const decayMultiplier = Math.max(
|
|
191
|
+
decay.minimumValueMultiplier,
|
|
192
|
+
Math.pow(1 - decay.ratePerQuarter, quartersUnused)
|
|
193
|
+
);
|
|
194
|
+
value *= decayMultiplier;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Determine confidence level
|
|
198
|
+
let confidenceLevel = 'low';
|
|
199
|
+
if (asset.usageCount >= confidence.highThreshold) {
|
|
200
|
+
confidenceLevel = 'high';
|
|
201
|
+
} else if (asset.usageCount >= confidence.mediumThreshold) {
|
|
202
|
+
confidenceLevel = 'medium';
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return {
|
|
206
|
+
value: Math.round(value * 100) / 100,
|
|
207
|
+
baseValue: Math.round(baseValue * 100) / 100,
|
|
208
|
+
effectivenessMultiplier: Math.round(effectivenessMultiplier * 100) / 100,
|
|
209
|
+
confidenceLevel,
|
|
210
|
+
breakdown: {
|
|
211
|
+
usageCount: asset.usageCount,
|
|
212
|
+
timeSavedMinutes: timeSaved,
|
|
213
|
+
hourlyRate,
|
|
214
|
+
effectiveness: asset.effectiveness || 0.5,
|
|
215
|
+
},
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Calculate compound value (reuse across projects)
|
|
221
|
+
* @param {object} asset - Asset with base value calculated
|
|
222
|
+
* @param {object} config - Configuration object
|
|
223
|
+
*/
|
|
224
|
+
function calculateCompoundValue(asset, config) {
|
|
225
|
+
const baseValue = asset.estimatedValue || 0;
|
|
226
|
+
|
|
227
|
+
// Projects used in (approximate based on context diversity)
|
|
228
|
+
const projectMultiplier = Math.min(3, 1 + (asset.contextDiversity || 0) * 0.5);
|
|
229
|
+
|
|
230
|
+
// Team members using it (for shared skills)
|
|
231
|
+
const teamMultiplier = asset.category === ASSET_CATEGORIES.SHARED ? 1.5 : 1.0;
|
|
232
|
+
|
|
233
|
+
const compoundMultiplier = projectMultiplier * teamMultiplier;
|
|
234
|
+
const totalValue = baseValue * compoundMultiplier;
|
|
235
|
+
|
|
236
|
+
return {
|
|
237
|
+
baseValue,
|
|
238
|
+
projectMultiplier: Math.round(projectMultiplier * 100) / 100,
|
|
239
|
+
teamMultiplier,
|
|
240
|
+
compoundMultiplier: Math.round(compoundMultiplier * 100) / 100,
|
|
241
|
+
totalValue: Math.round(totalValue * 100) / 100,
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Get all assets with calculated values
|
|
247
|
+
* @param {object} customConfig - Optional custom configuration
|
|
248
|
+
*/
|
|
249
|
+
function getAllAssetValues(customConfig = null) {
|
|
250
|
+
const config = customConfig || loadConfig();
|
|
251
|
+
const versions = loadVersionRegistry();
|
|
252
|
+
const effectiveness = loadSkillEffectiveness();
|
|
253
|
+
const antiPatterns = loadAntiPatterns();
|
|
254
|
+
const learned = countLearnedSkills();
|
|
255
|
+
const shared = countSharedSkills();
|
|
256
|
+
|
|
257
|
+
const assets = [];
|
|
258
|
+
|
|
259
|
+
// Process bundled skills
|
|
260
|
+
for (const [skillName, skillInfo] of Object.entries(versions.skills || {})) {
|
|
261
|
+
const effectivenessData = effectiveness.skills?.[skillName] || {};
|
|
262
|
+
|
|
263
|
+
const asset = {
|
|
264
|
+
name: skillName,
|
|
265
|
+
category: ASSET_CATEGORIES.BUNDLED,
|
|
266
|
+
version: skillInfo.version,
|
|
267
|
+
status: skillInfo.status,
|
|
268
|
+
usageCount: effectivenessData.applications || 0,
|
|
269
|
+
effectiveness: effectivenessData.effectiveness || 0.5,
|
|
270
|
+
lastUsed: effectivenessData.lastUsed || null,
|
|
271
|
+
daysSinceLastUse: calculateDaysSinceLastUse(effectivenessData.lastUsed),
|
|
272
|
+
trend: effectivenessData.trend || 'new',
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
const valueResult = calculateAssetValue(asset, config);
|
|
276
|
+
asset.estimatedValue = valueResult.value;
|
|
277
|
+
asset.confidenceLevel = valueResult.confidenceLevel;
|
|
278
|
+
asset.valueBreakdown = valueResult.breakdown;
|
|
279
|
+
|
|
280
|
+
assets.push(asset);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// Process agents
|
|
284
|
+
for (const [agentName, agentInfo] of Object.entries(versions.agents || {})) {
|
|
285
|
+
const effectivenessData = effectiveness.skills?.[agentName] || {};
|
|
286
|
+
|
|
287
|
+
const asset = {
|
|
288
|
+
name: agentName,
|
|
289
|
+
category: ASSET_CATEGORIES.AGENT,
|
|
290
|
+
version: agentInfo.version,
|
|
291
|
+
status: agentInfo.status,
|
|
292
|
+
usageCount: effectivenessData.applications || 0,
|
|
293
|
+
effectiveness: effectivenessData.effectiveness || 0.5,
|
|
294
|
+
lastUsed: effectivenessData.lastUsed || null,
|
|
295
|
+
daysSinceLastUse: calculateDaysSinceLastUse(effectivenessData.lastUsed),
|
|
296
|
+
trend: effectivenessData.trend || 'new',
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
const valueResult = calculateAssetValue(asset, config);
|
|
300
|
+
asset.estimatedValue = valueResult.value;
|
|
301
|
+
asset.confidenceLevel = valueResult.confidenceLevel;
|
|
302
|
+
asset.valueBreakdown = valueResult.breakdown;
|
|
303
|
+
|
|
304
|
+
assets.push(asset);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// Process learned skills
|
|
308
|
+
for (const skillName of learned.skills) {
|
|
309
|
+
const effectivenessData = effectiveness.skills?.[skillName] || {};
|
|
310
|
+
|
|
311
|
+
const asset = {
|
|
312
|
+
name: skillName,
|
|
313
|
+
category: ASSET_CATEGORIES.LEARNED,
|
|
314
|
+
version: '1.0.0',
|
|
315
|
+
status: 'active',
|
|
316
|
+
usageCount: effectivenessData.applications || 0,
|
|
317
|
+
effectiveness: effectivenessData.effectiveness || 0.5,
|
|
318
|
+
lastUsed: effectivenessData.lastUsed || null,
|
|
319
|
+
daysSinceLastUse: calculateDaysSinceLastUse(effectivenessData.lastUsed),
|
|
320
|
+
trend: effectivenessData.trend || 'new',
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
const valueResult = calculateAssetValue(asset, config);
|
|
324
|
+
asset.estimatedValue = valueResult.value;
|
|
325
|
+
asset.confidenceLevel = valueResult.confidenceLevel;
|
|
326
|
+
asset.valueBreakdown = valueResult.breakdown;
|
|
327
|
+
|
|
328
|
+
assets.push(asset);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// Process shared skills
|
|
332
|
+
for (const skillName of shared.skills) {
|
|
333
|
+
const effectivenessData = effectiveness.skills?.[skillName] || {};
|
|
334
|
+
|
|
335
|
+
const asset = {
|
|
336
|
+
name: skillName,
|
|
337
|
+
category: ASSET_CATEGORIES.SHARED,
|
|
338
|
+
version: '1.0.0',
|
|
339
|
+
status: 'active',
|
|
340
|
+
usageCount: effectivenessData.applications || 0,
|
|
341
|
+
effectiveness: effectivenessData.effectiveness || 0.5,
|
|
342
|
+
lastUsed: effectivenessData.lastUsed || null,
|
|
343
|
+
daysSinceLastUse: calculateDaysSinceLastUse(effectivenessData.lastUsed),
|
|
344
|
+
trend: effectivenessData.trend || 'new',
|
|
345
|
+
};
|
|
346
|
+
|
|
347
|
+
const valueResult = calculateAssetValue(asset, config);
|
|
348
|
+
asset.estimatedValue = valueResult.value;
|
|
349
|
+
asset.confidenceLevel = valueResult.confidenceLevel;
|
|
350
|
+
asset.valueBreakdown = valueResult.breakdown;
|
|
351
|
+
|
|
352
|
+
assets.push(asset);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// Process anti-patterns (as prevented mistakes)
|
|
356
|
+
if (antiPatterns.patterns && antiPatterns.patterns.length > 0) {
|
|
357
|
+
for (const pattern of antiPatterns.patterns) {
|
|
358
|
+
const asset = {
|
|
359
|
+
name: pattern.original || `pattern-${pattern.id || 'unknown'}`,
|
|
360
|
+
category: ASSET_CATEGORIES.PATTERN,
|
|
361
|
+
version: '1.0.0',
|
|
362
|
+
status: 'active',
|
|
363
|
+
usageCount: pattern.count || pattern.occurrences || 1,
|
|
364
|
+
effectiveness: 0.8, // Anti-patterns are inherently valuable
|
|
365
|
+
lastUsed: pattern.lastSeen || null,
|
|
366
|
+
daysSinceLastUse: calculateDaysSinceLastUse(pattern.lastSeen),
|
|
367
|
+
trend: 'stable',
|
|
368
|
+
};
|
|
369
|
+
|
|
370
|
+
const valueResult = calculateAssetValue(asset, config);
|
|
371
|
+
asset.estimatedValue = valueResult.value;
|
|
372
|
+
asset.confidenceLevel = valueResult.confidenceLevel;
|
|
373
|
+
asset.valueBreakdown = valueResult.breakdown;
|
|
374
|
+
|
|
375
|
+
assets.push(asset);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
// Calculate summary
|
|
380
|
+
const summary = calculateSummary(assets, config);
|
|
381
|
+
|
|
382
|
+
// Sort by value descending
|
|
383
|
+
assets.sort((a, b) => b.estimatedValue - a.estimatedValue);
|
|
384
|
+
|
|
385
|
+
return {
|
|
386
|
+
assets,
|
|
387
|
+
summary,
|
|
388
|
+
topValueAssets: assets.slice(0, config.reporting.topAssetsCount),
|
|
389
|
+
lowValueAssets: assets.filter((a) => a.usageCount > 0).slice(-config.reporting.topAssetsCount),
|
|
390
|
+
deprecationCandidates: assets.filter(
|
|
391
|
+
(a) => a.effectiveness < config.reporting.deprecationThreshold && a.usageCount >= 10
|
|
392
|
+
),
|
|
393
|
+
promotionCandidates: assets.filter(
|
|
394
|
+
(a) =>
|
|
395
|
+
a.effectiveness >= config.reporting.promotionThreshold &&
|
|
396
|
+
a.category === ASSET_CATEGORIES.LEARNED
|
|
397
|
+
),
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* Calculate summary statistics
|
|
403
|
+
*/
|
|
404
|
+
function calculateSummary(assets, config) {
|
|
405
|
+
const activeAssets = assets.filter((a) => a.status === 'active');
|
|
406
|
+
const deprecatedAssets = assets.filter((a) => a.status === 'deprecated');
|
|
407
|
+
|
|
408
|
+
const totalValue = assets.reduce((sum, a) => sum + (a.estimatedValue || 0), 0);
|
|
409
|
+
const totalUsage = assets.reduce((sum, a) => sum + (a.usageCount || 0), 0);
|
|
410
|
+
|
|
411
|
+
const effectivenessValues = assets
|
|
412
|
+
.filter((a) => a.usageCount >= config.confidence.lowThreshold)
|
|
413
|
+
.map((a) => a.effectiveness);
|
|
414
|
+
|
|
415
|
+
const avgEffectiveness =
|
|
416
|
+
effectivenessValues.length > 0
|
|
417
|
+
? effectivenessValues.reduce((sum, e) => sum + e, 0) / effectivenessValues.length
|
|
418
|
+
: 0;
|
|
419
|
+
|
|
420
|
+
// Determine overall confidence level
|
|
421
|
+
let confidenceLevel = 'low';
|
|
422
|
+
if (totalUsage >= 100) {
|
|
423
|
+
confidenceLevel = 'high';
|
|
424
|
+
} else if (totalUsage >= 30) {
|
|
425
|
+
confidenceLevel = 'medium';
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// Count by category
|
|
429
|
+
const byCategory = {};
|
|
430
|
+
for (const category of Object.values(ASSET_CATEGORIES)) {
|
|
431
|
+
const categoryAssets = assets.filter((a) => a.category === category);
|
|
432
|
+
byCategory[category] = {
|
|
433
|
+
count: categoryAssets.length,
|
|
434
|
+
totalValue: categoryAssets.reduce((sum, a) => sum + (a.estimatedValue || 0), 0),
|
|
435
|
+
avgEffectiveness:
|
|
436
|
+
categoryAssets.length > 0
|
|
437
|
+
? categoryAssets.reduce((sum, a) => sum + (a.effectiveness || 0), 0) /
|
|
438
|
+
categoryAssets.length
|
|
439
|
+
: 0,
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
return {
|
|
444
|
+
totalAssets: assets.length,
|
|
445
|
+
activeAssets: activeAssets.length,
|
|
446
|
+
deprecatedAssets: deprecatedAssets.length,
|
|
447
|
+
totalUsage,
|
|
448
|
+
avgEffectiveness: Math.round(avgEffectiveness * 100) / 100,
|
|
449
|
+
totalEstimatedValue: Math.round(totalValue * 100) / 100,
|
|
450
|
+
confidenceLevel,
|
|
451
|
+
currency: config.valueCalculation.currency,
|
|
452
|
+
byCategory,
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
/**
|
|
457
|
+
* Calculate days since last use
|
|
458
|
+
*/
|
|
459
|
+
function calculateDaysSinceLastUse(lastUsedStr) {
|
|
460
|
+
if (!lastUsedStr) return null;
|
|
461
|
+
|
|
462
|
+
try {
|
|
463
|
+
const lastUsed = new Date(lastUsedStr);
|
|
464
|
+
const now = new Date();
|
|
465
|
+
const diffMs = now - lastUsed;
|
|
466
|
+
return Math.floor(diffMs / (1000 * 60 * 60 * 24));
|
|
467
|
+
} catch {
|
|
468
|
+
return null;
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
/**
|
|
473
|
+
* Get value trend over time
|
|
474
|
+
* @param {number} days - Number of days to analyze
|
|
475
|
+
*/
|
|
476
|
+
function getValueTrend(days = 30) {
|
|
477
|
+
// This would require historical data stored
|
|
478
|
+
// For now, return placeholder trend data
|
|
479
|
+
const trend = [];
|
|
480
|
+
const now = new Date();
|
|
481
|
+
|
|
482
|
+
for (let i = days; i >= 0; i--) {
|
|
483
|
+
const date = new Date(now);
|
|
484
|
+
date.setDate(date.getDate() - i);
|
|
485
|
+
|
|
486
|
+
trend.push({
|
|
487
|
+
date: date.toISOString().split('T')[0],
|
|
488
|
+
value: 0, // Would be calculated from historical data
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
return {
|
|
493
|
+
trend,
|
|
494
|
+
periodDays: days,
|
|
495
|
+
growth: 0, // Percentage growth over period
|
|
496
|
+
};
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
/**
|
|
500
|
+
* Load asset summary from cache (for dashboard)
|
|
501
|
+
*/
|
|
502
|
+
function loadAssetSummary() {
|
|
503
|
+
// Try to load from cache first
|
|
504
|
+
try {
|
|
505
|
+
if (fs.existsSync(ASSET_CACHE_FILE)) {
|
|
506
|
+
const content = fs.readFileSync(ASSET_CACHE_FILE, 'utf8');
|
|
507
|
+
const cached = JSON.parse(content);
|
|
508
|
+
|
|
509
|
+
// Check if cache is fresh (less than 1 hour old)
|
|
510
|
+
const cacheAge = Date.now() - new Date(cached.generatedAt).getTime();
|
|
511
|
+
if (cacheAge < 60 * 60 * 1000) {
|
|
512
|
+
return cached;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
} catch (err) {
|
|
516
|
+
// Cache invalid, regenerate
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
// Generate fresh data
|
|
520
|
+
const data = getAllAssetValues();
|
|
521
|
+
|
|
522
|
+
// Save to cache
|
|
523
|
+
const cacheData = {
|
|
524
|
+
generatedAt: getDateTimeString(),
|
|
525
|
+
summary: data.summary,
|
|
526
|
+
topValueAssets: data.topValueAssets,
|
|
527
|
+
valueTrend: getValueTrend(30).trend,
|
|
528
|
+
};
|
|
529
|
+
|
|
530
|
+
try {
|
|
531
|
+
ensureDir(path.dirname(ASSET_CACHE_FILE));
|
|
532
|
+
fs.writeFileSync(ASSET_CACHE_FILE, JSON.stringify(cacheData, null, 2), 'utf8');
|
|
533
|
+
} catch (err) {
|
|
534
|
+
console.error(`[AssetValue] Error saving cache: ${err.message}`);
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
return cacheData;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
/**
|
|
541
|
+
* Format currency value
|
|
542
|
+
* @param {number} value - Value to format
|
|
543
|
+
* @param {string} currency - Currency code (default USD)
|
|
544
|
+
*/
|
|
545
|
+
function formatCurrency(value, currency = 'USD') {
|
|
546
|
+
const formatter = new Intl.NumberFormat('en-US', {
|
|
547
|
+
style: 'currency',
|
|
548
|
+
currency,
|
|
549
|
+
minimumFractionDigits: 0,
|
|
550
|
+
maximumFractionDigits: 0,
|
|
551
|
+
});
|
|
552
|
+
return formatter.format(value);
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
/**
|
|
556
|
+
* Format percentage
|
|
557
|
+
* @param {number} value - Value between 0 and 1
|
|
558
|
+
*/
|
|
559
|
+
function formatPercent(value) {
|
|
560
|
+
return `${Math.round(value * 100)}%`;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
/**
|
|
564
|
+
* Generate sparkline for terminal output
|
|
565
|
+
* @param {Array} values - Array of numeric values
|
|
566
|
+
*/
|
|
567
|
+
function generateSparkline(values) {
|
|
568
|
+
if (!values || values.length === 0) return '';
|
|
569
|
+
|
|
570
|
+
const chars = ['▁', '▂', '▃', '▄', '▅', '▆', '▇', '█'];
|
|
571
|
+
const numericValues = values.map((v) => (typeof v === 'object' ? v.value : v));
|
|
572
|
+
const min = Math.min(...numericValues);
|
|
573
|
+
const max = Math.max(...numericValues);
|
|
574
|
+
const range = max - min || 1;
|
|
575
|
+
|
|
576
|
+
return numericValues
|
|
577
|
+
.map((v) => {
|
|
578
|
+
const normalized = (v - min) / range;
|
|
579
|
+
const index = Math.min(Math.floor(normalized * chars.length), chars.length - 1);
|
|
580
|
+
return chars[index];
|
|
581
|
+
})
|
|
582
|
+
.join('');
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
module.exports = {
|
|
586
|
+
// Core functions
|
|
587
|
+
loadConfig,
|
|
588
|
+
loadVersionRegistry,
|
|
589
|
+
loadSkillEffectiveness,
|
|
590
|
+
calculateAssetValue,
|
|
591
|
+
calculateCompoundValue,
|
|
592
|
+
getAllAssetValues,
|
|
593
|
+
getValueTrend,
|
|
594
|
+
loadAssetSummary,
|
|
595
|
+
|
|
596
|
+
// Helpers
|
|
597
|
+
formatCurrency,
|
|
598
|
+
formatPercent,
|
|
599
|
+
generateSparkline,
|
|
600
|
+
calculateDaysSinceLastUse,
|
|
601
|
+
|
|
602
|
+
// Constants
|
|
603
|
+
ASSET_CATEGORIES,
|
|
604
|
+
|
|
605
|
+
// Paths (for testing)
|
|
606
|
+
CONFIG_PATH,
|
|
607
|
+
VERSIONS_PATH,
|
|
608
|
+
EFFECTIVENESS_FILE,
|
|
609
|
+
};
|