@agent-api/sdk 1.4.4 → 1.4.6

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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog — @agent-api/sdk
2
2
 
3
+ ## 1.4.6
4
+
5
+ ### Fixed
6
+
7
+ - Made local workdir scans skip inaccessible or broken child entries with structured `scan_warnings` instead of failing an otherwise valid workdir.
8
+
9
+ ## 1.4.5
10
+
11
+ ### Fixed
12
+
13
+ - Made local workdir summaries honor `maxDepth`, and aligned model-facing summarize options with the direct SDK API.
14
+
3
15
  ## 1.4.4
4
16
 
5
17
  ### Added
package/README.md CHANGED
@@ -219,7 +219,7 @@ await workdir.patchLines("src/index.ts", {
219
219
  replacement: "console.log('patched');",
220
220
  });
221
221
 
222
- const summary = await workdir.summarize();
222
+ const summary = await workdir.summarize({ maxDepth: 3, maxFiles: 500 });
223
223
  ```
224
224
 
225
225
  For project/workdir roots, prefer `local.workdir()` so SDK defaults protect common generated directories such as `.git`, `node_modules`, `dist`, and build caches.
@@ -66,6 +66,12 @@ export interface LocalEntry {
66
66
  export interface LocalEntryList {
67
67
  object: "list";
68
68
  entries: LocalEntry[];
69
+ scan_warnings?: LocalScanWarning[];
70
+ }
71
+ export interface LocalScanWarning {
72
+ path: string;
73
+ code?: string;
74
+ message: string;
69
75
  }
70
76
  export interface LocalSearchEntriesParams {
71
77
  query: string;
@@ -157,6 +163,7 @@ export interface LocalSummarizeParams {
157
163
  maxPreviews?: number;
158
164
  previewBytes?: number;
159
165
  topPaths?: number;
166
+ maxDepth?: number;
160
167
  ignore?: LocalListOptions["ignore"];
161
168
  }
162
169
  export interface LocalSummaryPreview {
@@ -173,6 +180,7 @@ export interface LocalSummary {
173
180
  text_previews: LocalSummaryPreview[];
174
181
  generated_at_unix: number;
175
182
  scan_truncated: boolean;
183
+ scan_warnings?: LocalScanWarning[];
176
184
  }
177
185
  export interface LocalWorkdirOptions {
178
186
  name?: string;
@@ -309,6 +317,7 @@ export declare class LocalFileStore {
309
317
  grep(params: LocalGrepParams): Promise<LocalGrepResponse>;
310
318
  private grepCandidates;
311
319
  summarize(params?: LocalSummarizeParams): Promise<LocalSummary>;
320
+ private listWithWarnings;
312
321
  private walk;
313
322
  }
314
323
  export declare class LocalConfigStore {
@@ -139,15 +139,11 @@ export class LocalFileStore {
139
139
  return fullPath;
140
140
  }
141
141
  async list(relativePath = ".", options = {}) {
142
- const base = this.resolvePath(relativePath);
143
- const maxDepth = options.recursive ? options.maxDepth ?? Number.POSITIVE_INFINITY : 1;
144
- const out = [];
145
- await this.walk(this.root, base, base, out, maxDepth, options);
146
- return out.sort((a, b) => a.path.localeCompare(b.path));
142
+ return (await this.listWithWarnings(relativePath, options)).stats;
147
143
  }
148
144
  async listEntries(relativePath = ".", options = {}) {
149
- const stats = await this.list(relativePath, { ...options, includeDirectories: options.includeDirectories ?? true });
150
- return { object: "list", entries: stats.map(localEntryFromStat) };
145
+ const { stats, warnings } = await this.listWithWarnings(relativePath, { ...options, includeDirectories: options.includeDirectories ?? true });
146
+ return withScanWarnings({ object: "list", entries: stats.map(localEntryFromStat) }, warnings);
151
147
  }
152
148
  async searchEntries(params) {
153
149
  const query = params.query.trim().toLowerCase();
@@ -374,7 +370,7 @@ export class LocalFileStore {
374
370
  const maxPreviews = positiveInt(params.maxPreviews, 20);
375
371
  const previewBytes = positiveInt(params.previewBytes, 4096);
376
372
  const topPaths = positiveInt(params.topPaths, 20);
377
- const stats = await this.list(params.path ?? ".", { recursive: true, ignore: params.ignore });
373
+ const { stats, warnings } = await this.listWithWarnings(params.path ?? ".", { recursive: true, maxDepth: params.maxDepth, ignore: params.ignore });
378
374
  const files = stats.filter((item) => item.type === "file").slice(0, maxFiles);
379
375
  const scanTruncated = stats.filter((item) => item.type === "file").length > files.length;
380
376
  const totalBytes = files.reduce((sum, item) => sum + item.size, 0);
@@ -402,7 +398,7 @@ export class LocalFileStore {
402
398
  preview_truncated: truncated || undefined,
403
399
  });
404
400
  }
405
- return {
401
+ return withScanWarnings({
406
402
  summary_path: "",
407
403
  file_count: files.length,
408
404
  total_bytes: totalBytes,
@@ -410,17 +406,34 @@ export class LocalFileStore {
410
406
  text_previews: previews,
411
407
  generated_at_unix: Math.floor(Date.now() / 1000),
412
408
  scan_truncated: scanTruncated,
413
- };
409
+ }, warnings);
414
410
  }
415
- async walk(storeRoot, scanRoot, dir, out, maxDepth, options) {
416
- const entries = await readdir(dir, { withFileTypes: true });
411
+ async listWithWarnings(relativePath = ".", options = {}) {
412
+ const base = this.resolvePath(relativePath);
413
+ const maxDepth = options.recursive ? options.maxDepth ?? Number.POSITIVE_INFINITY : 1;
414
+ const out = [];
415
+ const warnings = [];
416
+ await this.walk(this.root, base, base, out, maxDepth, options, warnings);
417
+ return { stats: out.sort((a, b) => a.path.localeCompare(b.path)), warnings };
418
+ }
419
+ async walk(storeRoot, scanRoot, dir, out, maxDepth, options, warnings) {
420
+ let entries;
421
+ try {
422
+ entries = await readdir(dir, { withFileTypes: true });
423
+ }
424
+ catch (error) {
425
+ if (dir !== scanRoot && recordScanWarning(warnings, toPortablePath(path.relative(storeRoot, dir)), error)) {
426
+ return;
427
+ }
428
+ throw error;
429
+ }
417
430
  for (const entry of entries) {
418
431
  const fullPath = path.join(dir, entry.name);
419
432
  const relativePath = toPortablePath(path.relative(storeRoot, fullPath));
420
433
  if (ignored(relativePath, options.ignore)) {
421
434
  continue;
422
435
  }
423
- const info = await lstatOptional(fullPath);
436
+ const info = await lstatOptional(fullPath, relativePath, warnings);
424
437
  if (!info) {
425
438
  continue;
426
439
  }
@@ -437,7 +450,7 @@ export class LocalFileStore {
437
450
  }
438
451
  const depth = toPortablePath(path.relative(scanRoot, fullPath)).split("/").filter(Boolean).length;
439
452
  if (depth < maxDepth) {
440
- await this.walk(storeRoot, scanRoot, fullPath, out, maxDepth, options);
453
+ await this.walk(storeRoot, scanRoot, fullPath, out, maxDepth, options, warnings);
441
454
  }
442
455
  continue;
443
456
  }
@@ -847,11 +860,38 @@ async function fileExists(fullPath) {
847
860
  return false;
848
861
  }
849
862
  }
850
- async function lstatOptional(fullPath) {
863
+ const maxScanWarnings = 20;
864
+ const ignorableScanErrorCodes = new Set(["ENOENT", "ENOTDIR", "EACCES", "EPERM", "ENOTCONN", "ELOOP", "EINVAL"]);
865
+ function withScanWarnings(value, warnings) {
866
+ const out = value;
867
+ if (warnings.length > 0) {
868
+ out.scan_warnings = warnings;
869
+ }
870
+ return out;
871
+ }
872
+ function recordScanWarning(warnings, relativePath, error) {
873
+ const scanError = error;
874
+ const code = typeof scanError?.code === "string" ? scanError.code : undefined;
875
+ if (!code || !ignorableScanErrorCodes.has(code)) {
876
+ return false;
877
+ }
878
+ if (warnings.length < maxScanWarnings) {
879
+ warnings.push({
880
+ path: relativePath || ".",
881
+ code,
882
+ message: typeof scanError.message === "string" ? scanError.message : code,
883
+ });
884
+ }
885
+ return true;
886
+ }
887
+ async function lstatOptional(fullPath, relativePath, warnings) {
851
888
  try {
852
889
  return await lstat(fullPath);
853
890
  }
854
891
  catch (error) {
892
+ if (warnings && relativePath && recordScanWarning(warnings, relativePath, error)) {
893
+ return null;
894
+ }
855
895
  if (error?.code === "ENOENT" || error?.code === "ENOTDIR") {
856
896
  return null;
857
897
  }
@@ -863,7 +903,7 @@ async function readOptionalFile(fullPath) {
863
903
  return await readFile(fullPath);
864
904
  }
865
905
  catch (error) {
866
- if (error?.code === "ENOENT" || error?.code === "ENOTDIR" || error?.code === "EISDIR") {
906
+ if (error?.code === "ENOENT" || error?.code === "ENOTDIR" || error?.code === "EISDIR" || error?.code === "ENOTCONN") {
867
907
  return null;
868
908
  }
869
909
  throw error;
@@ -202,6 +202,9 @@ function summaryArgs(args) {
202
202
  path: optionalStringArg(args, "path"),
203
203
  maxFiles: optionalNumberArg(args, "maxFiles", "max_files"),
204
204
  maxPreviews: optionalNumberArg(args, "maxPreviews", "max_previews"),
205
+ previewBytes: optionalNumberArg(args, "previewBytes", "preview_bytes"),
206
+ topPaths: optionalNumberArg(args, "topPaths", "top_paths"),
207
+ maxDepth: optionalNumberArg(args, "maxDepth", "max_depth"),
205
208
  };
206
209
  }
207
210
  function grepArgs(args) {
package/dist/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "1.4.4";
2
- export declare const USER_AGENT = "@agent-api/sdk/1.4.4";
1
+ export declare const VERSION = "1.4.6";
2
+ export declare const USER_AGENT = "@agent-api/sdk/1.4.6";
package/dist/version.js CHANGED
@@ -1,2 +1,2 @@
1
- export const VERSION = "1.4.4";
1
+ export const VERSION = "1.4.6";
2
2
  export const USER_AGENT = `@agent-api/sdk/${VERSION}`;
@@ -154,15 +154,11 @@ class LocalFileStore {
154
154
  return fullPath;
155
155
  }
156
156
  async list(relativePath = ".", options = {}) {
157
- const base = this.resolvePath(relativePath);
158
- const maxDepth = options.recursive ? options.maxDepth ?? Number.POSITIVE_INFINITY : 1;
159
- const out = [];
160
- await this.walk(this.root, base, base, out, maxDepth, options);
161
- return out.sort((a, b) => a.path.localeCompare(b.path));
157
+ return (await this.listWithWarnings(relativePath, options)).stats;
162
158
  }
163
159
  async listEntries(relativePath = ".", options = {}) {
164
- const stats = await this.list(relativePath, { ...options, includeDirectories: options.includeDirectories ?? true });
165
- return { object: "list", entries: stats.map(localEntryFromStat) };
160
+ const { stats, warnings } = await this.listWithWarnings(relativePath, { ...options, includeDirectories: options.includeDirectories ?? true });
161
+ return withScanWarnings({ object: "list", entries: stats.map(localEntryFromStat) }, warnings);
166
162
  }
167
163
  async searchEntries(params) {
168
164
  const query = params.query.trim().toLowerCase();
@@ -389,7 +385,7 @@ class LocalFileStore {
389
385
  const maxPreviews = positiveInt(params.maxPreviews, 20);
390
386
  const previewBytes = positiveInt(params.previewBytes, 4096);
391
387
  const topPaths = positiveInt(params.topPaths, 20);
392
- const stats = await this.list(params.path ?? ".", { recursive: true, ignore: params.ignore });
388
+ const { stats, warnings } = await this.listWithWarnings(params.path ?? ".", { recursive: true, maxDepth: params.maxDepth, ignore: params.ignore });
393
389
  const files = stats.filter((item) => item.type === "file").slice(0, maxFiles);
394
390
  const scanTruncated = stats.filter((item) => item.type === "file").length > files.length;
395
391
  const totalBytes = files.reduce((sum, item) => sum + item.size, 0);
@@ -417,7 +413,7 @@ class LocalFileStore {
417
413
  preview_truncated: truncated || undefined,
418
414
  });
419
415
  }
420
- return {
416
+ return withScanWarnings({
421
417
  summary_path: "",
422
418
  file_count: files.length,
423
419
  total_bytes: totalBytes,
@@ -425,17 +421,34 @@ class LocalFileStore {
425
421
  text_previews: previews,
426
422
  generated_at_unix: Math.floor(Date.now() / 1000),
427
423
  scan_truncated: scanTruncated,
428
- };
424
+ }, warnings);
429
425
  }
430
- async walk(storeRoot, scanRoot, dir, out, maxDepth, options) {
431
- const entries = await (0, promises_1.readdir)(dir, { withFileTypes: true });
426
+ async listWithWarnings(relativePath = ".", options = {}) {
427
+ const base = this.resolvePath(relativePath);
428
+ const maxDepth = options.recursive ? options.maxDepth ?? Number.POSITIVE_INFINITY : 1;
429
+ const out = [];
430
+ const warnings = [];
431
+ await this.walk(this.root, base, base, out, maxDepth, options, warnings);
432
+ return { stats: out.sort((a, b) => a.path.localeCompare(b.path)), warnings };
433
+ }
434
+ async walk(storeRoot, scanRoot, dir, out, maxDepth, options, warnings) {
435
+ let entries;
436
+ try {
437
+ entries = await (0, promises_1.readdir)(dir, { withFileTypes: true });
438
+ }
439
+ catch (error) {
440
+ if (dir !== scanRoot && recordScanWarning(warnings, toPortablePath(node_path_1.default.relative(storeRoot, dir)), error)) {
441
+ return;
442
+ }
443
+ throw error;
444
+ }
432
445
  for (const entry of entries) {
433
446
  const fullPath = node_path_1.default.join(dir, entry.name);
434
447
  const relativePath = toPortablePath(node_path_1.default.relative(storeRoot, fullPath));
435
448
  if (ignored(relativePath, options.ignore)) {
436
449
  continue;
437
450
  }
438
- const info = await lstatOptional(fullPath);
451
+ const info = await lstatOptional(fullPath, relativePath, warnings);
439
452
  if (!info) {
440
453
  continue;
441
454
  }
@@ -452,7 +465,7 @@ class LocalFileStore {
452
465
  }
453
466
  const depth = toPortablePath(node_path_1.default.relative(scanRoot, fullPath)).split("/").filter(Boolean).length;
454
467
  if (depth < maxDepth) {
455
- await this.walk(storeRoot, scanRoot, fullPath, out, maxDepth, options);
468
+ await this.walk(storeRoot, scanRoot, fullPath, out, maxDepth, options, warnings);
456
469
  }
457
470
  continue;
458
471
  }
@@ -867,11 +880,38 @@ async function fileExists(fullPath) {
867
880
  return false;
868
881
  }
869
882
  }
870
- async function lstatOptional(fullPath) {
883
+ const maxScanWarnings = 20;
884
+ const ignorableScanErrorCodes = new Set(["ENOENT", "ENOTDIR", "EACCES", "EPERM", "ENOTCONN", "ELOOP", "EINVAL"]);
885
+ function withScanWarnings(value, warnings) {
886
+ const out = value;
887
+ if (warnings.length > 0) {
888
+ out.scan_warnings = warnings;
889
+ }
890
+ return out;
891
+ }
892
+ function recordScanWarning(warnings, relativePath, error) {
893
+ const scanError = error;
894
+ const code = typeof scanError?.code === "string" ? scanError.code : undefined;
895
+ if (!code || !ignorableScanErrorCodes.has(code)) {
896
+ return false;
897
+ }
898
+ if (warnings.length < maxScanWarnings) {
899
+ warnings.push({
900
+ path: relativePath || ".",
901
+ code,
902
+ message: typeof scanError.message === "string" ? scanError.message : code,
903
+ });
904
+ }
905
+ return true;
906
+ }
907
+ async function lstatOptional(fullPath, relativePath, warnings) {
871
908
  try {
872
909
  return await (0, promises_1.lstat)(fullPath);
873
910
  }
874
911
  catch (error) {
912
+ if (warnings && relativePath && recordScanWarning(warnings, relativePath, error)) {
913
+ return null;
914
+ }
875
915
  if (error?.code === "ENOENT" || error?.code === "ENOTDIR") {
876
916
  return null;
877
917
  }
@@ -883,7 +923,7 @@ async function readOptionalFile(fullPath) {
883
923
  return await (0, promises_1.readFile)(fullPath);
884
924
  }
885
925
  catch (error) {
886
- if (error?.code === "ENOENT" || error?.code === "ENOTDIR" || error?.code === "EISDIR") {
926
+ if (error?.code === "ENOENT" || error?.code === "ENOTDIR" || error?.code === "EISDIR" || error?.code === "ENOTCONN") {
887
927
  return null;
888
928
  }
889
929
  throw error;
@@ -209,6 +209,9 @@ function summaryArgs(args) {
209
209
  path: optionalStringArg(args, "path"),
210
210
  maxFiles: optionalNumberArg(args, "maxFiles", "max_files"),
211
211
  maxPreviews: optionalNumberArg(args, "maxPreviews", "max_previews"),
212
+ previewBytes: optionalNumberArg(args, "previewBytes", "preview_bytes"),
213
+ topPaths: optionalNumberArg(args, "topPaths", "top_paths"),
214
+ maxDepth: optionalNumberArg(args, "maxDepth", "max_depth"),
212
215
  };
213
216
  }
214
217
  function grepArgs(args) {
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.USER_AGENT = exports.VERSION = void 0;
4
- exports.VERSION = "1.4.4";
4
+ exports.VERSION = "1.4.6";
5
5
  exports.USER_AGENT = `@agent-api/sdk/${exports.VERSION}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-api/sdk",
3
- "version": "1.4.4",
3
+ "version": "1.4.6",
4
4
  "description": "Production JavaScript SDK for the Managed Agent API",
5
5
  "license": "MIT",
6
6
  "repository": {