@defai.digital/context-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;;;;;;;;;;GAUG;AAIH,OAAO,EAOL,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,cAAc,EAAY,MAAM,YAAY,CAAC;AAmB3D;;GAEG;AACH,qBAAa,aAAc,YAAW,cAAc;IAClD,OAAO,CAAC,MAAM,CAAsB;gBAExB,MAAM,GAAE,OAAO,CAAC,mBAAmB,CAAM;IAIrD;;OAEG;IACH,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM;IAI3C;;OAEG;IACG,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAUvD;;OAEG;IACG,IAAI,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAiG3D;;OAEG;YACW,gBAAgB;IA8B9B;;OAEG;IACH,OAAO,CAAC,SAAS;IAcjB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAW7B;;OAEG;IACH,OAAO,CAAC,kBAAkB;CAW3B;AAMD;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,GACpC,cAAc,CAEhB;AAMD;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAG7E;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,iBAAiB,CAAC,CAG5B"}
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,EAOL,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,cAAc,EAAY,MAAM,YAAY,CAAC;AAmB3D;;GAEG;AACH,qBAAa,aAAc,YAAW,cAAc;IAClD,OAAO,CAAC,MAAM,CAAsB;gBAExB,MAAM,GAAE,OAAO,CAAC,mBAAmB,CAAM;IAIrD;;OAEG;IACH,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM;IAI3C;;OAEG;IACG,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAUvD;;OAEG;IACG,IAAI,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAwH3D;;OAEG;YACW,gBAAgB;IAkC9B;;OAEG;IACH,OAAO,CAAC,SAAS;IAcjB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAW7B;;OAEG;IACH,OAAO,CAAC,kBAAkB;CAW3B;AAMD;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,GACpC,cAAc,CAEhB;AAMD;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAG7E;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,iBAAiB,CAAC,CAG5B"}
package/dist/loader.js CHANGED
@@ -69,51 +69,69 @@ export class ContextLoader {
69
69
  };
70
70
  }
