@mks2508/better-logger 0.0.2-alpha.2 → 0.11.0-alpha.1

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 (247) hide show
  1. package/.github/workflows/ci-quality.yml +357 -0
  2. package/.github/workflows/docs-demo.yml +119 -0
  3. package/.github/workflows/releases-core.yml +512 -0
  4. package/.github/workflows/releases-full.yml +582 -0
  5. package/.github/{workflows → workflows-backup}/ci.yml +12 -110
  6. package/.github/workflows-backup/nightly.yml +196 -0
  7. package/.github/workflows-backup/release-optimized.yml +373 -0
  8. package/.release-notes-0.2.0.md +129 -0
  9. package/.yamllint +28 -0
  10. package/CHANGELOG.json +749 -0
  11. package/CLAUDE.md +92 -1
  12. package/README.md +142 -498
  13. package/bun.lock +323 -0
  14. package/demo.html +9 -2
  15. package/dist/Logger.d.ts +176 -0
  16. package/dist/Logger.d.ts.map +1 -0
  17. package/dist/Logger.js +498 -0
  18. package/dist/chunks/Logger-C2-cR3No.js +2 -0
  19. package/dist/chunks/Logger-C2-cR3No.js.map +1 -0
  20. package/dist/chunks/Logger-CVwk8cgA.js +2159 -0
  21. package/dist/chunks/Logger-CVwk8cgA.js.map +1 -0
  22. package/dist/chunks/RemoteLogHandler-CjWpWZGl.js +33 -0
  23. package/dist/chunks/RemoteLogHandler-CjWpWZGl.js.map +1 -0
  24. package/dist/chunks/RemoteLogHandler-ymkQ97xl.js +2 -0
  25. package/dist/chunks/RemoteLogHandler-ymkQ97xl.js.map +1 -0
  26. package/dist/chunks/StyleBuilder-BoJTmskd.js +361 -0
  27. package/dist/chunks/StyleBuilder-BoJTmskd.js.map +1 -0
  28. package/dist/chunks/StyleBuilder-LPLzsoHY.js +4 -0
  29. package/dist/chunks/StyleBuilder-LPLzsoHY.js.map +1 -0
  30. package/dist/cli/CommandProcessor.d.ts +103 -0
  31. package/dist/cli/CommandProcessor.d.ts.map +1 -0
  32. package/dist/cli/CommandProcessor.js +184 -0
  33. package/dist/cli/commands/ConfigCommand.d.ts +17 -0
  34. package/dist/cli/commands/ConfigCommand.d.ts.map +1 -0
  35. package/dist/cli/commands/ConfigCommand.js +88 -0
  36. package/dist/cli/commands/ExportCommand.d.ts +51 -0
  37. package/dist/cli/commands/ExportCommand.d.ts.map +1 -0
  38. package/dist/cli/commands/ExportCommand.js +243 -0
  39. package/dist/cli/commands/HistoryCommand.d.ts +50 -0
  40. package/dist/cli/commands/HistoryCommand.d.ts.map +1 -0
  41. package/dist/cli/commands/HistoryCommand.js +96 -0
  42. package/dist/cli/commands/StatusCommand.d.ts +33 -0
  43. package/dist/cli/commands/StatusCommand.d.ts.map +1 -0
  44. package/dist/cli/commands/StatusCommand.js +93 -0
  45. package/dist/cli/commands/ThemeCommand.d.ts +33 -0
  46. package/dist/cli/commands/ThemeCommand.d.ts.map +1 -0
  47. package/dist/cli/commands/ThemeCommand.js +79 -0
  48. package/dist/cli/help.d.ts +15 -0
  49. package/dist/cli/help.d.ts.map +1 -0
  50. package/dist/cli/help.js +118 -0
  51. package/dist/cli/index.d.ts +15 -0
  52. package/dist/cli/index.d.ts.map +1 -0
  53. package/dist/cli/index.js +46 -0
  54. package/dist/constants.d.ts +91 -0
  55. package/dist/constants.d.ts.map +1 -0
  56. package/dist/constants.js +80 -0
  57. package/dist/core.cjs +1 -1
  58. package/dist/core.cjs.map +1 -1
  59. package/dist/core.d.ts +130 -0
  60. package/dist/core.d.ts.map +1 -0
  61. package/dist/core.js +258 -242
  62. package/dist/core.js.map +1 -1
  63. package/dist/example.d.ts +18 -0
  64. package/dist/example.d.ts.map +1 -0
  65. package/dist/example.js +154 -0
  66. package/dist/exports-module.d.ts +203 -0
  67. package/dist/exports-module.d.ts.map +1 -0
  68. package/dist/exports-module.js +260 -0
  69. package/dist/exports.cjs +1 -1
  70. package/dist/exports.cjs.map +1 -1
  71. package/dist/exports.js +2 -2
  72. package/dist/handlers/AnalyticsLogHandler.d.ts +11 -0
  73. package/dist/handlers/AnalyticsLogHandler.d.ts.map +1 -0
  74. package/dist/handlers/AnalyticsLogHandler.js +19 -0
  75. package/dist/handlers/ExportLogHandler.d.ts +103 -0
  76. package/dist/handlers/ExportLogHandler.d.ts.map +1 -0
  77. package/dist/handlers/ExportLogHandler.js +516 -0
  78. package/dist/handlers/FileLogHandler.d.ts +13 -0
  79. package/dist/handlers/FileLogHandler.d.ts.map +1 -0
  80. package/dist/handlers/FileLogHandler.js +24 -0
  81. package/dist/handlers/RemoteLogHandler.d.ts +14 -0
  82. package/dist/handlers/RemoteLogHandler.d.ts.map +1 -0
  83. package/dist/handlers/RemoteLogHandler.js +37 -0
  84. package/dist/handlers/index.d.ts +8 -0
  85. package/dist/handlers/index.d.ts.map +1 -0
  86. package/dist/handlers/index.js +7 -0
  87. package/dist/index.cjs +1 -1
  88. package/dist/index.cjs.map +1 -1
  89. package/dist/index.d.ts +86 -0
  90. package/dist/index.d.ts.map +1 -0
  91. package/dist/index.js +89 -103
  92. package/dist/main.d.ts +2 -0
  93. package/dist/main.d.ts.map +1 -0
  94. package/dist/main.js +139 -0
  95. package/dist/styling/StyleBuilder.d.ts +132 -0
  96. package/dist/styling/StyleBuilder.d.ts.map +1 -0
  97. package/dist/styling/StyleBuilder.js +268 -0
  98. package/dist/styling/banners.d.ts +45 -0
  99. package/dist/styling/banners.d.ts.map +1 -0
  100. package/dist/styling/banners.js +155 -0
  101. package/dist/styling/index.d.ts +7 -0
  102. package/dist/styling/index.d.ts.map +1 -0
  103. package/dist/styling/index.js +6 -0
  104. package/dist/styling/themes.d.ts +10 -0
  105. package/dist/styling/themes.d.ts.map +1 -0
  106. package/dist/styling/themes.js +231 -0
  107. package/dist/styling-module.d.ts +185 -0
  108. package/dist/styling-module.d.ts.map +1 -0
  109. package/dist/styling-module.js +199 -0
  110. package/dist/styling.cjs +1 -1
  111. package/dist/styling.cjs.map +1 -1
  112. package/dist/styling.js +4 -4
  113. package/dist/types/Logger.d.ts +172 -0
  114. package/dist/types/Logger.d.ts.map +1 -0
  115. package/dist/types/cli/CommandProcessor.d.ts +100 -0
  116. package/dist/types/cli/CommandProcessor.d.ts.map +1 -0
  117. package/dist/types/cli/commands/ConfigCommand.d.ts +14 -0
  118. package/dist/types/cli/commands/ConfigCommand.d.ts.map +1 -0
  119. package/dist/types/cli/commands/ExportCommand.d.ts +48 -0
  120. package/dist/types/cli/commands/ExportCommand.d.ts.map +1 -0
  121. package/dist/types/cli/commands/HistoryCommand.d.ts +47 -0
  122. package/dist/types/cli/commands/HistoryCommand.d.ts.map +1 -0
  123. package/dist/types/cli/commands/StatusCommand.d.ts +30 -0
  124. package/dist/types/cli/commands/StatusCommand.d.ts.map +1 -0
  125. package/dist/types/cli/commands/ThemeCommand.d.ts +30 -0
  126. package/dist/types/cli/commands/ThemeCommand.d.ts.map +1 -0
  127. package/dist/types/cli/help.d.ts +12 -0
  128. package/dist/types/cli/help.d.ts.map +1 -0
  129. package/dist/types/cli/index.d.ts +15 -0
  130. package/dist/types/cli/index.d.ts.map +1 -0
  131. package/dist/types/constants.d.ts +88 -0
  132. package/dist/types/constants.d.ts.map +1 -0
  133. package/dist/types/core.d.ts +71 -211
  134. package/dist/types/core.d.ts.map +1 -0
  135. package/dist/types/core.js +13 -0
  136. package/dist/types/example.d.ts +18 -0
  137. package/dist/types/example.d.ts.map +1 -0
  138. package/dist/types/exports-module.d.ts +196 -0
  139. package/dist/types/exports-module.d.ts.map +1 -0
  140. package/dist/types/handlers/AnalyticsLogHandler.d.ts +8 -0
  141. package/dist/types/handlers/AnalyticsLogHandler.d.ts.map +1 -0
  142. package/dist/types/handlers/ExportLogHandler.d.ts +100 -0
  143. package/dist/types/handlers/ExportLogHandler.d.ts.map +1 -0
  144. package/dist/types/handlers/FileLogHandler.d.ts +10 -0
  145. package/dist/types/handlers/FileLogHandler.d.ts.map +1 -0
  146. package/dist/types/handlers/RemoteLogHandler.d.ts +11 -0
  147. package/dist/types/handlers/RemoteLogHandler.d.ts.map +1 -0
  148. package/dist/types/handlers/index.d.ts +8 -0
  149. package/dist/types/handlers/index.d.ts.map +1 -0
  150. package/dist/types/handlers.d.ts +88 -0
  151. package/dist/types/handlers.d.ts.map +1 -0
  152. package/dist/types/handlers.js +4 -0
  153. package/dist/types/index.d.ts +7 -675
  154. package/dist/types/index.d.ts.map +1 -0
  155. package/dist/types/index.js +4 -0
  156. package/dist/types/main.d.ts +2 -0
  157. package/dist/types/main.d.ts.map +1 -0
  158. package/dist/types/styling/StyleBuilder.d.ts +132 -0
  159. package/dist/types/styling/StyleBuilder.d.ts.map +1 -0
  160. package/dist/types/styling/banners.d.ts +42 -0
  161. package/dist/types/styling/banners.d.ts.map +1 -0
  162. package/dist/types/styling/index.d.ts +7 -0
  163. package/dist/types/styling/index.d.ts.map +1 -0
  164. package/dist/types/styling/themes.d.ts +7 -0
  165. package/dist/types/styling/themes.d.ts.map +1 -0
  166. package/dist/types/styling-module.d.ts +178 -0
  167. package/dist/types/styling-module.d.ts.map +1 -0
  168. package/dist/types/types/core.d.ts +71 -0
  169. package/dist/types/types/core.d.ts.map +1 -0
  170. package/dist/types/types/handlers.d.ts +85 -0
  171. package/dist/types/types/handlers.d.ts.map +1 -0
  172. package/dist/types/types/index.d.ts +7 -0
  173. package/dist/types/types/index.d.ts.map +1 -0
  174. package/dist/types/utils/index.d.ts +7 -0
  175. package/dist/types/utils/index.d.ts.map +1 -0
  176. package/dist/types/utils/output.d.ts +29 -0
  177. package/dist/types/utils/output.d.ts.map +1 -0
  178. package/dist/types/utils/stackTrace.d.ts +6 -0
  179. package/dist/types/utils/stackTrace.d.ts.map +1 -0
  180. package/dist/types/utils/timestamps.d.ts +20 -0
  181. package/dist/types/utils/timestamps.d.ts.map +1 -0
  182. package/dist/utils/index.d.ts +7 -0
  183. package/dist/utils/index.d.ts.map +1 -0
  184. package/dist/utils/index.js +6 -0
  185. package/dist/utils/output.d.ts +32 -0
  186. package/dist/utils/output.d.ts.map +1 -0
  187. package/dist/utils/output.js +97 -0
  188. package/dist/utils/stackTrace.d.ts +9 -0
  189. package/dist/utils/stackTrace.d.ts.map +1 -0
  190. package/dist/utils/stackTrace.js +81 -0
  191. package/dist/utils/timestamps.d.ts +20 -0
  192. package/dist/utils/timestamps.d.ts.map +1 -0
  193. package/dist/utils/timestamps.js +71 -0
  194. package/docs/API.md +691 -0
  195. package/docs/DEVELOPMENT.md +731 -0
  196. package/docs/PACKAGES.md +244 -0
  197. package/docs/_config.yml +36 -0
  198. package/docs/index.md +179 -0
  199. package/examples/README.md +208 -0
  200. package/examples/basic-logging.js +75 -0
  201. package/examples/data-export.js +234 -0
  202. package/examples/package.json +16 -0
  203. package/examples/performance-timing.js +170 -0
  204. package/examples/styling-themes.js +207 -0
  205. package/package.json +32 -21
  206. package/packages/core/package.json +35 -0
  207. package/packages/exports/package.json +41 -0
  208. package/packages/styling/package.json +41 -0
  209. package/project-utils/README.md +172 -0
  210. package/project-utils/auto-release-gemini.ts +1193 -0
  211. package/project-utils/commit-generator.ts +1385 -0
  212. package/project-utils/commit-ui.ts +264 -0
  213. package/project-utils/git-utils.ts +199 -0
  214. package/project-utils/github-release-manager.ts +466 -0
  215. package/project-utils/prompt-templates.js +345 -0
  216. package/project-utils/prompt-templates.ts +422 -0
  217. package/project-utils/version-manager.ts +1078 -0
  218. package/src/Logger.ts +2 -1
  219. package/src/cli/CommandProcessor.ts +173 -2
  220. package/src/cli/commands/HistoryCommand.ts +117 -0
  221. package/src/cli/index.ts +12 -0
  222. package/src/handlers/ExportLogHandler.ts +141 -0
  223. package/tests/test-conflict-resolution.ts +391 -0
  224. package/tests/validate-workflows.sh +131 -0
  225. package/tests/yaml-autofix.sh +146 -0
  226. package/vite.config.ts +152 -50
  227. package/.claude/settings.local.json +0 -22
  228. package/.npmrc.bak +0 -1
  229. package/dist/chunks/Logger-BQhMKy_T.js +0 -2
  230. package/dist/chunks/Logger-BQhMKy_T.js.map +0 -1
  231. package/dist/chunks/Logger-BrFKFZcD.js +0 -978
  232. package/dist/chunks/Logger-BrFKFZcD.js.map +0 -1
  233. package/dist/chunks/core-2opW4Pi3.js +0 -194
  234. package/dist/chunks/core-2opW4Pi3.js.map +0 -1
  235. package/dist/chunks/core-DyugwSYZ.js +0 -4
  236. package/dist/chunks/core-DyugwSYZ.js.map +0 -1
  237. package/dist/chunks/exports-BNP3R7dp.js +0 -421
  238. package/dist/chunks/exports-BNP3R7dp.js.map +0 -1
  239. package/dist/chunks/exports-U1xLBXrY.js +0 -2
  240. package/dist/chunks/exports-U1xLBXrY.js.map +0 -1
  241. package/dist/chunks/styling-DhUDzwlE.js +0 -654
  242. package/dist/chunks/styling-DhUDzwlE.js.map +0 -1
  243. package/dist/chunks/styling-tmRDI28D.js +0 -2
  244. package/dist/chunks/styling-tmRDI28D.js.map +0 -1
  245. package/dist/types/exports.d.ts +0 -600
  246. package/dist/types/styling.d.ts +0 -751
  247. /package/.github/{workflows → workflows-backup}/release.yml +0 -0
