@aigne/afs-fs 1.11.0-beta.2

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/index.cjs ADDED
@@ -0,0 +1,360 @@
1
+ const require_rolldown_runtime = require('./_virtual/rolldown_runtime.cjs');
2
+ const require_ripgrep = require('./utils/ripgrep.cjs');
3
+ let node_fs_promises = require("node:fs/promises");
4
+ let node_path = require("node:path");
5
+ let _aigne_afs_utils_zod = require("@aigne/afs/utils/zod");
6
+ let ignore = require("ignore");
7
+ ignore = require_rolldown_runtime.__toESM(ignore);
8
+ let minimatch = require("minimatch");
9
+ let zod = require("zod");
10
+
11
+ //#region src/index.ts
12
+ const LIST_MAX_LIMIT = 1e3;
13
+ const afsFSOptionsSchema = (0, _aigne_afs_utils_zod.camelize)(zod.z.object({
14
+ name: (0, _aigne_afs_utils_zod.optionalize)(zod.z.string()),
15
+ localPath: zod.z.string().describe("The path to the local directory to mount"),
16
+ description: (0, _aigne_afs_utils_zod.optionalize)(zod.z.string().describe("A description of the mounted directory")),
17
+ ignore: (0, _aigne_afs_utils_zod.optionalize)(zod.z.array(zod.z.string())),
18
+ accessMode: (0, _aigne_afs_utils_zod.optionalize)(zod.z.enum(["readonly", "readwrite"]).describe("Access mode for this module")),
19
+ agentSkills: (0, _aigne_afs_utils_zod.optionalize)(zod.z.boolean().describe("Enable automatic agent skill scanning for this module"))
20
+ }));
21
+ var AFSFS = class AFSFS {
22
+ static schema() {
23
+ return afsFSOptionsSchema;
24
+ }
25
+ static async load({ filepath, parsed }) {
26
+ return new AFSFS({
27
+ ...await AFSFS.schema().parseAsync(parsed),
28
+ cwd: (0, node_path.dirname)(filepath)
29
+ });
30
+ }
31
+ constructor(options) {
32
+ this.options = options;
33
+ (0, _aigne_afs_utils_zod.zodParse)(afsFSOptionsSchema, options);
34
+ let localPath;
35
+ if (options.localPath === ".") localPath = process.cwd();
36
+ else {
37
+ localPath = options.localPath.replaceAll("${CWD}", process.cwd());
38
+ if (localPath.startsWith("~/")) localPath = (0, node_path.join)(process.env.HOME || "", localPath.slice(2));
39
+ if (!(0, node_path.isAbsolute)(localPath)) localPath = (0, node_path.join)(options.cwd || process.cwd(), localPath);
40
+ }
41
+ this.name = options.name || (0, node_path.basename)(localPath) || "fs";
42
+ this.description = options.description;
43
+ this.agentSkills = options.agentSkills;
44
+ this.accessMode = options.accessMode ?? (options.agentSkills ? "readonly" : "readwrite");
45
+ this.options.localPath = localPath;
46
+ }
47
+ name;
48
+ description;
49
+ accessMode;
50
+ agentSkills;
51
+ get localPathExists() {
52
+ return (0, node_fs_promises.stat)(this.options.localPath).then(() => true).catch(() => false);
53
+ }
54
+ /**
55
+ * Detect MIME type based on file extension
56
+ */
57
+ getMimeType(filePath) {
58
+ return {
59
+ png: "image/png",
60
+ jpg: "image/jpeg",
61
+ jpeg: "image/jpeg",
62
+ gif: "image/gif",
63
+ bmp: "image/bmp",
64
+ webp: "image/webp",
65
+ svg: "image/svg+xml",
66
+ ico: "image/x-icon",
67
+ pdf: "application/pdf",
68
+ txt: "text/plain",
69
+ md: "text/markdown",
70
+ js: "text/javascript",
71
+ ts: "text/typescript",
72
+ json: "application/json",
73
+ html: "text/html",
74
+ css: "text/css",
75
+ xml: "text/xml"
76
+ }[(0, node_path.basename)(filePath).split(".").pop()?.toLowerCase() || ""] || "application/octet-stream";
77
+ }
78
+ /**
79
+ * Check if file is likely binary based on extension
80
+ */
81
+ isBinaryFile(filePath) {
82
+ const ext = (0, node_path.basename)(filePath).split(".").pop()?.toLowerCase();
83
+ return [
84
+ "png",
85
+ "jpg",
86
+ "jpeg",
87
+ "gif",
88
+ "bmp",
89
+ "webp",
90
+ "ico",
91
+ "pdf",
92
+ "zip",
93
+ "tar",
94
+ "gz",
95
+ "exe",
96
+ "dll",
97
+ "so",
98
+ "dylib",
99
+ "wasm"
100
+ ].includes(ext || "");
101
+ }
102
+ async symlinkToPhysical(path) {
103
+ if (await this.localPathExists) await (0, node_fs_promises.symlink)(this.options.localPath, path);
104
+ }
105
+ async list(path, options) {
106
+ path = (0, node_path.join)("/", path);
107
+ const limit = Math.min(options?.limit || LIST_MAX_LIMIT, LIST_MAX_LIMIT);
108
+ const maxChildren = typeof options?.maxChildren === "number" ? options.maxChildren : Number.MAX_SAFE_INTEGER;
109
+ const maxDepth = options?.maxDepth ?? 1;
110
+ const disableGitignore = options?.disableGitignore ?? false;
111
+ const pattern = options?.pattern;
112
+ const basePath = (0, node_path.join)(this.options.localPath, path);
113
+ const mountRoot = this.options.localPath;
114
+ if (typeof maxChildren === "number" && maxChildren <= 0) throw new Error(`Invalid maxChildren: ${maxChildren}. Must be positive.`);
115
+ const entries = [];
116
+ const queue = [];
117
+ queue.push({
118
+ fullPath: basePath,
119
+ relativePath: path || "/",
120
+ depth: 0,
121
+ gitignored: false
122
+ });
123
+ while (true) {
124
+ const item = queue.shift();
125
+ if (!item) break;
126
+ const { fullPath, relativePath, depth, gitignored } = item;
127
+ const stats = await (0, node_fs_promises.stat)(fullPath);
128
+ const isDirectory = stats.isDirectory();
129
+ let childItemsWithStatus;
130
+ if (isDirectory && !gitignored) {
131
+ const items = (await (0, node_fs_promises.readdir)(fullPath)).sort();
132
+ let ig = null;
133
+ let ignoreBase = mountRoot;
134
+ if (!disableGitignore) {
135
+ const result = await this.loadIgnoreRules(fullPath, mountRoot);
136
+ ig = result?.ig || null;
137
+ ignoreBase = result?.ignoreBase || mountRoot;
138
+ }
139
+ childItemsWithStatus = items.map((childName) => {
140
+ if (!ig) return {
141
+ name: childName,
142
+ gitignored: false
143
+ };
144
+ const itemFullPath = (0, node_path.join)(fullPath, childName);
145
+ const itemRelativePath = (0, node_path.relative)(ignoreBase, itemFullPath);
146
+ return {
147
+ name: childName,
148
+ gitignored: ig.ignores(itemRelativePath) || ig.ignores(`${itemRelativePath}/`)
149
+ };
150
+ });
151
+ }
152
+ const metadata = {
153
+ childrenCount: childItemsWithStatus?.length,
154
+ type: isDirectory ? "directory" : "file",
155
+ size: stats.size,
156
+ gitignored: gitignored || void 0
157
+ };
158
+ if (!isDirectory) metadata.mimeType = this.getMimeType(fullPath);
159
+ const entry = {
160
+ id: relativePath,
161
+ path: relativePath,
162
+ createdAt: stats.birthtime,
163
+ updatedAt: stats.mtime,
164
+ metadata
165
+ };
166
+ if (!pattern || (0, minimatch.minimatch)(relativePath, pattern, { matchBase: true })) entries.push(entry);
167
+ if (entries.length >= limit) {
168
+ if (isDirectory && entry.metadata) entry.metadata.childrenTruncated = true;
169
+ break;
170
+ }
171
+ if (isDirectory && depth < maxDepth && childItemsWithStatus) {
172
+ const itemsToProcess = childItemsWithStatus.length > maxChildren ? childItemsWithStatus.slice(0, maxChildren) : childItemsWithStatus;
173
+ if (itemsToProcess.length < childItemsWithStatus.length && entry.metadata) entry.metadata.childrenTruncated = true;
174
+ for (const child of itemsToProcess) queue.push({
175
+ fullPath: (0, node_path.join)(fullPath, child.name),
176
+ relativePath: (0, node_path.join)(relativePath, child.name),
177
+ depth: depth + 1,
178
+ gitignored: child.gitignored
179
+ });
180
+ }
181
+ }
182
+ return { data: entries };
183
+ }
184
+ async read(path, _options) {
185
+ try {
186
+ const fullPath = (0, node_path.join)(this.options.localPath, path);
187
+ const stats = await (0, node_fs_promises.stat)(fullPath);
188
+ let content;
189
+ const metadata = {
190
+ type: stats.isDirectory() ? "directory" : "file",
191
+ size: stats.size
192
+ };
193
+ if (stats.isFile()) {
194
+ const mimeType = this.getMimeType(fullPath);
195
+ const isBinary = this.isBinaryFile(fullPath);
196
+ metadata.mimeType = mimeType;
197
+ if (isBinary) {
198
+ content = (await (0, node_fs_promises.readFile)(fullPath)).toString("base64");
199
+ metadata.contentType = "base64";
200
+ } else content = await (0, node_fs_promises.readFile)(fullPath, "utf8");
201
+ }
202
+ return { data: {
203
+ id: path,
204
+ path,
205
+ createdAt: stats.birthtime,
206
+ updatedAt: stats.mtime,
207
+ content,
208
+ metadata
209
+ } };
210
+ } catch (error) {
211
+ return {
212
+ data: void 0,
213
+ message: error.message
214
+ };
215
+ }
216
+ }
217
+ async write(path, entry, options) {
218
+ const fullPath = (0, node_path.join)(this.options.localPath, path);
219
+ const append = options?.append ?? false;
220
+ await (0, node_fs_promises.mkdir)((0, node_path.dirname)(fullPath), { recursive: true });
221
+ if (entry.content !== void 0) {
222
+ let contentToWrite;
223
+ if (typeof entry.content === "string") contentToWrite = entry.content;
224
+ else contentToWrite = JSON.stringify(entry.content, null, 2);
225
+ await (0, node_fs_promises.writeFile)(fullPath, contentToWrite, {
226
+ encoding: "utf8",
227
+ flag: append ? "a" : "w"
228
+ });
229
+ }
230
+ const stats = await (0, node_fs_promises.stat)(fullPath);
231
+ return { data: {
232
+ id: path,
233
+ path,
234
+ createdAt: stats.birthtime,
235
+ updatedAt: stats.mtime,
236
+ content: entry.content,
237
+ summary: entry.summary,
238
+ metadata: {
239
+ ...entry.metadata,
240
+ type: stats.isDirectory() ? "directory" : "file",
241
+ size: stats.size
242
+ },
243
+ userId: entry.userId,
244
+ sessionId: entry.sessionId,
245
+ linkTo: entry.linkTo
246
+ } };
247
+ }
248
+ async delete(path, options) {
249
+ const fullPath = (0, node_path.join)(this.options.localPath, path);
250
+ const recursive = options?.recursive ?? false;
251
+ if ((await (0, node_fs_promises.stat)(fullPath)).isDirectory() && !recursive) throw new Error(`Cannot delete directory '${path}' without recursive option. Set recursive: true to delete directories.`);
252
+ await (0, node_fs_promises.rm)(fullPath, {
253
+ recursive,
254
+ force: true
255
+ });
256
+ return { message: `Successfully deleted: ${path}` };
257
+ }
258
+ async rename(oldPath, newPath, options) {
259
+ const oldFullPath = (0, node_path.join)(this.options.localPath, oldPath);
260
+ const newFullPath = (0, node_path.join)(this.options.localPath, newPath);
261
+ const overwrite = options?.overwrite ?? false;
262
+ await (0, node_fs_promises.stat)(oldFullPath);
263
+ try {
264
+ await (0, node_fs_promises.stat)(newFullPath);
265
+ if (!overwrite) throw new Error(`Destination '${newPath}' already exists. Set overwrite: true to replace it.`);
266
+ } catch (error) {
267
+ if (error.code !== "ENOENT") throw error;
268
+ }
269
+ await (0, node_fs_promises.mkdir)((0, node_path.dirname)(newFullPath), { recursive: true });
270
+ await (0, node_fs_promises.rename)(oldFullPath, newFullPath);
271
+ return { message: `Successfully renamed '${oldPath}' to '${newPath}'` };
272
+ }
273
+ async search(path, query, options) {
274
+ const limit = Math.min(options?.limit || LIST_MAX_LIMIT, LIST_MAX_LIMIT);
275
+ const basePath = (0, node_path.join)(this.options.localPath, path);
276
+ const matches = await require_ripgrep.searchWithRipgrep(basePath, query, options);
277
+ const entries = [];
278
+ const processedFiles = /* @__PURE__ */ new Set();
279
+ let hasMoreFiles = false;
280
+ for (const match of matches) if (match.type === "match" && match.data.path) {
281
+ const absolutePath = match.data.path.text;
282
+ const itemRelativePath = (0, node_path.join)(path, (0, node_path.relative)(basePath, absolutePath));
283
+ if (processedFiles.has(itemRelativePath)) continue;
284
+ processedFiles.add(itemRelativePath);
285
+ const stats = await (0, node_fs_promises.stat)(absolutePath);
286
+ const entry = {
287
+ id: itemRelativePath,
288
+ path: itemRelativePath,
289
+ createdAt: stats.birthtime,
290
+ updatedAt: stats.mtime,
291
+ summary: match.data.lines?.text,
292
+ metadata: {
293
+ type: "file",
294
+ size: stats.size
295
+ }
296
+ };
297
+ entries.push(entry);
298
+ if (entries.length >= limit) {
299
+ hasMoreFiles = true;
300
+ break;
301
+ }
302
+ }
303
+ return {
304
+ data: entries,
305
+ message: hasMoreFiles ? `Results truncated to limit ${limit}` : void 0
306
+ };
307
+ }
308
+ /**
309
+ * Load gitignore rules from mountRoot down to checkPath.
310
+ * Accumulates rules from parent to child for proper inheritance.
311
+ * Stops at .git boundaries (submodules are independent repos).
312
+ * @param checkPath - The directory whose files we're checking
313
+ * @param mountRoot - The mounted local filesystem root (stop point for walking up)
314
+ * @returns An object with ignore instance and the base path for matching
315
+ */
316
+ async loadIgnoreRules(checkPath, mountRoot) {
317
+ const ig = (0, ignore.default)();
318
+ const dirsToCheck = [];
319
+ let currentPath = checkPath;
320
+ let gitBoundary = null;
321
+ while (true) {
322
+ dirsToCheck.unshift(currentPath);
323
+ if (gitBoundary === null) try {
324
+ await (0, node_fs_promises.stat)((0, node_path.join)(currentPath, ".git"));
325
+ gitBoundary = currentPath;
326
+ } catch {}
327
+ if (currentPath === mountRoot) break;
328
+ const parentPath = (0, node_path.dirname)(currentPath);
329
+ if (!currentPath.startsWith(mountRoot) || parentPath === currentPath) break;
330
+ currentPath = parentPath;
331
+ }
332
+ const effectiveStart = gitBoundary || mountRoot;
333
+ const filteredDirs = dirsToCheck.filter((dir) => dir >= effectiveStart);
334
+ for (const dirPath of filteredDirs) try {
335
+ const gitignoreContent = await (0, node_fs_promises.readFile)((0, node_path.join)(dirPath, ".gitignore"), "utf8");
336
+ const effectiveBase = gitBoundary && dirPath >= gitBoundary ? gitBoundary : mountRoot;
337
+ if (dirPath !== effectiveBase) {
338
+ const prefix = (0, node_path.relative)(effectiveBase, dirPath);
339
+ const prefixedLines = gitignoreContent.split("\n").map((line) => {
340
+ const trimmed = line.trim();
341
+ if (!trimmed || trimmed.startsWith("#")) return line;
342
+ if (trimmed.startsWith("!")) return line;
343
+ if (trimmed.startsWith("/")) return `/${prefix}${trimmed}`;
344
+ if (trimmed.includes("/")) return `${prefix}/${trimmed}`;
345
+ return `${prefix}/**/${trimmed}`;
346
+ });
347
+ ig.add(prefixedLines.join("\n"));
348
+ } else ig.add(gitignoreContent);
349
+ } catch {}
350
+ ig.add(".git");
351
+ ig.add(this.options.ignore || []);
352
+ return {
353
+ ig,
354
+ ignoreBase: effectiveStart
355
+ };
356
+ }
357
+ };
358
+
359
+ //#endregion
360
+ exports.AFSFS = AFSFS;
@@ -0,0 +1,98 @@
1
+ import { AFSAccessMode, AFSDeleteOptions, AFSDeleteResult, AFSListOptions, AFSListResult, AFSModule, AFSModuleLoadParams, AFSReadOptions, AFSReadResult, AFSRenameOptions, AFSSearchOptions, AFSSearchResult, AFSWriteEntryPayload, AFSWriteOptions, AFSWriteResult } from "@aigne/afs";
2
+ import { z } from "zod";
3
+
4
+ //#region src/index.d.ts
5
+ interface AFSFSOptions {
6
+ name?: string;
7
+ localPath: string;
8
+ description?: string;
9
+ ignore?: string[];
10
+ /**
11
+ * Access mode for this module.
12
+ * - "readonly": Only read operations are allowed
13
+ * - "readwrite": All operations are allowed (default, unless agentSkills is enabled)
14
+ * @default "readwrite" (or "readonly" when agentSkills is true)
15
+ */
16
+ accessMode?: AFSAccessMode;
17
+ /**
18
+ * Enable automatic agent skill scanning for this module.
19
+ * When enabled, defaults accessMode to "readonly" if not explicitly set.
20
+ * @default false
21
+ */
22
+ agentSkills?: boolean;
23
+ }
24
+ declare class AFSFS implements AFSModule {
25
+ options: AFSFSOptions & {
26
+ cwd?: string;
27
+ };
28
+ static schema(): z.ZodEffects<z.ZodObject<{
29
+ name: z.ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
30
+ localPath: z.ZodString;
31
+ description: z.ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
32
+ ignore: z.ZodType<string[] | undefined, z.ZodTypeDef, string[] | undefined>;
33
+ accessMode: z.ZodType<"readonly" | "readwrite" | undefined, z.ZodTypeDef, "readonly" | "readwrite" | undefined>;
34
+ agentSkills: z.ZodType<boolean | undefined, z.ZodTypeDef, boolean | undefined>;
35
+ }, "strip", z.ZodTypeAny, {
36
+ localPath: string;
37
+ name?: string | undefined;
38
+ description?: string | undefined;
39
+ ignore?: string[] | undefined;
40
+ accessMode?: "readonly" | "readwrite" | undefined;
41
+ agentSkills?: boolean | undefined;
42
+ }, {
43
+ localPath: string;
44
+ name?: string | undefined;
45
+ description?: string | undefined;
46
+ ignore?: string[] | undefined;
47
+ accessMode?: "readonly" | "readwrite" | undefined;
48
+ agentSkills?: boolean | undefined;
49
+ }>, {
50
+ localPath: string;
51
+ name?: string | undefined;
52
+ description?: string | undefined;
53
+ ignore?: string[] | undefined;
54
+ accessMode?: "readonly" | "readwrite" | undefined;
55
+ agentSkills?: boolean | undefined;
56
+ }, any>;
57
+ static load({
58
+ filepath,
59
+ parsed
60
+ }: AFSModuleLoadParams): Promise<AFSFS>;
61
+ constructor(options: AFSFSOptions & {
62
+ cwd?: string;
63
+ });
64
+ name: string;
65
+ description?: string;
66
+ accessMode: AFSAccessMode;
67
+ agentSkills?: boolean;
68
+ private get localPathExists();
69
+ /**
70
+ * Detect MIME type based on file extension
71
+ */
72
+ private getMimeType;
73
+ /**
74
+ * Check if file is likely binary based on extension
75
+ */
76
+ private isBinaryFile;
77
+ symlinkToPhysical(path: string): Promise<void>;
78
+ list(path: string, options?: AFSListOptions): Promise<AFSListResult>;
79
+ read(path: string, _options?: AFSReadOptions): Promise<AFSReadResult>;
80
+ write(path: string, entry: AFSWriteEntryPayload, options?: AFSWriteOptions): Promise<AFSWriteResult>;
81
+ delete(path: string, options?: AFSDeleteOptions): Promise<AFSDeleteResult>;
82
+ rename(oldPath: string, newPath: string, options?: AFSRenameOptions): Promise<{
83
+ message?: string;
84
+ }>;
85
+ search(path: string, query: string, options?: AFSSearchOptions): Promise<AFSSearchResult>;
86
+ /**
87
+ * Load gitignore rules from mountRoot down to checkPath.
88
+ * Accumulates rules from parent to child for proper inheritance.
89
+ * Stops at .git boundaries (submodules are independent repos).
90
+ * @param checkPath - The directory whose files we're checking
91
+ * @param mountRoot - The mounted local filesystem root (stop point for walking up)
92
+ * @returns An object with ignore instance and the base path for matching
93
+ */
94
+ private loadIgnoreRules;
95
+ }
96
+ //#endregion
97
+ export { AFSFS, AFSFSOptions };
98
+ //# sourceMappingURL=index.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/index.ts"],"mappings":";;;;UA6BiB,YAAA;EAAA,IAAA;EAAA,SAAA;EAAA,WAAA;EAAA,MAAA;EAAA;AAmCjB;;;;;EAnCiB,UAAA,GAWF,aAAA;EAAA;AAwBf;;;;EAxBe,WAAA;AAAA;AAAA,cAwBF,KAAA,YAAiB,SAAA;EAAA,OAAA,EAWA,YAAA;IAAA,GAAA;EAAA;EAAA,OAAA,OAAA,GAVf,CAAA,CAAA,UAAA,CAAA,CAAA,CAAA,SAAA;IAAA,IAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAI2B,mBAAA,GAAmB,OAAA,CAAA,KAAA;EAAA,YAAA,OAAA,EAM/B,YAAA;IAAA,GAAA;EAAA;EAAA,IAAA;EAAA,WAAA;EAAA,UAAA,EA2BhB,aAAA;EAAA,WAAA;EAAA,YAAA,gBAAA;EAAA;;;EAAA,QAAA,WAAA;EAAA;;;EAAA,QAAA,YAAA;EAAA,kBAAA,IAAA,WAkE2B,OAAA;EAAA,KAAA,IAAA,UAAA,OAAA,GAMJ,cAAA,GAAiB,OAAA,CAAQ,aAAA;EAAA,KAAA,IAAA,UAAA,QAAA,GA8IxB,cAAA,GAAiB,OAAA,CAAQ,aAAA;EAAA,MAAA,IAAA,UAAA,KAAA,EAkDpD,oBAAA,EAAA,OAAA,GACG,eAAA,GACT,OAAA,CAAQ,cAAA;EAAA,OAAA,IAAA,UAAA,OAAA,GA6C0B,gBAAA,GAAmB,OAAA,CAAQ,eAAA;EAAA,OAAA,OAAA,UAAA,OAAA,UAAA,OAAA,GAoBpD,gBAAA,GACT,OAAA;IAAA,OAAA;EAAA;EAAA,OAAA,IAAA,UAAA,KAAA,UAAA,OAAA,GAiCiD,gBAAA,GAAmB,OAAA,CAAQ,eAAA;EAAA;;;;;;;;EAAA,QAAA,eAAA;AAAA"}
@@ -0,0 +1,98 @@
1
+ import { z } from "zod";
2
+ import { AFSAccessMode, AFSDeleteOptions, AFSDeleteResult, AFSListOptions, AFSListResult, AFSModule, AFSModuleLoadParams, AFSReadOptions, AFSReadResult, AFSRenameOptions, AFSSearchOptions, AFSSearchResult, AFSWriteEntryPayload, AFSWriteOptions, AFSWriteResult } from "@aigne/afs";
3
+
4
+ //#region src/index.d.ts
5
+ interface AFSFSOptions {
6
+ name?: string;
7
+ localPath: string;
8
+ description?: string;
9
+ ignore?: string[];
10
+ /**
11
+ * Access mode for this module.
12
+ * - "readonly": Only read operations are allowed
13
+ * - "readwrite": All operations are allowed (default, unless agentSkills is enabled)
14
+ * @default "readwrite" (or "readonly" when agentSkills is true)
15
+ */
16
+ accessMode?: AFSAccessMode;
17
+ /**
18
+ * Enable automatic agent skill scanning for this module.
19
+ * When enabled, defaults accessMode to "readonly" if not explicitly set.
20
+ * @default false
21
+ */
22
+ agentSkills?: boolean;
23
+ }
24
+ declare class AFSFS implements AFSModule {
25
+ options: AFSFSOptions & {
26
+ cwd?: string;
27
+ };
28
+ static schema(): z.ZodEffects<z.ZodObject<{
29
+ name: z.ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
30
+ localPath: z.ZodString;
31
+ description: z.ZodType<string | undefined, z.ZodTypeDef, string | undefined>;
32
+ ignore: z.ZodType<string[] | undefined, z.ZodTypeDef, string[] | undefined>;
33
+ accessMode: z.ZodType<"readonly" | "readwrite" | undefined, z.ZodTypeDef, "readonly" | "readwrite" | undefined>;
34
+ agentSkills: z.ZodType<boolean | undefined, z.ZodTypeDef, boolean | undefined>;
35
+ }, "strip", z.ZodTypeAny, {
36
+ localPath: string;
37
+ name?: string | undefined;
38
+ description?: string | undefined;
39
+ ignore?: string[] | undefined;
40
+ accessMode?: "readonly" | "readwrite" | undefined;
41
+ agentSkills?: boolean | undefined;
42
+ }, {
43
+ localPath: string;
44
+ name?: string | undefined;
45
+ description?: string | undefined;
46
+ ignore?: string[] | undefined;
47
+ accessMode?: "readonly" | "readwrite" | undefined;
48
+ agentSkills?: boolean | undefined;
49
+ }>, {
50
+ localPath: string;
51
+ name?: string | undefined;
52
+ description?: string | undefined;
53
+ ignore?: string[] | undefined;
54
+ accessMode?: "readonly" | "readwrite" | undefined;
55
+ agentSkills?: boolean | undefined;
56
+ }, any>;
57
+ static load({
58
+ filepath,
59
+ parsed
60
+ }: AFSModuleLoadParams): Promise<AFSFS>;
61
+ constructor(options: AFSFSOptions & {
62
+ cwd?: string;
63
+ });
64
+ name: string;
65
+ description?: string;
66
+ accessMode: AFSAccessMode;
67
+ agentSkills?: boolean;
68
+ private get localPathExists();
69
+ /**
70
+ * Detect MIME type based on file extension
71
+ */
72
+ private getMimeType;
73
+ /**
74
+ * Check if file is likely binary based on extension
75
+ */
76
+ private isBinaryFile;
77
+ symlinkToPhysical(path: string): Promise<void>;
78
+ list(path: string, options?: AFSListOptions): Promise<AFSListResult>;
79
+ read(path: string, _options?: AFSReadOptions): Promise<AFSReadResult>;
80
+ write(path: string, entry: AFSWriteEntryPayload, options?: AFSWriteOptions): Promise<AFSWriteResult>;
81
+ delete(path: string, options?: AFSDeleteOptions): Promise<AFSDeleteResult>;
82
+ rename(oldPath: string, newPath: string, options?: AFSRenameOptions): Promise<{
83
+ message?: string;
84
+ }>;
85
+ search(path: string, query: string, options?: AFSSearchOptions): Promise<AFSSearchResult>;
86
+ /**
87
+ * Load gitignore rules from mountRoot down to checkPath.
88
+ * Accumulates rules from parent to child for proper inheritance.
89
+ * Stops at .git boundaries (submodules are independent repos).
90
+ * @param checkPath - The directory whose files we're checking
91
+ * @param mountRoot - The mounted local filesystem root (stop point for walking up)
92
+ * @returns An object with ignore instance and the base path for matching
93
+ */
94
+ private loadIgnoreRules;
95
+ }
96
+ //#endregion
97
+ export { AFSFS, AFSFSOptions };
98
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":";;;;UA6BiB,YAAA;EAAA,IAAA;EAAA,SAAA;EAAA,WAAA;EAAA,MAAA;EAAA;AAmCjB;;;;;EAnCiB,UAAA,GAWF,aAAA;EAAA;AAwBf;;;;EAxBe,WAAA;AAAA;AAAA,cAwBF,KAAA,YAAiB,SAAA;EAAA,OAAA,EAWA,YAAA;IAAA,GAAA;EAAA;EAAA,OAAA,OAAA,GAVf,CAAA,CAAA,UAAA,CAAA,CAAA,CAAA,SAAA;IAAA,IAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAI2B,mBAAA,GAAmB,OAAA,CAAA,KAAA;EAAA,YAAA,OAAA,EAM/B,YAAA;IAAA,GAAA;EAAA;EAAA,IAAA;EAAA,WAAA;EAAA,UAAA,EA2BhB,aAAA;EAAA,WAAA;EAAA,YAAA,gBAAA;EAAA;;;EAAA,QAAA,WAAA;EAAA;;;EAAA,QAAA,YAAA;EAAA,kBAAA,IAAA,WAkE2B,OAAA;EAAA,KAAA,IAAA,UAAA,OAAA,GAMJ,cAAA,GAAiB,OAAA,CAAQ,aAAA;EAAA,KAAA,IAAA,UAAA,QAAA,GA8IxB,cAAA,GAAiB,OAAA,CAAQ,aAAA;EAAA,MAAA,IAAA,UAAA,KAAA,EAkDpD,oBAAA,EAAA,OAAA,GACG,eAAA,GACT,OAAA,CAAQ,cAAA;EAAA,OAAA,IAAA,UAAA,OAAA,GA6C0B,gBAAA,GAAmB,OAAA,CAAQ,eAAA;EAAA,OAAA,OAAA,UAAA,OAAA,UAAA,OAAA,GAoBpD,gBAAA,GACT,OAAA;IAAA,OAAA;EAAA;EAAA,OAAA,IAAA,UAAA,KAAA,UAAA,OAAA,GAiCiD,gBAAA,GAAmB,OAAA,CAAQ,eAAA;EAAA;;;;;;;;EAAA,QAAA,eAAA;AAAA"}