toolcraft 0.0.914 → 0.0.916

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/composition.json CHANGED
@@ -123,7 +123,7 @@
123
123
  },
124
124
  {
125
125
  "name": "tiny-http-mcp-server",
126
- "version": "0.1.131",
126
+ "version": "0.1.132",
127
127
  "license": "MIT"
128
128
  },
129
129
  {
@@ -138,7 +138,7 @@
138
138
  },
139
139
  {
140
140
  "name": "toolcraft",
141
- "version": "0.0.914",
141
+ "version": "0.0.916",
142
142
  "license": "MIT"
143
143
  },
144
144
  {
@@ -148,7 +148,7 @@
148
148
  },
149
149
  {
150
150
  "name": "toolcraft-schema",
151
- "version": "0.0.914",
151
+ "version": "0.0.916",
152
152
  "license": "MIT"
153
153
  },
154
154
  {
@@ -123,7 +123,7 @@
123
123
  },
124
124
  {
125
125
  "name": "tiny-http-mcp-server",
126
- "version": "0.1.131",
126
+ "version": "0.1.132",
127
127
  "license": "MIT"
128
128
  },
129
129
  {
@@ -138,7 +138,7 @@
138
138
  },
139
139
  {
140
140
  "name": "toolcraft",
141
- "version": "0.0.914",
141
+ "version": "0.0.916",
142
142
  "license": "MIT"
143
143
  },
144
144
  {
@@ -148,7 +148,7 @@
148
148
  },
149
149
  {
150
150
  "name": "toolcraft-schema",
151
- "version": "0.0.914",
151
+ "version": "0.0.916",
152
152
  "license": "MIT"
153
153
  },
