@cloudstreamsoftware/claude-tools 1.0.0 → 1.1.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/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,489 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session Memory Store for Real-Time Self-Healing
|
|
3
|
+
*
|
|
4
|
+
* Provides in-session learning that persists corrections, preferences,
|
|
5
|
+
* and effective patterns immediately as they happen - not just at session end.
|
|
6
|
+
*
|
|
7
|
+
* This module is the foundation of the real-time self-healing architecture.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const fs = require('fs');
|
|
11
|
+
const path = require('path');
|
|
12
|
+
const { getClaudeDir, ensureDir, getDateTimeString } = require('./utils');
|
|
13
|
+
|
|
14
|
+
// Session memory file path
|
|
15
|
+
const MEMORY_DIR = path.join(getClaudeDir(), 'memory');
|
|
16
|
+
const SESSION_MEMORY_FILE = path.join(MEMORY_DIR, 'current-session.json');
|
|
17
|
+
const KNOWLEDGE_DIR = path.join(getClaudeDir(), 'knowledge');
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Default session memory structure
|
|
21
|
+
*/
|
|
22
|
+
function createDefaultMemory() {
|
|
23
|
+
return {
|
|
24
|
+
sessionId: generateSessionId(),
|
|
25
|
+
startedAt: getDateTimeString(),
|
|
26
|
+
lastUpdated: getDateTimeString(),
|
|
27
|
+
messageCount: 0,
|
|
28
|
+
|
|
29
|
+
// Real-time corrections detected during session
|
|
30
|
+
corrections: [],
|
|
31
|
+
|
|
32
|
+
// User preferences learned during session
|
|
33
|
+
preferences: {
|
|
34
|
+
codeStyle: {}, // Formatting, naming preferences
|
|
35
|
+
tools: {}, // Which tools to use/avoid
|
|
36
|
+
patterns: {}, // Preferred patterns
|
|
37
|
+
communication: {}, // How to explain things
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
// Patterns that worked well this session
|
|
41
|
+
effectivePatterns: [],
|
|
42
|
+
|
|
43
|
+
// Anti-patterns detected (things that failed)
|
|
44
|
+
antiPatterns: [],
|
|
45
|
+
|
|
46
|
+
// Context for skill matching
|
|
47
|
+
context: {
|
|
48
|
+
files: [], // Files being worked on
|
|
49
|
+
technologies: [], // Technologies detected (zoho, gcp, react, etc.)
|
|
50
|
+
complianceMode: null, // HIPAA, SOC2, PCI-DSS, or null
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Generate a unique session ID
|
|
57
|
+
*/
|
|
58
|
+
function generateSessionId() {
|
|
59
|
+
const now = new Date();
|
|
60
|
+
const date = now.toISOString().split('T')[0];
|
|
61
|
+
const random = Math.random().toString(36).substring(2, 8);
|
|
62
|
+
return `session-${date}-${random}`;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Load current session memory (or create new)
|
|
67
|
+
*/
|
|
68
|
+
function loadSessionMemory() {
|
|
69
|
+
ensureDir(MEMORY_DIR);
|
|
70
|
+
|
|
71
|
+
try {
|
|
72
|
+
if (fs.existsSync(SESSION_MEMORY_FILE)) {
|
|
73
|
+
const data = fs.readFileSync(SESSION_MEMORY_FILE, 'utf8');
|
|
74
|
+
return JSON.parse(data);
|
|
75
|
+
}
|
|
76
|
+
} catch (err) {
|
|
77
|
+
// If corrupted, start fresh
|
|
78
|
+
console.error(`[SessionMemory] Error loading memory: ${err.message}`);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return createDefaultMemory();
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Save session memory to disk
|
|
86
|
+
*/
|
|
87
|
+
function saveSessionMemory(memory) {
|
|
88
|
+
ensureDir(MEMORY_DIR);
|
|
89
|
+
memory.lastUpdated = getDateTimeString();
|
|
90
|
+
|
|
91
|
+
try {
|
|
92
|
+
fs.writeFileSync(SESSION_MEMORY_FILE, JSON.stringify(memory, null, 2), 'utf8');
|
|
93
|
+
return true;
|
|
94
|
+
} catch (err) {
|
|
95
|
+
console.error(`[SessionMemory] Error saving memory: ${err.message}`);
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Record a user correction
|
|
102
|
+
* @param {object} correction - { category, original, corrected, context }
|
|
103
|
+
*/
|
|
104
|
+
function recordCorrection(correction) {
|
|
105
|
+
const memory = loadSessionMemory();
|
|
106
|
+
|
|
107
|
+
const record = {
|
|
108
|
+
timestamp: getDateTimeString(),
|
|
109
|
+
category: correction.category || 'general',
|
|
110
|
+
original: correction.original,
|
|
111
|
+
corrected: correction.corrected,
|
|
112
|
+
context: correction.context || null,
|
|
113
|
+
count: 1,
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
// Check if similar correction exists (merge if so)
|
|
117
|
+
const existingIndex = memory.corrections.findIndex(
|
|
118
|
+
(c) => c.category === record.category && c.original === record.original
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
if (existingIndex >= 0) {
|
|
122
|
+
memory.corrections[existingIndex].count++;
|
|
123
|
+
memory.corrections[existingIndex].timestamp = record.timestamp;
|
|
124
|
+
} else {
|
|
125
|
+
memory.corrections.push(record);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
saveSessionMemory(memory);
|
|
129
|
+
|
|
130
|
+
return record;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Record a user preference
|
|
135
|
+
* @param {string} category - 'codeStyle', 'tools', 'patterns', 'communication'
|
|
136
|
+
* @param {string} key - Preference key
|
|
137
|
+
* @param {any} value - Preference value
|
|
138
|
+
*/
|
|
139
|
+
function recordPreference(category, key, value) {
|
|
140
|
+
const memory = loadSessionMemory();
|
|
141
|
+
|
|
142
|
+
if (memory.preferences[category]) {
|
|
143
|
+
memory.preferences[category][key] = {
|
|
144
|
+
value,
|
|
145
|
+
recordedAt: getDateTimeString(),
|
|
146
|
+
};
|
|
147
|
+
saveSessionMemory(memory);
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Record an effective pattern (something that worked well)
|
|
156
|
+
* @param {object} pattern - { name, description, usage, outcome }
|
|
157
|
+
*/
|
|
158
|
+
function recordEffectivePattern(pattern) {
|
|
159
|
+
const memory = loadSessionMemory();
|
|
160
|
+
|
|
161
|
+
const record = {
|
|
162
|
+
timestamp: getDateTimeString(),
|
|
163
|
+
name: pattern.name,
|
|
164
|
+
description: pattern.description || '',
|
|
165
|
+
usage: pattern.usage || '',
|
|
166
|
+
outcome: pattern.outcome || 'success',
|
|
167
|
+
count: 1,
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
// Check if pattern already exists
|
|
171
|
+
const existingIndex = memory.effectivePatterns.findIndex((p) => p.name === record.name);
|
|
172
|
+
|
|
173
|
+
if (existingIndex >= 0) {
|
|
174
|
+
memory.effectivePatterns[existingIndex].count++;
|
|
175
|
+
memory.effectivePatterns[existingIndex].timestamp = record.timestamp;
|
|
176
|
+
} else {
|
|
177
|
+
memory.effectivePatterns.push(record);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
saveSessionMemory(memory);
|
|
181
|
+
|
|
182
|
+
return record;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Record an anti-pattern (something that failed)
|
|
187
|
+
* @param {object} pattern - { name, description, error, avoidance }
|
|
188
|
+
*/
|
|
189
|
+
function recordAntiPattern(pattern) {
|
|
190
|
+
const memory = loadSessionMemory();
|
|
191
|
+
|
|
192
|
+
const record = {
|
|
193
|
+
timestamp: getDateTimeString(),
|
|
194
|
+
name: pattern.name,
|
|
195
|
+
description: pattern.description || '',
|
|
196
|
+
error: pattern.error || '',
|
|
197
|
+
avoidance: pattern.avoidance || '',
|
|
198
|
+
count: 1,
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
// Check if anti-pattern already exists
|
|
202
|
+
const existingIndex = memory.antiPatterns.findIndex((p) => p.name === record.name);
|
|
203
|
+
|
|
204
|
+
if (existingIndex >= 0) {
|
|
205
|
+
memory.antiPatterns[existingIndex].count++;
|
|
206
|
+
memory.antiPatterns[existingIndex].timestamp = record.timestamp;
|
|
207
|
+
} else {
|
|
208
|
+
memory.antiPatterns.push(record);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
saveSessionMemory(memory);
|
|
212
|
+
|
|
213
|
+
return record;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Update session context
|
|
218
|
+
* @param {object} context - { files, technologies, complianceMode }
|
|
219
|
+
*/
|
|
220
|
+
function updateContext(context) {
|
|
221
|
+
const memory = loadSessionMemory();
|
|
222
|
+
|
|
223
|
+
if (context.files) {
|
|
224
|
+
// Add unique files
|
|
225
|
+
const existingFiles = new Set(memory.context.files);
|
|
226
|
+
context.files.forEach((f) => existingFiles.add(f));
|
|
227
|
+
memory.context.files = Array.from(existingFiles);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
if (context.technologies) {
|
|
231
|
+
// Add unique technologies
|
|
232
|
+
const existingTech = new Set(memory.context.technologies);
|
|
233
|
+
context.technologies.forEach((t) => existingTech.add(t));
|
|
234
|
+
memory.context.technologies = Array.from(existingTech);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
if (context.complianceMode) {
|
|
238
|
+
memory.context.complianceMode = context.complianceMode;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
saveSessionMemory(memory);
|
|
242
|
+
|
|
243
|
+
return memory.context;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Increment message count
|
|
248
|
+
*/
|
|
249
|
+
function incrementMessageCount() {
|
|
250
|
+
const memory = loadSessionMemory();
|
|
251
|
+
memory.messageCount++;
|
|
252
|
+
saveSessionMemory(memory);
|
|
253
|
+
return memory.messageCount;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Get corrections by category
|
|
258
|
+
* @param {string} category - Optional category filter
|
|
259
|
+
*/
|
|
260
|
+
function getCorrections(category = null) {
|
|
261
|
+
const memory = loadSessionMemory();
|
|
262
|
+
|
|
263
|
+
if (category) {
|
|
264
|
+
return memory.corrections.filter((c) => c.category === category);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
return memory.corrections;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Get preferences by category
|
|
272
|
+
* @param {string} category - Optional category filter
|
|
273
|
+
*/
|
|
274
|
+
function getPreferences(category = null) {
|
|
275
|
+
const memory = loadSessionMemory();
|
|
276
|
+
|
|
277
|
+
if (category && memory.preferences[category]) {
|
|
278
|
+
return memory.preferences[category];
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
return memory.preferences;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Check if a specific correction has been made before
|
|
286
|
+
* @param {string} category - Correction category
|
|
287
|
+
* @param {string} original - Original behavior to check
|
|
288
|
+
*/
|
|
289
|
+
function hasCorrection(category, original) {
|
|
290
|
+
const corrections = getCorrections(category);
|
|
291
|
+
return corrections.find((c) => c.original === original) || null;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Get session summary for learning extraction
|
|
296
|
+
*/
|
|
297
|
+
function getSessionSummary() {
|
|
298
|
+
const memory = loadSessionMemory();
|
|
299
|
+
|
|
300
|
+
return {
|
|
301
|
+
sessionId: memory.sessionId,
|
|
302
|
+
duration: calculateDuration(memory.startedAt, memory.lastUpdated),
|
|
303
|
+
messageCount: memory.messageCount,
|
|
304
|
+
correctionCount: memory.corrections.length,
|
|
305
|
+
effectivePatternCount: memory.effectivePatterns.length,
|
|
306
|
+
antiPatternCount: memory.antiPatterns.length,
|
|
307
|
+
technologies: memory.context.technologies,
|
|
308
|
+
complianceMode: memory.context.complianceMode,
|
|
309
|
+
|
|
310
|
+
// High-value corrections (count >= 2)
|
|
311
|
+
frequentCorrections: memory.corrections.filter((c) => c.count >= 2),
|
|
312
|
+
|
|
313
|
+
// Patterns worth extracting
|
|
314
|
+
valuablePatterns: memory.effectivePatterns.filter((p) => p.count >= 2),
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Calculate duration between two datetime strings
|
|
320
|
+
*/
|
|
321
|
+
function calculateDuration(start, end) {
|
|
322
|
+
try {
|
|
323
|
+
const startDate = new Date(start.replace(' ', 'T'));
|
|
324
|
+
const endDate = new Date(end.replace(' ', 'T'));
|
|
325
|
+
const diffMs = endDate - startDate;
|
|
326
|
+
|
|
327
|
+
const hours = Math.floor(diffMs / (1000 * 60 * 60));
|
|
328
|
+
const minutes = Math.floor((diffMs % (1000 * 60 * 60)) / (1000 * 60));
|
|
329
|
+
|
|
330
|
+
if (hours > 0) {
|
|
331
|
+
return `${hours}h ${minutes}m`;
|
|
332
|
+
}
|
|
333
|
+
return `${minutes}m`;
|
|
334
|
+
} catch {
|
|
335
|
+
return 'unknown';
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Archive current session to knowledge directory
|
|
341
|
+
* Called at session end to persist learnings
|
|
342
|
+
*/
|
|
343
|
+
function archiveSession() {
|
|
344
|
+
const memory = loadSessionMemory();
|
|
345
|
+
const summary = getSessionSummary();
|
|
346
|
+
|
|
347
|
+
ensureDir(KNOWLEDGE_DIR);
|
|
348
|
+
|
|
349
|
+
// Archive the session
|
|
350
|
+
const archivePath = path.join(KNOWLEDGE_DIR, 'sessions', `${memory.sessionId}.json`);
|
|
351
|
+
ensureDir(path.dirname(archivePath));
|
|
352
|
+
|
|
353
|
+
try {
|
|
354
|
+
fs.writeFileSync(
|
|
355
|
+
archivePath,
|
|
356
|
+
JSON.stringify(
|
|
357
|
+
{
|
|
358
|
+
...memory,
|
|
359
|
+
summary,
|
|
360
|
+
},
|
|
361
|
+
null,
|
|
362
|
+
2
|
|
363
|
+
),
|
|
364
|
+
'utf8'
|
|
365
|
+
);
|
|
366
|
+
|
|
367
|
+
// Clear current session memory for next session
|
|
368
|
+
fs.unlinkSync(SESSION_MEMORY_FILE);
|
|
369
|
+
|
|
370
|
+
return { success: true, archivePath, summary };
|
|
371
|
+
} catch (err) {
|
|
372
|
+
return { success: false, error: err.message };
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* Merge corrections into the persistent anti-patterns knowledge base
|
|
378
|
+
* Called during session aggregation
|
|
379
|
+
*/
|
|
380
|
+
function mergeCorrectionsToKnowledge() {
|
|
381
|
+
ensureDir(KNOWLEDGE_DIR);
|
|
382
|
+
|
|
383
|
+
const antiPatternsFile = path.join(KNOWLEDGE_DIR, 'anti-patterns.json');
|
|
384
|
+
const memory = loadSessionMemory();
|
|
385
|
+
|
|
386
|
+
// Load existing anti-patterns
|
|
387
|
+
let antiPatterns = { patterns: [], lastUpdated: null };
|
|
388
|
+
try {
|
|
389
|
+
if (fs.existsSync(antiPatternsFile)) {
|
|
390
|
+
antiPatterns = JSON.parse(fs.readFileSync(antiPatternsFile, 'utf8'));
|
|
391
|
+
}
|
|
392
|
+
} catch {
|
|
393
|
+
// Start fresh if corrupted
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// Merge corrections with count >= 2 (significant corrections)
|
|
397
|
+
const significantCorrections = memory.corrections.filter((c) => c.count >= 2);
|
|
398
|
+
|
|
399
|
+
for (const correction of significantCorrections) {
|
|
400
|
+
const existingIndex = antiPatterns.patterns.findIndex(
|
|
401
|
+
(p) => p.category === correction.category && p.original === correction.original
|
|
402
|
+
);
|
|
403
|
+
|
|
404
|
+
if (existingIndex >= 0) {
|
|
405
|
+
antiPatterns.patterns[existingIndex].totalCount += correction.count;
|
|
406
|
+
antiPatterns.patterns[existingIndex].sessions++;
|
|
407
|
+
antiPatterns.patterns[existingIndex].lastSeen = getDateTimeString();
|
|
408
|
+
} else {
|
|
409
|
+
antiPatterns.patterns.push({
|
|
410
|
+
category: correction.category,
|
|
411
|
+
original: correction.original,
|
|
412
|
+
corrected: correction.corrected,
|
|
413
|
+
context: correction.context,
|
|
414
|
+
totalCount: correction.count,
|
|
415
|
+
sessions: 1,
|
|
416
|
+
firstSeen: getDateTimeString(),
|
|
417
|
+
lastSeen: getDateTimeString(),
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
antiPatterns.lastUpdated = getDateTimeString();
|
|
423
|
+
|
|
424
|
+
try {
|
|
425
|
+
fs.writeFileSync(antiPatternsFile, JSON.stringify(antiPatterns, null, 2), 'utf8');
|
|
426
|
+
return { success: true, merged: significantCorrections.length };
|
|
427
|
+
} catch (err) {
|
|
428
|
+
return { success: false, error: err.message };
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* Get known anti-patterns from knowledge base
|
|
434
|
+
* Used by hooks to prevent repeating mistakes
|
|
435
|
+
*/
|
|
436
|
+
function getKnownAntiPatterns() {
|
|
437
|
+
const antiPatternsFile = path.join(KNOWLEDGE_DIR, 'anti-patterns.json');
|
|
438
|
+
|
|
439
|
+
try {
|
|
440
|
+
if (fs.existsSync(antiPatternsFile)) {
|
|
441
|
+
const data = JSON.parse(fs.readFileSync(antiPatternsFile, 'utf8'));
|
|
442
|
+
return data.patterns || [];
|
|
443
|
+
}
|
|
444
|
+
} catch {
|
|
445
|
+
// Return empty if not found or corrupted
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
return [];
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
/**
|
|
452
|
+
* Reset session memory (for testing or forced reset)
|
|
453
|
+
*/
|
|
454
|
+
function resetSession() {
|
|
455
|
+
const newMemory = createDefaultMemory();
|
|
456
|
+
saveSessionMemory(newMemory);
|
|
457
|
+
return newMemory;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
module.exports = {
|
|
461
|
+
// Core operations
|
|
462
|
+
loadSessionMemory,
|
|
463
|
+
saveSessionMemory,
|
|
464
|
+
resetSession,
|
|
465
|
+
|
|
466
|
+
// Recording functions
|
|
467
|
+
recordCorrection,
|
|
468
|
+
recordPreference,
|
|
469
|
+
recordEffectivePattern,
|
|
470
|
+
recordAntiPattern,
|
|
471
|
+
updateContext,
|
|
472
|
+
incrementMessageCount,
|
|
473
|
+
|
|
474
|
+
// Query functions
|
|
475
|
+
getCorrections,
|
|
476
|
+
getPreferences,
|
|
477
|
+
hasCorrection,
|
|
478
|
+
getSessionSummary,
|
|
479
|
+
|
|
480
|
+
// Persistence
|
|
481
|
+
archiveSession,
|
|
482
|
+
mergeCorrectionsToKnowledge,
|
|
483
|
+
getKnownAntiPatterns,
|
|
484
|
+
|
|
485
|
+
// Constants
|
|
486
|
+
MEMORY_DIR,
|
|
487
|
+
SESSION_MEMORY_FILE,
|
|
488
|
+
KNOWLEDGE_DIR,
|
|
489
|
+
};
|