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 @@
1
+ {"version":3,"file":"ConfigSchema.d.ts","sourceRoot":"","sources":["../../src/config/ConfigSchema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;GAEG;AAEH,eAAO,MAAM,kBAAkB;;;iBAG7B,CAAC;AAEH,eAAO,MAAM,iBAAiB;;;;;;;;;iBAM5B,CAAC;AAEH,eAAO,MAAM,cAAc;;;;iBAIzB,CAAC;AAEH,eAAO,MAAM,iBAAiB;;;iBAG5B,CAAC;AAEH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAQ9B,CAAC;AAGH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AACzE,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AACvE,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AACrE,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAE/D;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,OAAO,GAAG,sBAAsB,CAE3E;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,OAAO,GAAG;IACxD,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,sBAAsB,CAAC;IAC9B,MAAM,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC9C,CAaA"}
@@ -0,0 +1,54 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Zod schemas for runtime configuration validation
4
+ */
5
+ export const HackMDConfigSchema = z.object({
6
+ baseUrl: z.string().url(),
7
+ apiToken: z.string().min(1, 'API token is required'),
8
+ });
9
+ export const LLMProviderSchema = z.object({
10
+ type: z.enum(['anthropic', 'openai']),
11
+ apiKey: z.string().min(1, 'API key is required'),
12
+ baseUrl: z.string().url().optional(),
13
+ organizationId: z.string().optional(),
14
+ projectId: z.string().optional(),
15
+ });
16
+ export const LLMModelSchema = z.object({
17
+ provider: z.string().min(1, 'Provider name is required'),
18
+ model: z.string().min(1, 'Model name is required'),
19
+ maxContextSize: z.number().int().positive('Max context size must be positive'),
20
+ });
21
+ export const LoopControlSchema = z.object({
22
+ maxStepsPerRun: z.number().int().positive().default(100),
23
+ maxRetriesPerStep: z.number().int().nonnegative().default(3),
24
+ });
25
+ export const ConfigurationSchema = z.object({
26
+ defaultModel: z.string(),
27
+ models: z.record(z.string(), LLMModelSchema),
28
+ providers: z.record(z.string(), LLMProviderSchema),
29
+ services: z.object({
30
+ hackmd: HackMDConfigSchema.optional(),
31
+ }),
32
+ loopControl: LoopControlSchema,
33
+ });
34
+ /**
35
+ * Validate configuration object
36
+ */
37
+ export function validateConfiguration(data) {
38
+ return ConfigurationSchema.parse(data);
39
+ }
40
+ /**
41
+ * Safely validate configuration with detailed error messages
42
+ */
43
+ export function safeValidateConfiguration(data) {
44
+ const result = ConfigurationSchema.safeParse(data);
45
+ if (result.success) {
46
+ return { success: true, data: result.data };
47
+ }
48
+ const errors = result.error.issues.map(issue => ({
49
+ path: issue.path.join('.'),
50
+ message: issue.message,
51
+ }));
52
+ return { success: false, errors };
53
+ }
54
+ //# sourceMappingURL=ConfigSchema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfigSchema.js","sourceRoot":"","sources":["../../src/config/ConfigSchema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ export interface HackMDConfig {
2
+ baseUrl: string;
3
+ apiToken: string;
4
+ }
5
+ export type LLMProviderType = 'anthropic' | 'openai';
6
+ export interface LLMProvider {
7
+ type: LLMProviderType;
8
+ apiKey: string;
9
+ baseUrl?: string;
10
+ organizationId?: string;
11
+ projectId?: string;
12
+ }
13
+ export interface LLMModel {
14
+ provider: string;
15
+ model: string;
16
+ maxContextSize: number;
17
+ }
18
+ export interface Configuration {
19
+ defaultModel: string;
20
+ models: Record<string, LLMModel>;
21
+ providers: Record<string, LLMProvider>;
22
+ services: {
23
+ hackmd?: HackMDConfig;
24
+ };
25
+ loopControl: {
26
+ maxStepsPerRun: number;
27
+ maxRetriesPerStep: number;
28
+ };
29
+ }
30
+ //# sourceMappingURL=Configuration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Configuration.d.ts","sourceRoot":"","sources":["../../src/config/Configuration.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,MAAM,eAAe,GAAG,WAAW,GAAG,QAAQ,CAAC;AAErD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,eAAe,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACjC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACvC,QAAQ,EAAE;QACR,MAAM,CAAC,EAAE,YAAY,CAAC;KACvB,CAAC;IACF,WAAW,EAAE;QACX,cAAc,EAAE,MAAM,CAAC;QACvB,iBAAiB,EAAE,MAAM,CAAC;KAC3B,CAAC;CACH"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=Configuration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Configuration.js","sourceRoot":"","sources":["../../src/config/Configuration.ts"],"names":[],"mappings":""}
@@ -0,0 +1,8 @@
1
+ import type { Configuration } from './Configuration';
2
+ export declare class ConfigurationLoader {
3
+ private static configPath;
4
+ static load(): Promise<Configuration>;
5
+ static save(config: Configuration): Promise<void>;
6
+ private static getDefaultConfig;
7
+ }
8
+ //# sourceMappingURL=ConfigurationLoader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfigurationLoader.d.ts","sourceRoot":"","sources":["../../src/config/ConfigurationLoader.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAKrD,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,MAAM,CAAC,UAAU,CAIvB;WAEW,IAAI,IAAI,OAAO,CAAC,aAAa,CAAC;WA6C9B,IAAI,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAkCvD,OAAO,CAAC,MAAM,CAAC,gBAAgB;CAYhC"}
@@ -0,0 +1,75 @@
1
+ import { promises as fs } from 'fs';
2
+ import * as path from 'path';
3
+ import * as os from 'os';
4
+ import { safeValidateConfiguration } from './ConfigSchema';
5
+ import { ErrorFactory } from '../utils/ErrorTypes';
6
+ import { Logger } from '../utils/Logger';
7
+ export class ConfigurationLoader {
8
+ static configPath = path.join(os.homedir(), '.hackwriter', 'config.json');
9
+ static async load() {
10
+ try {
11
+ const content = await fs.readFile(this.configPath, 'utf-8');
12
+ const rawConfig = JSON.parse(content);
13
+ // Validate configuration
14
+ const validation = safeValidateConfiguration(rawConfig);
15
+ if (!validation.success) {
16
+ const errorMessages = validation.errors
17
+ .map((e) => ` - ${e.path}: ${e.message}`)
18
+ .join('\n');
19
+ throw ErrorFactory.configuration(`Invalid configuration:\n${errorMessages}`, 'Please check your config.json file or run `hackwriter setup` to reconfigure');
20
+ }
21
+ Logger.debug('ConfigLoader', 'Configuration loaded and validated successfully');
22
+ return validation.data;
23
+ }
24
+ catch (error) {
25
+ if (error.code === 'ENOENT') {
26
+ Logger.debug('ConfigLoader', 'No config file found, returning defaults');
27
+ return this.getDefaultConfig();
28
+ }
29
+ // Re-throw if it's already an AppError
30
+ if (error instanceof Error && error.name === 'AppError') {
31
+ throw error;
32
+ }
33
+ // Handle JSON parse errors
34
+ if (error instanceof SyntaxError) {
35
+ throw ErrorFactory.configuration(`Invalid JSON in config file: ${error.message}`, 'Please check your config.json file for syntax errors');
36
+ }
37
+ throw ErrorFactory.fromUnknown(error, 'Failed to load configuration');
38
+ }
39
+ }
40
+ static async save(config) {
41
+ try {
42
+ // Validate before saving
43
+ const validation = safeValidateConfiguration(config);
44
+ if (!validation.success) {
45
+ const errorMessages = validation.errors
46
+ .map(e => ` - ${e.path}: ${e.message}`)
47
+ .join('\n');
48
+ throw ErrorFactory.validation('configuration', `Invalid configuration data:\n${errorMessages}`);
49
+ }
50
+ const dir = path.dirname(this.configPath);
51
+ await fs.mkdir(dir, { recursive: true });
52
+ await fs.writeFile(this.configPath, JSON.stringify(config, null, 2), 'utf-8');
53
+ Logger.debug('ConfigLoader', 'Configuration saved successfully');
54
+ }
55
+ catch (error) {
56
+ if (error instanceof Error && error.name === 'AppError') {
57
+ throw error;
58
+ }
59
+ throw ErrorFactory.fromUnknown(error, 'Failed to save configuration');
60
+ }
61
+ }
62
+ static getDefaultConfig() {
63
+ return {
64
+ defaultModel: '',
65
+ models: {},
66
+ providers: {},
67
+ services: {},
68
+ loopControl: {
69
+ maxStepsPerRun: 100,
70
+ maxRetriesPerStep: 3,
71
+ },
72
+ };
73
+ }
74
+ }
75
+ //# sourceMappingURL=ConfigurationLoader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfigurationLoader.js","sourceRoot":"","sources":["../../src/config/ConfigurationLoader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { EventEmitter } from 'events';
2
+ import type { AgentMessage } from './MessageTypes';
3
+ export declare class MessageBus extends EventEmitter {
4
+ private static instance;
5
+ static getInstance(): MessageBus;
6
+ publish(message: AgentMessage): void;
7
+ subscribe(handler: (message: AgentMessage) => void): void;
8
+ unsubscribe(handler: (message: AgentMessage) => void): void;
9
+ clear(): void;
10
+ }
11
+ //# sourceMappingURL=MessageBus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MessageBus.d.ts","sourceRoot":"","sources":["../../src/messaging/MessageBus.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,qBAAa,UAAW,SAAQ,YAAY;IAC1C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAa;IAEpC,MAAM,CAAC,WAAW,IAAI,UAAU;IAOhC,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;IAIpC,SAAS,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,GAAG,IAAI;IAIzD,WAAW,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,GAAG,IAAI;IAI3D,KAAK,IAAI,IAAI;CAGd"}
@@ -0,0 +1,23 @@
1
+ import { EventEmitter } from 'events';
2
+ export class MessageBus extends EventEmitter {
3
+ static instance;
4
+ static getInstance() {
5
+ if (!MessageBus.instance) {
6
+ MessageBus.instance = new MessageBus();
7
+ }
8
+ return MessageBus.instance;
9
+ }
10
+ publish(message) {
11
+ this.emit('message', message);
12
+ }
13
+ subscribe(handler) {
14
+ this.on('message', handler);
15
+ }
16
+ unsubscribe(handler) {
17
+ this.off('message', handler);
18
+ }
19
+ clear() {
20
+ this.removeAllListeners();
21
+ }
22
+ }
23
+ //# sourceMappingURL=MessageBus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MessageBus.js","sourceRoot":"","sources":["../../src/messaging/MessageBus.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAGtC,MAAM,OAAO,UAAW,SAAQ,YAAY;IAClC,MAAM,CAAC,QAAQ,CAAa;IAEpC,MAAM,CAAC,WAAW;QAChB,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC;YACzB,UAAU,CAAC,QAAQ,GAAG,IAAI,UAAU,EAAE,CAAC;QACzC,CAAC;QACD,OAAO,UAAU,CAAC,QAAQ,CAAC;IAC7B,CAAC;IAED,OAAO,CAAC,OAAqB;QAC3B,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAChC,CAAC;IAED,SAAS,CAAC,OAAwC;QAChD,IAAI,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAC9B,CAAC;IAED,WAAW,CAAC,OAAwC;QAClD,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAC/B,CAAC;IAED,KAAK;QACH,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAC5B,CAAC;CACF"}
@@ -0,0 +1,39 @@
1
+ import type { ExecutorStatus } from '../agent/AgentExecutor';
2
+ import type { ToolResult } from '../tools/base/Tool';
3
+ export type AgentMessage = {
4
+ type: 'step_started';
5
+ stepNumber: number;
6
+ } | {
7
+ type: 'step_completed';
8
+ } | {
9
+ type: 'step_interrupted';
10
+ } | {
11
+ type: 'compression_started';
12
+ } | {
13
+ type: 'compression_completed';
14
+ } | {
15
+ type: 'text_chunk';
16
+ text: string;
17
+ } | {
18
+ type: 'tool_call_started';
19
+ toolCall: {
20
+ id: string;
21
+ name: string;
22
+ };
23
+ } | {
24
+ type: 'tool_arguments_chunk';
25
+ toolCallId: string;
26
+ chunk: string;
27
+ } | {
28
+ type: 'tool_completed';
29
+ toolCallId: string;
30
+ result: ToolResult;
31
+ } | {
32
+ type: 'tool_failed';
33
+ toolCallId: string;
34
+ error: string;
35
+ } | {
36
+ type: 'status_updated';
37
+ status: ExecutorStatus;
38
+ };
39
+ //# sourceMappingURL=MessageTypes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MessageTypes.d.ts","sourceRoot":"","sources":["../../src/messaging/MessageTypes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAC5C;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,GAC1B;IAAE,IAAI,EAAE,kBAAkB,CAAA;CAAE,GAC5B;IAAE,IAAI,EAAE,qBAAqB,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,uBAAuB,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACpC;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,QAAQ,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GACrE;IAAE,IAAI,EAAE,sBAAsB,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACnE;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,UAAU,CAAA;CAAE,GAClE;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC1D;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,MAAM,EAAE,cAAc,CAAA;CAAE,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=MessageTypes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MessageTypes.js","sourceRoot":"","sources":["../../src/messaging/MessageTypes.ts"],"names":[],"mappings":""}
@@ -0,0 +1,11 @@
1
+ export interface Session {
2
+ id: string;
3
+ workDir: string;
4
+ historyFile: string;
5
+ }
6
+ export declare class SessionManager {
7
+ private static sessionsDir;
8
+ static create(workDir: string): Promise<Session>;
9
+ static continue(workDir: string): Promise<Session | null>;
10
+ }
11
+ //# sourceMappingURL=SessionManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SessionManager.d.ts","sourceRoot":"","sources":["../../src/session/SessionManager.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAC,WAAW,CAIxB;WAEW,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;WAqBzC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;CAuChE"}
@@ -0,0 +1,56 @@
1
+ import { promises as fs } from 'fs';
2
+ import * as path from 'path';
3
+ import * as os from 'os';
4
+ import * as crypto from 'crypto';
5
+ import { Logger } from '../utils/Logger';
6
+ export class SessionManager {
7
+ static sessionsDir = path.join(os.homedir(), '.hackwriter', 'sessions');
8
+ static async create(workDir) {
9
+ const sessionId = crypto.randomUUID();
10
+ const workDirHash = crypto
11
+ .createHash('md5')
12
+ .update(workDir)
13
+ .digest('hex');
14
+ const sessionDir = path.join(this.sessionsDir, workDirHash);
15
+ await fs.mkdir(sessionDir, { recursive: true });
16
+ const historyFile = path.join(sessionDir, `${sessionId}.jsonl`);
17
+ Logger.debug('SessionManager', `New session: ${sessionId.slice(0, 8)}...`);
18
+ return {
19
+ id: sessionId,
20
+ workDir,
21
+ historyFile,
22
+ };
23
+ }
24
+ static async continue(workDir) {
25
+ const workDirHash = crypto
26
+ .createHash('md5')
27
+ .update(workDir)
28
+ .digest('hex');
29
+ const sessionDir = path.join(this.sessionsDir, workDirHash);
30
+ try {
31
+ const files = await fs.readdir(sessionDir);
32
+ const sessionFiles = files.filter((f) => f.endsWith('.jsonl'));
33
+ if (sessionFiles.length === 0) {
34
+ return null;
35
+ }
36
+ // Use most recent session
37
+ const stats = await Promise.all(sessionFiles.map(async (f) => ({
38
+ file: f,
39
+ mtime: (await fs.stat(path.join(sessionDir, f))).mtime,
40
+ })));
41
+ stats.sort((a, b) => b.mtime.getTime() - a.mtime.getTime());
42
+ const latestFile = stats[0].file;
43
+ const sessionId = latestFile.replace('.jsonl', '');
44
+ Logger.debug('SessionManager', `Continuing session: ${sessionId.slice(0, 8)}...`);
45
+ return {
46
+ id: sessionId,
47
+ workDir,
48
+ historyFile: path.join(sessionDir, latestFile),
49
+ };
50
+ }
51
+ catch {
52
+ return null;
53
+ }
54
+ }
55
+ }
56
+ //# sourceMappingURL=SessionManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SessionManager.js","sourceRoot":"","sources":["../../src/session/SessionManager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { JSONSchema7 } from 'json-schema';
2
+ export type ToolParams = Record<string, unknown>;
3
+ export interface ToolResult {
4
+ ok: boolean;
5
+ output: string;
6
+ message?: string;
7
+ brief?: string;
8
+ }
9
+ export type ToolSchema = JSONSchema7;
10
+ export declare abstract class Tool<P extends Record<string, unknown> = Record<string, unknown>> {
11
+ abstract readonly name: string;
12
+ abstract readonly description: string;
13
+ abstract readonly inputSchema: ToolSchema;
14
+ abstract call(params: P): Promise<ToolResult>;
15
+ protected ok(output: string, message?: string, brief?: string): ToolResult;
16
+ protected error(output: string, message: string, brief?: string): ToolResult;
17
+ protected formatError(error: unknown): string;
18
+ }
19
+ //# sourceMappingURL=Tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Tool.d.ts","sourceRoot":"","sources":["../../../src/tools/base/Tool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEjD,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,UAAU,GAAG,WAAW,CAAC;AAErC,8BAAsB,IAAI,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACpF,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,UAAU,CAAC;IAE1C,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC;IAE7C,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,UAAU;IAI1E,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,UAAU;IAI5E,SAAS,CAAC,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM;CAM9C"}
@@ -0,0 +1,15 @@
1
+ export class Tool {
2
+ ok(output, message, brief) {
3
+ return { ok: true, output, message, brief };
4
+ }
5
+ error(output, message, brief) {
6
+ return { ok: false, output, message, brief };
7
+ }
8
+ formatError(error) {
9
+ if (error instanceof Error) {
10
+ return error.message;
11
+ }
12
+ return String(error);
13
+ }
14
+ }
15
+ //# sourceMappingURL=Tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Tool.js","sourceRoot":"","sources":["../../../src/tools/base/Tool.ts"],"names":[],"mappings":"AAaA,MAAM,OAAgB,IAAI;IAOd,EAAE,CAAC,MAAc,EAAE,OAAgB,EAAE,KAAc;QAC3D,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC9C,CAAC;IAES,KAAK,CAAC,MAAc,EAAE,OAAe,EAAE,KAAc;QAC7D,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC/C,CAAC;IAES,WAAW,CAAC,KAAc;QAClC,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,OAAO,KAAK,CAAC,OAAO,CAAC;QACvB,CAAC;QACD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;CACF"}
@@ -0,0 +1,16 @@
1
+ import type { Tool } from './Tool';
2
+ export declare class ToolRegistry {
3
+ private tools;
4
+ register(tool: Tool): void;
5
+ get(name: string): Tool | undefined;
6
+ getAll(): Tool[];
7
+ getSchemas(): {
8
+ name: string;
9
+ description: string;
10
+ input_schema: unknown;
11
+ }[];
12
+ has(name: string): boolean;
13
+ remove(name: string): boolean;
14
+ clear(): void;
15
+ }
16
+ //# sourceMappingURL=ToolRegistry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToolRegistry.d.ts","sourceRoot":"","sources":["../../../src/tools/base/ToolRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAEnC,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAA2B;IAExC,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAI1B,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;IAInC,MAAM,IAAI,IAAI,EAAE;IAIhB,UAAU,IAAI;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,OAAO,CAAC;KACvB,EAAE;IAQH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI7B,KAAK,IAAI,IAAI;CAGd"}
@@ -0,0 +1,29 @@
1
+ export class ToolRegistry {
2
+ tools = new Map();
3
+ register(tool) {
4
+ this.tools.set(tool.name, tool);
5
+ }
6
+ get(name) {
7
+ return this.tools.get(name);
8
+ }
9
+ getAll() {
10
+ return Array.from(this.tools.values());
11
+ }
12
+ getSchemas() {
13
+ return this.getAll().map(tool => ({
14
+ name: tool.name,
15
+ description: tool.description,
16
+ input_schema: tool.inputSchema,
17
+ }));
18
+ }
19
+ has(name) {
20
+ return this.tools.has(name);
21
+ }
22
+ remove(name) {
23
+ return this.tools.delete(name);
24
+ }
25
+ clear() {
26
+ this.tools.clear();
27
+ }
28
+ }
29
+ //# sourceMappingURL=ToolRegistry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToolRegistry.js","sourceRoot":"","sources":["../../../src/tools/base/ToolRegistry.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,YAAY;IACf,KAAK,GAAG,IAAI,GAAG,EAAgB,CAAC;IAExC,QAAQ,CAAC,IAAU;QACjB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAClC,CAAC;IAED,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IAED,MAAM;QACJ,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IACzC,CAAC;IAED,UAAU;QAKR,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAChC,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,YAAY,EAAE,IAAI,CAAC,WAAW;SAC/B,CAAC,CAAC,CAAC;IACN,CAAC;IAED,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IAED,MAAM,CAAC,IAAY;QACjB,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAED,KAAK;QACH,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;CACF"}
@@ -0,0 +1,17 @@
1
+ import { Tool, type ToolResult, type ToolSchema } from '../base/Tool';
2
+ interface ListFilesParams {
3
+ directoryPath: string;
4
+ recursive?: boolean;
5
+ pattern?: string;
6
+ [key: string]: unknown;
7
+ }
8
+ export declare class ListFilesTool extends Tool<ListFilesParams> {
9
+ readonly name = "list_files";
10
+ readonly description = "List files in a local directory";
11
+ readonly inputSchema: ToolSchema;
12
+ call(params: ListFilesParams): Promise<ToolResult>;
13
+ private listFiles;
14
+ private matchPattern;
15
+ }
16
+ export {};
17
+ //# sourceMappingURL=ListFilesTool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ListFilesTool.d.ts","sourceRoot":"","sources":["../../../src/tools/file/ListFilesTool.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,KAAK,UAAU,EAAE,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAEtE,UAAU,eAAe;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,qBAAa,aAAc,SAAQ,IAAI,CAAC,eAAe,CAAC;IACtD,QAAQ,CAAC,IAAI,gBAAgB;IAC7B,QAAQ,CAAC,WAAW,qCAAqC;IACzD,QAAQ,CAAC,WAAW,EAAE,UAAU,CAiB9B;IAEI,IAAI,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC;YAyC1C,SAAS;IAmCvB,OAAO,CAAC,YAAY;CAMrB"}
@@ -0,0 +1,80 @@
1
+ import { promises as fs } from 'node:fs';
2
+ import { join, relative } from 'node:path';
3
+ import { Tool } from '../base/Tool';
4
+ export class ListFilesTool extends Tool {
5
+ name = 'list_files';
6
+ description = 'List files in a local directory';
7
+ inputSchema = {
8
+ type: 'object',
9
+ properties: {
10
+ directoryPath: {
11
+ type: 'string',
12
+ description: 'Path to the directory to list',
13
+ },
14
+ recursive: {
15
+ type: 'boolean',
16
+ description: 'List files recursively (default: false)',
17
+ },
18
+ pattern: {
19
+ type: 'string',
20
+ description: 'Filter files by pattern (e.g., "*.md", "*.txt")',
21
+ },
22
+ },
23
+ required: ['directoryPath'],
24
+ };
25
+ async call(params) {
26
+ try {
27
+ const files = await this.listFiles(params.directoryPath, params.recursive ?? false, params.pattern);
28
+ if (files.length === 0) {
29
+ return this.ok('No files found', 'No files found', 'Empty');
30
+ }
31
+ const output = files
32
+ .map((file, index) => {
33
+ const stats = file.stats;
34
+ const type = stats.isDirectory() ? '📁' : '📄';
35
+ return `${index + 1}. ${type} ${file.relativePath}\n` +
36
+ ` Size: ${stats.size} bytes\n` +
37
+ ` Modified: ${stats.mtime.toLocaleString()}`;
38
+ })
39
+ .join('\n\n');
40
+ return this.ok(output, `Found ${files.length} items in ${params.directoryPath}`, `${files.length} items`);
41
+ }
42
+ catch (error) {
43
+ const errorMsg = `Failed to list files: ${this.formatError(error)}`;
44
+ return this.error(errorMsg, errorMsg, 'List failed');
45
+ }
46
+ }
47
+ async listFiles(dir, recursive, pattern) {
48
+ const results = [];
49
+ const entries = await fs.readdir(dir, { withFileTypes: true });
50
+ for (const entry of entries) {
51
+ const fullPath = join(dir, entry.name);
52
+ const stats = await fs.stat(fullPath);
53
+ const relativePath = relative(dir, fullPath);
54
+ if (entry.isDirectory()) {
55
+ if (recursive) {
56
+ results.push({ relativePath, stats });
57
+ const subFiles = await this.listFiles(fullPath, true, pattern);
58
+ results.push(...subFiles.map(f => ({
59
+ relativePath: join(relativePath, f.relativePath),
60
+ stats: f.stats,
61
+ })));
62
+ }
63
+ else {
64
+ results.push({ relativePath, stats });
65
+ }
66
+ }
67
+ else {
68
+ if (!pattern || this.matchPattern(entry.name, pattern)) {
69
+ results.push({ relativePath, stats });
70
+ }
71
+ }
72
+ }
73
+ return results;
74
+ }
75
+ matchPattern(filename, pattern) {
76
+ const regex = new RegExp('^' + pattern.replace(/\*/g, '.*').replace(/\?/g, '.') + '$');
77
+ return regex.test(filename);
78
+ }
79
+ }
80
+ //# sourceMappingURL=ListFilesTool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ListFilesTool.js","sourceRoot":"","sources":["../../../src/tools/file/ListFilesTool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { Tool, type ToolResult, type ToolSchema } from '../base/Tool';
2
+ interface ReadFileParams {
3
+ filePath: string;
4
+ [key: string]: unknown;
5
+ }
6
+ export declare class ReadFileTool extends Tool<ReadFileParams> {
7
+ readonly name = "read_file";
8
+ readonly description = "Read the content of a local file";
9
+ readonly inputSchema: ToolSchema;
10
+ call(params: ReadFileParams): Promise<ToolResult>;
11
+ }
12
+ export {};
13
+ //# sourceMappingURL=ReadFileTool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ReadFileTool.d.ts","sourceRoot":"","sources":["../../../src/tools/file/ReadFileTool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,KAAK,UAAU,EAAE,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAGtE,UAAU,cAAc;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,qBAAa,YAAa,SAAQ,IAAI,CAAC,cAAc,CAAC;IACpD,QAAQ,CAAC,IAAI,eAAe;IAC5B,QAAQ,CAAC,WAAW,sCAAsC;IAC1D,QAAQ,CAAC,WAAW,EAAE,UAAU,CAS9B;IAEI,IAAI,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC;CAyBxD"}