@isolo/trinity 1.0.2 → 1.0.3

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@isolo/trinity",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "A Bun-based MCP server framework with dynamic tool loading, hot reload, and stdio/HTTP modes",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/Config.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import path from "node:path";
2
+ import fs from "node:fs";
2
3
 
3
4
  export class Config {
4
5
  private static instance: Config | null = null;
@@ -50,13 +51,18 @@ export class Config {
50
51
 
51
52
  if (!this._targetFolder) {
52
53
  throw new Error(
53
- "Missing required argument: --target <path>. Specify the folder containing tool files."
54
+ "Missing required argument: --target <path>. Specify the folder containing tool files.",
54
55
  );
55
56
  }
56
57
 
57
58
  // Resolve to absolute path
58
59
  this._targetFolder = path.resolve(this._targetFolder);
59
60
 
61
+ // Create target folder if it doesn't exist
62
+ if (!fs.existsSync(this._targetFolder)) {
63
+ fs.mkdirSync(this._targetFolder, { recursive: true });
64
+ }
65
+
60
66
  // Default log file relative to target folder
61
67
  if (!this._logFile) {
62
68
  this._logFile = path.join(this._targetFolder, "debug.log");
package/src/Tools.ts CHANGED
@@ -27,7 +27,7 @@ export class Tools {
27
27
 
28
28
  private constructor(
29
29
  private logger = new Logger(Tools),
30
- private config = Config.getInstance()
30
+ private config = Config.getInstance(),
31
31
  ) {}
32
32
 
33
33
  async loadTools(): Promise<ToolDefinition[]> {
@@ -40,8 +40,10 @@ export class Tools {
40
40
  try {
41
41
  const tool = await this.loadToolFromFile(filePath);
42
42
  tools.push(tool);
43
- } catch (err) {
44
- this.logger.error(`Failed to load tool from ${filePath}`, err as Error);
43
+ } catch (err: any) {
44
+ this.logger.error(`Failed to load tool from ${filePath}`, {
45
+ err: err.message,
46
+ });
45
47
  }
46
48
  }
47
49
 
@@ -51,7 +53,7 @@ export class Tools {
51
53
  async loadTool(name: string): Promise<ToolDefinition> {
52
54
  const files = await this.resolveToolFiles();
53
55
  const filePath = files.find(
54
- (f) => path.basename(f, path.extname(f)) === name
56
+ (f) => path.basename(f, path.extname(f)) === name,
55
57
  );
56
58
 
57
59
  if (!filePath) {
@@ -76,7 +78,7 @@ export class Tools {
76
78
  if (filename) {
77
79
  this.onFileChange(event, filename);
78
80
  }
79
- }
81
+ },
80
82
  );
81
83
 
82
84
  this.watcher.on("error", (err: Error) => {
@@ -110,19 +112,19 @@ export class Tools {
110
112
 
111
113
  if (!mod.description || typeof mod.description !== "string") {
112
114
  throw new Error(
113
- `Tool file ${filePath} must export a 'description' string`
115
+ `Tool file ${filePath} must export a 'description' string`,
114
116
  );
115
117
  }
116
118
 
117
119
  if (!mod.inputSchema || typeof mod.inputSchema !== "object") {
118
120
  throw new Error(
119
- `Tool file ${filePath} must export an 'inputSchema' object`
121
+ `Tool file ${filePath} must export an 'inputSchema' object`,
120
122
  );
121
123
  }
122
124
 
123
125
  if (!mod.default || typeof mod.default !== "function") {
124
126
  throw new Error(
125
- `Tool file ${filePath} must have a default export function (execute)`
127
+ `Tool file ${filePath} must have a default export function (execute)`,
126
128
  );
127
129
  }
128
130
 
@@ -134,9 +136,20 @@ export class Tools {
134
136
  };
135
137
  }
136
138
 
137
- private async dynamicImport(filePath: string): Promise<Record<string, unknown>> {
138
- // Cache-busting with timestamp to always get fresh module
139
- return import(`${filePath}?t=${Date.now()}`);
139
+ private async dynamicImport(
140
+ filePath: string,
141
+ ): Promise<Record<string, unknown>> {
142
+ try {
143
+ // Cache-busting with timestamp to always get fresh module
144
+ return import(`${filePath}?t=${Date.now()}`);
145
+ } catch (err) {
146
+ this.logger.error(`Failed to import tool module`, {
147
+ err: (err as Error).message,
148
+ filePath,
149
+ });
150
+
151
+ throw err;
152
+ }
140
153
  }
141
154
 
142
155
  private buildDescription(description: string, filePath: string): string {