@aigne/afs 1.4.0-beta.9 → 1.4.0

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,56 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.4.0](https://github.com/AIGNE-io/aigne-framework/compare/afs-v1.4.0-beta.11...afs-v1.4.0) (2026-01-16)
4
+
5
+
6
+ ### Dependencies
7
+
8
+ * The following workspace dependencies were updated
9
+ * dependencies
10
+ * @aigne/platform-helpers bumped to 0.6.7
11
+
12
+ ## [1.4.0-beta.11](https://github.com/AIGNE-io/aigne-framework/compare/afs-v1.4.0-beta.10...afs-v1.4.0-beta.11) (2026-01-16)
13
+
14
+
15
+ ### Features
16
+
17
+ * add Agent Skill support ([#787](https://github.com/AIGNE-io/aigne-framework/issues/787)) ([f04fbe7](https://github.com/AIGNE-io/aigne-framework/commit/f04fbe76ec24cf3c59c74adf92d87b0c3784a8f7))
18
+ * add session compact support for AIAgent ([#863](https://github.com/AIGNE-io/aigne-framework/issues/863)) ([9010918](https://github.com/AIGNE-io/aigne-framework/commit/9010918cd3f18b02b5c60ddc9ed5c34b568d0b28))
19
+ * **afs,bash:** add physical path mapping for AFS modules in bash execution ([#881](https://github.com/AIGNE-io/aigne-framework/issues/881)) ([50dbda2](https://github.com/AIGNE-io/aigne-framework/commit/50dbda224bd666d951494d2449779830d8db57fc))
20
+ * **afs:** add basic AFS(AIGNE File System) support ([#505](https://github.com/AIGNE-io/aigne-framework/issues/505)) ([ac2a18a](https://github.com/AIGNE-io/aigne-framework/commit/ac2a18a82470a2f31c466f329386525eb1cdab6d))
21
+ * **afs:** add edit/delete/rename methods for AFS ([#820](https://github.com/AIGNE-io/aigne-framework/issues/820)) ([68cb508](https://github.com/AIGNE-io/aigne-framework/commit/68cb508d1cfc9c516d56303018139f1e567f897e))
22
+ * **afs:** add module access control and schema validation support ([#904](https://github.com/AIGNE-io/aigne-framework/issues/904)) ([d0b279a](https://github.com/AIGNE-io/aigne-framework/commit/d0b279aac07ebe2bcc1fd4148498fc3f6bbcd561))
23
+ * **afs:** add module system fs for afs ([#594](https://github.com/AIGNE-io/aigne-framework/issues/594)) ([83c7b65](https://github.com/AIGNE-io/aigne-framework/commit/83c7b6555d21c606a5005eb05f6686882fb8ffa3))
24
+ * **afs:** improve list behavior to always include current path ([cb91f80](https://github.com/AIGNE-io/aigne-framework/commit/cb91f80c6ea3aa6e93dde26b6feeea8689fceb48))
25
+ * **afs:** support expand context into prompt template by call `$afs.xxx` ([#830](https://github.com/AIGNE-io/aigne-framework/issues/830)) ([5616acd](https://github.com/AIGNE-io/aigne-framework/commit/5616acd6ea257c91aa0b766608f45c5ce17f0345))
26
+ * **core:** add session history support ([#858](https://github.com/AIGNE-io/aigne-framework/issues/858)) ([28a070e](https://github.com/AIGNE-io/aigne-framework/commit/28a070ed33b821d1fd344b899706d817ca992b9f))
27
+ * support define agent by third library & orchestrator agent refactor ([#799](https://github.com/AIGNE-io/aigne-framework/issues/799)) ([7264b11](https://github.com/AIGNE-io/aigne-framework/commit/7264b11ab6eed787e928367f09aa08d254968d40))
28
+ * support mount mcp agent into AFS ([#740](https://github.com/AIGNE-io/aigne-framework/issues/740)) ([6d474fc](https://github.com/AIGNE-io/aigne-framework/commit/6d474fc05845a15e2c3e8fa97727b409bdd70945))
29
+
30
+
31
+ ### Bug Fixes
32
+
33
+ * **afs:** add case-sensitive option for search with case-insensitive default ([#814](https://github.com/AIGNE-io/aigne-framework/issues/814)) ([9dc9446](https://github.com/AIGNE-io/aigne-framework/commit/9dc944635104fc311e7756b4bde0a20275cfe8ec))
34
+ * **afs:** check module existence on normalized path ([#793](https://github.com/AIGNE-io/aigne-framework/issues/793)) ([0c991bf](https://github.com/AIGNE-io/aigne-framework/commit/0c991bf0caa948ce62948986ce885b5a98437689))
35
+ * **afs:** improve module path resolution and depth handling ([#659](https://github.com/AIGNE-io/aigne-framework/issues/659)) ([c609d4f](https://github.com/AIGNE-io/aigne-framework/commit/c609d4fc9614123afcf4b8f86b3382a613ace417))
36
+ * **afs:** read method should not throw not found error ([#835](https://github.com/AIGNE-io/aigne-framework/issues/835)) ([ebfdfc1](https://github.com/AIGNE-io/aigne-framework/commit/ebfdfc1cdba23efd23ac2ad4621e3f046990fd8b))
37
+ * **afs:** show gitignored files with marker instead of filtering ([c2bdea1](https://github.com/AIGNE-io/aigne-framework/commit/c2bdea155f47c9420f2fe810cdfed79ef70ef899))
38
+ * **afs:** throw errors instead of logging in AFS module operations ([#874](https://github.com/AIGNE-io/aigne-framework/issues/874)) ([f0cc1c4](https://github.com/AIGNE-io/aigne-framework/commit/f0cc1c4056f8b95b631d595892bb12eb75da4b9f))
39
+ * **afs:** use simple-list instead of tree as default type ([#839](https://github.com/AIGNE-io/aigne-framework/issues/839)) ([65a9a40](https://github.com/AIGNE-io/aigne-framework/commit/65a9a4054b3bdad6f7e40357299ef3dc48f7c3e4))
40
+ * bump version ([696560f](https://github.com/AIGNE-io/aigne-framework/commit/696560fa2673eddcb4d00ac0523fbbbde7273cb3))
41
+ * bump version ([70d217c](https://github.com/AIGNE-io/aigne-framework/commit/70d217c8360dd0dda7f5f17011c4e92ec836e801))
42
+ * bump version ([af04b69](https://github.com/AIGNE-io/aigne-framework/commit/af04b6931951afa35d52065430acc7fef4b10087))
43
+ * bump version ([ba7ad18](https://github.com/AIGNE-io/aigne-framework/commit/ba7ad184fcf32b49bf0507a3cb638d20fb00690d))
44
+ * bump version ([93a1c10](https://github.com/AIGNE-io/aigne-framework/commit/93a1c10cf35f88eaafe91092481f5d087bd5b3a9))
45
+ * improve test coverage tracking and reporting ([#903](https://github.com/AIGNE-io/aigne-framework/issues/903)) ([031144e](https://github.com/AIGNE-io/aigne-framework/commit/031144e74f29e882cffe52ffda8f7a18c76ace7f))
46
+
47
+ ## [1.4.0-beta.10](https://github.com/AIGNE-io/aigne-framework/compare/afs-v1.4.0-beta.9...afs-v1.4.0-beta.10) (2026-01-16)
48
+
49
+
50
+ ### Features
51
+
52
+ * **afs:** improve list behavior to always include current path ([cb91f80](https://github.com/AIGNE-io/aigne-framework/commit/cb91f80c6ea3aa6e93dde26b6feeea8689fceb48))
53
+
3
54
  ## [1.4.0-beta.9](https://github.com/AIGNE-io/aigne-framework/compare/afs-v1.4.0-beta.8...afs-v1.4.0-beta.9) (2026-01-14)
4
55
 
5
56
 
package/lib/cjs/afs.js CHANGED
@@ -32,11 +32,11 @@ class AFS extends strict_event_emitter_1.Emitter {
32
32
  }
33
33
  }
34
34
  mount(module) {
35
- let path = (0, ufo_1.joinURL)("/", module.name);
36
- if (!/^\/[^/]+$/.test(path)) {
37
- throw new Error(`Invalid mount path: ${path}. Must start with '/' and contain no other '/'`);
35
+ // Validate module name (should not contain '/')
36
+ if (module.name.includes("/")) {
37
+ throw new Error(`Invalid module name: ${module.name}. Module name must not contain '/'`);
38
38
  }
39
- path = (0, ufo_1.joinURL)(MODULES_ROOT_DIR, path);
39
+ const path = (0, ufo_1.joinURL)(MODULES_ROOT_DIR, module.name);
40
40
  if (this.modules.has(path)) {
41
41
  throw new Error(`Module already mounted at path: ${path}`);
42
42
  }
@@ -66,14 +66,36 @@ class AFS extends strict_event_emitter_1.Emitter {
66
66
  }
67
67
  async _list(path, options = {}) {
68
68
  const results = [];
69
+ // Special case: listing root "/" should return /modules directory
70
+ if (path === "/" && this.modules.size > 0) {
71
+ const maxDepth = options?.maxDepth ?? DEFAULT_MAX_DEPTH;
72
+ // Always include /modules directory first
73
+ results.push({
74
+ id: "modules",
75
+ path: MODULES_ROOT_DIR,
76
+ summary: "All mounted modules",
77
+ });
78
+ if (maxDepth === 1) {
79
+ // Only show /modules directory
80
+ return { data: results };
81
+ }
82
+ // For maxDepth > 1, also get children of /modules with reduced depth
83
+ const childrenResult = await this._list(MODULES_ROOT_DIR, {
84
+ ...options,
85
+ maxDepth: maxDepth - 1,
86
+ });
87
+ results.push(...childrenResult.data);
88
+ return { data: results };
89
+ }
69
90
  const matches = this.findModules(path, options);
70
91
  for (const matched of matches) {
71
- const moduleEntry = {
72
- id: matched.module.name,
73
- path: matched.remainedModulePath,
74
- summary: matched.module.description,
75
- };
76
92
  if (matched.maxDepth === 0) {
93
+ // When maxDepth is 0, show the module entry
94
+ const moduleEntry = {
95
+ id: matched.module.name,
96
+ path: matched.modulePath,
97
+ summary: matched.module.description,
98
+ };
77
99
  results.push(moduleEntry);
78
100
  continue;
79
101
  }
@@ -84,15 +106,13 @@ class AFS extends strict_event_emitter_1.Emitter {
84
106
  ...options,
85
107
  maxDepth: matched.maxDepth,
86
108
  });
87
- if (data.length) {
88
- results.push(...data.map((entry) => ({
89
- ...entry,
90
- path: (0, ufo_1.joinURL)(matched.modulePath, entry.path),
91
- })));
92
- }
93
- else {
94
- results.push(moduleEntry);
95
- }
109
+ const children = data.map((entry) => ({
110
+ ...entry,
111
+ path: (0, ufo_1.joinURL)(matched.modulePath, entry.path),
112
+ }));
113
+ // Always include all nodes (including the current path itself)
114
+ // This ensures consistent behavior across all listing scenarios
115
+ results.push(...children);
96
116
  }
97
117
  catch (error) {
98
118
  throw new Error(`Error listing from module at ${matched.modulePath}: ${error.message}`);
package/lib/esm/afs.js CHANGED
@@ -29,11 +29,11 @@ export class AFS extends Emitter {
29
29
  }
30
30
  }
31
31
  mount(module) {
32
- let path = joinURL("/", module.name);
33
- if (!/^\/[^/]+$/.test(path)) {
34
- throw new Error(`Invalid mount path: ${path}. Must start with '/' and contain no other '/'`);
32
+ // Validate module name (should not contain '/')
33
+ if (module.name.includes("/")) {
34
+ throw new Error(`Invalid module name: ${module.name}. Module name must not contain '/'`);
35
35
  }
36
- path = joinURL(MODULES_ROOT_DIR, path);
36
+ const path = joinURL(MODULES_ROOT_DIR, module.name);
37
37
  if (this.modules.has(path)) {
38
38
  throw new Error(`Module already mounted at path: ${path}`);
39
39
  }
@@ -63,14 +63,36 @@ export class AFS extends Emitter {
63
63
  }
64
64
  async _list(path, options = {}) {
65
65
  const results = [];
66
+ // Special case: listing root "/" should return /modules directory
67
+ if (path === "/" && this.modules.size > 0) {
68
+ const maxDepth = options?.maxDepth ?? DEFAULT_MAX_DEPTH;
69
+ // Always include /modules directory first
70
+ results.push({
71
+ id: "modules",
72
+ path: MODULES_ROOT_DIR,
73
+ summary: "All mounted modules",
74
+ });
75
+ if (maxDepth === 1) {
76
+ // Only show /modules directory
77
+ return { data: results };
78
+ }
79
+ // For maxDepth > 1, also get children of /modules with reduced depth
80
+ const childrenResult = await this._list(MODULES_ROOT_DIR, {
81
+ ...options,
82
+ maxDepth: maxDepth - 1,
83
+ });
84
+ results.push(...childrenResult.data);
85
+ return { data: results };
86
+ }
66
87
  const matches = this.findModules(path, options);
67
88
  for (const matched of matches) {
68
- const moduleEntry = {
69
- id: matched.module.name,
70
- path: matched.remainedModulePath,
71
- summary: matched.module.description,
72
- };
73
89
  if (matched.maxDepth === 0) {
90
+ // When maxDepth is 0, show the module entry
91
+ const moduleEntry = {
92
+ id: matched.module.name,
93
+ path: matched.modulePath,
94
+ summary: matched.module.description,
95
+ };
74
96
  results.push(moduleEntry);
75
97
  continue;
76
98
  }
@@ -81,15 +103,13 @@ export class AFS extends Emitter {
81
103
  ...options,
82
104
  maxDepth: matched.maxDepth,
83
105
  });
84
- if (data.length) {
85
- results.push(...data.map((entry) => ({
86
- ...entry,
87
- path: joinURL(matched.modulePath, entry.path),
88
- })));
89
- }
90
- else {
91
- results.push(moduleEntry);
92
- }
106
+ const children = data.map((entry) => ({
107
+ ...entry,
108
+ path: joinURL(matched.modulePath, entry.path),
109
+ }));
110
+ // Always include all nodes (including the current path itself)
111
+ // This ensures consistent behavior across all listing scenarios
112
+ results.push(...children);
93
113
  }
94
114
  catch (error) {
95
115
  throw new Error(`Error listing from module at ${matched.modulePath}: ${error.message}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aigne/afs",
3
- "version": "1.4.0-beta.9",
3
+ "version": "1.4.0",
4
4
  "description": "Agentic File System (AFS) is a virtual file system that supports various storage backends and provides a unified API for file operations.",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -50,8 +50,9 @@
50
50
  "@aigne/uuid": "^13.0.1",
51
51
  "strict-event-emitter": "^0.5.1",
52
52
  "ufo": "^1.6.1",
53
+ "yaml": "^2.8.1",
53
54
  "zod": "^3.25.67",
54
- "@aigne/platform-helpers": "^0.6.7-beta.2"
55
+ "@aigne/platform-helpers": "^0.6.7"
55
56
  },
56
57
  "devDependencies": {
57
58
  "@types/bun": "^1.2.22",