@defai.digital/ability-domain 13.2.3 → 13.2.5

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.
@@ -1 +1 @@
1
- {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAExD,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAYrE;;GAEG;AACH,qBAAa,uBAAwB,YAAW,aAAa;IAC3D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgC;IACvD,OAAO,CAAC,KAAK,CAA8B;IAC3C,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,mBAAmB;IAOjC,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC;IAOrD,OAAO,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAuC7B,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAO3C,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAK7B;;OAEG;YACW,QAAQ;IAwCtB;;OAEG;IACH,OAAO,CAAC,aAAa;IAkDrB;;OAEG;IACH,OAAO,CAAC,SAAS;CAMlB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,mBAAmB,GAAG,aAAa,CAE9E"}
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAExD,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAYrE;;GAEG;AACH,qBAAa,uBAAwB,YAAW,aAAa;IAC3D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgC;IACvD,OAAO,CAAC,KAAK,CAA8B;IAC3C,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,mBAAmB;IAOjC,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC;IAOrD,OAAO,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAsD7B,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAO3C,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAK7B;;OAEG;YACW,QAAQ;IAwCtB;;OAEG;IACH,OAAO,CAAC,aAAa;IAoFrB;;OAEG;IACH,OAAO,CAAC,SAAS;CAMlB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,mBAAmB,GAAG,aAAa,CAE9E"}
package/dist/loader.js CHANGED
@@ -4,7 +4,7 @@
4
4
  * Loads abilities from markdown files.
5
5
  * Format: Each .md file is an ability with YAML frontmatter for metadata.
6
6
  */
7
- import * as fs from 'node:fs';
7
+ import * as fsPromises from 'node:fs/promises';
8
8
  import * as path from 'node:path';
9
9
  import { validateAbility } from '@defai.digital/contracts';
10
10
  // ============================================================================
@@ -36,19 +36,34 @@ export class FileSystemAbilityLoader {
36
36
  async loadAll() {
37
37
  this.cache.clear();
38
38
  const dirPath = this.config.abilitiesDir;
39
- if (!fs.existsSync(dirPath)) {
40
- this.loaded = true;
41
- return [];
42
- }
43
- const files = fs.readdirSync(dirPath);
44
39
  const abilities = [];
45
- for (const file of files) {
46
- const ext = path.extname(file).toLowerCase();
47
- if (!this.config.extensions.includes(ext)) {
48
- continue;
40
+ // Read directory with file types to filter out directories
41
+ // Handle missing/inaccessible directory gracefully
42
+ let entries;
43
+ try {
44
+ entries = await fsPromises.readdir(dirPath, { withFileTypes: true });
45
+ }
46
+ catch (err) {
47
+ const code = err.code;
48
+ if (code === 'ENOENT' || code === 'EACCES' || code === 'ENOTDIR') {
49
+ this.loaded = true;
50
+ return [];
49
51
  }
52
+ throw err;
53
+ }
54
+ // Filter to only files with matching extensions
55
+ const files = entries
56
+ .filter((entry) => entry.isFile())
57
+ .map((entry) => entry.name)
58
+ .filter((name) => this.config.extensions.includes(path.extname(name).toLowerCase()));
59
+ // Load all files in parallel for better performance
60
+ const loadResults = await Promise.all(files.map(async (file) => {
50
61
  const filePath = path.join(dirPath, file);
51
62
  const ability = await this.loadFile(filePath, file);
63
+ return { file, ability };
64
+ }));
65
+ // Process results sequentially to handle duplicates consistently
66
+ for (const { file, ability } of loadResults) {
52
67
  if (ability) {
53
68
  if (this.cache.has(ability.abilityId)) {
54
69
  console.warn(`Duplicate ability ID "${ability.abilityId}" in ${file}, skipping`);
@@ -76,7 +91,7 @@ export class FileSystemAbilityLoader {
76
91
  */
77
92
  async loadFile(filePath, fileName) {
78
93
  try {
79
- const content = fs.readFileSync(filePath, 'utf-8');
94
+ const content = await fsPromises.readFile(filePath, 'utf-8');
80
95
  const { metadata, body } = this.parseMarkdown(content);
81
96
  // Generate ability ID from filename if not in metadata
82
97
  const abilityId = typeof metadata.abilityId === 'string'
@@ -112,25 +127,50 @@ export class FileSystemAbilityLoader {
112
127
  * Parse markdown with optional YAML frontmatter
113
128
  */
114
129
  parseMarkdown(content) {
130
+ // Normalize Windows line endings to Unix for cross-platform compatibility
131
+ const normalizedContent = content.replace(/\r\n/g, '\n');
115
132
  const frontmatterRegex = /^---\n([\s\S]*?)\n---\n([\s\S]*)$/;
116
- const match = frontmatterRegex.exec(content);
133
+ const match = frontmatterRegex.exec(normalizedContent);
117
134
  if (!match) {
118
- return { metadata: {}, body: content };
135
+ return { metadata: {}, body: normalizedContent };
119
136
  }
120
137
  const frontmatter = match[1] ?? '';
121
138
  const body = match[2] ?? '';
122
139
  // Simple YAML parser for frontmatter
123
140
  const metadata = {};
124
141
  const lines = frontmatter.split('\n');
125
- for (const line of lines) {
142
+ let currentKey = null;
143
+ let currentArray = null;
144
+ for (let i = 0; i < lines.length; i++) {
145
+ const line = lines[i] ?? '';
146
+ // Check if this is a YAML array item (starts with " - " or "- ")
147
+ const arrayItemMatch = /^\s+-\s+(.*)$/.exec(line);
148
+ if (arrayItemMatch && currentKey !== null && currentArray !== null) {
149
+ const itemValue = arrayItemMatch[1]?.trim().replace(/^['"]|['"]$/g, '') ?? '';
150
+ currentArray.push(itemValue);
151
+ continue;
152
+ }
153
+ // If we were building an array and hit a non-array line, save it
154
+ if (currentKey !== null && currentArray !== null) {
155
+ metadata[currentKey] = currentArray;
156
+ currentKey = null;
157
+ currentArray = null;
158
+ }
126
159
  const colonIndex = line.indexOf(':');
127
160
  if (colonIndex === -1)
128
161
  continue;
129
162
  const key = line.substring(0, colonIndex).trim();
130
163
  let value = line.substring(colonIndex + 1).trim();
131
- // Parse arrays
164
+ // Check if this starts a multi-line array
132
165
  if (value === '') {
133
- // Check if next lines are array items
166
+ // Look ahead to see if next line is an array item
167
+ const nextLine = lines[i + 1];
168
+ if (nextLine !== undefined && /^\s+-\s+/.test(nextLine)) {
169
+ currentKey = key;
170
+ currentArray = [];
171
+ continue;
172
+ }
173
+ // Empty value, skip
134
174
  continue;
135
175
  }
136
176
  // Parse booleans
@@ -150,6 +190,10 @@ export class FileSystemAbilityLoader {
150
190
  }
151
191
  metadata[key] = value;
152
192
  }
193
+ // Don't forget to save any trailing array
194
+ if (currentKey !== null && currentArray !== null) {
195
+ metadata[currentKey] = currentArray;
196
+ }
153
197
  return { metadata, body };
154
198
  }
155
199
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@defai.digital/ability-domain",
3
- "version": "13.2.3",
3
+ "version": "13.2.5",
4
4
  "type": "module",
5
5
  "description": "Ability management for AutomatosX agents",
6
6
  "license": "Apache-2.0",
@@ -33,7 +33,7 @@
33
33
  "access": "public"
34
34
  },
35
35
  "dependencies": {
36
- "@defai.digital/contracts": "13.2.3"
36
+ "@defai.digital/contracts": "13.2.5"
37
37
  },
38
38
  "devDependencies": {
39
39
  "typescript": "^5.7.2"
package/src/loader.ts CHANGED
@@ -6,6 +6,7 @@
6
6
  */
7
7
 
8
8
  import * as fs from 'node:fs';
9
+ import * as fsPromises from 'node:fs/promises';
9
10
  import * as path from 'node:path';
10
11
  import type { Ability } from '@defai.digital/contracts';
11
12
  import { validateAbility } from '@defai.digital/contracts';
@@ -47,24 +48,39 @@ export class FileSystemAbilityLoader implements AbilityLoader {
47
48
  this.cache.clear();
48
49
 
49
50
  const dirPath = this.config.abilitiesDir;
50
-
51
- if (!fs.existsSync(dirPath)) {
52
- this.loaded = true;
53
- return [];
54
- }
55
-
56
- const files = fs.readdirSync(dirPath);
57
51
  const abilities: Ability[] = [];
58
52
 
59
- for (const file of files) {
60
- const ext = path.extname(file).toLowerCase();
61
- if (!this.config.extensions.includes(ext)) {
62
- continue;
53
+ // Read directory with file types to filter out directories
54
+ // Handle missing/inaccessible directory gracefully
55
+ let entries: fs.Dirent[];
56
+ try {
57
+ entries = await fsPromises.readdir(dirPath, { withFileTypes: true });
58
+ } catch (err) {
59
+ const code = (err as NodeJS.ErrnoException).code;
60
+ if (code === 'ENOENT' || code === 'EACCES' || code === 'ENOTDIR') {
61
+ this.loaded = true;
62
+ return [];
63
63
  }
64
+ throw err;
65
+ }
64
66
 
65
- const filePath = path.join(dirPath, file);
66
- const ability = await this.loadFile(filePath, file);
67
-
67
+ // Filter to only files with matching extensions
68
+ const files = entries
69
+ .filter((entry) => entry.isFile())
70
+ .map((entry) => entry.name)
71
+ .filter((name) => this.config.extensions.includes(path.extname(name).toLowerCase()));
72
+
73
+ // Load all files in parallel for better performance
74
+ const loadResults = await Promise.all(
75
+ files.map(async (file) => {
76
+ const filePath = path.join(dirPath, file);
77
+ const ability = await this.loadFile(filePath, file);
78
+ return { file, ability };
79
+ })
80
+ );
81
+
82
+ // Process results sequentially to handle duplicates consistently
83
+ for (const { file, ability } of loadResults) {
68
84
  if (ability) {
69
85
  if (this.cache.has(ability.abilityId)) {
70
86
  console.warn(
@@ -102,7 +118,7 @@ export class FileSystemAbilityLoader implements AbilityLoader {
102
118
  fileName: string
103
119
  ): Promise<Ability | undefined> {
104
120
  try {
105
- const content = fs.readFileSync(filePath, 'utf-8');
121
+ const content = await fsPromises.readFile(filePath, 'utf-8');
106
122
  const { metadata, body } = this.parseMarkdown(content);
107
123
 
108
124
  // Generate ability ID from filename if not in metadata
@@ -144,11 +160,13 @@ export class FileSystemAbilityLoader implements AbilityLoader {
144
160
  metadata: Record<string, unknown>;
145
161
  body: string;
146
162
  } {
163
+ // Normalize Windows line endings to Unix for cross-platform compatibility
164
+ const normalizedContent = content.replace(/\r\n/g, '\n');
147
165
  const frontmatterRegex = /^---\n([\s\S]*?)\n---\n([\s\S]*)$/;
148
- const match = frontmatterRegex.exec(content);
166
+ const match = frontmatterRegex.exec(normalizedContent);
149
167
 
150
168
  if (!match) {
151
- return { metadata: {}, body: content };
169
+ return { metadata: {}, body: normalizedContent };
152
170
  }
153
171
 
154
172
  const frontmatter = match[1] ?? '';
@@ -158,16 +176,43 @@ export class FileSystemAbilityLoader implements AbilityLoader {
158
176
  const metadata: Record<string, unknown> = {};
159
177
  const lines = frontmatter.split('\n');
160
178
 
161
- for (const line of lines) {
179
+ let currentKey: string | null = null;
180
+ let currentArray: string[] | null = null;
181
+
182
+ for (let i = 0; i < lines.length; i++) {
183
+ const line = lines[i] ?? '';
184
+
185
+ // Check if this is a YAML array item (starts with " - " or "- ")
186
+ const arrayItemMatch = /^\s+-\s+(.*)$/.exec(line);
187
+ if (arrayItemMatch && currentKey !== null && currentArray !== null) {
188
+ const itemValue = arrayItemMatch[1]?.trim().replace(/^['"]|['"]$/g, '') ?? '';
189
+ currentArray.push(itemValue);
190
+ continue;
191
+ }
192
+
193
+ // If we were building an array and hit a non-array line, save it
194
+ if (currentKey !== null && currentArray !== null) {
195
+ metadata[currentKey] = currentArray;
196
+ currentKey = null;
197
+ currentArray = null;
198
+ }
199
+
162
200
  const colonIndex = line.indexOf(':');
163
201
  if (colonIndex === -1) continue;
164
202
 
165
203
  const key = line.substring(0, colonIndex).trim();
166
204
  let value: unknown = line.substring(colonIndex + 1).trim();
167
205
 
168
- // Parse arrays
206
+ // Check if this starts a multi-line array
169
207
  if (value === '') {
170
- // Check if next lines are array items
208
+ // Look ahead to see if next line is an array item
209
+ const nextLine = lines[i + 1];
210
+ if (nextLine !== undefined && /^\s+-\s+/.test(nextLine)) {
211
+ currentKey = key;
212
+ currentArray = [];
213
+ continue;
214
+ }
215
+ // Empty value, skip
171
216
  continue;
172
217
  }
173
218
 
@@ -187,6 +232,11 @@ export class FileSystemAbilityLoader implements AbilityLoader {
187
232
  metadata[key] = value;
188
233
  }
189
234
 
235
+ // Don't forget to save any trailing array
236
+ if (currentKey !== null && currentArray !== null) {
237
+ metadata[currentKey] = currentArray;
238
+ }
239
+
190
240
  return { metadata, body };
191
241
  }
192
242