@agent-api/sdk 1.4.7 → 1.4.8

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,13 @@
1
1
  # Changelog — @agent-api/sdk
2
2
 
3
+ ## 1.4.8
4
+
5
+ ### Changed
6
+
7
+ - Restored `LocalFileStore.list()` to strict complete-or-fail scan semantics while keeping `listWithWarnings()` as the explicit tolerant partial-scan API.
8
+ - Made local context packages leave recursive scan depth uncapped unless callers provide `maxDepth`.
9
+ - Moved local skill discovery onto the same warning-aware filesystem scan primitive used by workdir summaries and context packages.
10
+
3
11
  ## 1.4.7
4
12
 
5
13
  ### Added
@@ -6,7 +6,7 @@ export async function createLocalContextPackage(workdir, params = {}) {
6
6
  const maxFiles = positiveInt(params.maxFiles, 80);
7
7
  const maxBytes = positiveInt(params.maxBytes, 256 * 1024);
8
8
  const maxBytesPerFile = positiveInt(params.maxBytesPerFile, 32 * 1024);
9
- const maxDepth = positiveInt(params.maxDepth, 3);
9
+ const maxDepth = optionalPositiveInt(params.maxDepth);
10
10
  const previewBytes = positiveInt(params.previewBytes, maxBytesPerFile);
11
11
  const includeContent = params.includeContent ?? true;
12
12
  const includeHashes = params.includeHashes ?? true;
@@ -151,6 +151,10 @@ function positiveInt(value, fallback) {
151
151
  const parsed = Number(value);
152
152
  return Number.isFinite(parsed) && parsed > 0 ? Math.trunc(parsed) : fallback;
153
153
  }
154
+ function optionalPositiveInt(value) {
155
+ const parsed = Number(value);
156
+ return Number.isFinite(parsed) && parsed > 0 ? Math.trunc(parsed) : undefined;
157
+ }
154
158
  async function sha256File(workdir, relativePath) {
155
159
  const fullPath = workdir.files.resolvePath(relativePath);
156
160
  return createHash("sha256").update(await readFile(fullPath)).digest("hex");
@@ -139,7 +139,11 @@ export class LocalFileStore {
139
139
  return fullPath;
140
140
  }
141
141
  async list(relativePath = ".", options = {}) {
142
- return (await this.listWithWarnings(relativePath, options)).stats;
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));
143
147
  }
