hackwriter 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. package/LICENSE +9 -0
  2. package/README.md +55 -0
  3. package/dist/agent/Agent.d.ts +9 -0
  4. package/dist/agent/Agent.d.ts.map +1 -0
  5. package/dist/agent/Agent.js +2 -0
  6. package/dist/agent/Agent.js.map +1 -0
  7. package/dist/agent/AgentExecutor.d.ts +36 -0
  8. package/dist/agent/AgentExecutor.d.ts.map +1 -0
  9. package/dist/agent/AgentExecutor.js +306 -0
  10. package/dist/agent/AgentExecutor.js.map +1 -0
  11. package/dist/agent/ApprovalManager.d.ts +8 -0
  12. package/dist/agent/ApprovalManager.d.ts.map +1 -0
  13. package/dist/agent/ApprovalManager.js +45 -0
  14. package/dist/agent/ApprovalManager.js.map +1 -0
  15. package/dist/agent/ContextCompressor.d.ts +9 -0
  16. package/dist/agent/ContextCompressor.d.ts.map +1 -0
  17. package/dist/agent/ContextCompressor.js +58 -0
  18. package/dist/agent/ContextCompressor.js.map +1 -0
  19. package/dist/agent/ConversationContext.d.ts +19 -0
  20. package/dist/agent/ConversationContext.d.ts.map +1 -0
  21. package/dist/agent/ConversationContext.js +236 -0
  22. package/dist/agent/ConversationContext.js.map +1 -0
  23. package/dist/agent/ModelFactory.d.ts +4 -0
  24. package/dist/agent/ModelFactory.d.ts.map +1 -0
  25. package/dist/agent/ModelFactory.js +32 -0
  26. package/dist/agent/ModelFactory.js.map +1 -0
  27. package/dist/cli.d.ts +3 -0
  28. package/dist/cli.d.ts.map +1 -0
  29. package/dist/cli.js +146 -0
  30. package/dist/cli.js.map +1 -0
  31. package/dist/commands/setup.d.ts +2 -0
  32. package/dist/commands/setup.d.ts.map +1 -0
  33. package/dist/commands/setup.js +110 -0
  34. package/dist/commands/setup.js.map +1 -0
  35. package/dist/config/ConfigSchema.d.ts +75 -0
  36. package/dist/config/ConfigSchema.d.ts.map +1 -0
  37. package/dist/config/ConfigSchema.js +54 -0
  38. package/dist/config/ConfigSchema.js.map +1 -0
  39. package/dist/config/Configuration.d.ts +30 -0
  40. package/dist/config/Configuration.d.ts.map +1 -0
  41. package/dist/config/Configuration.js +2 -0
  42. package/dist/config/Configuration.js.map +1 -0
  43. package/dist/config/ConfigurationLoader.d.ts +8 -0
  44. package/dist/config/ConfigurationLoader.d.ts.map +1 -0
  45. package/dist/config/ConfigurationLoader.js +75 -0
  46. package/dist/config/ConfigurationLoader.js.map +1 -0
  47. package/dist/messaging/MessageBus.d.ts +11 -0
  48. package/dist/messaging/MessageBus.d.ts.map +1 -0
  49. package/dist/messaging/MessageBus.js +23 -0
  50. package/dist/messaging/MessageBus.js.map +1 -0
  51. package/dist/messaging/MessageTypes.d.ts +39 -0
  52. package/dist/messaging/MessageTypes.d.ts.map +1 -0
  53. package/dist/messaging/MessageTypes.js +2 -0
  54. package/dist/messaging/MessageTypes.js.map +1 -0
  55. package/dist/session/SessionManager.d.ts +11 -0
  56. package/dist/session/SessionManager.d.ts.map +1 -0
  57. package/dist/session/SessionManager.js +56 -0
  58. package/dist/session/SessionManager.js.map +1 -0
  59. package/dist/tools/base/Tool.d.ts +19 -0
  60. package/dist/tools/base/Tool.d.ts.map +1 -0
  61. package/dist/tools/base/Tool.js +15 -0
  62. package/dist/tools/base/Tool.js.map +1 -0
  63. package/dist/tools/base/ToolRegistry.d.ts +16 -0
  64. package/dist/tools/base/ToolRegistry.d.ts.map +1 -0
  65. package/dist/tools/base/ToolRegistry.js +29 -0
  66. package/dist/tools/base/ToolRegistry.js.map +1 -0
  67. package/dist/tools/file/ListFilesTool.d.ts +17 -0
  68. package/dist/tools/file/ListFilesTool.d.ts.map +1 -0
  69. package/dist/tools/file/ListFilesTool.js +80 -0
  70. package/dist/tools/file/ListFilesTool.js.map +1 -0
  71. package/dist/tools/file/ReadFileTool.d.ts +13 -0
  72. package/dist/tools/file/ReadFileTool.d.ts.map +1 -0
  73. package/dist/tools/file/ReadFileTool.js +32 -0
  74. package/dist/tools/file/ReadFileTool.js.map +1 -0
  75. package/dist/tools/file/WriteFileTool.d.ts +18 -0
  76. package/dist/tools/file/WriteFileTool.d.ts.map +1 -0
  77. package/dist/tools/file/WriteFileTool.js +54 -0
  78. package/dist/tools/file/WriteFileTool.js.map +1 -0
  79. package/dist/tools/file/index.d.ts +4 -0
  80. package/dist/tools/file/index.d.ts.map +1 -0
  81. package/dist/tools/file/index.js +4 -0
  82. package/dist/tools/file/index.js.map +1 -0
  83. package/dist/tools/hackmd/CreateNoteTool.d.ts +27 -0
  84. package/dist/tools/hackmd/CreateNoteTool.d.ts.map +1 -0
  85. package/dist/tools/hackmd/CreateNoteTool.js +85 -0
  86. package/dist/tools/hackmd/CreateNoteTool.js.map +1 -0
  87. package/dist/tools/hackmd/DeleteNoteTool.d.ts +19 -0
  88. package/dist/tools/hackmd/DeleteNoteTool.d.ts.map +1 -0
  89. package/dist/tools/hackmd/DeleteNoteTool.js +54 -0
  90. package/dist/tools/hackmd/DeleteNoteTool.js.map +1 -0
  91. package/dist/tools/hackmd/ExportNoteTool.d.ts +18 -0
  92. package/dist/tools/hackmd/ExportNoteTool.d.ts.map +1 -0
  93. package/dist/tools/hackmd/ExportNoteTool.js +75 -0
  94. package/dist/tools/hackmd/ExportNoteTool.js.map +1 -0
  95. package/dist/tools/hackmd/GetHistoryTool.d.ts +16 -0
  96. package/dist/tools/hackmd/GetHistoryTool.d.ts.map +1 -0
  97. package/dist/tools/hackmd/GetHistoryTool.js +51 -0
  98. package/dist/tools/hackmd/GetHistoryTool.js.map +1 -0
  99. package/dist/tools/hackmd/GetUserInfoTool.d.ts +13 -0
  100. package/dist/tools/hackmd/GetUserInfoTool.d.ts.map +1 -0
  101. package/dist/tools/hackmd/GetUserInfoTool.js +30 -0
  102. package/dist/tools/hackmd/GetUserInfoTool.js.map +1 -0
  103. package/dist/tools/hackmd/ListNotesTool.d.ts +17 -0
  104. package/dist/tools/hackmd/ListNotesTool.d.ts.map +1 -0
  105. package/dist/tools/hackmd/ListNotesTool.js +48 -0
  106. package/dist/tools/hackmd/ListNotesTool.js.map +1 -0
  107. package/dist/tools/hackmd/ListTeamsTool.d.ts +13 -0
  108. package/dist/tools/hackmd/ListTeamsTool.d.ts.map +1 -0
  109. package/dist/tools/hackmd/ListTeamsTool.js +34 -0
  110. package/dist/tools/hackmd/ListTeamsTool.js.map +1 -0
  111. package/dist/tools/hackmd/ReadNoteTool.d.ts +16 -0
  112. package/dist/tools/hackmd/ReadNoteTool.d.ts.map +1 -0
  113. package/dist/tools/hackmd/ReadNoteTool.js +36 -0
  114. package/dist/tools/hackmd/ReadNoteTool.js.map +1 -0
  115. package/dist/tools/hackmd/SearchNotesTool.d.ts +17 -0
  116. package/dist/tools/hackmd/SearchNotesTool.d.ts.map +1 -0
  117. package/dist/tools/hackmd/SearchNotesTool.js +49 -0
  118. package/dist/tools/hackmd/SearchNotesTool.js.map +1 -0
  119. package/dist/tools/hackmd/UpdateNoteTool.d.ts +20 -0
  120. package/dist/tools/hackmd/UpdateNoteTool.d.ts.map +1 -0
  121. package/dist/tools/hackmd/UpdateNoteTool.js +62 -0
  122. package/dist/tools/hackmd/UpdateNoteTool.js.map +1 -0
  123. package/dist/tools/hackmd/errorHandler.d.ts +6 -0
  124. package/dist/tools/hackmd/errorHandler.d.ts.map +1 -0
  125. package/dist/tools/hackmd/errorHandler.js +59 -0
  126. package/dist/tools/hackmd/errorHandler.js.map +1 -0
  127. package/dist/tools/hackmd/index.d.ts +11 -0
  128. package/dist/tools/hackmd/index.d.ts.map +1 -0
  129. package/dist/tools/hackmd/index.js +24 -0
  130. package/dist/tools/hackmd/index.js.map +1 -0
  131. package/dist/ui/shell/CommandRegistry.d.ts +20 -0
  132. package/dist/ui/shell/CommandRegistry.d.ts.map +1 -0
  133. package/dist/ui/shell/CommandRegistry.js +77 -0
  134. package/dist/ui/shell/CommandRegistry.js.map +1 -0
  135. package/dist/ui/shell/InteractiveShell.d.ts +15 -0
  136. package/dist/ui/shell/InteractiveShell.d.ts.map +1 -0
  137. package/dist/ui/shell/InteractiveShell.js +94 -0
  138. package/dist/ui/shell/InteractiveShell.js.map +1 -0
  139. package/dist/ui/shell/OutputRenderer.d.ts +8 -0
  140. package/dist/ui/shell/OutputRenderer.d.ts.map +1 -0
  141. package/dist/ui/shell/OutputRenderer.js +85 -0
  142. package/dist/ui/shell/OutputRenderer.js.map +1 -0
  143. package/dist/utils/ErrorTypes.d.ts +58 -0
  144. package/dist/utils/ErrorTypes.d.ts.map +1 -0
  145. package/dist/utils/ErrorTypes.js +156 -0
  146. package/dist/utils/ErrorTypes.js.map +1 -0
  147. package/dist/utils/Logger.d.ts +13 -0
  148. package/dist/utils/Logger.d.ts.map +1 -0
  149. package/dist/utils/Logger.js +72 -0
  150. package/dist/utils/Logger.js.map +1 -0
  151. package/package.json +66 -0
