@procedures/fs 0.3.0 → 0.5.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,49 @@
1
1
  # @procedures/fs
2
2
 
3
+ ## 0.5.0
4
+
5
+ ### Minor Changes
6
+
7
+ - a47bee6: The hosts can confine the file procedures to a root (roadmap R33).
8
+
9
+ - `confineFsProcedures(registry, root)` of `@procedures/fs` replaces the handler of each `fs.*` procedure of a registry with the handler of `createFsModule({ root })`. It adds no procedure. A nested `fs.*` call of another procedure is confined too. The root must be a folder that exists.
10
+ - `mark --fs-root <folder>` confines the `fs.*` procedures of each mode and host of `mark`: a command, the REPL, `--server`, `serve` and `mcp`. Give the flag before the command.
11
+ - A `mark` command uses a CLI server only when the server has the same root. The lockfile of `@procedures/peer` has the new field `fsRoot`, and `findServer()` compares it.
12
+ - `procedure-server --fs-root <folder>` and `mark serve --fs-root <folder>` confine the procedures of the server.
13
+ - The MCP server reads `MCP_FS_ROOT`, and `mark mcp` has the flag `--fs-root`. `fs` is not a tool namespace, so the tools do not change.
14
+ - A path outside the root gives `FORBIDDEN` with the reason `outside-root`. A procedure that reads files with `node:fs`, or that starts a program, is not confined.
15
+ - `@procedures/lib/cli-flags` has the global flags `--fs-root` and `--events`, and the field `repeatable`.
16
+
17
+ ### Patch Changes
18
+
19
+ - Updated dependencies [0f75644]
20
+ - Updated dependencies [09e5566]
21
+ - Updated dependencies [ab77f75]
22
+ - Updated dependencies [a47bee6]
23
+ - Updated dependencies [bc74091]
24
+ - @procedures/client@0.5.0
25
+
26
+ ## 0.4.0
27
+
28
+ ### Minor Changes
29
+
30
+ - 3d76cb7: `fs.copy` refuses an existing destination without `overwrite`: the error has the code `EEXIST`, and the copy changes nothing. This applies to a file and to a folder, with `recursive` true or false. Before, the default copy (`recursive: true`) kept an existing file, merged a folder into an existing folder, and reported success. With `overwrite`, the copy replaces the files at the destination, as before.
31
+
32
+ ### Patch Changes
33
+
34
+ - Updated dependencies [d919678]
35
+ - Updated dependencies [057d69a]
36
+ - Updated dependencies [b2a1a1e]
37
+ - Updated dependencies [057d69a]
38
+ - Updated dependencies [057d69a]
39
+ - Updated dependencies [057d69a]
40
+ - Updated dependencies [057d69a]
41
+ - Updated dependencies [057d69a]
42
+ - Updated dependencies [afd6a19]
43
+ - Updated dependencies [057d69a]
44
+ - Updated dependencies [4e751da]
45
+ - @procedures/client@0.4.0
46
+
3
47
  ## 0.3.0
4
48
 
5
49
  ### Minor Changes
package/README.md CHANGED
@@ -117,6 +117,19 @@ const registry = createRegistry(createFsModule({ root: "/work/project" }), bundl
117
117
 
118
118
  `registerFsProcedures(registry, { root })` registers the procedures with the root in one registry.
119
119
 
120
+ A host that has a registry already starts `confineFsProcedures(registry, root)`. The function replaces the handler of each `fs.*` procedure of the registry, and it adds no procedure:
121
+
122
+ ```ts
123
+ import { confineFsProcedures } from "@procedures/fs/module";
124
+
125
+ const { root, procedures } = confineFsProcedures(registry, "/work/project");
126
+ ```
127
+
128
+ - A nested call of another procedure finds the new handler in the registry. Thus `lib.scan`, which calls `fs.readdir`, reads only the folders in the root.
129
+ - The root must be a folder that exists. Otherwise the function throws, and the host does not start.
130
+ - An `fs.*` procedure of another package is an error, because the root cannot confine it.
131
+ - The hosts use this function: `mark --fs-root <folder>`, `procedure-server --fs-root <folder>` and `MCP_FS_ROOT` of the MCP server.
132
+
120
133
  ### Rules
121
134
 
122
135
  - A relative path starts at the root, not at the working folder of the process.
@@ -138,7 +151,7 @@ const registry = createRegistry(createFsModule({ root: "/work/project" }), bundl
138
151
  ### Limits
139
152
 
140
153
  - The check and the operation are two steps. The check does not see a symlink that a process changes between the two steps.
141
- - The root applies only to the `fs.*` procedures. A package that uses `node:fs` directly does not get the root. Examples are `git.*` and `lib.*`.
154
+ - The root applies only to the `fs.*` procedures and their nested calls. A procedure that uses `node:fs` directly, or that starts a program, does not get the root. Examples are `git.*`, `archive.*`, `snapshot.*`, `sqlite.*`, the `existsSync` of `lib.*` and the TypeScript files of `lib.rename`.
142
155
  - The root does not replace the permissions of the operating system.
143
156
 
144
157
  ## API Reference
@@ -402,6 +415,8 @@ interface ReaddirEntry {
402
415
 
403
416
  Copy a file or directory.
404
417
 
418
+ Without `overwrite`, an existing destination is an error with the code `EEXIST`, and the copy changes nothing. This applies to a file and to a folder. With `overwrite`, the copy replaces the files at the destination.
419
+
405
420
  ```typescript
406
421
  // Copy file
407
422
  await client.exec(
@@ -430,7 +445,7 @@ interface CopyInput {
430
445
  src: string;
431
446
  dest: string;
432
447
  recursive?: boolean; // Default: true
433
- overwrite?: boolean; // Default: false
448
+ overwrite?: boolean; // Default: false. Without it, an existing destination is an error (EEXIST)
434
449
  }
435
450
  ```
436
451