pikakit 3.0.5 → 3.7.2
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 +1 -1
- package/bin/lib/commands/install.js +119 -242
- package/package.json +3 -4
- package/lib/agent-cli/bin/agent.js +0 -187
- package/lib/agent-cli/dashboard/dashboard_server.js +0 -312
- package/lib/agent-cli/lib/ab-testing.js +0 -364
- package/lib/agent-cli/lib/audit.js +0 -154
- package/lib/agent-cli/lib/audit.test.js +0 -100
- package/lib/agent-cli/lib/auto-learn.js +0 -319
- package/lib/agent-cli/lib/backup.js +0 -138
- package/lib/agent-cli/lib/backup.test.js +0 -78
- package/lib/agent-cli/lib/causality-engine.js +0 -331
- package/lib/agent-cli/lib/cognitive-lesson.js +0 -476
- package/lib/agent-cli/lib/completion.js +0 -149
- package/lib/agent-cli/lib/config.js +0 -35
- package/lib/agent-cli/lib/dashboard-data.js +0 -380
- package/lib/agent-cli/lib/eslint-fix.js +0 -238
- package/lib/agent-cli/lib/evolution-signal.js +0 -215
- package/lib/agent-cli/lib/export.js +0 -86
- package/lib/agent-cli/lib/export.test.js +0 -65
- package/lib/agent-cli/lib/fix.js +0 -337
- package/lib/agent-cli/lib/fix.test.js +0 -80
- package/lib/agent-cli/lib/gemini-export.js +0 -83
- package/lib/agent-cli/lib/generate-registry.js +0 -42
- package/lib/agent-cli/lib/hooks/install-hooks.js +0 -152
- package/lib/agent-cli/lib/hooks/lint-learn.js +0 -172
- package/lib/agent-cli/lib/icons.js +0 -93
- package/lib/agent-cli/lib/ignore.js +0 -116
- package/lib/agent-cli/lib/ignore.test.js +0 -58
- package/lib/agent-cli/lib/init.js +0 -124
- package/lib/agent-cli/lib/knowledge-index.js +0 -326
- package/lib/agent-cli/lib/knowledge-metrics.js +0 -335
- package/lib/agent-cli/lib/knowledge-retention.js +0 -398
- package/lib/agent-cli/lib/knowledge-validator.js +0 -312
- package/lib/agent-cli/lib/learn.js +0 -255
- package/lib/agent-cli/lib/learn.test.js +0 -70
- package/lib/agent-cli/lib/metrics-collector.js +0 -410
- package/lib/agent-cli/lib/proposals.js +0 -199
- package/lib/agent-cli/lib/proposals.test.js +0 -56
- package/lib/agent-cli/lib/recall.js +0 -835
- package/lib/agent-cli/lib/recall.test.js +0 -107
- package/lib/agent-cli/lib/reinforcement.js +0 -299
- package/lib/agent-cli/lib/selfevolution-bridge.js +0 -167
- package/lib/agent-cli/lib/settings.js +0 -203
- package/lib/agent-cli/lib/skill-generator.js +0 -379
- package/lib/agent-cli/lib/skill-learn.js +0 -296
- package/lib/agent-cli/lib/stats.js +0 -132
- package/lib/agent-cli/lib/stats.test.js +0 -94
- package/lib/agent-cli/lib/types.js +0 -33
- package/lib/agent-cli/lib/ui/audit-ui.js +0 -146
- package/lib/agent-cli/lib/ui/backup-ui.js +0 -107
- package/lib/agent-cli/lib/ui/clack-helpers.js +0 -317
- package/lib/agent-cli/lib/ui/common.js +0 -83
- package/lib/agent-cli/lib/ui/completion-ui.js +0 -126
- package/lib/agent-cli/lib/ui/custom-select.js +0 -69
- package/lib/agent-cli/lib/ui/dashboard-ui.js +0 -222
- package/lib/agent-cli/lib/ui/evolution-signals-ui.js +0 -107
- package/lib/agent-cli/lib/ui/export-ui.js +0 -94
- package/lib/agent-cli/lib/ui/fix-all-ui.js +0 -191
- package/lib/agent-cli/lib/ui/help-ui.js +0 -49
- package/lib/agent-cli/lib/ui/index.js +0 -199
- package/lib/agent-cli/lib/ui/init-ui.js +0 -56
- package/lib/agent-cli/lib/ui/knowledge-ui.js +0 -55
- package/lib/agent-cli/lib/ui/learn-ui.js +0 -706
- package/lib/agent-cli/lib/ui/lessons-ui.js +0 -148
- package/lib/agent-cli/lib/ui/pretty.js +0 -145
- package/lib/agent-cli/lib/ui/proposals-ui.js +0 -99
- package/lib/agent-cli/lib/ui/recall-ui.js +0 -342
- package/lib/agent-cli/lib/ui/routing-demo.js +0 -79
- package/lib/agent-cli/lib/ui/routing-ui.js +0 -325
- package/lib/agent-cli/lib/ui/settings-ui.js +0 -381
- package/lib/agent-cli/lib/ui/stats-ui.js +0 -123
- package/lib/agent-cli/lib/ui/watch-ui.js +0 -236
- package/lib/agent-cli/lib/watcher.js +0 -181
- package/lib/agent-cli/lib/watcher.test.js +0 -85
- package/lib/agent-cli/src/MIGRATION.md +0 -418
- package/lib/agent-cli/src/README.md +0 -367
- package/lib/agent-cli/src/core/evolution/evolution-signal.js +0 -42
- package/lib/agent-cli/src/core/evolution/index.js +0 -17
- package/lib/agent-cli/src/core/evolution/review-gate.js +0 -40
- package/lib/agent-cli/src/core/evolution/signal-detector.js +0 -137
- package/lib/agent-cli/src/core/evolution/signal-queue.js +0 -79
- package/lib/agent-cli/src/core/evolution/threshold-checker.js +0 -79
- package/lib/agent-cli/src/core/index.js +0 -15
- package/lib/agent-cli/src/core/learning/cognitive-enhancer.js +0 -282
- package/lib/agent-cli/src/core/learning/index.js +0 -12
- package/lib/agent-cli/src/core/learning/lesson-synthesizer.js +0 -83
- package/lib/agent-cli/src/core/scanning/index.js +0 -14
- package/lib/agent-cli/src/data/index.js +0 -13
- package/lib/agent-cli/src/data/repositories/index.js +0 -8
- package/lib/agent-cli/src/data/repositories/lesson-repository.js +0 -130
- package/lib/agent-cli/src/data/repositories/signal-repository.js +0 -119
- package/lib/agent-cli/src/data/storage/index.js +0 -8
- package/lib/agent-cli/src/data/storage/json-storage.js +0 -64
- package/lib/agent-cli/src/data/storage/yaml-storage.js +0 -66
- package/lib/agent-cli/src/infrastructure/index.js +0 -13
- package/lib/agent-cli/src/presentation/formatters/skill-formatter.js +0 -232
- package/lib/agent-cli/src/services/export-service.js +0 -162
- package/lib/agent-cli/src/services/index.js +0 -13
- package/lib/agent-cli/src/services/learning-service.js +0 -99
|
@@ -1,203 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Settings management for PikaKit
|
|
3
|
-
* Handles Auto-Learning and Auto-Updating preferences
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import fs from "fs";
|
|
7
|
-
import yaml from "js-yaml";
|
|
8
|
-
import path from "path";
|
|
9
|
-
import { KNOWLEDGE_DIR } from "./config.js";
|
|
10
|
-
|
|
11
|
-
/** Path to settings file */
|
|
12
|
-
export const SETTINGS_PATH = path.join(KNOWLEDGE_DIR, "settings.yaml");
|
|
13
|
-
|
|
14
|
-
/** Default settings */
|
|
15
|
-
const DEFAULT_SETTINGS = {
|
|
16
|
-
version: 1,
|
|
17
|
-
autoLearning: true, // ON by default - learn from mistakes
|
|
18
|
-
autoUpdating: false, // OFF by default - requires user trust
|
|
19
|
-
updateThreshold: 5, // Hits before proposing update
|
|
20
|
-
lastUpdateCheck: null,
|
|
21
|
-
apiKeys: {
|
|
22
|
-
gemini: null, // Gemini API key for agent coding
|
|
23
|
-
claude: null, // Claude API key (alternative)
|
|
24
|
-
}
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Load settings from YAML file
|
|
29
|
-
* @returns {object} Settings object
|
|
30
|
-
*/
|
|
31
|
-
export function loadSettings() {
|
|
32
|
-
try {
|
|
33
|
-
if (fs.existsSync(SETTINGS_PATH)) {
|
|
34
|
-
const content = fs.readFileSync(SETTINGS_PATH, "utf8");
|
|
35
|
-
return { ...DEFAULT_SETTINGS, ...yaml.load(content) };
|
|
36
|
-
}
|
|
37
|
-
} catch (e) {
|
|
38
|
-
console.error("Failed to load settings:", e.message);
|
|
39
|
-
}
|
|
40
|
-
return { ...DEFAULT_SETTINGS };
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Save settings to YAML file
|
|
45
|
-
* @param {object} settings - Settings to save
|
|
46
|
-
*/
|
|
47
|
-
export function saveSettings(settings) {
|
|
48
|
-
try {
|
|
49
|
-
fs.mkdirSync(KNOWLEDGE_DIR, { recursive: true });
|
|
50
|
-
fs.writeFileSync(SETTINGS_PATH, yaml.dump(settings), "utf8");
|
|
51
|
-
return true;
|
|
52
|
-
} catch (e) {
|
|
53
|
-
console.error("Failed to save settings:", e.message);
|
|
54
|
-
return false;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Toggle Auto-Learning setting
|
|
60
|
-
* @returns {boolean} New value
|
|
61
|
-
*/
|
|
62
|
-
export function toggleAutoLearning() {
|
|
63
|
-
const settings = loadSettings();
|
|
64
|
-
settings.autoLearning = !settings.autoLearning;
|
|
65
|
-
saveSettings(settings);
|
|
66
|
-
return settings.autoLearning;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Toggle Auto-Updating setting
|
|
71
|
-
* @returns {boolean} New value
|
|
72
|
-
*/
|
|
73
|
-
export function toggleAutoUpdating() {
|
|
74
|
-
const settings = loadSettings();
|
|
75
|
-
settings.autoUpdating = !settings.autoUpdating;
|
|
76
|
-
saveSettings(settings);
|
|
77
|
-
return settings.autoUpdating;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Check if Auto-Learning is enabled
|
|
82
|
-
* @returns {boolean}
|
|
83
|
-
*/
|
|
84
|
-
export function isAutoLearningEnabled() {
|
|
85
|
-
return loadSettings().autoLearning;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Check if Auto-Updating is enabled
|
|
90
|
-
* @returns {boolean}
|
|
91
|
-
*/
|
|
92
|
-
export function isAutoUpdatingEnabled() {
|
|
93
|
-
return loadSettings().autoUpdating;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Get update threshold
|
|
98
|
-
* @returns {number}
|
|
99
|
-
*/
|
|
100
|
-
export function getUpdateThreshold() {
|
|
101
|
-
return loadSettings().updateThreshold;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Initialize settings file if not exists
|
|
106
|
-
*/
|
|
107
|
-
export function initSettings() {
|
|
108
|
-
if (!fs.existsSync(SETTINGS_PATH)) {
|
|
109
|
-
saveSettings(DEFAULT_SETTINGS);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Set API key for a provider
|
|
115
|
-
* Auto-exports to SelfEvolution for AI-powered optimization
|
|
116
|
-
* @param {'gemini' | 'claude'} provider - API provider
|
|
117
|
-
* @param {string} apiKey - The API key
|
|
118
|
-
* @returns {boolean} Success status
|
|
119
|
-
*/
|
|
120
|
-
export function setApiKey(provider, apiKey) {
|
|
121
|
-
try {
|
|
122
|
-
const settings = loadSettings();
|
|
123
|
-
if (!settings.apiKeys) {
|
|
124
|
-
settings.apiKeys = { gemini: null, claude: null };
|
|
125
|
-
}
|
|
126
|
-
settings.apiKeys[provider] = apiKey;
|
|
127
|
-
saveSettings(settings);
|
|
128
|
-
|
|
129
|
-
// Auto-export to SelfEvolution (async, non-blocking)
|
|
130
|
-
import('./selfevolution-bridge.js')
|
|
131
|
-
.then(({ exportApiKeysToSelfEvolution }) => {
|
|
132
|
-
exportApiKeysToSelfEvolution();
|
|
133
|
-
})
|
|
134
|
-
.catch(() => {
|
|
135
|
-
// Silent fail - SelfEvolution might not be present
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
return true;
|
|
139
|
-
} catch (e) {
|
|
140
|
-
console.error(`Failed to set ${provider} API key:`, e.message);
|
|
141
|
-
return false;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Get API key for a provider
|
|
147
|
-
* @param {'gemini' | 'claude'} provider - API provider
|
|
148
|
-
* @returns {string | null} The API key or null
|
|
149
|
-
*/
|
|
150
|
-
export function getApiKey(provider) {
|
|
151
|
-
const settings = loadSettings();
|
|
152
|
-
return settings.apiKeys?.[provider] || null;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* Remove API key for a provider
|
|
157
|
-
* Auto-syncs with SelfEvolution
|
|
158
|
-
* @param {'gemini' | 'claude'} provider - API provider
|
|
159
|
-
* @returns {boolean} Success status
|
|
160
|
-
*/
|
|
161
|
-
export function removeApiKey(provider) {
|
|
162
|
-
try {
|
|
163
|
-
const settings = loadSettings();
|
|
164
|
-
if (settings.apiKeys) {
|
|
165
|
-
settings.apiKeys[provider] = null;
|
|
166
|
-
saveSettings(settings);
|
|
167
|
-
|
|
168
|
-
// Re-export or cleanup if no keys left
|
|
169
|
-
import('./selfevolution-bridge.js')
|
|
170
|
-
.then(({ exportApiKeysToSelfEvolution, cleanupSelfEvolutionEnv }) => {
|
|
171
|
-
const hasAnyKey = settings.apiKeys.gemini || settings.apiKeys.claude;
|
|
172
|
-
if (hasAnyKey) {
|
|
173
|
-
exportApiKeysToSelfEvolution();
|
|
174
|
-
} else {
|
|
175
|
-
cleanupSelfEvolutionEnv();
|
|
176
|
-
}
|
|
177
|
-
})
|
|
178
|
-
.catch(() => {
|
|
179
|
-
// Silent fail
|
|
180
|
-
});
|
|
181
|
-
}
|
|
182
|
-
return true;
|
|
183
|
-
} catch (e) {
|
|
184
|
-
console.error(`Failed to remove ${provider} API key:`, e.message);
|
|
185
|
-
return false;
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
export default {
|
|
190
|
-
loadSettings,
|
|
191
|
-
saveSettings,
|
|
192
|
-
toggleAutoLearning,
|
|
193
|
-
toggleAutoUpdating,
|
|
194
|
-
isAutoLearningEnabled,
|
|
195
|
-
isAutoUpdatingEnabled,
|
|
196
|
-
getUpdateThreshold,
|
|
197
|
-
initSettings,
|
|
198
|
-
setApiKey,
|
|
199
|
-
getApiKey,
|
|
200
|
-
removeApiKey,
|
|
201
|
-
SETTINGS_PATH
|
|
202
|
-
};
|
|
203
|
-
|
|
@@ -1,379 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Skill Generator v7.0 - Auto-generate Skills from Patterns
|
|
3
|
-
*
|
|
4
|
-
* Automatically generates new skills from learned patterns.
|
|
5
|
-
* Converts high-confidence patterns into reusable skills.
|
|
6
|
-
*
|
|
7
|
-
* @version 7.0.0
|
|
8
|
-
* @author PikaKit
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import fs from 'fs';
|
|
12
|
-
import path from 'path';
|
|
13
|
-
import { fileURLToPath } from 'url';
|
|
14
|
-
|
|
15
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
16
|
-
const __dirname = path.dirname(__filename);
|
|
17
|
-
|
|
18
|
-
// Find project root
|
|
19
|
-
function findProjectRoot() {
|
|
20
|
-
let dir = process.cwd();
|
|
21
|
-
while (dir !== path.dirname(dir)) {
|
|
22
|
-
if (fs.existsSync(path.join(dir, '.agent'))) return dir;
|
|
23
|
-
if (fs.existsSync(path.join(dir, 'package.json'))) return dir;
|
|
24
|
-
dir = path.dirname(dir);
|
|
25
|
-
}
|
|
26
|
-
return process.cwd();
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const projectRoot = findProjectRoot();
|
|
30
|
-
const SKILLS_DIR = path.join(projectRoot, '.agent', 'skills', 'auto-generated');
|
|
31
|
-
const SKILLS_REGISTRY = path.join(SKILLS_DIR, 'registry.json');
|
|
32
|
-
|
|
33
|
-
// ============================================================================
|
|
34
|
-
// SKILL TEMPLATES
|
|
35
|
-
// ============================================================================
|
|
36
|
-
|
|
37
|
-
const SKILL_TEMPLATE = `---
|
|
38
|
-
name: {{name}}
|
|
39
|
-
description: {{description}}
|
|
40
|
-
metadata:
|
|
41
|
-
auto_generated: true
|
|
42
|
-
source_pattern: {{patternId}}
|
|
43
|
-
confidence: {{confidence}}
|
|
44
|
-
created: {{created}}
|
|
45
|
-
version: 7.0.0
|
|
46
|
-
---
|
|
47
|
-
|
|
48
|
-
# {{name}}
|
|
49
|
-
|
|
50
|
-
> Auto-generated skill from learned pattern
|
|
51
|
-
|
|
52
|
-
## Description
|
|
53
|
-
{{description}}
|
|
54
|
-
|
|
55
|
-
## When to Use
|
|
56
|
-
{{trigger}}
|
|
57
|
-
|
|
58
|
-
## Resolution
|
|
59
|
-
{{resolution}}
|
|
60
|
-
|
|
61
|
-
## Examples
|
|
62
|
-
\`\`\`
|
|
63
|
-
{{example}}
|
|
64
|
-
\`\`\`
|
|
65
|
-
|
|
66
|
-
## Related Patterns
|
|
67
|
-
- Source: {{patternId}}
|
|
68
|
-
- Confidence: {{confidence}}%
|
|
69
|
-
- Occurrences: {{occurrences}}
|
|
70
|
-
`;
|
|
71
|
-
|
|
72
|
-
// ============================================================================
|
|
73
|
-
// DATA LOADERS
|
|
74
|
-
// ============================================================================
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Ensure skills directory exists
|
|
78
|
-
*/
|
|
79
|
-
function ensureSkillsDir() {
|
|
80
|
-
if (!fs.existsSync(SKILLS_DIR)) {
|
|
81
|
-
fs.mkdirSync(SKILLS_DIR, { recursive: true });
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Load skills registry
|
|
87
|
-
*/
|
|
88
|
-
function loadRegistry() {
|
|
89
|
-
if (fs.existsSync(SKILLS_REGISTRY)) {
|
|
90
|
-
try {
|
|
91
|
-
return JSON.parse(fs.readFileSync(SKILLS_REGISTRY, 'utf8'));
|
|
92
|
-
} catch (e) {
|
|
93
|
-
return getDefaultRegistry();
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
return getDefaultRegistry();
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Save skills registry
|
|
101
|
-
*/
|
|
102
|
-
function saveRegistry(registry) {
|
|
103
|
-
ensureSkillsDir();
|
|
104
|
-
registry.lastUpdated = new Date().toISOString();
|
|
105
|
-
fs.writeFileSync(SKILLS_REGISTRY, JSON.stringify(registry, null, 2));
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Get default registry structure
|
|
110
|
-
*/
|
|
111
|
-
function getDefaultRegistry() {
|
|
112
|
-
return {
|
|
113
|
-
skills: [],
|
|
114
|
-
totalGenerated: 0,
|
|
115
|
-
lastUpdated: new Date().toISOString()
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// ============================================================================
|
|
120
|
-
// SKILL GENERATION
|
|
121
|
-
// ============================================================================
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* Generate a skill from a pattern
|
|
125
|
-
*/
|
|
126
|
-
export function generateSkillFromPattern(pattern) {
|
|
127
|
-
ensureSkillsDir();
|
|
128
|
-
|
|
129
|
-
// Validate pattern has required fields
|
|
130
|
-
if (!pattern || !pattern.id || !pattern.cause) {
|
|
131
|
-
return { success: false, error: 'Invalid pattern' };
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// Check confidence threshold (min 70%)
|
|
135
|
-
const confidence = pattern.confidence || 0.7;
|
|
136
|
-
if (confidence < 0.7) {
|
|
137
|
-
return { success: false, error: 'Pattern confidence too low (min 70%)' };
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// Generate skill name from pattern
|
|
141
|
-
const skillName = generateSkillName(pattern);
|
|
142
|
-
const skillSlug = skillName.toLowerCase().replace(/\s+/g, '-').replace(/[^a-z0-9-]/g, '');
|
|
143
|
-
|
|
144
|
-
// Check if skill already exists
|
|
145
|
-
const registry = loadRegistry();
|
|
146
|
-
if (registry.skills.some(s => s.patternId === pattern.id)) {
|
|
147
|
-
return { success: false, error: 'Skill already generated for this pattern' };
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// Generate skill content
|
|
151
|
-
const content = SKILL_TEMPLATE
|
|
152
|
-
.replace(/\{\{name\}\}/g, skillName)
|
|
153
|
-
.replace(/\{\{description\}\}/g, pattern.effect || 'Auto-generated skill')
|
|
154
|
-
.replace(/\{\{patternId\}\}/g, pattern.id)
|
|
155
|
-
.replace(/\{\{confidence\}\}/g, Math.round(confidence * 100).toString())
|
|
156
|
-
.replace(/\{\{created\}\}/g, new Date().toISOString())
|
|
157
|
-
.replace(/\{\{trigger\}\}/g, pattern.cause || 'When pattern detected')
|
|
158
|
-
.replace(/\{\{resolution\}\}/g, pattern.resolution || 'Apply learned fix')
|
|
159
|
-
.replace(/\{\{example\}\}/g, pattern.cause || '// Example code')
|
|
160
|
-
.replace(/\{\{occurrences\}\}/g, (pattern.occurrences || 1).toString());
|
|
161
|
-
|
|
162
|
-
// Write skill file
|
|
163
|
-
const skillPath = path.join(SKILLS_DIR, `${skillSlug}.md`);
|
|
164
|
-
fs.writeFileSync(skillPath, content);
|
|
165
|
-
|
|
166
|
-
// Update registry
|
|
167
|
-
const skillEntry = {
|
|
168
|
-
id: `auto-${skillSlug}`,
|
|
169
|
-
name: skillName,
|
|
170
|
-
patternId: pattern.id,
|
|
171
|
-
path: skillPath,
|
|
172
|
-
confidence: Math.round(confidence * 100),
|
|
173
|
-
created: new Date().toISOString(),
|
|
174
|
-
usageCount: 0
|
|
175
|
-
};
|
|
176
|
-
|
|
177
|
-
registry.skills.push(skillEntry);
|
|
178
|
-
registry.totalGenerated = (registry.totalGenerated || 0) + 1;
|
|
179
|
-
saveRegistry(registry);
|
|
180
|
-
|
|
181
|
-
return { success: true, skill: skillEntry };
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
/**
|
|
185
|
-
* Generate a readable skill name from pattern
|
|
186
|
-
*/
|
|
187
|
-
function generateSkillName(pattern) {
|
|
188
|
-
const category = pattern.category || 'general';
|
|
189
|
-
const cause = pattern.cause || 'unknown';
|
|
190
|
-
|
|
191
|
-
// Extract key words from cause
|
|
192
|
-
const words = cause
|
|
193
|
-
.replace(/[^a-zA-Z0-9\s]/g, ' ')
|
|
194
|
-
.split(/\s+/)
|
|
195
|
-
.filter(w => w.length > 2)
|
|
196
|
-
.slice(0, 3)
|
|
197
|
-
.map(w => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase());
|
|
198
|
-
|
|
199
|
-
if (words.length === 0) {
|
|
200
|
-
words.push('Auto');
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
// Add category prefix
|
|
204
|
-
const categoryMap = {
|
|
205
|
-
'import-error': 'Import Fix',
|
|
206
|
-
'type-error': 'Type Fix',
|
|
207
|
-
'syntax-error': 'Syntax Fix',
|
|
208
|
-
'null-reference': 'Null Check',
|
|
209
|
-
'async-error': 'Async Fix',
|
|
210
|
-
'api-error': 'API Fix',
|
|
211
|
-
'file-error': 'File Fix',
|
|
212
|
-
'config-error': 'Config Fix',
|
|
213
|
-
'general': 'Auto'
|
|
214
|
-
};
|
|
215
|
-
|
|
216
|
-
const prefix = categoryMap[category] || 'Auto';
|
|
217
|
-
return `${prefix}: ${words.join(' ')}`;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
// ============================================================================
|
|
221
|
-
// QUERIES
|
|
222
|
-
// ============================================================================
|
|
223
|
-
|
|
224
|
-
/**
|
|
225
|
-
* Get all auto-generated skills
|
|
226
|
-
*/
|
|
227
|
-
export function getAllSkills() {
|
|
228
|
-
const registry = loadRegistry();
|
|
229
|
-
return registry.skills || [];
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
/**
|
|
233
|
-
* Get skill count
|
|
234
|
-
*/
|
|
235
|
-
export function getSkillCount() {
|
|
236
|
-
const registry = loadRegistry();
|
|
237
|
-
return registry.skills?.length || 0;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
/**
|
|
241
|
-
* Get skill stats
|
|
242
|
-
*/
|
|
243
|
-
export function getSkillStats() {
|
|
244
|
-
const registry = loadRegistry();
|
|
245
|
-
const skills = registry.skills || [];
|
|
246
|
-
|
|
247
|
-
// Group by category
|
|
248
|
-
const byCategory = {};
|
|
249
|
-
for (const skill of skills) {
|
|
250
|
-
const cat = skill.name?.split(':')[0] || 'Auto';
|
|
251
|
-
byCategory[cat] = (byCategory[cat] || 0) + 1;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
// Calculate average confidence
|
|
255
|
-
const avgConfidence = skills.length > 0
|
|
256
|
-
? skills.reduce((sum, s) => sum + (s.confidence || 0), 0) / skills.length
|
|
257
|
-
: 0;
|
|
258
|
-
|
|
259
|
-
return {
|
|
260
|
-
total: skills.length,
|
|
261
|
-
totalGenerated: registry.totalGenerated || 0,
|
|
262
|
-
byCategory,
|
|
263
|
-
avgConfidence: Math.round(avgConfidence)
|
|
264
|
-
};
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
/**
|
|
268
|
-
* Load auto skills (alias for dashboard)
|
|
269
|
-
*/
|
|
270
|
-
export function loadAutoSkills() {
|
|
271
|
-
return getAllSkills();
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
/**
|
|
275
|
-
* Get skill by ID
|
|
276
|
-
*/
|
|
277
|
-
export function getSkill(skillId) {
|
|
278
|
-
const registry = loadRegistry();
|
|
279
|
-
return registry.skills?.find(s => s.id === skillId);
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
/**
|
|
283
|
-
* Record skill usage
|
|
284
|
-
*/
|
|
285
|
-
export function recordSkillUsage(skillId) {
|
|
286
|
-
const registry = loadRegistry();
|
|
287
|
-
const skill = registry.skills?.find(s => s.id === skillId);
|
|
288
|
-
|
|
289
|
-
if (skill) {
|
|
290
|
-
skill.usageCount = (skill.usageCount || 0) + 1;
|
|
291
|
-
skill.lastUsed = new Date().toISOString();
|
|
292
|
-
saveRegistry(registry);
|
|
293
|
-
return { success: true };
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
return { success: false, error: 'Skill not found' };
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
/**
|
|
300
|
-
* Delete an auto-generated skill
|
|
301
|
-
*/
|
|
302
|
-
export function deleteSkill(skillId) {
|
|
303
|
-
const registry = loadRegistry();
|
|
304
|
-
const skillIndex = registry.skills?.findIndex(s => s.id === skillId);
|
|
305
|
-
|
|
306
|
-
if (skillIndex === -1 || skillIndex === undefined) {
|
|
307
|
-
return { success: false, error: 'Skill not found' };
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
const skill = registry.skills[skillIndex];
|
|
311
|
-
|
|
312
|
-
// Delete the skill file
|
|
313
|
-
if (skill.path && fs.existsSync(skill.path)) {
|
|
314
|
-
fs.unlinkSync(skill.path);
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
// Remove from registry
|
|
318
|
-
registry.skills.splice(skillIndex, 1);
|
|
319
|
-
saveRegistry(registry);
|
|
320
|
-
|
|
321
|
-
return { success: true };
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
// ============================================================================
|
|
325
|
-
// BATCH GENERATION
|
|
326
|
-
// ============================================================================
|
|
327
|
-
|
|
328
|
-
/**
|
|
329
|
-
* Generate skills from all high-confidence patterns
|
|
330
|
-
*/
|
|
331
|
-
export async function generateFromAllPatterns(minConfidence = 0.7) {
|
|
332
|
-
// Try to import causality engine
|
|
333
|
-
let causalityEngine;
|
|
334
|
-
try {
|
|
335
|
-
causalityEngine = await import('./causality-engine.js');
|
|
336
|
-
} catch (e) {
|
|
337
|
-
return { success: false, error: 'Causality engine not available' };
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
const patterns = causalityEngine.loadCausalPatterns?.() || [];
|
|
341
|
-
const results = {
|
|
342
|
-
generated: 0,
|
|
343
|
-
skipped: 0,
|
|
344
|
-
errors: []
|
|
345
|
-
};
|
|
346
|
-
|
|
347
|
-
for (const pattern of patterns) {
|
|
348
|
-
if ((pattern.confidence || 0) >= minConfidence) {
|
|
349
|
-
const result = generateSkillFromPattern(pattern);
|
|
350
|
-
if (result.success) {
|
|
351
|
-
results.generated++;
|
|
352
|
-
} else {
|
|
353
|
-
if (result.error === 'Skill already generated for this pattern') {
|
|
354
|
-
results.skipped++;
|
|
355
|
-
} else {
|
|
356
|
-
results.errors.push({ patternId: pattern.id, error: result.error });
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
return { success: true, results };
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
// ============================================================================
|
|
366
|
-
// EXPORTS
|
|
367
|
-
// ============================================================================
|
|
368
|
-
|
|
369
|
-
export default {
|
|
370
|
-
generateSkillFromPattern,
|
|
371
|
-
getAllSkills,
|
|
372
|
-
getSkillCount,
|
|
373
|
-
getSkillStats,
|
|
374
|
-
loadAutoSkills,
|
|
375
|
-
getSkill,
|
|
376
|
-
recordSkillUsage,
|
|
377
|
-
deleteSkill,
|
|
378
|
-
generateFromAllPatterns
|
|
379
|
-
};
|