154
154
  {
@@ -99,6 +99,7 @@ cause. Preserve cancellation/control exceptions separately. Cross-family
99
99
  | Read and write bytes | `readFile`, `writeFile`, `appendFile` |
100
100
  | Inspect entries | `stat`, `lstat`, `readdir`, `realpath`, `access` |
101
101
  | Change the namespace | `mkdir`, `rm`, `rename`, `copyFile` |
102
+ | Follow directory renames | Optional synchronous `trackDirectory(path)` metadata; memory tracks directory and ancestor moves. Returns `undefined` when unavailable; removal ends tracking. |
102
103
  | Remove an empty directory | Optional `rmdir`; never a recursive-delete fallback |
103
104
  | Links and metadata | Optional `readlink`, `symlink`, `link`, `chmod`, `utimes`, `truncate` |
104
105
  | Enumerate directories lazily | Optional `iterateDirectory`; memory, native and paged S3 backends, with mount/overlay/readonly/quota/device/scoped delegation; backend order, no sorted-array fallback |
@@ -335,6 +335,12 @@ export interface ExtractionOptions extends FsOptions {
335
335
  readonly commitGuard?: () => true;
336
336
  }
337
337
  export interface FileSystem {
338
+ /** Synchronous metadata for following directory and ancestor renames. Returns
339
+ * undefined when unavailable. Not a lease, retained inode, or permission bypass;
340
+ * removal invalidates tracking and leaves the last known path. */
341
+ readonly trackDirectory?: ((path: string) => {
342
+ readonly path: string;
343
+ } | undefined) | undefined;
338
344
  /** Retain each extraction root and enforce no-symlink ancestry atomically with
339
345
  * every mutation (including metadata and both hardlink paths). Returned views
340
346
  * must refuse unsupported mutations; no check-then-write emulation is allowed.
@@ -10,6 +10,7 @@ export declare class DeviceFileSystem implements FileSystem {
10
10
  get [pathNamespace](): any;
11
11
  _resolveEntryView: (path: string, options: FsOptions) => Promise<EntryLocation>;
12
12
  _entryAuthority: () => Promise<"unknown">;
13
+ get trackDirectory(): FileSystem["trackDirectory"];
13
14
  constructor(filesystem: FileSystem);
14
15
  canonicalizeMissingTarget(path: string, options?: FsOptions): string | undefined;
15
16
  capabilitiesFor(path: string, options?: CapabilityQueryOptions): Promise<FileSystemCapabilities>;
@@ -108,6 +108,9 @@ export class DeviceFileSystem {
108
108
  return { filesystem: this.#filesystem, path };
109
109
  };
110
110
  _entryAuthority = sharedUnknownEntryAuthority;
111
+ get trackDirectory() {
112
+ return this.#filesystem.trackDirectory?.bind(this.#filesystem);
113
+ }
111
114
  constructor(filesystem) {
112
115
  this.#filesystem = filesystem;
113
116
  this.capabilities = globalCapabilities(filesystem);
@@ -72,6 +72,7 @@ export declare class MemoryFileSystem implements FileSystem {
72
72
  mutationTick: number;
73
73
  readonly _owner: OwnedStore;
74
74
  private readonly root;
75
+ private readonly directoryLocations;
75
76
  private totalBytes;
76
77
  symlinkCount: number;
77
78
  _getAtomicView(): MemoryAtomicView | undefined;
@@ -147,6 +148,10 @@ export declare class MemoryFileSystem implements FileSystem {
147
148
  rename(source: string, destination: string, options?: RenameOptions): Promise<void>;
148
149
  copyFile(source: string, destination: string, options?: CopyFileOptions): Promise<void>;
149
150
  realpath(path: string, options?: FsOptions): Promise<string>;
151
+ private rememberDirectory;
152
+ trackDirectory(path: string): {
153
+ readonly path: string;
154
+ } | undefined;
150
155
  access(path: string, mode?: number, options?: FsOptions): Promise<void>;
151
156
  readlink(path: string, options?: FsOptions): Promise<string>;
152
157
  symlink(target: string, path: string, options?: FsOptions): Promise<void>;
@@ -627,6 +627,7 @@ export class MemoryFileSystem {
627
627
  mutationTick = 0;
628
628
  _owner;
629
629
  root;
630
+ directoryLocations = new WeakMap();
630
631
  totalBytes = 0;
631
632
  symlinkCount = 0;
632
633
  _getAtomicView() {
@@ -2806,6 +2807,9 @@ export class MemoryFileSystem {
2806
2807
  this.changed(target.parent);
2807
2808
  node.ctimeMs = Date.now();
2808
2809
  node.revision = Math.min(Number.MAX_SAFE_INTEGER + 1, node.revision + 1);
2810
+ if (node.type === "directory" && this.directoryLocations.has(node)) {
2811
+ this.rememberDirectory(target.path);
2812
+ }
2809
2813
  }
2810
2814
  catch (error) {
2811
2815
  if (error instanceof FsError)
@@ -2837,6 +2841,52 @@ export class MemoryFileSystem {
2837
2841
  options.signal?.throwIfAborted();
2838
2842
  return this.resolve(path, "realpath").path;
2839
2843
  }
2844
+ rememberDirectory(path) {
2845
+ let parent = this.root;
2846
+ for (const name of path.split("/").filter(Boolean)) {
2847
+ const node = parent.entries.get(name);
2848
+ if (node?.type !== "directory")
2849
+ return;
2850
+ this.directoryLocations.set(node, { parent, name });
2851
+ parent = node;
2852
+ }
2853
+ }
2854
+ trackDirectory(path) {
2855
+ let resolved;
2856
+ try {
2857
+ resolved = this.resolve(path, "trackDirectory");
2858
+ }
2859
+ catch (error) {
2860
+ if (error instanceof FsError && ["ENOENT", "ENOTDIR", "EACCES"].includes(error.code))
2861
+ return undefined;
2862
+ throw error;
2863
+ }
2864
+ const directory = resolved.node;
2865
+ if (directory?.type !== "directory")
2866
+ return undefined;
2867
+ this.rememberDirectory(resolved.path);
2868
+ const inode = directory.ino;
2869
+ let currentPath = resolved.path;
2870
+ let tick = this.mutationTick;
2871
+ return Object.freeze(Object.defineProperty({ path: currentPath }, "path", { get: () => {
2872
+ if (tick === this.mutationTick)
2873
+ return currentPath;
2874
+ tick = this.mutationTick;
2875
+ if (directory.ino !== inode)
2876
+ return currentPath;
2877
+ const names = [];
2878
+ let node = directory;
2879
+ while (node !== this.root) {
2880
+ const location = this.directoryLocations.get(node);
2881
+ if (!location || location.parent.entries.get(location.name) !== node)
2882
+ return currentPath;
2883
+ names.push(location.name);
2884
+ node = location.parent;
2885
+ }
2886
+ currentPath = `/${names.reverse().join("/")}`;
2887
+ return currentPath;
2888
+ } }));
2889
+ }
2840
2890
  access(path, mode = 0, options = {}) {
2841
2891
  try {
2842
2892
  options.signal?.throwIfAborted();
@@ -38,7 +38,7 @@
38
38
  },
39
39
  {
40
40
  "name": "tiny-http-mcp-server",
41
- "version": "0.1.131",
41
+ "version": "0.1.132",
42
42
  "license": "MIT"
43
43
  },
44
44
  {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tiny-http-mcp-server",
3
- "version": "0.1.131",
3
+ "version": "0.1.132",
4
4
  "description": "Minimal MCP server over HTTP built on tiny-stdio-mcp-server",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -8,7 +8,7 @@
8
8
  },
9
9
  {
10
10
  "name": "toolcraft-schema",
11
- "version": "0.0.914",
11
+ "version": "0.0.916",
12
12
  "license": "MIT"
13
13
  }
14
14
  ]
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toolcraft-schema",
3
- "version": "0.0.914",
3
+ "version": "0.0.916",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toolcraft",
3
- "version": "0.0.914",
3
+ "version": "0.0.916",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -177,7 +177,7 @@
177
177
  "saxes"
178
178
  ],
179
179
  "optionalDependencies": {
180
- "toolcraft-schema": "0.0.914",
180
+ "toolcraft-schema": "0.0.916",
181
181
  "toolcraft-design": "*",
182
182
  "@poe-code/frontmatter": "*",
183
183
  "@poe-code/agent-mcp-config": "*",