144
148
  async listWithWarnings(relativePath = ".", options = {}) {
145
149
  const base = this.resolvePath(relativePath);
@@ -422,7 +426,7 @@ export class LocalFileStore {
422
426
  entries = await readdir(dir, { withFileTypes: true });
423
427
  }
424
428
  catch (error) {
425
- if (dir !== scanRoot && recordScanWarning(warnings, toPortablePath(path.relative(storeRoot, dir)), error)) {
429
+ if (warnings && dir !== scanRoot && recordScanWarning(warnings, toPortablePath(path.relative(storeRoot, dir)), error)) {
426
430
  return;
427
431
  }
428
432
  throw error;
@@ -820,8 +824,9 @@ function defaultDirs(platform, env, home, authorSegment, appSegment, baseDir) {
820
824
  };
821
825
  }
822
826
  async function discoverSkillDirectories(root, options) {
827
+ const rootStore = new LocalFileStore(root);
823
828
  try {
824
- const info = await stat(root);
829
+ const info = await stat(rootStore.root);
825
830
  if (!info.isDirectory()) {
826
831
  return [];
827
832
  }
@@ -832,27 +837,20 @@ async function discoverSkillDirectories(root, options) {
832
837
  }
833
838
  throw error;
834
839
  }
840
+ const { stats } = await rootStore.listWithWarnings(".", {
841
+ recursive: options.recursive ?? false,
842
+ includeDirectories: true,
843
+ maxDepth: options.maxDepth,
844
+ ignore: [".git", "node_modules", "__pycache__"],
845
+ });
846
+ const dirs = [rootStore.root, ...stats.filter((item) => item.type === "directory").map((item) => item.fullPath)];
835
847
  const out = [];
836
- const maxDepth = options.recursive ? options.maxDepth ?? Number.POSITIVE_INFINITY : 1;
837
- await walkSkillDirectories(root, root, out, maxDepth);
838
- return out;
839
- }
840
- async function walkSkillDirectories(root, dir, out, maxDepth) {
841
- if (await fileExists(path.join(dir, "SKILL.md"))) {
842
- out.push(dir);
843
- }
844
- const relative = path.relative(root, dir);
845
- const depth = relative ? relative.split(path.sep).length : 0;
846
- if (depth >= maxDepth) {
847
- return;
848
- }
849
- const entries = await readdir(dir, { withFileTypes: true });
850
- for (const entry of entries) {
851
- if (!entry.isDirectory() || ignoredDirectoryName(entry.name)) {
852
- continue;
848
+ for (const dir of dirs) {
849
+ if (await fileExists(path.join(dir, "SKILL.md"))) {
850
+ out.push(dir);
853
851
  }
854
- await walkSkillDirectories(root, path.join(dir, entry.name), out, maxDepth);
855
852
  }
853
+ return out;
856
854
  }
857
855
  async function fileExists(fullPath) {
858
856
  try {
@@ -0,0 +1,13 @@
1
+ export interface LocalScanWarning {
2
+ path: string;
3
+ code?: string;
4
+ message: string;
5
+ }
6
+ export interface LocalScanWarningList<T> {
7
+ value: T;
8
+ warnings: LocalScanWarning[];
9
+ }
10
+ export declare function withScanWarnings<T>(value: T, warnings: LocalScanWarning[]): T & {
11
+ scan_warnings?: LocalScanWarning[];
12
+ };
13
+ export declare function recordScanWarning(warnings: LocalScanWarning[], relativePath: string, error: unknown): boolean;
@@ -0,0 +1,24 @@
1
+ const maxScanWarnings = 20;
2
+ const ignorableScanErrorCodes = new Set(["ENOENT", "ENOTDIR", "EACCES", "EPERM", "ENOTCONN", "ELOOP", "EINVAL"]);
3
+ export function withScanWarnings(value, warnings) {
4
+ const out = value;
5
+ if (warnings.length > 0) {
6
+ out.scan_warnings = warnings;
7
+ }
8
+ return out;
9
+ }
10
+ export function recordScanWarning(warnings, relativePath, error) {
11
+ const scanError = error;
12
+ const code = typeof scanError?.code === "string" ? scanError.code : undefined;
13
+ if (!code || !ignorableScanErrorCodes.has(code)) {
14
+ return false;
15
+ }
16
+ if (warnings.length < maxScanWarnings) {
17
+ warnings.push({
18
+ path: relativePath || ".",
19
+ code,
20
+ message: typeof scanError.message === "string" ? scanError.message : code,
21
+ });
22
+ }
23
+ return true;
24
+ }
package/dist/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "1.4.7";
2
- export declare const USER_AGENT = "@agent-api/sdk/1.4.7";
1
+ export declare const VERSION = "1.4.8";
2
+ export declare const USER_AGENT = "@agent-api/sdk/1.4.8";
package/dist/version.js CHANGED
@@ -1,2 +1,2 @@
1
- export const VERSION = "1.4.7";
1
+ export const VERSION = "1.4.8";
2
2
  export const USER_AGENT = `@agent-api/sdk/${VERSION}`;
@@ -10,7 +10,7 @@ async function createLocalContextPackage(workdir, params = {}) {
10
10
  const maxFiles = positiveInt(params.maxFiles, 80);
11
11
  const maxBytes = positiveInt(params.maxBytes, 256 * 1024);
12
12
  const maxBytesPerFile = positiveInt(params.maxBytesPerFile, 32 * 1024);
13
- const maxDepth = positiveInt(params.maxDepth, 3);
13
+ const maxDepth = optionalPositiveInt(params.maxDepth);
14
14
  const previewBytes = positiveInt(params.previewBytes, maxBytesPerFile);
15
15
  const includeContent = params.includeContent ?? true;
16
16
  const includeHashes = params.includeHashes ?? true;
@@ -155,6 +155,10 @@ function positiveInt(value, fallback) {
155
155
  const parsed = Number(value);
156
156
  return Number.isFinite(parsed) && parsed > 0 ? Math.trunc(parsed) : fallback;
157
157
  }
158
+ function optionalPositiveInt(value) {
159
+ const parsed = Number(value);
160
+ return Number.isFinite(parsed) && parsed > 0 ? Math.trunc(parsed) : undefined;
161
+ }
158
162
  async function sha256File(workdir, relativePath) {
159
163
  const fullPath = workdir.files.resolvePath(relativePath);
160
164
  return (0, node_crypto_1.createHash)("sha256").update(await (0, promises_1.readFile)(fullPath)).digest("hex");
@@ -154,7 +154,11 @@ class LocalFileStore {
154
154
  return fullPath;
155
155
  }
156
156
  async list(relativePath = ".", options = {}) {
157
- return (await this.listWithWarnings(relativePath, options)).stats;
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));
158
162
  }
159
163
  async listWithWarnings(relativePath = ".", options = {}) {
160
164
  const base = this.resolvePath(relativePath);
@@ -437,7 +441,7 @@ class LocalFileStore {
437
441
  entries = await (0, promises_1.readdir)(dir, { withFileTypes: true });
438
442
  }
439
443
  catch (error) {
440
- if (dir !== scanRoot && recordScanWarning(warnings, toPortablePath(node_path_1.default.relative(storeRoot, dir)), error)) {
444
+ if (warnings && dir !== scanRoot && recordScanWarning(warnings, toPortablePath(node_path_1.default.relative(storeRoot, dir)), error)) {
441
445
  return;
442
446
  }
443
447
  throw error;
@@ -840,8 +844,9 @@ function defaultDirs(platform, env, home, authorSegment, appSegment, baseDir) {
840
844
  };
841
845
  }
842
846
  async function discoverSkillDirectories(root, options) {
847
+ const rootStore = new LocalFileStore(root);
843
848
  try {
844
- const info = await (0, promises_1.stat)(root);
849
+ const info = await (0, promises_1.stat)(rootStore.root);
845
850
  if (!info.isDirectory()) {
846
851
  return [];
847
852
  }
@@ -852,27 +857,20 @@ async function discoverSkillDirectories(root, options) {
852
857
  }
853
858
  throw error;
854
859
  }
860
+ const { stats } = await rootStore.listWithWarnings(".", {
861
+ recursive: options.recursive ?? false,
862
+ includeDirectories: true,
863
+ maxDepth: options.maxDepth,
864
+ ignore: [".git", "node_modules", "__pycache__"],
865
+ });
866
+ const dirs = [rootStore.root, ...stats.filter((item) => item.type === "directory").map((item) => item.fullPath)];
855
867
  const out = [];
856
- const maxDepth = options.recursive ? options.maxDepth ?? Number.POSITIVE_INFINITY : 1;
857
- await walkSkillDirectories(root, root, out, maxDepth);
858
- return out;
859
- }
860
- async function walkSkillDirectories(root, dir, out, maxDepth) {
861
- if (await fileExists(node_path_1.default.join(dir, "SKILL.md"))) {
862
- out.push(dir);
863
- }
864
- const relative = node_path_1.default.relative(root, dir);
865
- const depth = relative ? relative.split(node_path_1.default.sep).length : 0;
866
- if (depth >= maxDepth) {
867
- return;
868
- }
869
- const entries = await (0, promises_1.readdir)(dir, { withFileTypes: true });
870
- for (const entry of entries) {
871
- if (!entry.isDirectory() || ignoredDirectoryName(entry.name)) {
872
- continue;
868
+ for (const dir of dirs) {
869
+ if (await fileExists(node_path_1.default.join(dir, "SKILL.md"))) {
870
+ out.push(dir);
873
871
  }
874
- await walkSkillDirectories(root, node_path_1.default.join(dir, entry.name), out, maxDepth);
875
872
  }
873
+ return out;
876
874
  }
877
875
  async function fileExists(fullPath) {
878
876
  try {
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.withScanWarnings = withScanWarnings;
4
+ exports.recordScanWarning = recordScanWarning;
5
+ const maxScanWarnings = 20;
6
+ const ignorableScanErrorCodes = new Set(["ENOENT", "ENOTDIR", "EACCES", "EPERM", "ENOTCONN", "ELOOP", "EINVAL"]);
7
+ function withScanWarnings(value, warnings) {
8
+ const out = value;
9
+ if (warnings.length > 0) {
10
+ out.scan_warnings = warnings;
11
+ }
12
+ return out;
13
+ }
14
+ function recordScanWarning(warnings, relativePath, error) {
15
+ const scanError = error;
16
+ const code = typeof scanError?.code === "string" ? scanError.code : undefined;
17
+ if (!code || !ignorableScanErrorCodes.has(code)) {
18
+ return false;
19
+ }
20
+ if (warnings.length < maxScanWarnings) {
21
+ warnings.push({
22
+ path: relativePath || ".",
23
+ code,
24
+ message: typeof scanError.message === "string" ? scanError.message : code,
25
+ });
26
+ }
27
+ return true;
28
+ }
@@ -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.7";
4
+ exports.VERSION = "1.4.8";
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.7",
3
+ "version": "1.4.8",
4
4
  "description": "Production JavaScript SDK for the Managed Agent API",
5
5
  "license": "MIT",
6
6
  "repository": {