myshell-tools 1.0.0 → 2.0.0-alpha.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.
Files changed (150) hide show
  1. package/CHANGELOG.md +44 -69
  2. package/LICENSE +21 -21
  3. package/README.md +178 -318
  4. package/dist/cli.d.ts +8 -0
  5. package/dist/cli.js +106 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/commands/cost.d.ts +36 -0
  8. package/dist/commands/cost.js +103 -0
  9. package/dist/commands/cost.js.map +1 -0
  10. package/dist/commands/doctor.d.ts +36 -0
  11. package/dist/commands/doctor.js +115 -0
  12. package/dist/commands/doctor.js.map +1 -0
  13. package/dist/core/assess.d.ts +25 -0
  14. package/dist/core/assess.js +142 -0
  15. package/dist/core/assess.js.map +1 -0
  16. package/dist/core/classify.d.ts +19 -0
  17. package/dist/core/classify.js +80 -0
  18. package/dist/core/classify.js.map +1 -0
  19. package/dist/core/escalate.d.ts +32 -0
  20. package/dist/core/escalate.js +57 -0
  21. package/dist/core/escalate.js.map +1 -0
  22. package/dist/core/index.d.ts +13 -0
  23. package/dist/core/index.js +12 -0
  24. package/dist/core/index.js.map +1 -0
  25. package/dist/core/orchestrate.d.ts +42 -0
  26. package/dist/core/orchestrate.js +439 -0
  27. package/dist/core/orchestrate.js.map +1 -0
  28. package/dist/core/policy.d.ts +9 -0
  29. package/dist/core/policy.js +27 -0
  30. package/dist/core/policy.js.map +1 -0
  31. package/dist/core/prompt.d.ts +26 -0
  32. package/dist/core/prompt.js +125 -0
  33. package/dist/core/prompt.js.map +1 -0
  34. package/dist/core/review.d.ts +46 -0
  35. package/dist/core/review.js +148 -0
  36. package/dist/core/review.js.map +1 -0
  37. package/dist/core/route.d.ts +28 -0
  38. package/dist/core/route.js +52 -0
  39. package/dist/core/route.js.map +1 -0
  40. package/dist/core/types.d.ts +141 -0
  41. package/dist/core/types.js +14 -0
  42. package/dist/core/types.js.map +1 -0
  43. package/dist/infra/atomic.d.ts +53 -0
  44. package/dist/infra/atomic.js +171 -0
  45. package/dist/infra/atomic.js.map +1 -0
  46. package/dist/infra/clock.d.ts +9 -0
  47. package/dist/infra/clock.js +15 -0
  48. package/dist/infra/clock.js.map +1 -0
  49. package/dist/infra/index.d.ts +9 -0
  50. package/dist/infra/index.js +7 -0
  51. package/dist/infra/index.js.map +1 -0
  52. package/dist/infra/ledger.d.ts +49 -0
  53. package/dist/infra/ledger.js +90 -0
  54. package/dist/infra/ledger.js.map +1 -0
  55. package/dist/infra/paths.d.ts +28 -0
  56. package/dist/infra/paths.js +38 -0
  57. package/dist/infra/paths.js.map +1 -0
  58. package/dist/infra/pricing.d.ts +47 -0
  59. package/dist/infra/pricing.js +151 -0
  60. package/dist/infra/pricing.js.map +1 -0
  61. package/dist/infra/session.d.ts +28 -0
  62. package/dist/infra/session.js +61 -0
  63. package/dist/infra/session.js.map +1 -0
  64. package/dist/interface/render.d.ts +27 -0
  65. package/dist/interface/render.js +134 -0
  66. package/dist/interface/render.js.map +1 -0
  67. package/dist/interface/repl.d.ts +23 -0
  68. package/dist/interface/repl.js +90 -0
  69. package/dist/interface/repl.js.map +1 -0
  70. package/dist/interface/run.d.ts +20 -0
  71. package/dist/interface/run.js +31 -0
  72. package/dist/interface/run.js.map +1 -0
  73. package/dist/providers/claude-parse.d.ts +24 -0
  74. package/dist/providers/claude-parse.js +113 -0
  75. package/dist/providers/claude-parse.js.map +1 -0
  76. package/dist/providers/claude.d.ts +45 -0
  77. package/dist/providers/claude.js +122 -0
  78. package/dist/providers/claude.js.map +1 -0
  79. package/dist/providers/codex-parse.d.ts +32 -0
  80. package/dist/providers/codex-parse.js +145 -0
  81. package/dist/providers/codex-parse.js.map +1 -0
  82. package/dist/providers/codex.d.ts +44 -0
  83. package/dist/providers/codex.js +124 -0
  84. package/dist/providers/codex.js.map +1 -0
  85. package/dist/providers/detect.d.ts +49 -0
  86. package/dist/providers/detect.js +125 -0
  87. package/dist/providers/detect.js.map +1 -0
  88. package/dist/providers/errors.d.ts +49 -0
  89. package/dist/providers/errors.js +189 -0
  90. package/dist/providers/errors.js.map +1 -0
  91. package/dist/providers/index.d.ts +9 -0
  92. package/dist/providers/index.js +7 -0
  93. package/dist/providers/index.js.map +1 -0
  94. package/dist/providers/port.d.ts +74 -0
  95. package/dist/providers/port.js +16 -0
  96. package/dist/providers/port.js.map +1 -0
  97. package/dist/providers/registry.d.ts +21 -0
  98. package/dist/providers/registry.js +34 -0
  99. package/dist/providers/registry.js.map +1 -0
  100. package/dist/ui/banner.d.ts +19 -0
  101. package/dist/ui/banner.js +32 -0
  102. package/dist/ui/banner.js.map +1 -0
  103. package/dist/ui/spinner.d.ts +27 -0
  104. package/dist/ui/spinner.js +67 -0
  105. package/dist/ui/spinner.js.map +1 -0
  106. package/dist/ui/theme.d.ts +32 -0
  107. package/dist/ui/theme.js +56 -0
  108. package/dist/ui/theme.js.map +1 -0
  109. package/package.json +55 -49
  110. package/data/orchestrator.json +0 -113
  111. package/src/auth/recovery.mjs +0 -328
  112. package/src/auth/refresh.mjs +0 -373
  113. package/src/chef.mjs +0 -348
  114. package/src/cli/doctor.mjs +0 -568
  115. package/src/cli/reset.mjs +0 -447
  116. package/src/cli/status.mjs +0 -379
  117. package/src/cli.mjs +0 -429
  118. package/src/commands/doctor.mjs +0 -375
  119. package/src/commands/help.mjs +0 -324
  120. package/src/commands/status.mjs +0 -331
  121. package/src/monitor/health.mjs +0 -486
  122. package/src/monitor/performance.mjs +0 -442
  123. package/src/monitor/report.mjs +0 -535
  124. package/src/orchestrator/classify.mjs +0 -391
  125. package/src/orchestrator/confidence.mjs +0 -151
  126. package/src/orchestrator/handoffs.mjs +0 -231
  127. package/src/orchestrator/review.mjs +0 -222
  128. package/src/providers/balance.mjs +0 -201
  129. package/src/providers/claude.mjs +0 -236
  130. package/src/providers/codex.mjs +0 -255
  131. package/src/providers/detect.mjs +0 -185
  132. package/src/providers/errors.mjs +0 -373
  133. package/src/providers/select.mjs +0 -162
  134. package/src/repl-enhanced.mjs +0 -417
  135. package/src/repl.mjs +0 -321
  136. package/src/state/archive.mjs +0 -366
  137. package/src/state/atomic.mjs +0 -116
  138. package/src/state/cleanup.mjs +0 -440
  139. package/src/state/recovery.mjs +0 -461
  140. package/src/state/session.mjs +0 -147
  141. package/src/ui/errors.mjs +0 -456
  142. package/src/ui/formatter.mjs +0 -327
  143. package/src/ui/icons.mjs +0 -318
  144. package/src/ui/progress.mjs +0 -468
  145. package/templates/prompts/confidence-format.txt +0 -14
  146. package/templates/prompts/ic-with-feedback.txt +0 -41
  147. package/templates/prompts/ic.txt +0 -13
  148. package/templates/prompts/manager-review.txt +0 -40
  149. package/templates/prompts/manager.txt +0 -14
  150. package/templates/prompts/worker.txt +0 -12