package/src/Logger.ts CHANGED
@@ -594,4 +594,5 @@ export const cli = (command: string) => defaultLogger.cli(command);
594
594
 
595
595
  // Re-export handlers and utilities for backward compatibility
596
596
  export { FileLogHandler, RemoteLogHandler, AnalyticsLogHandler, ExportLogHandler } from './handlers/index.js';
597
- export { StyleBuilder, StylePresets as Styles } from './styling/index.js';
597
+ export { StyleBuilder, StylePresets as Styles } from './styling/index.js';// Test change to trigger workflow
598
+ // Test permissions fix
@@ -11,20 +11,101 @@ export interface ICommand {
11
11
  name: string;
12
12
  description: string;
13
13
  usage: string;
14
+ category?: string;
15
+ aliases?: string[];
14
16
  execute(args: string, logger: Logger): void | Promise<void>;
15
17
  }
16
18
 
19
+ /**
20
+ * Plugin interface for extending CLI functionality
21
+ */
22
+ export interface ICLIPlugin {
23
+ name: string;
24
+ version: string;
25
+ description: string;
26
+ commands: ICommand[];
27
+ initialize?(processor: CommandProcessor, logger: Logger): void;
28
+ cleanup?(): void;
29
+ }
30
+
31
+ /**
32
+ * Command history entry
33
+ */
34
+ interface HistoryEntry {
35
+ command: string;
36
+ timestamp: Date;
37
+ success: boolean;
38
+ }
39
+
17
40
  /**
18
41
  * CLI command processor
19
42
  */
