add-skill-kit 3.2.3 โ†’ 3.2.5

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.
Files changed (126) hide show
  1. package/README.md +1 -1
  2. package/bin/lib/commands/help.js +0 -4
  3. package/bin/lib/commands/install.js +90 -9
  4. package/bin/lib/ui.js +1 -1
  5. package/lib/agent-cli/__tests__/adaptive_engine.test.js +190 -0
  6. package/lib/agent-cli/__tests__/integration/cross_script.test.js +222 -0
  7. package/lib/agent-cli/__tests__/integration/full_cycle.test.js +230 -0
  8. package/lib/agent-cli/__tests__/pattern_analyzer.test.js +173 -0
  9. package/lib/agent-cli/__tests__/pre_execution_check.test.js +167 -0
  10. package/lib/agent-cli/__tests__/skill_injector.test.js +191 -0
  11. package/lib/agent-cli/bin/agent.js +191 -0
  12. package/lib/agent-cli/dashboard/dashboard_server.js +340 -0
  13. package/lib/agent-cli/dashboard/index.html +538 -0
  14. package/lib/agent-cli/lib/audit.js +154 -0
  15. package/lib/agent-cli/lib/audit.test.js +100 -0
  16. package/lib/agent-cli/lib/auto-learn.js +319 -0
  17. package/lib/agent-cli/lib/auto_preview.py +148 -0
  18. package/lib/agent-cli/lib/backup.js +138 -0
  19. package/lib/agent-cli/lib/backup.test.js +78 -0
  20. package/lib/agent-cli/lib/checklist.py +222 -0
  21. package/lib/agent-cli/lib/cognitive-lesson.js +476 -0
  22. package/lib/agent-cli/lib/completion.js +149 -0
  23. package/lib/agent-cli/lib/config.js +35 -0
  24. package/lib/agent-cli/lib/eslint-fix.js +238 -0
  25. package/lib/agent-cli/lib/evolution-signal.js +215 -0
  26. package/lib/agent-cli/lib/export.js +86 -0
  27. package/lib/agent-cli/lib/export.test.js +65 -0
  28. package/lib/agent-cli/lib/fix.js +337 -0
  29. package/lib/agent-cli/lib/fix.test.js +80 -0
  30. package/lib/agent-cli/lib/gemini-export.js +83 -0
  31. package/lib/agent-cli/lib/generate-registry.js +42 -0
  32. package/lib/agent-cli/lib/hooks/install-hooks.js +152 -0
  33. package/lib/agent-cli/lib/hooks/lint-learn.js +172 -0
  34. package/lib/agent-cli/lib/ignore.js +116 -0
  35. package/lib/agent-cli/lib/ignore.test.js +58 -0
  36. package/lib/agent-cli/lib/init.js +124 -0
  37. package/lib/agent-cli/lib/learn.js +255 -0
  38. package/lib/agent-cli/lib/learn.test.js +70 -0
  39. package/lib/agent-cli/lib/migrate-to-v4.js +322 -0
  40. package/lib/agent-cli/lib/proposals.js +199 -0
  41. package/lib/agent-cli/lib/proposals.test.js +56 -0
  42. package/lib/agent-cli/lib/recall.js +820 -0
  43. package/lib/agent-cli/lib/recall.test.js +107 -0
  44. package/lib/agent-cli/lib/selfevolution-bridge.js +167 -0
  45. package/lib/agent-cli/lib/session_manager.py +120 -0
  46. package/lib/agent-cli/lib/settings.js +227 -0
  47. package/lib/agent-cli/lib/skill-learn.js +296 -0
  48. package/lib/agent-cli/lib/stats.js +132 -0
  49. package/lib/agent-cli/lib/stats.test.js +94 -0
  50. package/lib/agent-cli/lib/types.js +33 -0
  51. package/lib/agent-cli/lib/ui/audit-ui.js +146 -0
  52. package/lib/agent-cli/lib/ui/backup-ui.js +107 -0
  53. package/lib/agent-cli/lib/ui/clack-helpers.js +317 -0
  54. package/lib/agent-cli/lib/ui/common.js +83 -0
  55. package/lib/agent-cli/lib/ui/completion-ui.js +126 -0
  56. package/lib/agent-cli/lib/ui/custom-select.js +69 -0
  57. package/lib/agent-cli/lib/ui/dashboard-ui.js +222 -0
  58. package/lib/agent-cli/lib/ui/evolution-signals-ui.js +107 -0
  59. package/lib/agent-cli/lib/ui/export-ui.js +94 -0
  60. package/lib/agent-cli/lib/ui/fix-all-ui.js +191 -0
  61. package/lib/agent-cli/lib/ui/help-ui.js +49 -0
  62. package/lib/agent-cli/lib/ui/index.js +199 -0
  63. package/lib/agent-cli/lib/ui/init-ui.js +56 -0
  64. package/lib/agent-cli/lib/ui/knowledge-ui.js +55 -0
  65. package/lib/agent-cli/lib/ui/learn-ui.js +706 -0
  66. package/lib/agent-cli/lib/ui/lessons-ui.js +148 -0
  67. package/lib/agent-cli/lib/ui/pretty.js +145 -0
  68. package/lib/agent-cli/lib/ui/proposals-ui.js +99 -0
  69. package/lib/agent-cli/lib/ui/recall-ui.js +342 -0
  70. package/lib/agent-cli/lib/ui/routing-demo.js +79 -0
  71. package/lib/agent-cli/lib/ui/routing-ui.js +325 -0
  72. package/lib/agent-cli/lib/ui/settings-ui.js +381 -0
  73. package/lib/agent-cli/lib/ui/stats-ui.js +123 -0
  74. package/lib/agent-cli/lib/ui/watch-ui.js +236 -0
  75. package/lib/agent-cli/lib/verify_all.py +327 -0
  76. package/lib/agent-cli/lib/watcher.js +181 -0
  77. package/lib/agent-cli/lib/watcher.test.js +85 -0
  78. package/lib/agent-cli/package.json +51 -0
  79. package/lib/agent-cli/scripts/adaptive_engine.js +381 -0
  80. package/lib/agent-cli/scripts/dashboard_server.js +224 -0
  81. package/lib/agent-cli/scripts/error_sensor.js +565 -0
  82. package/lib/agent-cli/scripts/learn_from_failure.js +225 -0
  83. package/lib/agent-cli/scripts/pattern_analyzer.js +781 -0
  84. package/lib/agent-cli/scripts/pre_execution_check.js +623 -0
  85. package/lib/agent-cli/scripts/rule_sharing.js +374 -0
  86. package/lib/agent-cli/scripts/skill_injector.js +387 -0
  87. package/lib/agent-cli/scripts/success_sensor.js +500 -0
  88. package/lib/agent-cli/scripts/user_correction_sensor.js +426 -0
  89. package/lib/agent-cli/services/auto-learn-service.js +247 -0
  90. package/lib/agent-cli/src/MIGRATION.md +418 -0
  91. package/lib/agent-cli/src/README.md +367 -0
  92. package/lib/agent-cli/src/core/evolution/evolution-signal.js +42 -0
  93. package/lib/agent-cli/src/core/evolution/index.js +17 -0
  94. package/lib/agent-cli/src/core/evolution/review-gate.js +40 -0
  95. package/lib/agent-cli/src/core/evolution/signal-detector.js +137 -0
  96. package/lib/agent-cli/src/core/evolution/signal-queue.js +79 -0
  97. package/lib/agent-cli/src/core/evolution/threshold-checker.js +79 -0
  98. package/lib/agent-cli/src/core/index.js +15 -0
  99. package/lib/agent-cli/src/core/learning/cognitive-enhancer.js +282 -0
  100. package/lib/agent-cli/src/core/learning/index.js +12 -0
  101. package/lib/agent-cli/src/core/learning/lesson-synthesizer.js +83 -0
  102. package/lib/agent-cli/src/core/scanning/index.js +14 -0
  103. package/lib/agent-cli/src/data/index.js +13 -0
  104. package/lib/agent-cli/src/data/repositories/index.js +8 -0
  105. package/lib/agent-cli/src/data/repositories/lesson-repository.js +130 -0
  106. package/lib/agent-cli/src/data/repositories/signal-repository.js +119 -0
  107. package/lib/agent-cli/src/data/storage/index.js +8 -0
  108. package/lib/agent-cli/src/data/storage/json-storage.js +64 -0
  109. package/lib/agent-cli/src/data/storage/yaml-storage.js +66 -0
  110. package/lib/agent-cli/src/infrastructure/index.js +13 -0
  111. package/lib/agent-cli/src/presentation/formatters/skill-formatter.js +232 -0
  112. package/lib/agent-cli/src/services/export-service.js +162 -0
  113. package/lib/agent-cli/src/services/index.js +13 -0
  114. package/lib/agent-cli/src/services/learning-service.js +99 -0
  115. package/lib/agent-cli/types/index.d.ts +343 -0
  116. package/lib/agent-cli/utils/benchmark.js +269 -0
  117. package/lib/agent-cli/utils/logger.js +303 -0
  118. package/lib/agent-cli/utils/ml_patterns.js +300 -0
  119. package/lib/agent-cli/utils/recovery.js +312 -0
  120. package/lib/agent-cli/utils/telemetry.js +290 -0
  121. package/lib/agentskillskit-cli/README.md +21 -0
  122. package/{node_modules/agentskillskit-cli/bin โ†’ lib/agentskillskit-cli}/ag-smart.js +15 -15
  123. package/lib/agentskillskit-cli/package.json +51 -0
  124. package/package.json +19 -9
  125. /package/bin/{cli.js โ†’ kit.js} +0 -0
  126. /package/{node_modules/agentskillskit-cli โ†’ lib/agent-cli}/README.md +0 -0