@@ -1,327 +0,0 @@
1
- /**
2
- * formatter.mjs — Rich terminal output formatting utilities
3
- */
4
-
5
- /**
6
- * Colors and formatting
7
- */
8
- export const colors = {
9
- // Basic colors
10
- red: '\x1b[31m',
11
- green: '\x1b[32m',
12
- yellow: '\x1b[33m',
13
- blue: '\x1b[34m',
14
- magenta: '\x1b[35m',
15
- cyan: '\x1b[36m',
16
- white: '\x1b[37m',
17
-
18
- // Extended colors
19
- orange: '\x1b[38;5;208m',
20
- brightBlue: '\x1b[38;5;33m',
21
- brightGreen: '\x1b[38;5;40m',
22
- purple: '\x1b[38;5;135m',
23
-
24
- // Formatting
25
- reset: '\x1b[0m',
26
- bold: '\x1b[1m',
27
- dim: '\x1b[2m',
28
- italic: '\x1b[3m',
29
- underline: '\x1b[4m',
30
-
31
- // Background colors
32
- bgRed: '\x1b[41m',
33
- bgGreen: '\x1b[42m',
34
- bgYellow: '\x1b[43m',
35
- bgBlue: '\x1b[44m',
36
- };
37
-
38
- /**
39
- * Helper functions for color formatting
40
- */
41
- export const fmt = {
42
- red: (text) => `${colors.red}${text}${colors.reset}`,
43
- green: (text) => `${colors.green}${text}${colors.reset}`,
44
- yellow: (text) => `${colors.yellow}${text}${colors.reset}`,
45
- blue: (text) => `${colors.blue}${text}${colors.reset}`,
46
- magenta: (text) => `${colors.magenta}${text}${colors.reset}`,
47
- cyan: (text) => `${colors.cyan}${text}${colors.reset}`,
48
- orange: (text) => `${colors.orange}${text}${colors.reset}`,
49
- brightBlue: (text) => `${colors.brightBlue}${text}${colors.reset}`,
50
- brightGreen: (text) => `${colors.brightGreen}${text}${colors.reset}`,
51
- purple: (text) => `${colors.purple}${text}${colors.reset}`,
52
-
53
- bold: (text) => `${colors.bold}${text}${colors.reset}`,
54
- dim: (text) => `${colors.dim}${text}${colors.reset}`,
55
- italic: (text) => `${colors.italic}${text}${colors.reset}`,
56
- underline: (text) => `${colors.underline}${text}${colors.reset}`,
57
-
58
- success: (text) => `${colors.bold}${colors.green}${text}${colors.reset}`,
59
- error: (text) => `${colors.bold}${colors.red}${text}${colors.reset}`,
60
- warning: (text) => `${colors.bold}${colors.yellow}${text}${colors.reset}`,
61
- info: (text) => `${colors.bold}${colors.blue}${text}${colors.reset}`,
62
-
63
- // Combinations
64
- redBold: (text) => `${colors.bold}${colors.red}${text}${colors.reset}`,
65
- greenBold: (text) => `${colors.bold}${colors.green}${text}${colors.reset}`,
66
- yellowBold: (text) => `${colors.bold}${colors.yellow}${text}${colors.reset}`,
67
- blueBold: (text) => `${colors.bold}${colors.blue}${text}${colors.reset}`,
68
- orangeBold: (text) => `${colors.bold}${colors.orange}${text}${colors.reset}`,
69
-
70
- // Add formatModel to fmt object for easier access
71
- formatModel: formatModel,
72
- // Add providerBalanceBar to fmt object
73
- providerBalanceBar: providerBalanceBar
74
- };
75
-
76
- /**
77
- * Tier color mapping for consistent hierarchy display
78
- */
79
- export const tierColors = {
80
- worker: colors.blue,
81
- ic: colors.yellow,
82
- manager: colors.red,
83
- system: colors.cyan
84
- };
85
-
86
- /**
87
- * Format tier name with appropriate color
88
- */
89
- export function formatTier(tier) {
90
- const color = tierColors[tier] || colors.white;
91
- return `${color}${colors.bold}${tier.toUpperCase()}${colors.reset}`;
92
- }
93
-
94
- /**
95
- * Create a visual tree structure
96
- */
97
- export function createTree(items, options = {}) {
98
- const { indent = ' ', branch = '├─', lastBranch = '└─', continuation = '│ ' } = options;
99
- const lines = [];
100
-
101
- for (let i = 0; i < items.length; i++) {
102
- const item = items[i];
103
- const isLast = i === items.length - 1;
104
- const prefix = isLast ? lastBranch : branch;
105
-
106
- if (typeof item === 'string') {
107
- lines.push(`${indent}${prefix} ${item}`);
108
- } else if (item.text) {
109
- lines.push(`${indent}${prefix} ${item.text}`);
110
- if (item.children && item.children.length > 0) {
111
- const childLines = createTree(item.children, {
112
- ...options,
113
- indent: indent + (isLast ? ' ' : continuation)
114
- });
115
- lines.push(...childLines);
116
- }
117
- }
118
- }
119
-
120
- return lines;
121
- }
122
-
123
- /**
124
- * Format duration in human-readable format
125
- */
126
- export function formatDuration(milliseconds) {
127
- if (milliseconds < 1000) {
128
- return `${milliseconds}ms`;
129
- }
130
-
131
- const seconds = milliseconds / 1000;
132
- if (seconds < 60) {
133
- return `${seconds.toFixed(1)}s`;
134
- }
135
-
136
- const minutes = seconds / 60;
137
- if (minutes < 60) {
138
- return `${minutes.toFixed(1)}m`;
139
- }
140
-
141
- const hours = minutes / 60;
142
- return `${hours.toFixed(1)}h`;
143
- }
144
-
145
- /**
146
- * Format confidence level with color coding
147
- */
148
- export function formatConfidence(confidence) {
149
- const percent = Math.round(confidence * 100);
150
-
151
- if (confidence >= 0.8) {
152
- return `${colors.green}${percent}%${colors.reset}`;
153
- } else if (confidence >= 0.6) {
154
- return `${colors.yellow}${percent}%${colors.reset}`;
155
- } else {
156
- return `${colors.red}${percent}%${colors.reset}`;
157
- }
158
- }
159
-
160
- /**
161
- * Create a horizontal separator line
162
- */
163
- export function separator(length = 60, char = '═', color = colors.blue) {
164
- return `${color}${char.repeat(length)}${colors.reset}`;
165
- }
166
-
167
- /**
168
- * Create a bordered box around text
169
- */
170
- export function box(text, options = {}) {
171
- const {
172
- padding = 1,
173
- margin = 0,
174
- borderColor = colors.blue,
175
- textColor = colors.reset,
176
- width = null
177
- } = options;
178
-
179
- const lines = text.split('\n');
180
- const maxLineLength = width || Math.max(...lines.map(line => line.length));
181
- const totalWidth = maxLineLength + (padding * 2);
182
-
183
- const topBorder = `${borderColor}╭${'─'.repeat(totalWidth)}╮${colors.reset}`;
184
- const bottomBorder = `${borderColor}╰${'─'.repeat(totalWidth)}╯${colors.reset}`;
185
-
186
- const result = [];
187
-
188
- // Add margin above
189
- for (let i = 0; i < margin; i++) {
190
- result.push('');
191
- }
192
-
193
- result.push(topBorder);
194
-
195
- for (const line of lines) {
196
- const paddedLine = line.padEnd(maxLineLength);
197
- result.push(`${borderColor}│${' '.repeat(padding)}${textColor}${paddedLine}${' '.repeat(padding)}${borderColor}│${colors.reset}`);
198
- }
199
-
200
- result.push(bottomBorder);
201
-
202
- // Add margin below
203
- for (let i = 0; i < margin; i++) {
204
- result.push('');
205
- }
206
-
207
- return result.join('\n');
208
- }
209
-
210
- /**
211
- * Format a progress bar
212
- */
213
- export function progressBar(current, total, options = {}) {
214
- const {
215
- width = 20,
216
- filled = '█',
217
- empty = '░',
218
- showPercent = true,
219
- color = colors.green
220
- } = options;
221
-
222
- const progress = Math.min(current / total, 1);
223
- const filledWidth = Math.round(progress * width);
224
- const emptyWidth = width - filledWidth;
225
-
226
- const bar = `${color}${filled.repeat(filledWidth)}${colors.dim}${empty.repeat(emptyWidth)}${colors.reset}`;
227
-
228
- if (showPercent) {
229
- const percent = Math.round(progress * 100);
230
- return `${bar} ${percent}%`;
231
- }
232
-
233
- return bar;
234
- }
235
-
236
- /**
237
- * Format provider balance bar (like dual-brain)
238
- */
239
- export function providerBalanceBar(claudePercent, openaiPercent, options = {}) {
240
- const { width = 20, label = true } = options;
241
-
242
- if (claudePercent === 0 && openaiPercent === 0) {
243
- const bar = fmt.dim('░'.repeat(width));
244
- return label ? `${bar} no activity` : bar;
245
- }
246
-
247
- const claudeFill = Math.round((claudePercent / 100) * width);
248
- const openaieFill = width - claudeFill;
249
-
250
- const claudeBar = fmt.orange('█'.repeat(claudeFill));
251
- const openaiBar = fmt.green('▓'.repeat(openaieFill));
252
-
253
- const bar = `${claudeBar}${openaiBar}`;
254
-
255
- if (label) {
256
- return `${bar} ${fmt.orange(claudePercent + '%')} Claude · ${fmt.green(openaiPercent + '%')} GPT`;
257
- }
258
-
259
- return bar;
260
- }
261
-
262
- /**
263
- * Format time ago (like dual-brain)
264
- */
265
- export function timeAgo(timestamp) {
266
- const now = Date.now();
267
- const diff = now - timestamp;
268
- const minutes = Math.floor(diff / 60000);
269
-
270
- if (minutes < 1) return 'just now';
271
- if (minutes < 60) return `${minutes}m ago`;
272
-
273
- const hours = Math.floor(minutes / 60);
274
- if (hours < 24) return `${hours}h ago`;
275
-
276
- const days = Math.floor(hours / 24);
277
- return `${days}d ago`;
278
- }
279
-
280
- /**
281
- * Truncate text with ellipsis
282
- */
283
- export function truncate(text, maxLength = 50) {
284
- if (!text) return '';
285
- const cleaned = text.replace(/\s+/g, ' ').trim();
286
- if (cleaned.length <= maxLength) return cleaned;
287
- return cleaned.slice(0, maxLength - 1) + '…';
288
- }
289
-
290
- /**
291
- * Format model name consistently
292
- */
293
- export function formatModel(provider, model) {
294
- if (provider === 'claude') {
295
- return fmt.orange(`${provider}/${model}`);
296
- } else if (provider === 'openai' || provider === 'codex') {
297
- return fmt.green(`GPT/${model}`);
298
- }
299
- return fmt.dim(`${provider}/${model}`);
300
- }
301
-
302
- /**
303
- * Create a status indicator
304
- */
305
- export function statusIndicator(status) {
306
- switch (status) {
307
- case 'success':
308
- case 'ready':
309
- case 'active':
310
- return fmt.green('✅');
311
- case 'warning':
312
- case 'partial':
313
- return fmt.yellow('⚠️');
314
- case 'error':
315
- case 'failed':
316
- return fmt.red('❌');
317
- case 'loading':
318
- case 'processing':
319
- return fmt.blue('🔄');
320
- case 'info':
321
- return fmt.blue('💡');
322
- case 'docs':
323
- return fmt.blue('📖');
324
- default:
325
- return fmt.dim('●');
326
- }
327
- }
package/src/ui/icons.mjs DELETED
@@ -1,318 +0,0 @@
1
- /**
2
- * icons.mjs — Unicode symbols and visual indicators
3
- */
4
-
5
- /**
6
- * Status icons
7
- */
8
- export const status = {
9
- success: '✅',
10
- error: '❌',
11
- warning: '⚠️',
12
- info: '💡',
13
- loading: '🔄',
14
- docs: '📖',
15
- checkmark: '✓',
16
- cross: '✗',
17
- bullet: '●',
18
- diamond: '◆',
19
- triangle: '▲',
20
- square: '■',
21
- circle: '○',
22
- star: '★',
23
- heart: '♥',
24
- brain: '🧠',
25
- robot: '🤖',
26
- gear: '⚙️',
27
- rocket: '🚀',
28
- fire: '🔥',
29
- lightning: '⚡',
30
- shield: '🛡️',
31
- crown: '👑',
32
- crystal: '💎',
33
- target: '🎯'
34
- };
35
-
36
- /**
37
- * Provider and model icons
38
- */
39
- export const provider = {
40
- claude: '🟠',
41
- openai: '🟢',
42
- codex: '🟢',
43
- anthropic: '🟠',
44
- gpt: '🟢'
45
- };
46
-
47
- /**
48
- * Tier/role icons
49
- */
50
- export const tier = {
51
- manager: '👔',
52
- ic: '👨‍💻',
53
- worker: '🏗️',
54
- search: '🔍',
55
- execute: '⚡',
56
- think: '🧠',
57
- review: '👀',
58
- architect: '🏛️',
59
- debug: '🐛',
60
- test: '🧪',
61
- deploy: '🚀',
62
- security: '🔒',
63
- docs: '📝'
64
- };
65
-
66
- /**
67
- * Progress and activity icons
68
- */
69
- export const progress = {
70
- spinner: ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'],
71
- dots: ['⠁', '⠂', '⠄', '⡀', '⢀', '⠠', '⠐', '⠈'],
72
- blocks: ['▁', '▂', '▃', '▄', '▅', '▆', '▇', '█'],
73
- arrow: ['←', '↖', '↑', '↗', '→', '↘', '↓', '↙'],
74
- clock: ['🕐', '🕑', '🕒', '🕓', '🕔', '🕕', '🕖', '🕗', '🕘', '🕙', '🕚', '🕛']
75
- };
76
-
77
- /**
78
- * Tree structure characters
79
- */
80
- export const tree = {
81
- branch: '├─',
82
- lastBranch: '└─',
83
- pipe: '│',
84
- space: ' ',
85
- tee: '├',
86
- corner: '└',
87
- horizontal: '─',
88
- vertical: '│'
89
- };
90
-
91
- /**
92
- * Box drawing characters
93
- */
94
- export const box = {
95
- // Single line
96
- topLeft: '╭',
97
- topRight: '╮',
98
- bottomLeft: '╰',
99
- bottomRight: '╯',
100
- horizontal: '─',
101
- vertical: '│',
102
-
103
- // Double line
104
- doubleTopLeft: '╔',
105
- doubleTopRight: '╗',
106
- doubleBottomLeft: '╚',
107
- doubleBottomRight: '╝',
108
- doubleHorizontal: '═',
109
- doubleVertical: '║',
110
-
111
- // Heavy line
112
- heavyTopLeft: '┏',
113
- heavyTopRight: '┓',
114
- heavyBottomLeft: '┗',
115
- heavyBottomRight: '┛',
116
- heavyHorizontal: '━',
117
- heavyVertical: '┃'
118
- };
119
-
120
- /**
121
- * Progress bar characters
122
- */
123
- export const progressChars = {
124
- filled: '█',
125
- empty: '░',
126
- partial: ['▏', '▎', '▍', '▌', '▋', '▊', '▉'],
127
- blocks: ['▁', '▂', '▃', '▄', '▅', '▆', '▇', '█'],
128
- dots: '⣿',
129
- emptyDots: '⣀'
130
- };
131
-
132
- /**
133
- * Confidence level icons
134
- */
135
- export const confidence = {
136
- high: '🟢', // >= 80%
137
- medium: '🟡', // 60-79%
138
- low: '🟠', // 40-59%
139
- veryLow: '🔴' // < 40%
140
- };
141
-
142
- /**
143
- * Get confidence icon based on numeric value
144
- */
145
- export function getConfidenceIcon(value) {
146
- if (value >= 0.8) return confidence.high;
147
- if (value >= 0.6) return confidence.medium;
148
- if (value >= 0.4) return confidence.low;
149
- return confidence.veryLow;
150
- }
151
-
152
- /**
153
- * Model-specific icons
154
- */
155
- export const models = {
156
- // Claude models
157
- opus: '👔', // Manager tier
158
- sonnet: '👨‍💻', // IC tier
159
- haiku: '🏗️', // Worker tier
160
-
161
- // GPT models
162
- 'gpt-5.5': '👔',
163
- 'gpt-5.4': '👨‍💻',
164
- 'gpt-4.1-mini': '🏗️',
165
- 'gpt-4.1': '👨‍💻',
166
- 'gpt-4': '👨‍💻',
167
- 'gpt-3.5': '🏗️'
168
- };
169
-
170
- /**
171
- * Get model icon by name
172
- */
173
- export function getModelIcon(modelName) {
174
- if (!modelName) return tier.worker;
175
-
176
- const name = modelName.toLowerCase();
177
-
178
- // Check exact matches first
179
- if (models[name]) return models[name];
180
-
181
- // Check partial matches
182
- if (name.includes('opus')) return models.opus;
183
- if (name.includes('sonnet')) return models.sonnet;
184
- if (name.includes('haiku')) return models.haiku;
185
- if (name.includes('gpt-5.5')) return models['gpt-5.5'];
186
- if (name.includes('gpt-5.4')) return models['gpt-5.4'];
187
- if (name.includes('gpt-4.1-mini') || name.includes('mini')) return models['gpt-4.1-mini'];
188
- if (name.includes('gpt-4.1')) return models['gpt-4.1'];
189
- if (name.includes('gpt-4')) return models['gpt-4'];
190
- if (name.includes('gpt-3.5')) return models['gpt-3.5'];
191
-
192
- // Default fallback
193
- return tier.worker;
194
- }
195
-
196
- /**
197
- * Activity/action icons
198
- */
199
- export const actions = {
200
- start: '▶️',
201
- stop: '⏹️',
202
- pause: '⏸️',
203
- restart: '🔄',
204
- create: '➕',
205
- delete: '🗑️',
206
- edit: '✏️',
207
- save: '💾',
208
- load: '📂',
209
- upload: '⬆️',
210
- download: '⬇️',
211
- sync: '🔄',
212
- backup: '💾',
213
- restore: '🔄',
214
- configure: '⚙️',
215
- install: '📦',
216
- uninstall: '🗑️',
217
- upgrade: '⬆️',
218
- downgrade: '⬇️',
219
- reset: '🔄',
220
- clear: '🧹',
221
- search: '🔍',
222
- filter: '🔎',
223
- sort: '📊',
224
- export: '📤',
225
- import: '📥',
226
- copy: '📋',
227
- cut: '✂️',
228
- paste: '📋',
229
- undo: '↶',
230
- redo: '↷'
231
- };
232
-
233
- /**
234
- * Session state icons
235
- */
236
- export const session = {
237
- new: '🆕',
238
- active: '🟢',
239
- paused: '⏸️',
240
- completed: '✅',
241
- failed: '❌',
242
- interrupted: '⚠️',
243
- archived: '📦',
244
- deleted: '🗑️'
245
- };
246
-
247
- /**
248
- * File operation icons
249
- */
250
- export const files = {
251
- read: '📖',
252
- write: '✏️',
253
- create: '➕',
254
- delete: '🗑️',
255
- move: '📦',
256
- copy: '📋',
257
- folder: '📁',
258
- file: '📄',
259
- code: '💻',
260
- config: '⚙️',
261
- data: '📊',
262
- image: '🖼️',
263
- document: '📝',
264
- archive: '📦',
265
- lock: '🔒',
266
- unlock: '🔓'
267
- };
268
-
269
- /**
270
- * System health icons
271
- */
272
- export const health = {
273
- healthy: '💚',
274
- warning: '💛',
275
- critical: '❤️',
276
- unknown: '🤍',
277
- offline: '💔',
278
- maintenance: '🔧',
279
- degraded: '⚠️'
280
- };
281
-
282
- /**
283
- * Networking icons
284
- */
285
- export const network = {
286
- connected: '🌐',
287
- disconnected: '📡',
288
- uploading: '⬆️',
289
- downloading: '⬇️',
290
- syncing: '🔄',
291
- error: '💥',
292
- timeout: '⏰',
293
- retry: '🔄'
294
- };
295
-
296
- /**
297
- * Get a random spinner frame
298
- */
299
- export function getSpinnerFrame(index) {
300
- return progress.spinner[index % progress.spinner.length];
301
- }
302
-
303
- /**
304
- * Create a simple spinner animation
305
- */
306
- export function createSpinner() {
307
- let frame = 0;
308
- return {
309
- tick() {
310
- const icon = getSpinnerFrame(frame);
311
- frame++;
312
- return icon;
313
- },
314
- stop() {
315
- frame = 0;
316
- }
317
- };
318
- }