@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.
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +60 -16
- package/dist/loader.js.map +1 -1
- package/package.json +2 -2
- package/src/loader.ts +70 -20
package/dist/loader.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
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
|
|
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
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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 =
|
|
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(
|
|
133
|
+
const match = frontmatterRegex.exec(normalizedContent);
|
|
117
134
|
if (!match) {
|
|
118
|
-
return { metadata: {}, body:
|
|
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
|
-
|
|
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
|
-
//
|
|
164
|
+
// Check if this starts a multi-line array
|
|
132
165
|
if (value === '') {
|
|
133
|
-
//
|
|
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
|
/**
|
package/dist/loader.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
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
|
+
"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.
|
|
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
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
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
|
-
|
|
66
|
-
|
|
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 =
|
|
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(
|
|
166
|
+
const match = frontmatterRegex.exec(normalizedContent);
|
|
149
167
|
|
|
150
168
|
if (!match) {
|
|
151
|
-
return { metadata: {}, body:
|
|
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
|
-
|
|
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
|
-
//
|
|
206
|
+
// Check if this starts a multi-line array
|
|
169
207
|
if (value === '') {
|
|
170
|
-
//
|
|
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
|
|