20
43
  export class CommandProcessor {
21
44
  private commands: Map<string, ICommand> = new Map();
45
+ private aliases: Map<string, string> = new Map();
46
+ private plugins: Map<string, ICLIPlugin> = new Map();
47
+ private history: HistoryEntry[] = [];
48
+ private maxHistorySize: number = 100;
49
+ private isInteractiveMode: boolean = false;
22
50
 
23
51
  /**
24
52
  * Register a command
25
53
  */
26
54
  registerCommand(command: ICommand): void {
27
55
  this.commands.set(command.name, command);
56
+
57
+ // Register aliases
58
+ if (command.aliases) {
59
+ for (const alias of command.aliases) {
60
+ this.aliases.set(alias, command.name);
61
+ }
62
+ }
63
+ }
64
+
65
+ /**
66
+ * Register a plugin
67
+ */
68
+ registerPlugin(plugin: ICLIPlugin, logger?: Logger): void {
69
+ if (this.plugins.has(plugin.name)) {
70
+ throw new Error(`Plugin ${plugin.name} is already registered`);
71
+ }
72
+
73
+ this.plugins.set(plugin.name, plugin);
74
+
75
+ // Register plugin commands
76
+ for (const command of plugin.commands) {
77
+ this.registerCommand(command);
78
+ }
79
+
80
+ // Initialize plugin
81
+ if (plugin.initialize && logger) {
82
+ plugin.initialize(this, logger);
83
+ }
84
+ }
85
+
86
+ /**
87
+ * Unregister a plugin
88
+ */
89
+ unregisterPlugin(pluginName: string): void {
90
+ const plugin = this.plugins.get(pluginName);
91
+ if (!plugin) return;
92
+
93
+ // Remove plugin commands
94
+ for (const command of plugin.commands) {
95
+ this.commands.delete(command.name);
96
+ if (command.aliases) {
97
+ for (const alias of command.aliases) {
98
+ this.aliases.delete(alias);
99
+ }
100
+ }
101
+ }
102
+
103
+ // Cleanup plugin
104
+ if (plugin.cleanup) {
105
+ plugin.cleanup();
106
+ }
107
+
108
+ this.plugins.delete(pluginName);
28
109
  }
29
110
 
30
111
  /**
@@ -38,7 +119,70 @@ export class CommandProcessor {
38
119
  * Get a specific command
39
120
  */
40
121
  getCommand(name: string): ICommand | undefined {
41
- return this.commands.get(name);
122
+ // Check direct command name
123
+ let command = this.commands.get(name);
124
+ if (command) return command;
125
+
126
+ // Check aliases
127
+ const aliasTarget = this.aliases.get(name);
128
+ if (aliasTarget) {
129
+ return this.commands.get(aliasTarget);
130
+ }
131
+
132
+ return undefined;
133
+ }
134
+
135
+ /**
136
+ * Get command history
137
+ */
138
+ getHistory(): HistoryEntry[] {
139
+ return [...this.history];
140
+ }
141
+
142
+ /**
143
+ * Clear command history
144
+ */
145
+ clearHistory(): void {
146
+ this.history = [];
147
+ }
148
+
149
+ /**
150
+ * Get registered plugins
151
+ */
152
+ getPlugins(): ICLIPlugin[] {
153
+ return Array.from(this.plugins.values());
154
+ }
155
+
156
+ /**
157
+ * Enter interactive mode
158
+ */
159
+ enterInteractiveMode(logger: Logger): void {
160
+ this.isInteractiveMode = true;
161
+ logger.info('🔧 Interactive CLI mode activated. Type /exit to quit, /help for commands.');
162
+
163
+ // Set up browser console listener for interactive commands
164
+ if (typeof window !== 'undefined') {
165
+ this.setupBrowserInteractiveMode(logger);
166
+ }
167
+ }
168
+
169
+ /**
170
+ * Exit interactive mode
171
+ */
172
+ exitInteractiveMode(): void {
173
+ this.isInteractiveMode = false;
174
+ }
175
+
176
+ /**
177
+ * Setup browser interactive mode
178
+ */
179
+ private setupBrowserInteractiveMode(logger: Logger): void {
180
+ // Add global CLI function for browser usage
181
+ (window as any).cli = (commandString: string) => {
182
+ return this.processCommand(`/${commandString}`, logger);
183
+ };
184
+
185
+ logger.info('💡 Use cli("command") to execute CLI commands in browser console.');
42
186
  }
43
187
 
44
188
  /**
@@ -47,6 +191,7 @@ export class CommandProcessor {
47
191
  async processCommand(commandString: string, logger: Logger): Promise<void> {
48
192
  if (!commandString.startsWith('/')) {
49
193
  logger.error('Invalid command. Commands must start with /');
194
+ this.addToHistory(commandString, false);
50
195
  return;
51
196
  }
52
197
 
@@ -54,16 +199,42 @@ export class CommandProcessor {
54
199
  const commandName = parts[0] || '';
55
200
  const args = parts.slice(1).join(' ');
56
201
 
57
- const command = this.commands.get(commandName);
202
+ const command = this.getCommand(commandName);
58
203
  if (!command) {
59
204
  logger.error(`Unknown command: ${commandName}. Type /help for available commands.`);
205
+
206
+ // Suggest similar commands
207
+ const suggestions = this.getSuggestions(commandName);
208
+ if (suggestions.length > 0) {
209
+ logger.info(`📋 Did you mean: ${suggestions.slice(0, 3).join(', ')}?`);
210
+ }
211
+
212
+ this.addToHistory(commandString, false);
60
213
  return;
61
214
  }
62
215
 
63
216
  try {
64
217
  await command.execute(args || '', logger);
218
+ this.addToHistory(commandString, true);
65
219
  } catch (error) {
66
220
  logger.error(`Command '${commandName}' failed:`, error);
221
+ this.addToHistory(commandString, false);
222
+ }
223
+ }
224
+
225
+ /**
226
+ * Add command to history
227
+ */
228
+ private addToHistory(command: string, success: boolean): void {
229
+ this.history.unshift({
230
+ command,
231
+ timestamp: new Date(),
232
+ success
233
+ });
234
+
235
+ // Limit history size
236
+ if (this.history.length > this.maxHistorySize) {
237
+ this.history = this.history.slice(0, this.maxHistorySize);
67
238
  }
68
239
  }
69
240
 
@@ -0,0 +1,117 @@
1
+ /**
2
+ * @fileoverview History management commands for CLI
3
+ */
4
+
5
+ import type { ICommand } from '../CommandProcessor.js';
6
+ import type { Logger } from '../../Logger.js';
7
+
8
+ /**
9
+ * Show command history
10
+ */
11
+ export class HistoryCommand implements ICommand {
12
+ name = 'history';
13
+ description = 'Show command execution history';
14
+ usage = '/history [limit] - Show recent commands (default: 10)';
15
+ category = 'system';
16
+ aliases = ['hist', 'h'];
17
+
18
+ execute(args: string, logger: Logger): void {
19
+ const processor = (logger as any).cliProcessor;
20
+ if (!processor) {
21
+ logger.error('CLI processor not available');
22
+ return;
23
+ }
24
+
25
+ const limit = parseInt(args) || 10;
26
+ const history = processor.getHistory().slice(0, limit);
27
+
28
+ if (history.length === 0) {
29
+ logger.info('📝 No command history available');
30
+ return;
31
+ }
32
+
33
+ logger.info(`📋 Last ${history.length} commands:`);
34
+
35
+ history.forEach((entry: any, index: number) => {
36
+ const status = entry.success ? '✅' : '❌';
37
+ const time = entry.timestamp.toLocaleTimeString();
38
+ logger.info(`${status} [${time}] ${entry.command}`);
39
+ });
40
+ }
41
+ }
42
+
43
+ /**
44
+ * Clear command history
45
+ */
46
+ export class ClearHistoryCommand implements ICommand {
47
+ name = 'clearhistory';
48
+ description = 'Clear command execution history';
49
+ usage = '/clearhistory - Remove all command history';
50
+ category = 'system';
51
+ aliases = ['clrhist'];
52
+
53
+ execute(args: string, logger: Logger): void {
54
+ const processor = (logger as any).cliProcessor;
55
+ if (!processor) {
56
+ logger.error('CLI processor not available');
57
+ return;
58
+ }
59
+
60
+ processor.clearHistory();
61
+ logger.success('🗑️ Command history cleared');
62
+ }
63
+ }
64
+
65
+ /**
66
+ * Interactive mode command
67
+ */
68
+ export class InteractiveCommand implements ICommand {
69
+ name = 'interactive';
70
+ description = 'Enter interactive CLI mode';
71
+ usage = '/interactive - Start interactive command mode';
72
+ category = 'system';
73
+ aliases = ['i', 'repl'];
74
+
75
+ execute(args: string, logger: Logger): void {
76
+ const processor = (logger as any).cliProcessor;
77
+ if (!processor) {
78
+ logger.error('CLI processor not available');
79
+ return;
80
+ }
81
+
82
+ processor.enterInteractiveMode(logger);
83
+ }
84
+ }
85
+
86
+ /**
87
+ * Plugin management command
88
+ */
89
+ export class PluginsCommand implements ICommand {
90
+ name = 'plugins';
91
+ description = 'List loaded CLI plugins';
92
+ usage = '/plugins - Show all registered plugins';
93
+ category = 'system';
94
+ aliases = ['plug'];
95
+
96
+ execute(args: string, logger: Logger): void {
97
+ const processor = (logger as any).cliProcessor;
98
+ if (!processor) {
99
+ logger.error('CLI processor not available');
100
+ return;
101
+ }
102
+
103
+ const plugins = processor.getPlugins();
104
+
105
+ if (plugins.length === 0) {
106
+ logger.info('🔌 No plugins registered');
107
+ return;
108
+ }
109
+
110
+ logger.info(`🔌 Loaded plugins (${plugins.length}):`);
111
+
112
+ plugins.forEach((plugin: any) => {
113
+ logger.info(` 📦 ${plugin.name} v${plugin.version} - ${plugin.description}`);
114
+ logger.info(` Commands: ${plugin.commands.map((c: any) => c.name).join(', ')}`);
115
+ });
116
+ }
117
+ }
package/src/cli/index.ts CHANGED
@@ -33,6 +33,12 @@ import {
33
33
  ClearBufferCommand,
34
34
  BufferInfoCommand
35
35
  } from './commands/ExportCommand.js';
36
+ import {
37
+ HistoryCommand,
38
+ ClearHistoryCommand,
39
+ InteractiveCommand,
40
+ PluginsCommand
41
+ } from './commands/HistoryCommand.js';
36
42
 
37
43
  /**
38
44
  * Create and configure default CLI processor
@@ -55,5 +61,11 @@ export function createDefaultCLI(): CommandProcessor {
55
61
  processor.registerCommand(new ClearBufferCommand());
56
62
  processor.registerCommand(new BufferInfoCommand());
57
63
 
64
+ // Register new enhanced commands
65
+ processor.registerCommand(new HistoryCommand());
66
+ processor.registerCommand(new ClearHistoryCommand());
67
+ processor.registerCommand(new InteractiveCommand());
68
+ processor.registerCommand(new PluginsCommand());
69
+
58
70
  return processor;
59
71
  }
@@ -465,4 +465,145 @@ export class ExportLogHandler implements ILogHandler {
465
465
  getAllLogs(): LogEntry[] {
466
466
  return [...this.buffer];
467
467
  }
468
+
469
+ /**
470
+ * Save export to file with download prompt
471
+ */
472
+ async saveToFile(format: ExportFormat, filters: ExportFilters = {}, options: ExportOptions = {}): Promise<boolean> {
473
+ try {
474
+ const result = this.export(format, filters, options);
475
+ const blob = new Blob([result.data], {
476
+ type: this.getMimeType(format)
477
+ });
478
+
479
+ const url = URL.createObjectURL(blob);
480
+ const a = document.createElement('a');
481
+ const filename = this.generateFilename(format, filters);
482
+
483
+ a.href = url;
484
+ a.download = filename;
485
+ a.style.display = 'none';
486
+ document.body.appendChild(a);
487
+ a.click();
488
+ document.body.removeChild(a);
489
+ URL.revokeObjectURL(url);
490
+
491
+ return true;
492
+ } catch (error) {
493
+ console.error('Failed to save file:', error);
494
+ return false;
495
+ }
496
+ }
497
+
498
+ /**
499
+ * Get MIME type for format
500
+ */
501
+ private getMimeType(format: ExportFormat): string {
502
+ const mimeTypes = {
503
+ json: 'application/json',
504
+ csv: 'text/csv',
505
+ markdown: 'text/markdown',
506
+ plain: 'text/plain',
507
+ html: 'text/html'
508
+ };
509
+ return mimeTypes[format] || 'text/plain';
510
+ }
511
+
512
+ /**
513
+ * Generate filename with timestamp
514
+ */
515
+ private generateFilename(format: ExportFormat, filters: ExportFilters): string {
516
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, -5);
517
+ const prefix = filters.prefixes?.length === 1 ? `_${filters.prefixes[0]}` : '';
518
+ const extension = format === 'markdown' ? 'md' : format;
519
+ return `logs${prefix}_${timestamp}.${extension}`;
520
+ }
521
+
522
+ /**
523
+ * Stream logs to external endpoint
524
+ */
525
+ async streamToEndpoint(endpoint: string, filters: ExportFilters = {}, options: {
526
+ apiKey?: string;
527
+ batchSize?: number;
528
+ format?: ExportFormat
529
+ } = {}): Promise<boolean> {
530
+ try {
531
+ const logs = this.filterLogs(filters);
532
+ const batchSize = options.batchSize || 100;
533
+ const format = options.format || 'json';
534
+
535
+ // Send in batches
536
+ for (let i = 0; i < logs.length; i += batchSize) {
537
+ const batch = logs.slice(i, i + batchSize);
538
+ const result = this.export(format, {}, { compact: true });
539
+
540
+ const headers: Record<string, string> = {
541
+ 'Content-Type': 'application/json'
542
+ };
543
+
544
+ if (options.apiKey) {
545
+ headers['Authorization'] = `Bearer ${options.apiKey}`;
546
+ }
547
+
548
+ const response = await fetch(endpoint, {
549
+ method: 'POST',
550
+ headers,
551
+ body: JSON.stringify({
552
+ logs: batch,
553
+ metadata: {
554
+ batchIndex: Math.floor(i / batchSize),
555
+ totalBatches: Math.ceil(logs.length / batchSize),
556
+ timestamp: new Date().toISOString()
557
+ }
558
+ })
559
+ });
560
+
561
+ if (!response.ok) {
562
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
563
+ }
564
+ }
565
+
566
+ return true;
567
+ } catch (error) {
568
+ console.error('Failed to stream logs:', error);
569
+ return false;
570
+ }
571
+ }
572
+
573
+ /**
574
+ * Create export with metadata enrichment
575
+ */
576
+ exportWithMetadata(format: ExportFormat, filters: ExportFilters = {}, options: ExportOptions = {}): ExportResult {
577
+ const baseResult = this.export(format, filters, options);
578
+ const bufferStats = this.getBufferStats();
579
+
580
+ return {
581
+ ...baseResult,
582
+ metadata: {
583
+ ...baseResult.metadata,
584
+ bufferStats: bufferStats,
585
+ performance: {
586
+ memoryUsage: this.estimateMemoryUsage(),
587
+ processingTime: Date.now()
588
+ },
589
+ system: {
590
+ userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : 'Node.js',
591
+ timestamp: new Date().toISOString(),
592
+ timezone: Intl.DateTimeFormat().resolvedOptions().timeZone
593
+ }
594
+ } as any
595
+ };
596
+ }
597
+
598
+ /**
599
+ * Estimate memory usage of buffer
600
+ */
601
+ private estimateMemoryUsage(): number {
602
+ const sampleEntry = this.buffer[0];
603
+ if (!sampleEntry) return 0;
604
+
605
+ // Rough estimation: JSON.stringify size * buffer length
606
+ const sampleSize = JSON.stringify(sampleEntry).length;
607
+ return sampleSize * this.buffer.length;
608
+ }
468
609
  }