add-skill-kit 3.2.3 → 3.2.4

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 (71) hide show
  1. package/lib/agent-cli/lib/audit.js +154 -0
  2. package/lib/agent-cli/lib/audit.test.js +100 -0
  3. package/lib/agent-cli/lib/auto-learn.js +319 -0
  4. package/lib/agent-cli/lib/auto_preview.py +148 -0
  5. package/lib/agent-cli/lib/backup.js +138 -0
  6. package/lib/agent-cli/lib/backup.test.js +78 -0
  7. package/lib/agent-cli/lib/checklist.py +222 -0
  8. package/lib/agent-cli/lib/cognitive-lesson.js +476 -0
  9. package/lib/agent-cli/lib/completion.js +149 -0
  10. package/lib/agent-cli/lib/config.js +35 -0
  11. package/lib/agent-cli/lib/eslint-fix.js +238 -0
  12. package/lib/agent-cli/lib/evolution-signal.js +215 -0
  13. package/lib/agent-cli/lib/export.js +86 -0
  14. package/lib/agent-cli/lib/export.test.js +65 -0
  15. package/lib/agent-cli/lib/fix.js +337 -0
  16. package/lib/agent-cli/lib/fix.test.js +80 -0
  17. package/lib/agent-cli/lib/gemini-export.js +83 -0
  18. package/lib/agent-cli/lib/generate-registry.js +42 -0
  19. package/lib/agent-cli/lib/hooks/install-hooks.js +152 -0
  20. package/lib/agent-cli/lib/hooks/lint-learn.js +172 -0
  21. package/lib/agent-cli/lib/ignore.js +116 -0
  22. package/lib/agent-cli/lib/ignore.test.js +58 -0
  23. package/lib/agent-cli/lib/init.js +124 -0
  24. package/lib/agent-cli/lib/learn.js +255 -0
  25. package/lib/agent-cli/lib/learn.test.js +70 -0
  26. package/lib/agent-cli/lib/migrate-to-v4.js +322 -0
  27. package/lib/agent-cli/lib/proposals.js +199 -0
  28. package/lib/agent-cli/lib/proposals.test.js +56 -0
  29. package/lib/agent-cli/lib/recall.js +820 -0
  30. package/lib/agent-cli/lib/recall.test.js +107 -0
  31. package/lib/agent-cli/lib/selfevolution-bridge.js +167 -0
  32. package/lib/agent-cli/lib/session_manager.py +120 -0
  33. package/lib/agent-cli/lib/settings.js +203 -0
  34. package/lib/agent-cli/lib/skill-learn.js +296 -0
  35. package/lib/agent-cli/lib/stats.js +132 -0
  36. package/lib/agent-cli/lib/stats.test.js +94 -0
  37. package/lib/agent-cli/lib/types.js +33 -0
  38. package/lib/agent-cli/lib/ui/audit-ui.js +146 -0
  39. package/lib/agent-cli/lib/ui/backup-ui.js +107 -0
  40. package/lib/agent-cli/lib/ui/clack-helpers.js +317 -0
  41. package/lib/agent-cli/lib/ui/common.js +83 -0
  42. package/lib/agent-cli/lib/ui/completion-ui.js +126 -0
  43. package/lib/agent-cli/lib/ui/custom-select.js +69 -0
  44. package/lib/agent-cli/lib/ui/dashboard-ui.js +123 -0
  45. package/lib/agent-cli/lib/ui/evolution-signals-ui.js +107 -0
  46. package/lib/agent-cli/lib/ui/export-ui.js +94 -0
  47. package/lib/agent-cli/lib/ui/fix-all-ui.js +191 -0
  48. package/lib/agent-cli/lib/ui/help-ui.js +49 -0
  49. package/lib/agent-cli/lib/ui/index.js +169 -0
  50. package/lib/agent-cli/lib/ui/init-ui.js +56 -0
  51. package/lib/agent-cli/lib/ui/knowledge-ui.js +55 -0
  52. package/lib/agent-cli/lib/ui/learn-ui.js +706 -0
  53. package/lib/agent-cli/lib/ui/lessons-ui.js +148 -0
  54. package/lib/agent-cli/lib/ui/pretty.js +145 -0
  55. package/lib/agent-cli/lib/ui/proposals-ui.js +99 -0
  56. package/lib/agent-cli/lib/ui/recall-ui.js +342 -0
  57. package/lib/agent-cli/lib/ui/routing-demo.js +79 -0
  58. package/lib/agent-cli/lib/ui/routing-ui.js +325 -0
  59. package/lib/agent-cli/lib/ui/settings-ui.js +381 -0
  60. package/lib/agent-cli/lib/ui/stats-ui.js +123 -0
  61. package/lib/agent-cli/lib/ui/watch-ui.js +236 -0
  62. package/lib/agent-cli/lib/verify_all.py +327 -0
  63. package/lib/agent-cli/lib/watcher.js +181 -0
  64. package/lib/agent-cli/lib/watcher.test.js +85 -0
  65. package/lib/agent-cli/package.json +51 -0
  66. package/lib/agentskillskit-cli/README.md +21 -0
  67. package/lib/agentskillskit-cli/ag-smart.js +158 -0
  68. package/lib/agentskillskit-cli/package.json +51 -0
  69. package/package.json +10 -6
  70. /package/{node_modules/agentskillskit-cli → lib/agent-cli}/README.md +0 -0
  71. /package/{node_modules/agentskillskit-cli → lib/agent-cli}/bin/ag-smart.js +0 -0
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Backup UI - Interactive backup and restore
3
+ */
4
+ import * as p from "@clack/prompts";
5
+ import pc from "picocolors";
6
+ import { createBackup, listBackups, restoreBackup, pruneBackups } from "../backup.js";
7
+
8
+ /**
9
+ * Interactive backup/restore menu
10
+ */
11
+ export async function runBackupUI() {
12
+ p.intro("Backup & Restore (Press ESC to return)");
13
+
14
+ while (true) {
15
+
16
+ const action = await p.select({
17
+ message: "What would you like to do?",
18
+ options: [
19
+ { value: "create", label: "💾 Create Backup", hint: "Save current lessons & settings" },
20
+ { value: "restore", label: "♻️ Restore Backup", hint: "Recover from previous backup" },
21
+ { value: "list", label: "📋 List Backups", hint: "View available backups" },
22
+ { value: "prune", label: "🗑️ Prune Old", hint: "Keep only last 5 backups" },
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 "create": {
33
+ const result = createBackup();
34
+ if (result) {
35
+ p.note(
36
+ `Backup created:\n${pc.dim(result.path)}`,
37
+ pc.green("Success")
38
+ );
39
+ break; // Continue to show menu again
40
+ } else {
41
+ p.note("Failed to create backup", pc.red("Error"));
42
+ }
43
+ break;
44
+ }
45
+
46
+ case "restore": {
47
+ const backups = listBackups();
48
+ if (backups.length === 0) {
49
+ p.note("No backups found", "Info");
50
+ break;
51
+ }
52
+
53
+ const selected = await p.select({
54
+ message: "Select backup to restore:",
55
+ options: backups.map(b => ({
56
+ value: b.path,
57
+ label: b.name,
58
+ hint: b.date.toLocaleString()
59
+ }))
60
+ });
61
+
62
+ if (p.isCancel(selected)) break;
63
+
64
+ const confirm = await p.confirm({
65
+ message: "Restore this backup? Current data will be overwritten."
66
+ });
67
+
68
+ if (confirm) {
69
+ const success = restoreBackup(selected);
70
+ if (success) {
71
+ p.note("Backup restored successfully", pc.green("Success"));
72
+ } else {
73
+ p.note("Failed to restore backup", pc.red("Error"));
74
+ }
75
+ }
76
+ break;
77
+ }
78
+
79
+ case "list": {
80
+ const backups = listBackups();
81
+ if (backups.length === 0) {
82
+ p.note("No backups found", "Info");
83
+ } else {
84
+ const list = backups.map(b =>
85
+ `• ${b.name}\n ${pc.dim(b.date.toLocaleString())}`
86
+ ).join("\n\n");
87
+ p.note(list, `${backups.length} Backup(s)`);
88
+ }
89
+ break;
90
+ }
91
+
92
+ case "prune": {
93
+ const confirm = await p.confirm({
94
+ message: "Delete old backups, keep only last 5?"
95
+ });
96
+
97
+ if (confirm) {
98
+ pruneBackups(5);
99
+ p.note("Old backups pruned", pc.green("Done"));
100
+ }
101
+ break;
102
+ }
103
+ }
104
+ }
105
+ }
106
+
107
+ export default runBackupUI;
@@ -0,0 +1,317 @@
1
+ /**
2
+ * Clack UI Helpers - Agent Skill Kit
3
+ * Reusable UI patterns for consistent CLI experience
4
+ */
5
+
6
+ import * as p from '@clack/prompts';
7
+ import color from 'picocolors';
8
+
9
+ // ============================================================================
10
+ // COLOR SCHEME
11
+ // ============================================================================
12
+
13
+ export const theme = {
14
+ // Primary colors
15
+ primary: color.cyan,
16
+ success: color.green,
17
+ error: color.red,
18
+ warning: color.yellow,
19
+ info: color.blue,
20
+
21
+ // Text styles
22
+ dim: color.dim,
23
+ bold: color.bold,
24
+
25
+ // Brand color
26
+ brand: (text) => color.bgCyan(color.black(text)),
27
+ };
28
+
29
+ // ============================================================================
30
+ // INTRO & OUTRO
31
+ // ============================================================================
32
+
33
+ /**
34
+ * Show branded intro banner
35
+ * @param {string} title - Title text to display
36
+ */
37
+ export function showIntro(title) {
38
+ console.clear();
39
+ p.intro(theme.brand(` ${title} `));
40
+ }
41
+
42
+ /**
43
+ * Show success outro
44
+ * @param {string} message - Success message
45
+ */
46
+ export function showSuccess(message) {
47
+ p.outro(theme.success(`✓ ${message}`));
48
+ }
49
+
50
+ /**
51
+ * Show error outro
52
+ * @param {string} message - Error message
53
+ */
54
+ export function showError(message) {
55
+ p.outro(theme.error(`✗ ${message}`));
56
+ }
57
+
58
+ /**
59
+ * Show info outro
60
+ * @param {string} message - Info message
61
+ */
62
+ export function showInfo(message) {
63
+ p.outro(theme.info(message));
64
+ }
65
+
66
+ // ============================================================================
67
+ // MENUS
68
+ // ============================================================================
69
+
70
+ /**
71
+ * Show main action menu with Exit option
72
+ * @param {Object} options
73
+ * @param {string} options.message - Menu message
74
+ * @param {Array} options.items - Menu items {value, label, hint?}
75
+ * @param {boolean} options.includeExit - Include Exit option (default: true)
76
+ * @param {boolean} options.allowCancel - Allow ESC to return to parent (default: true)
77
+ * @returns {Promise<string|null>} Selected value or null if cancelled
78
+ */
79
+ export async function showActionMenu({ message, items, includeExit = true, allowCancel = true }) {
80
+ const menuItems = [...items];
81
+
82
+ if (includeExit) {
83
+ menuItems.push({ value: 'exit', label: 'Exit', hint: 'Close CLI' });
84
+ }
85
+
86
+ const selected = await p.select({
87
+ message,
88
+ options: menuItems,
89
+ });
90
+
91
+ // Handle cancel - return null to let parent decide
92
+ if (p.isCancel(selected)) {
93
+ if (allowCancel) {
94
+ return null; // Let parent handle navigation
95
+ } else {
96
+ p.cancel('Operation cancelled.');
97
+ process.exit(0);
98
+ }
99
+ }
100
+
101
+ // Handle explicit exit
102
+ if (selected === 'exit') {
103
+ p.cancel('Goodbye! 👋');
104
+ process.exit(0);
105
+ }
106
+
107
+ return selected;
108
+ }
109
+
110
+ /**
111
+ * Show confirmation prompt
112
+ * @param {string} message - Confirmation message
113
+ * @param {boolean} initialValue - Default value
114
+ * @returns {Promise<boolean>}
115
+ */
116
+ export async function confirm(message, initialValue = false) {
117
+ const result = await p.confirm({
118
+ message,
119
+ initialValue,
120
+ });
121
+
122
+ if (p.isCancel(result)) {
123
+ p.cancel('Operation cancelled.');
124
+ process.exit(0);
125
+ }
126
+
127
+ return result;
128
+ }
129
+
130
+ // ============================================================================
131
+ // INPUTS
132
+ // ============================================================================
133
+
134
+ /**
135
+ * Get text input with validation
136
+ * @param {Object} options
137
+ * @param {string} options.message - Input message
138
+ * @param {string} options.placeholder - Placeholder text
139
+ * @param {Function} options.validate - Validation function
140
+ * @returns {Promise<string>}
141
+ */
142
+ export async function textInput({ message, placeholder = '', validate }) {
143
+ const result = await p.text({
144
+ message,
145
+ placeholder,
146
+ validate,
147
+ });
148
+
149
+ if (p.isCancel(result)) {
150
+ p.cancel('Operation cancelled.');
151
+ process.exit(0);
152
+ }
153
+
154
+ return result;
155
+ }
156
+
157
+ // ============================================================================
158
+ // PROGRESS
159
+ // ============================================================================
160
+
161
+ /**
162
+ * Create and manage a spinner
163
+ * @param {string} message - Initial message
164
+ * @returns {Object} Spinner instance with update/stop methods
165
+ */
166
+ export function createSpinner(message) {
167
+ const spinner = p.spinner();
168
+ spinner.start(message);
169
+
170
+ return {
171
+ update: (msg) => {
172
+ spinner.message(msg);
173
+ },
174
+ stop: (msg) => {
175
+ spinner.stop(msg);
176
+ },
177
+ stopSuccess: (msg) => {
178
+ spinner.stop(theme.success(`✓ ${msg}`));
179
+ },
180
+ stopError: (msg) => {
181
+ spinner.stop(theme.error(`✗ ${msg}`));
182
+ },
183
+ };
184
+ }
185
+
186
+ // ============================================================================
187
+ // NOTES & INFO BOXES
188
+ // ============================================================================
189
+
190
+ /**
191
+ * Show info note box
192
+ * @param {string} content - Note content
193
+ * @param {string} title - Note title (optional)
194
+ */
195
+ export function showNote(content, title = '') {
196
+ p.note(content, title);
197
+ }
198
+
199
+ /**
200
+ * Show success note
201
+ * @param {string} content - Note content
202
+ * @param {string} title - Note title
203
+ */
204
+ export function showSuccessNote(content, title = '✓ Success') {
205
+ p.note(content, theme.success(title));
206
+ }
207
+
208
+ /**
209
+ * Show error note
210
+ * @param {string} content - Note content
211
+ * @param {string} title - Note title
212
+ */
213
+ export function showErrorNote(content, title = '✗ Error') {
214
+ p.note(content, theme.error(title));
215
+ }
216
+
217
+ /**
218
+ * Show info note with cyan title
219
+ * @param {string} content - Note content
220
+ * @param {string} title - Note title
221
+ */
222
+ export function showInfoNote(content, title) {
223
+ p.note(content, theme.primary(title));
224
+ }
225
+
226
+ // ============================================================================
227
+ // RESULTS
228
+ // ============================================================================
229
+
230
+ /**
231
+ * Format results for display
232
+ * @param {Object} results - Results object
233
+ * @returns {string} Formatted string
234
+ */
235
+ export function formatResults(results) {
236
+ const lines = [];
237
+
238
+ if (results.success !== undefined) {
239
+ const icon = results.success ? theme.success('✓') : theme.error('✗');
240
+ lines.push(`${icon} ${results.message || ''}`);
241
+ }
242
+
243
+ if (results.details) {
244
+ lines.push('');
245
+ lines.push(theme.dim('Details:'));
246
+ Object.entries(results.details).forEach(([key, value]) => {
247
+ lines.push(` ${key}: ${theme.primary(value)}`);
248
+ });
249
+ }
250
+
251
+ if (results.errors && results.errors.length > 0) {
252
+ lines.push('');
253
+ lines.push(theme.error('Errors:'));
254
+ results.errors.forEach(err => {
255
+ lines.push(` ${theme.error('•')} ${err}`);
256
+ });
257
+ }
258
+
259
+ return lines.join('\n');
260
+ }
261
+
262
+ // ============================================================================
263
+ // NEXT STEPS
264
+ // ============================================================================
265
+
266
+ /**
267
+ * Show next steps guide
268
+ * @param {Array<string>} steps - Array of step descriptions
269
+ */
270
+ export function showNextSteps(steps) {
271
+ const content = steps
272
+ .map((step, i) => `${theme.primary(`${i + 1}.`)} ${step}`)
273
+ .join('\n');
274
+
275
+ showInfoNote(content, 'Next Steps');
276
+ }
277
+
278
+ // ============================================================================
279
+ // UTILITIES
280
+ // ============================================================================
281
+
282
+ /**
283
+ * Check if value is cancelled
284
+ * @param {*} value - Value to check
285
+ * @returns {boolean}
286
+ */
287
+ export function isCancelled(value) {
288
+ return p.isCancel(value);
289
+ }
290
+
291
+ /**
292
+ * Handle cancellation
293
+ */
294
+ export function handleCancel() {
295
+ p.cancel('Operation cancelled.');
296
+ process.exit(0);
297
+ }
298
+
299
+ export default {
300
+ theme,
301
+ showIntro,
302
+ showSuccess,
303
+ showError,
304
+ showInfo,
305
+ showActionMenu,
306
+ confirm,
307
+ textInput,
308
+ createSpinner,
309
+ showNote,
310
+ showSuccessNote,
311
+ showErrorNote,
312
+ showInfoNote,
313
+ formatResults,
314
+ showNextSteps,
315
+ isCancelled,
316
+ handleCancel,
317
+ };
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Common UI helpers for Clack-based CLI
3
+ */
4
+ import * as p from "@clack/prompts";
5
+ import { loadKnowledge } from "../recall.js";
6
+ import { VERSION } from "../config.js";
7
+
8
+ // ============================================================================
9
+ // CLACK SYMBOLS (no emoji for consistency)
10
+ // ============================================================================
11
+
12
+ export const ICONS = {
13
+ brain: "◆",
14
+ learn: "◆",
15
+ recall: "◇",
16
+ stats: "▣",
17
+ success: "✓",
18
+ error: "✖",
19
+ warning: "⚠",
20
+ info: "●"
21
+ };
22
+
23
+ // ============================================================================
24
+ // SHARED FUNCTIONS
25
+ // ============================================================================
26
+
27
+ /**
28
+ * Show app header
29
+ */
30
+ export function showHeader() {
31
+ p.intro(`${ICONS.brain} Agent Skill Kit v${VERSION}`);
32
+ }
33
+
34
+ /**
35
+ * Show outro message
36
+ * @param {string} message
37
+ */
38
+ export function showSuccess(message) {
39
+ p.outro(`${ICONS.success} ${message}`);
40
+ }
41
+
42
+ /**
43
+ * Show error and exit
44
+ * @param {string} message
45
+ */
46
+ export function showError(message) {
47
+ p.cancel(`${ICONS.error} ${message}`);
48
+ process.exit(1);
49
+ }
50
+
51
+ /**
52
+ * Handle user cancellation (CTRL+C)
53
+ * @param {any} value
54
+ */
55
+ export function handleCancel(value) {
56
+ if (p.isCancel(value)) {
57
+ p.cancel("Operation cancelled.");
58
+ process.exit(0);
59
+ }
60
+ }
61
+
62
+ /**
63
+ * Get knowledge base with error handling
64
+ * @returns {object}
65
+ */
66
+ export function getKnowledge() {
67
+ try {
68
+ return loadKnowledge();
69
+ } catch (e) {
70
+ showError("Failed to load knowledge base");
71
+ return { lessons: [] };
72
+ }
73
+ }
74
+
75
+ /**
76
+ * Format horizontal line
77
+ * @param {number} width
78
+ */
79
+ export function line(width = 50) {
80
+ return "─".repeat(width);
81
+ }
82
+
83
+ export { p, VERSION };
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Completion UI - Shell completion setup
3
+ */
4
+ import * as p from "@clack/prompts";
5
+ import pc from "picocolors";
6
+ import fs from "fs";
7
+ import path from "path";
8
+ import os from "os";
9
+ import {
10
+ getCompletionScript,
11
+ detectShell,
12
+ generatePowerShellCompletion,
13
+ generateBashCompletion,
14
+ generateZshCompletion
15
+ } from "../completion.js";
16
+
17
+ /**
18
+ * Interactive completion setup
19
+ */
20
+ export async function runCompletionUI() {
21
+ p.intro("Shell Completion (Press ESC to exit)");
22
+
23
+ const action = await p.select({
24
+ message: "What would you like to do?",
25
+ options: [
26
+ { value: "install", label: "Install", hint: "Add shell completions" },
27
+ { value: "uninstall", label: "Uninstall", hint: "Remove completions" },
28
+ { value: "back", label: "← Back", hint: "Return to main menu" }
29
+ ]
30
+ });
31
+
32
+ if (p.isCancel(action) || action === "back") {
33
+ return;
34
+ }
35
+
36
+ const shell = await p.select({
37
+ message: "Select shell:",
38
+ options: [
39
+ { value: "powershell", label: "PowerShell", hint: "Windows default" },
40
+ { value: "bash", label: "Bash", hint: "Linux/macOS" },
41
+ { value: "zsh", label: "Zsh", hint: "macOS default" }
42
+ ],
43
+ initialValue: detectedShell
44
+ });
45
+
46
+ if (p.isCancel(shell)) return;
47
+
48
+ const { script } = getCompletionScript(shell);
49
+
50
+ if (action === "show") {
51
+ console.log("\n" + pc.dim("─".repeat(50)));
52
+ console.log(script);
53
+ console.log(pc.dim("─".repeat(50)) + "\n");
54
+
55
+ p.note(
56
+ `Copy the script above and add to your shell profile:\n` +
57
+ `• PowerShell: $PROFILE\n` +
58
+ `• Bash: ~/.bashrc\n` +
59
+ `• Zsh: ~/.zshrc`,
60
+ "Instructions"
61
+ );
62
+ return;
63
+ }
64
+
65
+ if (action === "install") {
66
+ const confirm = await p.confirm({
67
+ message: `Install completion for ${shell}?`
68
+ });
69
+
70
+ if (!confirm) return;
71
+
72
+ try {
73
+ let profilePath;
74
+
75
+ switch (shell) {
76
+ case "powershell": {
77
+ // Get PowerShell profile path
78
+ const psProfile = process.env.USERPROFILE
79
+ ? path.join(process.env.USERPROFILE, "Documents", "PowerShell", "Microsoft.PowerShell_profile.ps1")
80
+ : path.join(os.homedir(), "Documents", "PowerShell", "Microsoft.PowerShell_profile.ps1");
81
+
82
+ profilePath = psProfile;
83
+ break;
84
+ }
85
+ case "bash":
86
+ profilePath = path.join(os.homedir(), ".bashrc");
87
+ break;
88
+ case "zsh":
89
+ profilePath = path.join(os.homedir(), ".zshrc");
90
+ break;
91
+ }
92
+
93
+ // Ensure directory exists
94
+ fs.mkdirSync(path.dirname(profilePath), { recursive: true });
95
+
96
+ // Check if already installed
97
+ const existing = fs.existsSync(profilePath)
98
+ ? fs.readFileSync(profilePath, "utf8")
99
+ : "";
100
+
101
+ if (existing.includes("Agent Skill Kit")) {
102
+ p.note("Completion already installed!", pc.yellow("Skipped"));
103
+ return;
104
+ }
105
+
106
+ // Append to profile
107
+ fs.appendFileSync(profilePath, "\n" + script);
108
+
109
+ p.note(
110
+ `Completion installed to:\n${pc.cyan(profilePath)}\n\n` +
111
+ `Restart your terminal or run:\n` +
112
+ (shell === "powershell" ? `. $PROFILE` : `source ${profilePath}`),
113
+ pc.green("Installed")
114
+ );
115
+
116
+ } catch (e) {
117
+ p.note(
118
+ `Could not install automatically.\nError: ${e.message}\n\n` +
119
+ `Please manually add the script to your shell profile.`,
120
+ pc.red("Error")
121
+ );
122
+ }
123
+ }
124
+ }
125
+
126
+ export default runCompletionUI;
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Custom Select Component - Using @clack/prompts native select
3
+ * This fixes the Windows terminal rendering issues with @clack/core
4
+ */
5
+ import * as p from "@clack/prompts";
6
+ import pc from "picocolors";
7
+
8
+ // ============================================================================
9
+ // CUSTOM ICONS
10
+ // ============================================================================
11
+
12
+ const ITEM_ICONS = {
13
+ routing: "◆",
14
+ learn: "◆",
15
+ recall: "◇",
16
+ stats: "▣",
17
+ settings: "◇",
18
+ backup: "◇",
19
+ export: "◇",
20
+ proposals: "◇",
21
+ completion: "◇",
22
+ init: "◇",
23
+ exit: "×"
24
+ };
25
+
26
+ const ITEM_COLORS = {
27
+ routing: pc.cyan,
28
+ learn: pc.green,
29
+ recall: pc.blue,
30
+ stats: pc.yellow,
31
+ settings: pc.cyan,
32
+ backup: pc.gray,
33
+ export: pc.gray,
34
+ proposals: pc.yellow,
35
+ completion: pc.gray,
36
+ init: pc.green,
37
+ exit: pc.red
38
+ };
39
+
40
+ // ============================================================================
41
+ // CUSTOM SELECT - Using native @clack/prompts
42
+ // ============================================================================
43
+
44
+ /**
45
+ * Custom select with icons - uses native clack select to fix Windows rendering
46
+ * @param {object} config
47
+ * @returns {Promise<string|symbol>}
48
+ */
49
+ export async function customSelect(config) {
50
+ const { message, items } = config;
51
+
52
+ // Transform items to clack format - clean labels without icons
53
+ const options = items.map((item) => ({
54
+ value: item.value,
55
+ label: item.label,
56
+ hint: item.hint
57
+ }));
58
+
59
+ const result = await p.select({
60
+ message,
61
+ options,
62
+ initialValue: items[0]?.value
63
+ });
64
+
65
+ return result;
66
+ }
67
+
68
+ export { ITEM_ICONS, ITEM_COLORS, pc };
69
+ export { isCancel } from "@clack/prompts";