@@ -0,0 +1,222 @@
1
+ /**
2
+ * Dashboard UI - Launch Auto-Learn Dashboard in browser
3
+ */
4
+ import * as p from "@clack/prompts";
5
+ import { spawn, exec } from "child_process";
6
+ import path from "path";
7
+ import fs from "fs";
8
+ import http from "http";
9
+
10
+ // Track running server globally
11
+ let runningServer = null;
12
+ let runningPort = null;
13
+
14
+ /**
15
+ * Check if a port is already in use by our dashboard
16
+ * Uses /api/summary to verify it's actually our dashboard server
17
+ */
18
+ async function checkPortInUse(port) {
19
+ return new Promise((resolve) => {
20
+ const req = http.get(`http://localhost:${port}/api/summary`, (res) => {
21
+ // If we get 200 response from /api/summary, it's our dashboard
22
+ if (res.statusCode === 200) {
23
+ resolve(true);
24
+ } else {
25
+ resolve(false);
26
+ }
27
+ req.destroy();
28
+ });
29
+ req.on('error', () => {
30
+ resolve(false);
31
+ });
32
+ // Faster timeout - 500ms is enough for localhost
33
+ req.setTimeout(500, () => {
34
+ req.destroy();
35
+ resolve(false);
36
+ });
37
+ });
38
+ }
39
+
40
+ /**
41
+ * Find existing dashboard server on ports 3030-3040
42
+ */
43
+ async function findExistingServer() {
44
+ // Check ports in parallel for faster detection
45
+ const portChecks = [];
46
+ for (let port = 3030; port <= 3040; port++) {
47
+ portChecks.push(checkPortInUse(port).then(inUse => inUse ? port : null));
48
+ }
49
+
50
+ const results = await Promise.all(portChecks);
51
+ const existingPort = results.find(port => port !== null);
52
+ return existingPort || null;
53
+ }
54
+
55
+ /**
56
+ * Find an available port
57
+ */
58
+ async function findAvailablePort(startPort = 3030) {
59
+ return new Promise((resolve) => {
60
+ const server = http.createServer();
61
+ server.listen(startPort, () => {
62
+ server.close(() => resolve(startPort));
63
+ });
64
+ server.on("error", () => {
65
+ resolve(findAvailablePort(startPort + 1));
66
+ });
67
+ });
68
+ }
69
+
70
+ /**
71
+ * Find dashboard server script
72
+ */
73
+ function findDashboardScript() {
74
+ // Get the directory where this module is located
75
+ const moduleDir = path.dirname(new URL(import.meta.url).pathname.replace(/^\/([A-Z]:)/i, '$1'));
76
+ const cliRoot = path.resolve(moduleDir, '..', '..');
77
+
78
+ // User home directory
79
+ const homeDir = process.env.USERPROFILE || process.env.HOME || '';
80
+
81
+ const possiblePaths = [
82
+ // PRIORITY 1: Bundled with CLI package (always available)
83
+ path.join(cliRoot, "dashboard", "dashboard_server.js"),
84
+ // PRIORITY 2: Current project paths
85
+ path.join(process.cwd(), ".agent", "skills", "auto-learner", "scripts", "dashboard_server.js"),
86
+ path.join(process.cwd(), ".agent", "agentskillskit", ".agent", "skills", "auto-learner", "scripts", "dashboard_server.js"),
87
+ // PRIORITY 3: Fallback user paths (Windows Desktop)
88
+ path.join(homeDir, "Desktop", "agent-skill-kit", ".agent", "skills", "auto-learner", "scripts", "dashboard_server.js"),
89
+ ];
90
+
91
+ for (const searchPath of possiblePaths) {
92
+ if (fs.existsSync(searchPath)) {
93
+ return searchPath;
94
+ }
95
+ }
96
+ return null;
97
+ }
98
+
99
+ /**
100
+ * Open URL in default browser
101
+ */
102
+ function openBrowser(url) {
103
+ const platform = process.platform;
104
+ let command;
105
+
106
+ if (platform === "win32") {
107
+ command = `start "" "${url}"`;
108
+ } else if (platform === "darwin") {
109
+ command = `open "${url}"`;
110
+ } else {
111
+ command = `xdg-open "${url}"`;
112
+ }
113
+
114
+ exec(command, (err) => {
115
+ if (err) {
116
+ p.log.warn(`Could not open browser automatically. Visit: ${url}`);
117
+ }
118
+ });
119
+ }
120
+
121
+ /**
122
+ * Run Dashboard UI
123
+ */
124
+ export async function runDashboardUI() {
125
+ const spinner = p.spinner();
126
+
127
+ // Check if there's already a server running
128
+ spinner.start("Checking for existing dashboard server...");
129
+ const existingPort = await findExistingServer();
130
+
131
+ if (existingPort) {
132
+ spinner.stop(`Found existing server on port ${existingPort}`);
133
+ const url = `http://localhost:${existingPort}`;
134
+
135
+ p.log.success(`Dashboard already running at: ${url}`);
136
+ openBrowser(url);
137
+
138
+ p.note(`Server running on port ${existingPort}\nUsing existing server`, "๐Ÿ“Š Auto-Learn Dashboard");
139
+
140
+ const action = await p.select({
141
+ message: "Dashboard is running. What would you like to do?",
142
+ options: [
143
+ { value: "keep", label: "๐Ÿ  Back to menu", hint: "Keep server running" },
144
+ { value: "stop", label: "๐Ÿ›‘ Stop server", hint: "Shutdown dashboard" }
145
+ ]
146
+ });
147
+
148
+ if (action === "stop") {
149
+ // Kill all node processes on that port
150
+ p.log.info("Stopping existing server...");
151
+ if (process.platform === "win32") {
152
+ exec(`for /f "tokens=5" %a in ('netstat -aon ^| findstr :${existingPort}') do taskkill /F /PID %a`, () => { });
153
+ } else {
154
+ exec(`lsof -ti:${existingPort} | xargs kill -9`, () => { });
155
+ }
156
+ await new Promise(r => setTimeout(r, 1000));
157
+ p.log.success("Dashboard server stopped");
158
+ }
159
+ return;
160
+ }
161
+
162
+ spinner.stop("No existing server found");
163
+
164
+ // Find dashboard script
165
+ const scriptPath = findDashboardScript();
166
+
167
+ if (!scriptPath) {
168
+ p.log.error("Dashboard script not found!");
169
+ p.log.info("Install auto-learner skill first or check .agent/skills/auto-learner/scripts/");
170
+ return;
171
+ }
172
+
173
+ // Find available port
174
+ spinner.start("Finding available port...");
175
+ const port = await findAvailablePort(3030);
176
+ runningPort = port;
177
+ spinner.stop(`Using port ${port}`);
178
+
179
+ // Start dashboard server
180
+ spinner.start("Starting dashboard server...");
181
+
182
+ const child = spawn("node", [scriptPath, "--port", String(port)], {
183
+ stdio: ["ignore", "pipe", "pipe"],
184
+ detached: false
185
+ });
186
+
187
+ runningServer = child;
188
+
189
+ // Wait for server to start
190
+ await new Promise((resolve) => setTimeout(resolve, 1500));
191
+
192
+ spinner.stop("Dashboard server started!");
193
+
194
+ const url = `http://localhost:${port}`;
195
+
196
+ // Open browser
197
+ p.log.success(`Dashboard running at: ${url}`);
198
+ openBrowser(url);
199
+
200
+ p.log.info("Dashboard opened in browser");
201
+ p.note(`Server running on port ${port}\nPress Ctrl+C in terminal to stop`, "๐Ÿ“Š Auto-Learn Dashboard");
202
+
203
+ // Keep server running and wait for user
204
+ const action = await p.select({
205
+ message: "Dashboard is running. What would you like to do?",
206
+ options: [
207
+ { value: "keep", label: "๐Ÿ  Back to menu", hint: "Keep server running" },
208
+ { value: "stop", label: "๐Ÿ›‘ Stop server", hint: "Shutdown dashboard" }
209
+ ]
210
+ });
211
+
212
+ if (action === "stop" || p.isCancel(action)) {
213
+ child.kill();
214
+ runningServer = null;
215
+ runningPort = null;
216
+ p.log.info("Dashboard server stopped");
217
+ } else {
218
+ p.log.info(`Dashboard still running at ${url}`);
219
+ }
220
+ }
221
+
222
+ export default runDashboardUI;
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Evolution Signals UI - View and manage pending evolution signals
3
+ */
4
+ import * as p from "@clack/prompts";
5
+ import pc from "picocolors";
6
+ import { signalQueue, getEvolutionStats, reviewGate } from "../evolution-signal.js";
7
+ import { loadKnowledge } from "../recall.js";
8
+ import { loadSettings } from "../settings.js";
9
+
10
+ /**
11
+ * Show pending evolution signals
12
+ */
13
+ export async function runEvolutionSignalsUI() {
14
+ p.intro("๐Ÿ“ก Evolution Signals");
15
+
16
+ const pending = signalQueue.getPending();
17
+ const stats = getEvolutionStats();
18
+
19
+ // Show summary
20
+ p.note(
21
+ `Pending: ${pc.yellow(stats.pending)}\n` +
22
+ `Approved: ${pc.green(stats.approved)}\n` +
23
+ `Rejected: ${pc.red(stats.rejected)}\n` +
24
+ `Executed: ${pc.cyan(stats.executed)}`,
25
+ "๐Ÿ“Š Signal Queue Status"
26
+ );
27
+
28
+ if (pending.length === 0) {
29
+ p.note(pc.dim("No pending evolution signals"), "โœ… All Clear");
30
+ return;
31
+ }
32
+
33
+ // Load lessons for context
34
+ const db = loadKnowledge();
35
+ const settings = loadSettings();
36
+
37
+ // Display pending signals with details
38
+ const signalChoices = pending.map(signal => {
39
+ const lesson = db.lessons.find(l => l.id === signal.lessonId);
40
+ const lessonName = lesson ? lesson.id : signal.lessonId;
41
+ const gate = reviewGate(signal, {
42
+ autoUpdating: settings.autoUpdating,
43
+ confidenceThreshold: 0.8
44
+ });
45
+
46
+ return {
47
+ value: signal.id,
48
+ label: `${pc.yellow('โ—')} ${lessonName}`,
49
+ hint: `${signal.reason} ยท confidence: ${(signal.confidence * 100).toFixed(0)}% ${gate.shouldAuto ? pc.green('(auto-eligible)') : pc.dim('(review)')}`
50
+ };
51
+ });
52
+
53
+ const action = await p.select({
54
+ message: "Pending Evolution Signals",
55
+ options: [
56
+ ...signalChoices,
57
+ { value: "back", label: "โ† Back" }
58
+ ]
59
+ });
60
+
61
+ if (p.isCancel(action) || action === "back") {
62
+ return;
63
+ }
64
+
65
+ // Show signal details
66
+ const signal = pending.find(s => s.id === action);
67
+ if (!signal) return;
68
+
69
+ const lesson = db.lessons.find(l => l.id === signal.lessonId);
70
+
71
+ p.note(
72
+ `${pc.bold('Lesson:')} ${signal.lessonId}\n` +
73
+ `${pc.bold('Reason:')} ${signal.reason}\n` +
74
+ `${pc.bold('Confidence:')} ${(signal.confidence * 100).toFixed(0)}%\n` +
75
+ `${pc.bold('Created:')} ${new Date(signal.createdAt).toLocaleString()}\n\n` +
76
+ `${pc.bold('Current Stats:')}\n` +
77
+ ` Hit Count: ${lesson?.hitCount || 0}\n` +
78
+ ` Maturity: ${lesson?.cognitive?.maturity || 'unknown'}\n` +
79
+ ` Intent: ${lesson?.intent || 'unknown'}\n\n` +
80
+ `${pc.bold('Metadata:')}\n` +
81
+ ` Trigger: ${signal.metadata.triggerEvent}\n` +
82
+ ` File: ${signal.metadata.file || 'N/A'}`,
83
+ "๐Ÿ” Signal Details"
84
+ );
85
+
86
+ // Action options
87
+ const signalAction = await p.select({
88
+ message: "What would you like to do?",
89
+ options: [
90
+ { value: "approve", label: "โœ… Approve", hint: "Mark for evolution" },
91
+ { value: "reject", label: "โŒ Reject", hint: "Dismiss this signal" },
92
+ { value: "back", label: "โ† Back" }
93
+ ]
94
+ });
95
+
96
+ if (p.isCancel(signalAction) || signalAction === "back") {
97
+ return;
98
+ }
99
+
100
+ if (signalAction === "approve") {
101
+ signalQueue.approve(signal.id);
102
+ p.note(pc.green(`โœ… Signal approved for [${signal.lessonId}]`));
103
+ } else if (signalAction === "reject") {
104
+ signalQueue.reject(signal.id);
105
+ p.note(pc.red(`โŒ Signal rejected for [${signal.lessonId}]`));
106
+ }
107
+ }
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Export/Import UI - Share settings between projects
3
+ */
4
+ import * as p from "@clack/prompts";
5
+ import pc from "picocolors";
6
+ import path from "path";
7
+ import { cwd } from "../config.js";
8
+ import { exportData, importData } from "../export.js";
9
+
10
+ /**
11
+ * Interactive export/import menu
12
+ */
13
+ export async function runExportUI() {
14
+ p.intro("Export & Import (Press ESC to exit)");
15
+
16
+ while (true) {
17
+
18
+ const action = await p.select({
19
+ message: "What would you like to do?",
20
+ options: [
21
+ { value: "export", label: "Export", hint: "Export lessons to file" },
22
+ { value: "import", label: "Import", hint: "Import lessons from file" },
23
+ { value: "back", label: "โ† Back", hint: "Return to main menu" }
24
+ ]
25
+ });
26
+
27
+ if (p.isCancel(action) || action === "back") {
28
+ return;
29
+ }
30
+
31
+ switch (action) {
32
+ case "export": {
33
+ const filename = await p.text({
34
+ message: "Export filename:",
35
+ placeholder: "agent-skills-export.json",
36
+ initialValue: "agent-skills-export.json"
37
+ });
38
+
39
+ if (p.isCancel(filename)) break;
40
+
41
+ const outputPath = path.join(cwd, filename);
42
+ const success = exportData(outputPath);
43
+
44
+ if (success) {
45
+ p.note(
46
+ `Exported to:\n${pc.dim(outputPath)}`,
47
+ pc.green("Success")
48
+ );
49
+ } else {
50
+ p.note("Failed to export", pc.red("Error"));
51
+ }
52
+ break;
53
+ }
54
+
55
+ case "import": {
56
+ const filename = await p.text({
57
+ message: "Import filename:",
58
+ placeholder: "agent-skills-export.json",
59
+ validate: (v) => {
60
+ if (!v) return "Filename required";
61
+ }
62
+ });
63
+
64
+ if (p.isCancel(filename)) break;
65
+
66
+ const mode = await p.select({
67
+ message: "Import mode:",
68
+ options: [
69
+ { value: "merge", label: "Merge", hint: "Add new, keep existing" },
70
+ { value: "replace", label: "Replace", hint: "Overwrite all data" }
71
+ ]
72
+ });
73
+
74
+ if (p.isCancel(mode)) break;
75
+
76
+ const inputPath = path.join(cwd, filename);
77
+ const result = importData(inputPath, mode);
78
+
79
+ if (result.success) {
80
+ p.note(
81
+ `Imported ${result.lessonsCount} lesson(s)\n` +
82
+ `Settings: ${result.hasSettings ? "Yes" : "No"}`,
83
+ pc.green("Success")
84
+ );
85
+ } else {
86
+ p.note("Failed to import. Check file exists and is valid JSON.", pc.red("Error"));
87
+ }
88
+ break;
89
+ }
90
+ }
91
+ }
92
+ }
93
+
94
+ export default runExportUI;
@@ -0,0 +1,191 @@
1
+ /**
2
+ * Fix All UI - Agent Coding Handoff (Smart Version)
3
+ * Instead of brittle regex auto-fix, generates AI-friendly prompts
4
+ */
5
+ import * as p from "@clack/prompts";
6
+ import pc from "picocolors";
7
+ import path from "path";
8
+ import fs from "fs";
9
+ import { execSync } from "child_process";
10
+ import { showIntro, createSpinner, showSuccessNote, showErrorNote, theme } from "./clack-helpers.js";
11
+ import { loadMostRecentScan, loadScanResult } from "../recall.js";
12
+
13
+ /**
14
+ * Fix All UI - Generate Agent handoff prompts
15
+ */
16
+ export async function runFixAllUI(scanId = null) {
17
+ showIntro('๐Ÿ”ง Fix All - Agent Handoff');
18
+
19
+ // 1. Get scan results
20
+ let scanResult;
21
+ const spinner = createSpinner('Loading scan results...');
22
+
23
+ if (!scanId) {
24
+ scanResult = loadMostRecentScan();
25
+ } else {
26
+ scanResult = loadScanResult(scanId);
27
+ }
28
+
29
+ spinner.stop();
30
+
31
+ if (!scanResult) {
32
+ showErrorNote(
33
+ 'No scan results found.\\n\\n' +
34
+ 'Run "Scan All" first to generate scan data.',
35
+ 'โœ— No Scan Results'
36
+ );
37
+ return;
38
+ }
39
+
40
+ // 2. Show summary
41
+ console.log(`\\n${theme.primary(scanResult.totalIssues)} violations found\\n`);
42
+
43
+ // 3. Offer handoff options
44
+ const choice = await p.select({
45
+ message: "How would you like to fix these violations?",
46
+ options: [
47
+ { value: "agent", label: "๐Ÿค– Hand off to Agent", hint: "Generate AI fix request" },
48
+ { value: "skip", label: "โ† Skip", hint: "Return to menu" }
49
+ ]
50
+ });
51
+
52
+ if (p.isCancel(choice) || choice === "skip") {
53
+ p.cancel('Cancelled');
54
+ return;
55
+ }
56
+
57
+ // 4. Generate fix prompt
58
+ const fixPrompt = generateAgentFixPrompt(scanResult);
59
+
60
+ // 5. Ask where to send
61
+ const outputChoice = await p.select({
62
+ message: "Where to send the fix request?",
63
+ options: [
64
+ { value: "clipboard", label: "๐Ÿ“‹ Copy to Clipboard", hint: "Paste into AI chat" },
65
+ { value: "file", label: "๐Ÿ’พ Save to File", hint: ".agent/fix-request.md" },
66
+ { value: "both", label: "โœจ Both", hint: "Copy and save" }
67
+ ]
68
+ });
69
+
70
+ if (p.isCancel(outputChoice)) {
71
+ p.cancel('Cancelled');
72
+ return;
73
+ }
74
+
75
+ // 6. Execute handoff
76
+ let copied = false;
77
+ let saved = false;
78
+
79
+ if (outputChoice === "clipboard" || outputChoice === "both") {
80
+ copied = copyToClipboard(fixPrompt);
81
+ }
82
+
83
+ if (outputChoice === "file" || outputChoice === "both") {
84
+ saved = saveFixRequest(fixPrompt);
85
+ }
86
+
87
+ // 7. Show success
88
+ let message = '';
89
+ if (copied && saved) {
90
+ message = 'โœ“ Copied to clipboard\\nโœ“ Saved to .agent/fix-request.md\\n\\nPaste into your AI coding assistant!';
91
+ } else if (copied) {
92
+ message = 'โœ“ Copied to clipboard\\n\\nPaste into your AI coding assistant!';
93
+ } else if (saved) {
94
+ message = 'โœ“ Saved to .agent/fix-request.md\\n\\nOpen file and copy into your AI coding assistant!';
95
+ } else {
96
+ message = 'Failed to copy or save. Check console for errors.';
97
+ }
98
+
99
+ p.note(message, '๐ŸŽ‰ Fix Request Ready');
100
+ }
101
+
102
+ /**
103
+ * Generate AI-friendly fix prompt from scan results
104
+ */
105
+ function generateAgentFixPrompt(scanResult) {
106
+ // Group by file
107
+ const byFile = {};
108
+ scanResult.issues.forEach(issue => {
109
+ const file = path.relative(process.cwd(), issue.file);
110
+ if (!byFile[file]) byFile[file] = [];
111
+ byFile[file].push(issue);
112
+ });
113
+
114
+ const fileList = Object.entries(byFile).sort((a, b) => b[1].length - a[1].length);
115
+
116
+ let prompt = '# Code Violation Fix Request\\n\\n## Summary\\n';
117
+ prompt += `- **Total violations**: ${scanResult.totalIssues}\\n`;
118
+ prompt += `- **Files affected**: ${fileList.length}\\n`;
119
+ prompt += `- **Errors**: ${scanResult.summary.errors}\\n`;
120
+ prompt += `- **Warnings**: ${scanResult.summary.warnings}\\n\\n`;
121
+ prompt += '## Violations by File\\n\\n';
122
+
123
+ fileList.forEach(([file, issues]) => {
124
+ prompt += `### ๐Ÿ“ \`${file}\`\\n\\n`;
125
+ issues.forEach(issue => {
126
+ const icon = issue.severity === 'ERROR' ? '๐Ÿ”ด' : 'โš ๏ธ';
127
+ prompt += `${icon} **Line ${issue.line}** - ${issue.severity}\\n`;
128
+ prompt += `- **Issue**: ${issue.message}\\n`;
129
+ if (issue.pattern) {
130
+ prompt += `- **Pattern**: \`${issue.pattern}\`\\n`;
131
+ }
132
+ prompt += '\\n';
133
+ });
134
+ prompt += '\\n';
135
+ });
136
+
137
+ prompt += '## Instructions\\n\\n';
138
+ prompt += 'Please fix all violations following these guidelines:\\n\\n';
139
+ prompt += '1. **Understand Context**: Read the entire file before making changes\\n';
140
+ prompt += '2. **Fix Correctly**: Address the root cause, not just the symptom\\n';
141
+ prompt += '3. **Maintain Style**: Keep existing code style and formatting\\n';
142
+ prompt += '4. **Test Changes**: Ensure no functionality is broken\\n';
143
+ prompt += '5. **Verify**: Check that all violations are resolved\\n\\n';
144
+ prompt += '**Important**: Some violations may be false positives. Use your judgment and skip if the code is actually correct.\\n\\n';
145
+ prompt += 'Ready to proceed with fixing these violations?\\n';
146
+
147
+ return prompt;
148
+ }
149
+
150
+ /**
151
+ * Copy text to clipboard (cross-platform)
152
+ */
153
+ function copyToClipboard(text) {
154
+ try {
155
+ if (process.platform === 'win32') {
156
+ execSync('clip', { input: text });
157
+ return true;
158
+ } else if (process.platform === 'darwin') {
159
+ execSync('pbcopy', { input: text });
160
+ return true;
161
+ } else {
162
+ execSync('xclip -selection clipboard', { input: text });
163
+ return true;
164
+ }
165
+ } catch (e) {
166
+ console.error(`Clipboard error: ${e.message}`);
167
+ return false;
168
+ }
169
+ }
170
+
171
+ /**
172
+ * Save fix request to file
173
+ */
174
+ function saveFixRequest(text) {
175
+ try {
176
+ const fixRequestPath = path.join('.agent', 'fix-request.md');
177
+ const dir = path.dirname(fixRequestPath);
178
+
179
+ if (!fs.existsSync(dir)) {
180
+ fs.mkdirSync(dir, { recursive: true });
181
+ }
182
+
183
+ fs.writeFileSync(fixRequestPath, text, 'utf8');
184
+ return true;
185
+ } catch (e) {
186
+ console.error(`Save error: ${e.message}`);
187
+ return false;
188
+ }
189
+ }
190
+
191
+ export default runFixAllUI;
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Help/Guide UI - Compact Visual Guide
3
+ */
4
+ import * as p from "@clack/prompts";
5
+ import pc from "picocolors";
6
+
7
+ /**
8
+ * Show compact visual guide (fits in one screen)
9
+ */
10
+ export async function runHelpUI() {
11
+ // Clear terminal vร  reset cursor vแป top-left
12
+ process.stdout.write('\x1Bc'); // Full terminal reset
13
+
14
+ p.intro(pc.cyan("๐Ÿ“– Agent Skill Kit - Quick Guide"));
15
+
16
+ console.log(`
17
+ ${pc.bold(pc.yellow("๐ŸŽฏ HOW IT WORKS"))}
18
+ ${pc.green("Write Code")} โ†’ ${pc.yellow("Agent Scans")} โ†’ ${pc.blue("Learns Patterns")} โ†’ ${pc.magenta("Auto Warns")}
19
+
20
+ ${pc.bold(pc.yellow("๐Ÿ”ง MENU OPTIONS"))}
21
+ ${pc.cyan("๐Ÿ”Ž Scan All")} - Check violations + option to auto-fix
22
+ ${pc.cyan("๐Ÿ“ Learn")} - Teach agent new patterns (manual mode only)
23
+ ${pc.cyan("๐Ÿ“š Knowledge")} - View lessons & review pending patterns
24
+ ${pc.cyan("๐Ÿ“Š Stats")} - Project metrics & insights
25
+ ${pc.cyan("โš™๏ธ Settings")} - Configure auto-learning, API keys
26
+ ${pc.cyan("๐Ÿ’พ Backup")} - Manage knowledge backups
27
+
28
+ ${pc.bold(pc.yellow("๐Ÿš€ QUICK START"))}
29
+ ${pc.bold("1.")} ${pc.cyan("Scan All")} ${pc.dim("โ†’ See current violations")}
30
+ ${pc.bold("2.")} ${pc.cyan("Fix All")} ${pc.dim("โ†’ Auto-fix simple issues")}
31
+ ${pc.bold("3.")} ${pc.cyan("Knowledge")} ${pc.dim("โ†’ Review what agent learned")}
32
+
33
+ ${pc.green("โœ“")} Agent learns from your code automatically
34
+ ${pc.green("โœ“")} All fixes are backed up safely
35
+ ${pc.green("โœ“")} The more you use it, the smarter it gets!
36
+ `);
37
+
38
+ // User selects next action
39
+ const action = await p.select({
40
+ message: "What's next?",
41
+ options: [
42
+ { value: "back", label: "โ† Back to Main Menu" }
43
+ ]
44
+ });
45
+
46
+ if (!p.isCancel(action)) {
47
+ p.outro(pc.cyan("๐Ÿ‘‹ Returning to menu"));
48
+ }
49
+ }