@@ -0,0 +1,94 @@
1
+ import * as readline from 'readline';
2
+ import chalk from 'chalk';
3
+ import { OutputRenderer } from './OutputRenderer';
4
+ import { CommandRegistry } from './CommandRegistry';
5
+ import { MessageBus } from '../../messaging/MessageBus';
6
+ import { Logger } from '../../utils/Logger';
7
+ export class InteractiveShell {
8
+ executor;
9
+ renderer;
10
+ commandRegistry;
11
+ rl;
12
+ isClosed = false;
13
+ constructor(executor) {
14
+ this.executor = executor;
15
+ this.renderer = new OutputRenderer();
16
+ this.commandRegistry = new CommandRegistry(executor);
17
+ this.rl = readline.createInterface({
18
+ input: process.stdin,
19
+ output: process.stdout,
20
+ prompt: this.getPrompt(),
21
+ });
22
+ }
23
+ async start(initialCommand) {
24
+ this.printWelcome();
25
+ this.setupMessageHandling();
26
+ // If there's an initial command, execute it first
27
+ if (initialCommand) {
28
+ await this.handleInput(initialCommand);
29
+ }
30
+ // Always enter interactive mode (unless explicitly exited)
31
+ return new Promise((resolve) => {
32
+ this.rl.on('line', (input) => {
33
+ void this.handleInput(input.trim())
34
+ .then(() => {
35
+ // Input handled successfully
36
+ })
37
+ .catch((error) => {
38
+ Logger.error('Shell', 'handleInput error', error);
39
+ })
40
+ .finally(() => {
41
+ if (this.isClosed) {
42
+ return;
43
+ }
44
+ this.rl.setPrompt(this.getPrompt());
45
+ this.rl.prompt();
46
+ });
47
+ });
48
+ this.rl.on('close', () => {
49
+ this.isClosed = true;
50
+ console.log(chalk.gray('\nGoodbye! 👋'));
51
+ resolve();
52
+ });
53
+ this.rl.prompt();
54
+ });
55
+ }
56
+ async handleInput(input) {
57
+ if (!input)
58
+ return;
59
+ if (input === 'exit' || input === 'quit') {
60
+ this.isClosed = true;
61
+ this.rl.close();
62
+ return;
63
+ }
64
+ // Handle commands
65
+ if (input.startsWith('/')) {
66
+ await this.commandRegistry.execute(input.slice(1));
67
+ return;
68
+ }
69
+ // Execute agent
70
+ try {
71
+ await this.executor.execute(input);
72
+ }
73
+ catch (error) {
74
+ console.log(chalk.red('Error: '), error instanceof Error ? error.message : String(error));
75
+ }
76
+ }
77
+ setupMessageHandling() {
78
+ const bus = MessageBus.getInstance();
79
+ this.renderer.attachToBus(bus);
80
+ }
81
+ getPrompt() {
82
+ const status = this.executor.status;
83
+ const contextPercent = (status.contextUsage * 100).toFixed(0);
84
+ return chalk.bold(`${process.env.USER ?? 'user'}` +
85
+ chalk.gray(` [${contextPercent}%]`) +
86
+ ' > ');
87
+ }
88
+ printWelcome() {
89
+ console.log(chalk.bold.cyan('\n📝 HackWriter\n'));
90
+ console.log(chalk.gray('Writing agent for HackMD'));
91
+ console.log(chalk.gray('Type /help for available commands\n'));
92
+ }
93
+ }
94
+ //# sourceMappingURL=InteractiveShell.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InteractiveShell.js","sourceRoot":"","sources":["../../../src/ui/shell/InteractiveShell.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { MessageBus } from '../../messaging/MessageBus';
2
+ export declare class OutputRenderer {
3
+ private activeSpinner;
4
+ private toolCalls;
5
+ attachToBus(bus: MessageBus): void;
6
+ private render;
7
+ }
8
+ //# sourceMappingURL=OutputRenderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OutputRenderer.d.ts","sourceRoot":"","sources":["../../../src/ui/shell/OutputRenderer.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAQxD,qBAAa,cAAc;IACzB,OAAO,CAAC,aAAa,CAAoB;IACzC,OAAO,CAAC,SAAS,CAAoC;IAErD,WAAW,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI;IAIlC,OAAO,CAAC,MAAM;CAsFf"}
@@ -0,0 +1,85 @@
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ export class OutputRenderer {
4
+ activeSpinner = null;
5
+ toolCalls = new Map();
6
+ attachToBus(bus) {
7
+ bus.subscribe((message) => this.render(message));
8
+ }
9
+ render(message) {
10
+ switch (message.type) {
11
+ case 'step_started':
12
+ // Optional: show step number
13
+ break;
14
+ case 'text_chunk':
15
+ if (this.activeSpinner) {
16
+ this.activeSpinner.stop();
17
+ this.activeSpinner = null;
18
+ }
19
+ process.stdout.write(chalk.blue(message.text));
20
+ break;
21
+ case 'tool_call_started':
22
+ this.toolCalls.set(message.toolCall.id, {
23
+ name: message.toolCall.name,
24
+ args: '',
25
+ });
26
+ this.activeSpinner = ora({
27
+ text: chalk.yellow(`Using ${message.toolCall.name}...`),
28
+ color: 'yellow',
29
+ discardStdin: false,
30
+ }).start();
31
+ break;
32
+ case 'tool_arguments_chunk': {
33
+ const state = this.toolCalls.get(message.toolCallId);
34
+ if (state) {
35
+ state.args += message.chunk;
36
+ }
37
+ break;
38
+ }
39
+ case 'tool_completed':
40
+ if (this.activeSpinner) {
41
+ const brief = message.result.brief ?? 'Completed';
42
+ // Check if tool execution was successful
43
+ if (message.result.ok) {
44
+ this.activeSpinner.succeed(chalk.green(`✓ ${brief}`));
45
+ }
46
+ else {
47
+ this.activeSpinner.fail(chalk.red(`✗ ${brief}`));
48
+ }
49
+ this.activeSpinner = null;
50
+ }
51
+ if (message.result.output) {
52
+ console.log(message.result.output);
53
+ }
54
+ this.toolCalls.delete(message.toolCallId);
55
+ break;
56
+ case 'tool_failed':
57
+ if (this.activeSpinner) {
58
+ this.activeSpinner.fail(chalk.red(`✗ ${message.error}`));
59
+ this.activeSpinner = null;
60
+ }
61
+ this.toolCalls.delete(message.toolCallId);
62
+ break;
63
+ case 'compression_started':
64
+ this.activeSpinner = ora({
65
+ text: 'Compressing context...',
66
+ discardStdin: false,
67
+ }).start();
68
+ break;
69
+ case 'compression_completed':
70
+ if (this.activeSpinner) {
71
+ this.activeSpinner.succeed(chalk.green('✓ Context compressed'));
72
+ this.activeSpinner = null;
73
+ }
74
+ break;
75
+ case 'step_completed':
76
+ if (this.activeSpinner) {
77
+ this.activeSpinner.stop();
78
+ this.activeSpinner = null;
79
+ }
80
+ console.log(); // Add newline
81
+ break;
82
+ }
83
+ }
84
+ }
85
+ //# sourceMappingURL=OutputRenderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OutputRenderer.js","sourceRoot":"","sources":["../../../src/ui/shell/OutputRenderer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Structured error types for better error handling and user feedback
3
+ */
4
+ export declare enum ErrorCategory {
5
+ CONFIGURATION = "configuration",
6
+ AUTH = "auth",
7
+ NETWORK = "network",
8
+ VALIDATION = "validation",
9
+ NOT_FOUND = "not_found",
10
+ PERMISSION = "permission",
11
+ RATE_LIMIT = "rate_limit",
12
+ INTERNAL = "internal"
13
+ }
14
+ export interface ErrorDetails {
15
+ category: ErrorCategory;
16
+ message: string;
17
+ userMessage: string;
18
+ code?: string;
19
+ context?: Record<string, unknown>;
20
+ suggestion?: string;
21
+ }
22
+ /**
23
+ * Base application error class with rich context
24
+ */
25
+ export declare class AppError extends Error {
26
+ readonly category: ErrorCategory;
27
+ readonly userMessage: string;
28
+ readonly code?: string;
29
+ readonly context?: Record<string, unknown>;
30
+ readonly suggestion?: string;
31
+ constructor(details: ErrorDetails);
32
+ /**
33
+ * Format error for user display
34
+ */
35
+ toUserString(): string;
36
+ /**
37
+ * Format error for logging
38
+ */
39
+ toLogString(): string;
40
+ }
41
+ /**
42
+ * Helper functions to create common error types
43
+ */
44
+ export declare class ErrorFactory {
45
+ static configuration(message: string, suggestion?: string): AppError;
46
+ static auth(message: string, service?: string): AppError;
47
+ static network(message: string, endpoint?: string): AppError;
48
+ static validation(field: string, reason: string): AppError;
49
+ static notFound(resource: string, identifier?: string): AppError;
50
+ static permission(action: string, resource?: string): AppError;
51
+ static rateLimit(retryAfter?: number): AppError;
52
+ static internal(message: string, originalError?: Error): AppError;
53
+ /**
54
+ * Convert unknown error to AppError
55
+ */
56
+ static fromUnknown(error: unknown, context?: string): AppError;
57
+ }
58
+ //# sourceMappingURL=ErrorTypes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ErrorTypes.d.ts","sourceRoot":"","sources":["../../src/utils/ErrorTypes.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,oBAAY,aAAa;IAEvB,aAAa,kBAAkB;IAG/B,IAAI,SAAS;IAGb,OAAO,YAAY;IAGnB,UAAU,eAAe;IAGzB,SAAS,cAAc;IAGvB,UAAU,eAAe;IAGzB,UAAU,eAAe;IAGzB,QAAQ,aAAa;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,aAAa,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,qBAAa,QAAS,SAAQ,KAAK;IACjC,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;gBAEjB,OAAO,EAAE,YAAY;IAajC;;OAEG;IACH,YAAY,IAAI,MAAM;IAUtB;;OAEG;IACH,WAAW,IAAI,MAAM;CAGtB;AAED;;GAEG;AACH,qBAAa,YAAY;IACvB,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,QAAQ;IASpE,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,QAAQ;IAYxD,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,QAAQ;IAW5D,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,QAAQ;IAU1D,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,QAAQ;IAWhE,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,QAAQ;IAU9D,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,QAAQ;IAa/C,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,KAAK,GAAG,QAAQ;IAWjE;;OAEG;IACH,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,QAAQ;CAgB/D"}
@@ -0,0 +1,156 @@
1
+ /**
2
+ * Structured error types for better error handling and user feedback
3
+ */
4
+ export var ErrorCategory;
5
+ (function (ErrorCategory) {
6
+ // Configuration errors
7
+ ErrorCategory["CONFIGURATION"] = "configuration";
8
+ // Authentication/authorization errors
9
+ ErrorCategory["AUTH"] = "auth";
10
+ // Network/API errors
11
+ ErrorCategory["NETWORK"] = "network";
12
+ // Validation errors (user input)
13
+ ErrorCategory["VALIDATION"] = "validation";
14
+ // Resource not found
15
+ ErrorCategory["NOT_FOUND"] = "not_found";
16
+ // Permission/access denied
17
+ ErrorCategory["PERMISSION"] = "permission";
18
+ // Rate limiting
19
+ ErrorCategory["RATE_LIMIT"] = "rate_limit";
20
+ // Internal/unknown errors
21
+ ErrorCategory["INTERNAL"] = "internal";
22
+ })(ErrorCategory || (ErrorCategory = {}));
23
+ /**
24
+ * Base application error class with rich context
25
+ */
26
+ export class AppError extends Error {
27
+ category;
28
+ userMessage;
29
+ code;
30
+ context;
31
+ suggestion;
32
+ constructor(details) {
33
+ super(details.message);
34
+ this.name = 'AppError';
35
+ this.category = details.category;
36
+ this.userMessage = details.userMessage;
37
+ this.code = details.code;
38
+ this.context = details.context;
39
+ this.suggestion = details.suggestion;
40
+ // Maintains proper stack trace for where error was thrown
41
+ Error.captureStackTrace(this, this.constructor);
42
+ }
43
+ /**
44
+ * Format error for user display
45
+ */
46
+ toUserString() {
47
+ let output = `❌ ${this.userMessage}`;
48
+ if (this.suggestion) {
49
+ output += `\n\n💡 ${this.suggestion}`;
50
+ }
51
+ return output;
52
+ }
53
+ /**
54
+ * Format error for logging
55
+ */
56
+ toLogString() {
57
+ return `[${this.category}${this.code ? `:${this.code}` : ''}] ${this.message}`;
58
+ }
59
+ }
60
+ /**
61
+ * Helper functions to create common error types
62
+ */
63
+ export class ErrorFactory {
64
+ static configuration(message, suggestion) {
65
+ return new AppError({
66
+ category: ErrorCategory.CONFIGURATION,
67
+ message,
68
+ userMessage: `Configuration error: ${message}`,
69
+ suggestion: suggestion ?? 'Please run `hackwriter setup` to configure',
70
+ });
71
+ }
72
+ static auth(message, service) {
73
+ return new AppError({
74
+ category: ErrorCategory.AUTH,
75
+ message,
76
+ userMessage: `Authentication failed${service ? ` for ${service}` : ''}`,
77
+ code: 'AUTH_FAILED',
78
+ suggestion: service
79
+ ? `Please check your ${service} API token in the configuration`
80
+ : 'Please check your API credentials',
81
+ });
82
+ }
83
+ static network(message, endpoint) {
84
+ return new AppError({
85
+ category: ErrorCategory.NETWORK,
86
+ message,
87
+ userMessage: 'Network request failed',
88
+ code: 'NETWORK_ERROR',
89
+ context: endpoint ? { endpoint } : undefined,
90
+ suggestion: 'Please check your internet connection and try again',
91
+ });
92
+ }
93
+ static validation(field, reason) {
94
+ return new AppError({
95
+ category: ErrorCategory.VALIDATION,
96
+ message: `Validation failed for ${field}: ${reason}`,
97
+ userMessage: `Invalid ${field}: ${reason}`,
98
+ code: 'VALIDATION_ERROR',
99
+ context: { field, reason },
100
+ });
101
+ }
102
+ static notFound(resource, identifier) {
103
+ return new AppError({
104
+ category: ErrorCategory.NOT_FOUND,
105
+ message: `${resource} not found${identifier ? `: ${identifier}` : ''}`,
106
+ userMessage: `${resource} not found${identifier ? ` (${identifier})` : ''}`,
107
+ code: 'NOT_FOUND',
108
+ context: identifier ? { resource, identifier } : { resource },
109
+ suggestion: `Please verify the ${resource.toLowerCase()} exists`,
110
+ });
111
+ }
112
+ static permission(action, resource) {
113
+ return new AppError({
114
+ category: ErrorCategory.PERMISSION,
115
+ message: `Permission denied: ${action}${resource ? ` on ${resource}` : ''}`,
116
+ userMessage: `You don't have permission to ${action}${resource ? ` ${resource}` : ''}`,
117
+ code: 'PERMISSION_DENIED',
118
+ suggestion: 'Please check your access permissions',
119
+ });
120
+ }
121
+ static rateLimit(retryAfter) {
122
+ return new AppError({
123
+ category: ErrorCategory.RATE_LIMIT,
124
+ message: 'Rate limit exceeded',
125
+ userMessage: 'Too many requests',
126
+ code: 'RATE_LIMIT',
127
+ context: retryAfter ? { retryAfter } : undefined,
128
+ suggestion: retryAfter
129
+ ? `Please wait ${retryAfter} seconds before trying again`
130
+ : 'Please wait a moment before trying again',
131
+ });
132
+ }
133
+ static internal(message, originalError) {
134
+ return new AppError({
135
+ category: ErrorCategory.INTERNAL,
136
+ message: originalError ? `${message}: ${originalError.message}` : message,
137
+ userMessage: 'An unexpected error occurred',
138
+ code: 'INTERNAL_ERROR',
139
+ context: originalError ? { originalError: originalError.message } : undefined,
140
+ suggestion: 'Please try again or contact support if the issue persists',
141
+ });
142
+ }
143
+ /**
144
+ * Convert unknown error to AppError
145
+ */
146
+ static fromUnknown(error, context) {
147
+ if (error instanceof AppError) {
148
+ return error;
149
+ }
150
+ if (error instanceof Error) {
151
+ return ErrorFactory.internal(context ? `${context}: ${error.message}` : error.message, error);
152
+ }
153
+ return ErrorFactory.internal(context ? `${context}: ${String(error)}` : String(error));
154
+ }
155
+ }
156
+ //# sourceMappingURL=ErrorTypes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ErrorTypes.js","sourceRoot":"","sources":["../../src/utils/ErrorTypes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ type LogLevel = 'silent' | 'info' | 'debug';
2
+ export declare class Logger {
3
+ private static level;
4
+ static setLevel(level: LogLevel): void;
5
+ static getLevel(): LogLevel;
6
+ static debug(category: string, message: string, data?: unknown): void;
7
+ static info(category: string, message: string, data?: unknown): void;
8
+ static warn(category: string, message: string, data?: unknown): void;
9
+ static error(category: string, message: string, error?: unknown): void;
10
+ private static log;
11
+ }
12
+ export {};
13
+ //# sourceMappingURL=Logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Logger.d.ts","sourceRoot":"","sources":["../../src/utils/Logger.ts"],"names":[],"mappings":"AAEA,KAAK,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;AAE5C,qBAAa,MAAM;IACjB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAsB;IAE1C,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;IAItC,MAAM,CAAC,QAAQ,IAAI,QAAQ;IAI3B,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI;IAWrE,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI;IAWpE,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI;IAWpE,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,IAAI;IAqBtE,OAAO,CAAC,MAAM,CAAC,GAAG;CAuBnB"}
@@ -0,0 +1,72 @@
1
+ import chalk from 'chalk';
2
+ export class Logger {
3
+ static level = 'silent';
4
+ static setLevel(level) {
5
+ Logger.level = level;
6
+ }
7
+ static getLevel() {
8
+ return Logger.level;
9
+ }
10
+ static debug(category, message, data) {
11
+ if (Logger.level !== 'debug') {
12
+ return;
13
+ }
14
+ Logger.log(category, message, data, {
15
+ category: chalk.cyan,
16
+ message: chalk.white,
17
+ });
18
+ }
19
+ static info(category, message, data) {
20
+ if (Logger.level === 'silent') {
21
+ return;
22
+ }
23
+ Logger.log(category, message, data, {
24
+ category: chalk.blue,
25
+ message: chalk.white,
26
+ });
27
+ }
28
+ static warn(category, message, data) {
29
+ if (Logger.level === 'silent') {
30
+ return;
31
+ }
32
+ Logger.log(category, message, data, {
33
+ category: chalk.yellow,
34
+ message: chalk.yellow,
35
+ });
36
+ }
37
+ static error(category, message, error) {
38
+ if (Logger.level === 'silent') {
39
+ return;
40
+ }
41
+ Logger.log(category, message, undefined, {
42
+ category: chalk.red,
43
+ message: chalk.red,
44
+ });
45
+ if (error !== undefined) {
46
+ if (error instanceof Error) {
47
+ console.log(chalk.red(error.stack ?? error.message));
48
+ }
49
+ else if (typeof error === 'object' && error !== null) {
50
+ console.log(chalk.red(JSON.stringify(error, null, 2)));
51
+ }
52
+ else if (typeof error === 'string' || typeof error === 'number' || typeof error === 'boolean') {
53
+ console.log(chalk.red(String(error)));
54
+ }
55
+ }
56
+ }
57
+ static log(category, message, data, colors) {
58
+ const timestamp = new Date().toISOString().split('T')[1].slice(0, -1);
59
+ const categoryFormatted = colors.category(`[${category}]`);
60
+ const timestampFormatted = chalk.gray(timestamp);
61
+ console.log(`${timestampFormatted} ${categoryFormatted} ${colors.message(message)}`);
62
+ if (data !== undefined) {
63
+ if (typeof data === 'object' && data !== null) {
64
+ console.log(chalk.gray(JSON.stringify(data, null, 2)));
65
+ }
66
+ else if (typeof data === 'string' || typeof data === 'number' || typeof data === 'boolean') {
67
+ console.log(chalk.gray(String(data)));
68
+ }
69
+ }
70
+ }
71
+ }
72
+ //# sourceMappingURL=Logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Logger.js","sourceRoot":"","sources":["../../src/utils/Logger.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "hackwriter",
3
+ "version": "0.0.2",
4
+ "description": "Writing agent for HackMD",
5
+ "type": "module",
6
+ "main": "dist/cli.js",
7
+ "bin": {
8
+ "hackwriter": "./dist/cli.js"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "README.md",
13
+ "LICENSE"
14
+ ],
15
+ "keywords": [
16
+ "hackmd",
17
+ "ai",
18
+ "agent",
19
+ "cli",
20
+ "markdown",
21
+ "writing",
22
+ "llm"
23
+ ],
24
+ "author": "Michael Wang <hi@eastsun.me>",
25
+ "license": "MIT",
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "https://github.com/EastSun566/hackwriter"
29
+ },
30
+ "dependencies": {
31
+ "@ai-sdk/anthropic": "^2.0.47",
32
+ "@ai-sdk/openai": "^2.0.72",
33
+ "@hackmd/api": "^2.5.0",
34
+ "@inquirer/prompts": "^8.0.1",
35
+ "ai": "^5.0.101",
36
+ "chalk": "^5.6.2",
37
+ "commander": "^14.0.2",
38
+ "ora": "^9.0.0",
39
+ "uuid": "^13.0.0",
40
+ "zod": "^4.1.13"
41
+ },
42
+ "devDependencies": {
43
+ "@eslint/js": "^9.39.1",
44
+ "@types/json-schema": "^7.0.15",
45
+ "@types/node": "^24.10.1",
46
+ "@vitest/coverage-v8": "^4.0.13",
47
+ "@vitest/ui": "^4.0.13",
48
+ "eslint": "^9.39.1",
49
+ "tsx": "^4.20.6",
50
+ "typescript": "^5.9.3",
51
+ "typescript-eslint": "^8.47.0",
52
+ "vitest": "^4.0.13"
53
+ },
54
+ "engines": {
55
+ "node": ">=18.0.0"
56
+ },
57
+ "scripts": {
58
+ "build": "rm -rf dist && tsc",
59
+ "dev": "tsx src/cli.ts",
60
+ "start": "node dist/cli.js",
61
+ "typecheck": "tsc --noEmit",
62
+ "test": "vitest run",
63
+ "lint": "eslint . --fix",
64
+ "release": "pnpx standard-version && git push --follow-tags && pnpm publish"
65
+ }
66
+ }