@agent-api/sdk 1.4.6 → 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 +18 -0
- package/dist/local/context.d.ts +3 -1
- package/dist/local/context.js +8 -1
- package/dist/local/core.d.ts +6 -1
- package/dist/local/core.js +30 -29
- package/dist/local/scan.d.ts +13 -0
- package/dist/local/scan.js +24 -0
- package/dist/local/tools.js +1 -0
- package/dist/version.d.ts +2 -2
- package/dist/version.js +1 -1
- package/dist-cjs/local/context.js +8 -1
- package/dist-cjs/local/core.js +30 -29
- package/dist-cjs/local/scan.js +28 -0
- package/dist-cjs/local/tools.js +1 -0
- package/dist-cjs/version.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
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
|
+
|
|
11
|
+
## 1.4.7
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- Added warning-aware low-level local workdir listing via `listWithWarnings()`.
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- Made local context packages use bounded recursive scans and expose `scan_warnings` for skipped child paths.
|
|
20
|
+
|
|
3
21
|
## 1.4.6
|
|
4
22
|
|
|
5
23
|
### Fixed
|
package/dist/local/context.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type LocalFileDeliver, type LocalGrepResponse, type LocalPathSensitivity, type LocalPathSensitivityInfo, type LocalSummary, type LocalWorkdir, type LocalWorkdirSnapshotFile } from "./core.js";
|
|
1
|
+
import { type LocalFileDeliver, type LocalGrepResponse, type LocalPathSensitivity, type LocalPathSensitivityInfo, type LocalScanWarning, type LocalSummary, type LocalWorkdir, type LocalWorkdirSnapshotFile } from "./core.js";
|
|
2
2
|
export interface LocalContextPackageParams {
|
|
3
3
|
path?: string;
|
|
4
4
|
include?: string[];
|
|
@@ -7,6 +7,7 @@ export interface LocalContextPackageParams {
|
|
|
7
7
|
maxFiles?: number;
|
|
8
8
|
maxBytes?: number;
|
|
9
9
|
maxBytesPerFile?: number;
|
|
10
|
+
maxDepth?: number;
|
|
10
11
|
previewBytes?: number;
|
|
11
12
|
includeContent?: boolean;
|
|
12
13
|
includeHashes?: boolean;
|
|
@@ -38,6 +39,7 @@ export interface LocalContextManifest {
|
|
|
38
39
|
included_bytes: number;
|
|
39
40
|
truncated: boolean;
|
|
40
41
|
files: LocalContextFile[];
|
|
42
|
+
scan_warnings?: LocalScanWarning[];
|
|
41
43
|
summary?: LocalSummary;
|
|
42
44
|
search?: LocalGrepResponse;
|
|
43
45
|
}
|
package/dist/local/context.js
CHANGED
|
@@ -6,13 +6,14 @@ 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 = optionalPositiveInt(params.maxDepth);
|
|
9
10
|
const previewBytes = positiveInt(params.previewBytes, maxBytesPerFile);
|
|
10
11
|
const includeContent = params.includeContent ?? true;
|
|
11
12
|
const includeHashes = params.includeHashes ?? true;
|
|
12
13
|
const includeSummary = params.includeSummary ?? true;
|
|
13
14
|
const includeSearch = Boolean(params.includeSearch && params.query?.trim());
|
|
14
15
|
const includeSecrets = params.includeSecrets ?? false;
|
|
15
|
-
const stats = await workdir.
|
|
16
|
+
const { stats, warnings } = await workdir.listWithWarnings(basePath, { recursive: true, maxDepth });
|
|
16
17
|
const fileStats = stats
|
|
17
18
|
.filter((item) => item.type === "file")
|
|
18
19
|
.filter((item) => matchesPathFilters(item.path, params.include, params.exclude))
|
|
@@ -75,6 +76,7 @@ export async function createLocalContextPackage(workdir, params = {}) {
|
|
|
75
76
|
? await workdir.summarize({
|
|
76
77
|
path: basePath,
|
|
77
78
|
maxFiles,
|
|
79
|
+
maxDepth,
|
|
78
80
|
previewBytes,
|
|
79
81
|
ignore: params.exclude,
|
|
80
82
|
})
|
|
@@ -99,6 +101,7 @@ export async function createLocalContextPackage(workdir, params = {}) {
|
|
|
99
101
|
included_bytes: includedBytes,
|
|
100
102
|
truncated,
|
|
101
103
|
files,
|
|
104
|
+
scan_warnings: warnings.length ? warnings : undefined,
|
|
102
105
|
summary,
|
|
103
106
|
search,
|
|
104
107
|
};
|
|
@@ -148,6 +151,10 @@ function positiveInt(value, fallback) {
|
|
|
148
151
|
const parsed = Number(value);
|
|
149
152
|
return Number.isFinite(parsed) && parsed > 0 ? Math.trunc(parsed) : fallback;
|
|
150
153
|
}
|
|
154
|
+
function optionalPositiveInt(value) {
|
|
155
|
+
const parsed = Number(value);
|
|
156
|
+
return Number.isFinite(parsed) && parsed > 0 ? Math.trunc(parsed) : undefined;
|
|
157
|
+
}
|
|
151
158
|
async function sha256File(workdir, relativePath) {
|
|
152
159
|
const fullPath = workdir.files.resolvePath(relativePath);
|
|
153
160
|
return createHash("sha256").update(await readFile(fullPath)).digest("hex");
|
package/dist/local/core.d.ts
CHANGED
|
@@ -68,6 +68,10 @@ export interface LocalEntryList {
|
|
|
68
68
|
entries: LocalEntry[];
|
|
69
69
|
scan_warnings?: LocalScanWarning[];
|
|
70
70
|
}
|
|
71
|
+
export interface LocalFileStatList {
|
|
72
|
+
stats: LocalFileStat[];
|
|
73
|
+
warnings: LocalScanWarning[];
|
|
74
|
+
}
|
|
71
75
|
export interface LocalScanWarning {
|
|
72
76
|
path: string;
|
|
73
77
|
code?: string;
|
|
@@ -286,6 +290,7 @@ export declare class LocalFileStore {
|
|
|
286
290
|
stat(relativePath?: string): Promise<LocalFileStat>;
|
|
287
291
|
mkdir(relativePath?: string): Promise<string>;
|
|
288
292
|
list(relativePath?: string, options?: LocalListOptions): Promise<LocalFileStat[]>;
|
|
293
|
+
listWithWarnings(relativePath?: string, options?: LocalListOptions): Promise<LocalFileStatList>;
|
|
289
294
|
listEntries(relativePath?: string, options?: LocalListOptions): Promise<LocalEntryList>;
|
|
290
295
|
searchEntries(params: LocalSearchEntriesParams): Promise<LocalEntryList>;
|
|
291
296
|
readText(relativePath: string): Promise<string>;
|
|
@@ -317,7 +322,6 @@ export declare class LocalFileStore {
|
|
|
317
322
|
grep(params: LocalGrepParams): Promise<LocalGrepResponse>;
|
|
318
323
|
private grepCandidates;
|
|
319
324
|
summarize(params?: LocalSummarizeParams): Promise<LocalSummary>;
|
|
320
|
-
private listWithWarnings;
|
|
321
325
|
private walk;
|
|
322
326
|
}
|
|
323
327
|
export declare class LocalConfigStore {
|
|
@@ -348,6 +352,7 @@ export declare class LocalWorkdir {
|
|
|
348
352
|
child(relativePath: string, options?: LocalWorkdirOptions): LocalWorkdir;
|
|
349
353
|
resolvePath(relativePath?: string): string;
|
|
350
354
|
list(relativePath?: string, options?: LocalListOptions): Promise<LocalFileStat[]>;
|
|
355
|
+
listWithWarnings(relativePath?: string, options?: LocalListOptions): Promise<LocalFileStatList>;
|
|
351
356
|
listEntries(relativePath?: string, options?: LocalListOptions): Promise<LocalEntryList>;
|
|
352
357
|
searchEntries(params: LocalSearchEntriesParams): Promise<LocalEntryList>;
|
|
353
358
|
readFile(relativePath: string, params: LocalReadFileRawParams): Promise<LocalFileRaw>;
|
package/dist/local/core.js
CHANGED
|
@@ -139,7 +139,19 @@ export class LocalFileStore {
|
|
|
139
139
|
return fullPath;
|
|
140
140
|
}
|
|
141
141
|
async list(relativePath = ".", options = {}) {
|
|
142
|
-
|
|
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));
|
|
147
|
+
}
|
|
148
|
+
async listWithWarnings(relativePath = ".", options = {}) {
|
|
149
|
+
const base = this.resolvePath(relativePath);
|
|
150
|
+
const maxDepth = options.recursive ? options.maxDepth ?? Number.POSITIVE_INFINITY : 1;
|
|
151
|
+
const out = [];
|
|
152
|
+
const warnings = [];
|
|
153
|
+
await this.walk(this.root, base, base, out, maxDepth, options, warnings);
|
|
154
|
+
return { stats: out.sort((a, b) => a.path.localeCompare(b.path)), warnings };
|
|
143
155
|
}
|
|
144
156
|
async listEntries(relativePath = ".", options = {}) {
|
|
145
157
|
const { stats, warnings } = await this.listWithWarnings(relativePath, { ...options, includeDirectories: options.includeDirectories ?? true });
|
|
@@ -408,21 +420,13 @@ export class LocalFileStore {
|
|
|
408
420
|
scan_truncated: scanTruncated,
|
|
409
421
|
}, warnings);
|
|
410
422
|
}
|
|
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
423
|
async walk(storeRoot, scanRoot, dir, out, maxDepth, options, warnings) {
|
|
420
424
|
let entries;
|
|
421
425
|
try {
|
|
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;
|
|
@@ -562,6 +566,9 @@ export class LocalWorkdir {
|
|
|
562
566
|
async list(relativePath = ".", options = {}) {
|
|
563
567
|
return await this.files.list(relativePath, this.scopedListOptions(options));
|
|
564
568
|
}
|
|
569
|
+
async listWithWarnings(relativePath = ".", options = {}) {
|
|
570
|
+
return await this.files.listWithWarnings(relativePath, this.scopedListOptions(options));
|
|
571
|
+
}
|
|
565
572
|
async listEntries(relativePath = ".", options = {}) {
|
|
566
573
|
return await this.files.listEntries(relativePath, this.scopedListOptions(options));
|
|
567
574
|
}
|
|
@@ -817,8 +824,9 @@ function defaultDirs(platform, env, home, authorSegment, appSegment, baseDir) {
|
|
|
817
824
|
};
|
|
818
825
|
}
|
|
819
826
|
async function discoverSkillDirectories(root, options) {
|
|
827
|
+
const rootStore = new LocalFileStore(root);
|
|
820
828
|
try {
|
|
821
|
-
const info = await stat(root);
|
|
829
|
+
const info = await stat(rootStore.root);
|
|
822
830
|
if (!info.isDirectory()) {
|
|
823
831
|
return [];
|
|
824
832
|
}
|
|
@@ -829,27 +837,20 @@ async function discoverSkillDirectories(root, options) {
|
|
|
829
837
|
}
|
|
830
838
|
throw error;
|
|
831
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)];
|
|
832
847
|
const out = [];
|
|
833
|
-
const
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
}
|
|
837
|
-
async function walkSkillDirectories(root, dir, out, maxDepth) {
|
|
838
|
-
if (await fileExists(path.join(dir, "SKILL.md"))) {
|
|
839
|
-
out.push(dir);
|
|
840
|
-
}
|
|
841
|
-
const relative = path.relative(root, dir);
|
|
842
|
-
const depth = relative ? relative.split(path.sep).length : 0;
|
|
843
|
-
if (depth >= maxDepth) {
|
|
844
|
-
return;
|
|
845
|
-
}
|
|
846
|
-
const entries = await readdir(dir, { withFileTypes: true });
|
|
847
|
-
for (const entry of entries) {
|
|
848
|
-
if (!entry.isDirectory() || ignoredDirectoryName(entry.name)) {
|
|
849
|
-
continue;
|
|
848
|
+
for (const dir of dirs) {
|
|
849
|
+
if (await fileExists(path.join(dir, "SKILL.md"))) {
|
|
850
|
+
out.push(dir);
|
|
850
851
|
}
|
|
851
|
-
await walkSkillDirectories(root, path.join(dir, entry.name), out, maxDepth);
|
|
852
852
|
}
|
|
853
|
+
return out;
|
|
853
854
|
}
|
|
854
855
|
async function fileExists(fullPath) {
|
|
855
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/local/tools.js
CHANGED
|
@@ -255,6 +255,7 @@ function contextPackageArgs(args) {
|
|
|
255
255
|
maxFiles: optionalNumberArg(args, "maxFiles", "max_files"),
|
|
256
256
|
maxBytes: optionalNumberArg(args, "maxBytes", "max_bytes"),
|
|
257
257
|
maxBytesPerFile: optionalNumberArg(args, "maxBytesPerFile", "max_bytes_per_file"),
|
|
258
|
+
maxDepth: optionalNumberArg(args, "maxDepth", "max_depth"),
|
|
258
259
|
includeContent: optionalBooleanArg(args, "includeContent", "include_content"),
|
|
259
260
|
includeSummary: optionalBooleanArg(args, "includeSummary", "include_summary"),
|
|
260
261
|
includeSearch: optionalBooleanArg(args, "includeSearch", "include_search"),
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "1.4.
|
|
2
|
-
export declare const USER_AGENT = "@agent-api/sdk/1.4.
|
|
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.
|
|
1
|
+
export const VERSION = "1.4.8";
|
|
2
2
|
export const USER_AGENT = `@agent-api/sdk/${VERSION}`;
|
|
@@ -10,13 +10,14 @@ 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 = optionalPositiveInt(params.maxDepth);
|
|
13
14
|
const previewBytes = positiveInt(params.previewBytes, maxBytesPerFile);
|
|
14
15
|
const includeContent = params.includeContent ?? true;
|
|
15
16
|
const includeHashes = params.includeHashes ?? true;
|
|
16
17
|
const includeSummary = params.includeSummary ?? true;
|
|
17
18
|
const includeSearch = Boolean(params.includeSearch && params.query?.trim());
|
|
18
19
|
const includeSecrets = params.includeSecrets ?? false;
|
|
19
|
-
const stats = await workdir.
|
|
20
|
+
const { stats, warnings } = await workdir.listWithWarnings(basePath, { recursive: true, maxDepth });
|
|
20
21
|
const fileStats = stats
|
|
21
22
|
.filter((item) => item.type === "file")
|
|
22
23
|
.filter((item) => matchesPathFilters(item.path, params.include, params.exclude))
|
|
@@ -79,6 +80,7 @@ async function createLocalContextPackage(workdir, params = {}) {
|
|
|
79
80
|
? await workdir.summarize({
|
|
80
81
|
path: basePath,
|
|
81
82
|
maxFiles,
|
|
83
|
+
maxDepth,
|
|
82
84
|
previewBytes,
|
|
83
85
|
ignore: params.exclude,
|
|
84
86
|
})
|
|
@@ -103,6 +105,7 @@ async function createLocalContextPackage(workdir, params = {}) {
|
|
|
103
105
|
included_bytes: includedBytes,
|
|
104
106
|
truncated,
|
|
105
107
|
files,
|
|
108
|
+
scan_warnings: warnings.length ? warnings : undefined,
|
|
106
109
|
summary,
|
|
107
110
|
search,
|
|
108
111
|
};
|
|
@@ -152,6 +155,10 @@ function positiveInt(value, fallback) {
|
|
|
152
155
|
const parsed = Number(value);
|
|
153
156
|
return Number.isFinite(parsed) && parsed > 0 ? Math.trunc(parsed) : fallback;
|
|
154
157
|
}
|
|
158
|
+
function optionalPositiveInt(value) {
|
|
159
|
+
const parsed = Number(value);
|
|
160
|
+
return Number.isFinite(parsed) && parsed > 0 ? Math.trunc(parsed) : undefined;
|
|
161
|
+
}
|
|
155
162
|
async function sha256File(workdir, relativePath) {
|
|
156
163
|
const fullPath = workdir.files.resolvePath(relativePath);
|
|
157
164
|
return (0, node_crypto_1.createHash)("sha256").update(await (0, promises_1.readFile)(fullPath)).digest("hex");
|
package/dist-cjs/local/core.js
CHANGED
|
@@ -154,7 +154,19 @@ class LocalFileStore {
|
|
|
154
154
|
return fullPath;
|
|
155
155
|
}
|
|
156
156
|
async list(relativePath = ".", options = {}) {
|
|
157
|
-
|
|
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));
|
|
162
|
+
}
|
|
163
|
+
async listWithWarnings(relativePath = ".", options = {}) {
|
|
164
|
+
const base = this.resolvePath(relativePath);
|
|
165
|
+
const maxDepth = options.recursive ? options.maxDepth ?? Number.POSITIVE_INFINITY : 1;
|
|
166
|
+
const out = [];
|
|
167
|
+
const warnings = [];
|
|
168
|
+
await this.walk(this.root, base, base, out, maxDepth, options, warnings);
|
|
169
|
+
return { stats: out.sort((a, b) => a.path.localeCompare(b.path)), warnings };
|
|
158
170
|
}
|
|
159
171
|
async listEntries(relativePath = ".", options = {}) {
|
|
160
172
|
const { stats, warnings } = await this.listWithWarnings(relativePath, { ...options, includeDirectories: options.includeDirectories ?? true });
|
|
@@ -423,21 +435,13 @@ class LocalFileStore {
|
|
|
423
435
|
scan_truncated: scanTruncated,
|
|
424
436
|
}, warnings);
|
|
425
437
|
}
|
|
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
438
|
async walk(storeRoot, scanRoot, dir, out, maxDepth, options, warnings) {
|
|
435
439
|
let entries;
|
|
436
440
|
try {
|
|
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;
|
|
@@ -580,6 +584,9 @@ class LocalWorkdir {
|
|
|
580
584
|
async list(relativePath = ".", options = {}) {
|
|
581
585
|
return await this.files.list(relativePath, this.scopedListOptions(options));
|
|
582
586
|
}
|
|
587
|
+
async listWithWarnings(relativePath = ".", options = {}) {
|
|
588
|
+
return await this.files.listWithWarnings(relativePath, this.scopedListOptions(options));
|
|
589
|
+
}
|
|
583
590
|
async listEntries(relativePath = ".", options = {}) {
|
|
584
591
|
return await this.files.listEntries(relativePath, this.scopedListOptions(options));
|
|
585
592
|
}
|
|
@@ -837,8 +844,9 @@ function defaultDirs(platform, env, home, authorSegment, appSegment, baseDir) {
|
|
|
837
844
|
};
|
|
838
845
|
}
|
|
839
846
|
async function discoverSkillDirectories(root, options) {
|
|
847
|
+
const rootStore = new LocalFileStore(root);
|
|
840
848
|
try {
|
|
841
|
-
const info = await (0, promises_1.stat)(root);
|
|
849
|
+
const info = await (0, promises_1.stat)(rootStore.root);
|
|
842
850
|
if (!info.isDirectory()) {
|
|
843
851
|
return [];
|
|
844
852
|
}
|
|
@@ -849,27 +857,20 @@ async function discoverSkillDirectories(root, options) {
|
|
|
849
857
|
}
|
|
850
858
|
throw error;
|
|
851
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)];
|
|
852
867
|
const out = [];
|
|
853
|
-
const
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
}
|
|
857
|
-
async function walkSkillDirectories(root, dir, out, maxDepth) {
|
|
858
|
-
if (await fileExists(node_path_1.default.join(dir, "SKILL.md"))) {
|
|
859
|
-
out.push(dir);
|
|
860
|
-
}
|
|
861
|
-
const relative = node_path_1.default.relative(root, dir);
|
|
862
|
-
const depth = relative ? relative.split(node_path_1.default.sep).length : 0;
|
|
863
|
-
if (depth >= maxDepth) {
|
|
864
|
-
return;
|
|
865
|
-
}
|
|
866
|
-
const entries = await (0, promises_1.readdir)(dir, { withFileTypes: true });
|
|
867
|
-
for (const entry of entries) {
|
|
868
|
-
if (!entry.isDirectory() || ignoredDirectoryName(entry.name)) {
|
|
869
|
-
continue;
|
|
868
|
+
for (const dir of dirs) {
|
|
869
|
+
if (await fileExists(node_path_1.default.join(dir, "SKILL.md"))) {
|
|
870
|
+
out.push(dir);
|
|
870
871
|
}
|
|
871
|
-
await walkSkillDirectories(root, node_path_1.default.join(dir, entry.name), out, maxDepth);
|
|
872
872
|
}
|
|
873
|
+
return out;
|
|
873
874
|
}
|
|
874
875
|
async function fileExists(fullPath) {
|
|
875
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
|
+
}
|
package/dist-cjs/local/tools.js
CHANGED
|
@@ -262,6 +262,7 @@ function contextPackageArgs(args) {
|
|
|
262
262
|
maxFiles: optionalNumberArg(args, "maxFiles", "max_files"),
|
|
263
263
|
maxBytes: optionalNumberArg(args, "maxBytes", "max_bytes"),
|
|
264
264
|
maxBytesPerFile: optionalNumberArg(args, "maxBytesPerFile", "max_bytes_per_file"),
|
|
265
|
+
maxDepth: optionalNumberArg(args, "maxDepth", "max_depth"),
|
|
265
266
|
includeContent: optionalBooleanArg(args, "includeContent", "include_content"),
|
|
266
267
|
includeSummary: optionalBooleanArg(args, "includeSummary", "include_summary"),
|
|
267
268
|
includeSearch: optionalBooleanArg(args, "includeSearch", "include_search"),
|
package/dist-cjs/version.js
CHANGED