71
71
  try {
72
- // List files in context directory
72
+ // PHASE 1: List files with stats (already parallelized in listContextFiles)
73
73
  const fileInfos = await this.listContextFiles(contextPath);
74
- // Load files with size limits
75
74
  const loadedFiles = [];
76
75
  const skippedReasons = [];
77
- let totalSize = 0;
76
+ // PHASE 2: Filter by budget BEFORE reading (two-phase pattern)
77
+ // First, filter out files that exceed individual size limit
78
+ const validFiles = [];
78
79
  for (const fileInfo of fileInfos) {
79
- // Check individual file size
80
80
  if (fileInfo.size > this.config.maxFileSize) {
81
81
  skippedReasons.push({
82
82
  filename: fileInfo.name,
83
83
  reason: `File exceeds max size (${fileInfo.size} > ${this.config.maxFileSize})`,
84
84
  });
85
- continue;
86
85
  }
87
- // Check total size limit
88
- if (totalSize + fileInfo.size > this.config.maxTotalSize) {
86
+ else {
87
+ validFiles.push(fileInfo);
88
+ }
89
+ }
90
+ // Sort by size (smallest first) to maximize number of files within budget
91
+ const sortedBySize = [...validFiles].sort((a, b) => a.size - b.size);
92
+ // Select files that fit within total size budget
93
+ let budgetUsed = 0;
94
+ const selected = [];
95
+ for (const file of sortedBySize) {
96
+ if (budgetUsed + file.size <= this.config.maxTotalSize) {
97
+ selected.push(file);
98
+ budgetUsed += file.size;
99
+ }
100
+ else {
89
101
  skippedReasons.push({
90
- filename: fileInfo.name,
102
+ filename: file.name,
91
103
  reason: `Would exceed total size limit`,
92
104
  });
93
- continue;
94
- }
95
- // Load file content
96
- try {
97
- const content = await fs.readFile(fileInfo.path, 'utf-8');
98
- const now = new Date().toISOString();
99
- loadedFiles.push({
100
- filename: fileInfo.name,
101
- relativePath: path.relative(contextPath, fileInfo.path),
102
- content,
103
- size: fileInfo.size,
104
- loadedAt: now,
105
- });
106
- totalSize += fileInfo.size;
107
105
  }
108
- catch (error) {
106
+ }
107
+ // PHASE 3: Parallel read of ONLY selected files
108
+ const loadResults = await Promise.allSettled(selected.map(async (fileInfo) => {
109
+ const content = await fs.readFile(fileInfo.path, 'utf-8');
110
+ return { fileInfo, content };
111
+ }));
112
+ // Process results
113
+ const now = new Date().toISOString();
114
+ for (const result of loadResults) {
115
+ if (result.status === 'rejected') {
109
116
  skippedReasons.push({
110
- filename: fileInfo.name,
111
- reason: `Read error: ${error instanceof Error ? error.message : 'Unknown'}`,
117
+ filename: 'unknown',
118
+ reason: `Read error: ${result.reason?.message || 'Unknown'}`,
112
119
  });
120
+ continue;
113
121
  }
122
+ const { fileInfo, content } = result.value;
123
+ loadedFiles.push({
124
+ filename: fileInfo.name,
125
+ relativePath: path.relative(contextPath, fileInfo.path),
126
+ content,
127
+ size: fileInfo.size,
128
+ loadedAt: now,
129
+ });
114
130
  }
115
- // Sort files
131
+ // Sort files for consistent output
116
132
  this.sortFiles(loadedFiles);
133
+ // Calculate actual total size from loaded files (may differ from budget if reads failed)
134
+ const totalSize = loadedFiles.reduce((sum, file) => sum + file.size, 0);
117
135
  // Create combined content
118
136
  const combinedContent = this.createCombinedContent(loadedFiles);
119
137
  const context = {
@@ -146,27 +164,29 @@ export class ContextLoader {
146
164
  * List context files in directory
147
165
  */
148
166
  async listContextFiles(contextPath) {
149
- const files = [];
150
167
  const entries = await fs.readdir(contextPath, { withFileTypes: true });
151
- for (const entry of entries) {
168
+ // Filter valid entries first (sync operations)
169
+ const validEntries = entries.filter((entry) => {
152
170
  if (!entry.isFile())
153
- continue;
171
+ return false;
154
172
  // Check file extension
155
173
  const ext = path.extname(entry.name).toLowerCase();
156
174
  if (!this.config.fileExtensions.includes(ext))
157
- continue;
175
+ return false;
158
176
  // Check exclude patterns
159
177
  const excluded = this.config.excludePatterns.some((pattern) => entry.name.includes(pattern));
160
- if (excluded)
161
- continue;
178
+ return !excluded;
179
+ });
180
+ // Stat all valid files in parallel for better performance
181
+ const files = await Promise.all(validEntries.map(async (entry) => {
162
182
  const filePath = path.join(contextPath, entry.name);
163
183
  const stat = await fs.stat(filePath);
164
- files.push({
184
+ return {
165
185
  path: filePath,
166
186
  name: entry.name,
167
187
  size: stat.size,
168
- });
169
- }
188
+ };
189
+ }));
170
190
  return files;
171
191
  }
172
192
  /**
@@ -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/context-domain",
3
- "version": "13.2.3",
3
+ "version": "13.2.5",
4
4
  "type": "module",
5
5
  "description": "Project context loading for AutomatosX - inject project-specific conventions into agent prompts",
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
@@ -89,58 +89,81 @@ export class ContextLoader implements IContextLoader {
89
89
  }
90
90
 
91
91
  try {
92
- // List files in context directory
92
+ // PHASE 1: List files with stats (already parallelized in listContextFiles)
93
93
  const fileInfos = await this.listContextFiles(contextPath);
94
94
 
95
- // Load files with size limits
96
95
  const loadedFiles: ContextFile[] = [];
97
96
  const skippedReasons: { filename: string; reason: string }[] = [];
98
- let totalSize = 0;
99
97
 
98
+ // PHASE 2: Filter by budget BEFORE reading (two-phase pattern)
99
+ // First, filter out files that exceed individual size limit
100
+ const validFiles: FileInfo[] = [];
100
101
  for (const fileInfo of fileInfos) {
101
- // Check individual file size
102
102
  if (fileInfo.size > this.config.maxFileSize) {
103
103
  skippedReasons.push({
104
104
  filename: fileInfo.name,
105
105
  reason: `File exceeds max size (${fileInfo.size} > ${this.config.maxFileSize})`,
106
106
  });
107
- continue;
107
+ } else {
108
+ validFiles.push(fileInfo);
108
109
  }
110
+ }
111
+
112
+ // Sort by size (smallest first) to maximize number of files within budget
113
+ const sortedBySize = [...validFiles].sort((a, b) => a.size - b.size);
109
114
 
110
- // Check total size limit
111
- if (totalSize + fileInfo.size > this.config.maxTotalSize) {
115
+ // Select files that fit within total size budget
116
+ let budgetUsed = 0;
117
+ const selected: FileInfo[] = [];
118
+
119
+ for (const file of sortedBySize) {
120
+ if (budgetUsed + file.size <= this.config.maxTotalSize) {
121
+ selected.push(file);
122
+ budgetUsed += file.size;
123
+ } else {
112
124
  skippedReasons.push({
113
- filename: fileInfo.name,
125
+ filename: file.name,
114
126
  reason: `Would exceed total size limit`,
115
127
  });
116
- continue;
117
128
  }
129
+ }
118
130
 
119
- // Load file content
120
- try {
131
+ // PHASE 3: Parallel read of ONLY selected files
132
+ const loadResults = await Promise.allSettled(
133
+ selected.map(async (fileInfo) => {
121
134
  const content = await fs.readFile(fileInfo.path, 'utf-8');
122
- const now = new Date().toISOString();
135
+ return { fileInfo, content };
136
+ })
137
+ );
123
138
 
124
- loadedFiles.push({
125
- filename: fileInfo.name,
126
- relativePath: path.relative(contextPath, fileInfo.path),
127
- content,
128
- size: fileInfo.size,
129
- loadedAt: now,
130
- });
139
+ // Process results
140
+ const now = new Date().toISOString();
131
141
 
132
- totalSize += fileInfo.size;
133
- } catch (error) {
142
+ for (const result of loadResults) {
143
+ if (result.status === 'rejected') {
134
144
  skippedReasons.push({
135
- filename: fileInfo.name,
136
- reason: `Read error: ${error instanceof Error ? error.message : 'Unknown'}`,
145
+ filename: 'unknown',
146
+ reason: `Read error: ${result.reason?.message || 'Unknown'}`,
137
147
  });
148
+ continue;
138
149
  }
150
+
151
+ const { fileInfo, content } = result.value;
152
+ loadedFiles.push({
153
+ filename: fileInfo.name,
154
+ relativePath: path.relative(contextPath, fileInfo.path),
155
+ content,
156
+ size: fileInfo.size,
157
+ loadedAt: now,
158
+ });
139
159
  }
140
160
 
141
- // Sort files
161
+ // Sort files for consistent output
142
162
  this.sortFiles(loadedFiles);
143
163
 
164
+ // Calculate actual total size from loaded files (may differ from budget if reads failed)
165
+ const totalSize = loadedFiles.reduce((sum, file) => sum + file.size, 0);
166
+
144
167
  // Create combined content
145
168
  const combinedContent = this.createCombinedContent(loadedFiles);
146
169
 
@@ -175,31 +198,35 @@ export class ContextLoader implements IContextLoader {
175
198
  * List context files in directory
176
199
  */
177
200
  private async listContextFiles(contextPath: string): Promise<FileInfo[]> {
178
- const files: FileInfo[] = [];
179
201
  const entries = await fs.readdir(contextPath, { withFileTypes: true });
180
202
 
181
- for (const entry of entries) {
182
- if (!entry.isFile()) continue;
203
+ // Filter valid entries first (sync operations)
204
+ const validEntries = entries.filter((entry) => {
205
+ if (!entry.isFile()) return false;
183
206
 
184
207
  // Check file extension
185
208
  const ext = path.extname(entry.name).toLowerCase();
186
- if (!this.config.fileExtensions.includes(ext)) continue;
209
+ if (!this.config.fileExtensions.includes(ext)) return false;
187
210
 
188
211
  // Check exclude patterns
189
212
  const excluded = this.config.excludePatterns.some((pattern) =>
190
213
  entry.name.includes(pattern)
191
214
  );
192
- if (excluded) continue;
193
-
194
- const filePath = path.join(contextPath, entry.name);
195
- const stat = await fs.stat(filePath);
215
+ return !excluded;
216
+ });
196
217
 
197
- files.push({
198
- path: filePath,
199
- name: entry.name,
200
- size: stat.size,
201
- });
202
- }
218
+ // Stat all valid files in parallel for better performance
219
+ const files = await Promise.all(
220
+ validEntries.map(async (entry) => {
221
+ const filePath = path.join(contextPath, entry.name);
222
+ const stat = await fs.stat(filePath);
223
+ return {
224
+ path: filePath,
225
+ name: entry.name,
226
+ size: stat.size,
227
+ };
228
+ })
229
+ );
203
230
 
204
231
  return files;
205
232
  }