toolcraft 0.0.760 → 0.0.761
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 +2 -2
- package/dist/composition.json +2 -2
- package/node_modules/@poe-code/safe-fs/README.md +2 -0
- package/node_modules/@poe-code/safe-fs/dist/core.d.ts +1 -0
- package/node_modules/@poe-code/safe-fs/dist/core.js +1 -0
- package/node_modules/@poe-code/safe-fs/dist/fs/mount/index.js +6 -2
- package/node_modules/@poe-code/safe-fs/dist/fs/read-file-stream.d.ts +7 -0
- package/node_modules/@poe-code/safe-fs/dist/fs/read-file-stream.js +77 -0
- package/node_modules/@poe-code/safe-fs/dist/index.d.ts +1 -0
- package/node_modules/@poe-code/safe-fs/dist/index.js +1 -0
- package/node_modules/@poe-code/safe-fs/dist/runtime-core.d.ts +1 -0
- package/node_modules/@poe-code/safe-fs/dist/runtime-core.js +1 -0
- package/node_modules/tiny-stdio-mcp-server/dist/composition.json +1 -1
- package/node_modules/toolcraft-schema/package.json +1 -1
- package/package.json +2 -2
package/composition.json
CHANGED
|
@@ -133,7 +133,7 @@
|
|
|
133
133
|
},
|
|
134
134
|
{
|
|
135
135
|
"name": "toolcraft",
|
|
136
|
-
"version": "0.0.
|
|
136
|
+
"version": "0.0.761",
|
|
137
137
|
"license": "MIT"
|
|
138
138
|
},
|
|
139
139
|
{
|
|
@@ -143,7 +143,7 @@
|
|
|
143
143
|
},
|
|
144
144
|
{
|
|
145
145
|
"name": "toolcraft-schema",
|
|
146
|
-
"version": "0.0.
|
|
146
|
+
"version": "0.0.761",
|
|
147
147
|
"license": "MIT"
|
|
148
148
|
},
|
|
149
149
|
{
|
package/dist/composition.json
CHANGED
|
@@ -133,7 +133,7 @@
|
|
|
133
133
|
},
|
|
134
134
|
{
|
|
135
135
|
"name": "toolcraft",
|
|
136
|
-
"version": "0.0.
|
|
136
|
+
"version": "0.0.761",
|
|
137
137
|
"license": "MIT"
|
|
138
138
|
},
|
|
139
139
|
{
|
|
@@ -143,7 +143,7 @@
|
|
|
143
143
|
},
|
|
144
144
|
{
|
|
145
145
|
"name": "toolcraft-schema",
|
|
146
|
-
"version": "0.0.
|
|
146
|
+
"version": "0.0.761",
|
|
147
147
|
"license": "MIT"
|
|
148
148
|
},
|
|
149
149
|
{
|
|
@@ -303,6 +303,8 @@ For Workers, `externalSpool` must store payloads outside isolate RAM and satisfy
|
|
|
303
303
|
|
|
304
304
|
The reusable metadata-only fixture in [`tests/fixtures/bounded-filesystem.ts`](tests/fixtures/bounded-filesystem.ts) generates file ranges and consumes slow writes without storing payload bytes. [`tests/overlay-bounded.test.ts`](tests/overlay-bounded.test.ts) checks fixed transfer sizes, source backpressure, cancellation/error cleanup, byte results, and Memory publication allocation/identity. These deterministic conformance checks do not qualify a deployed Worker backend; follow the [Worker QA plan](../../docs/plans/safe-fs-bounded-overlay-qa.md) for runtime measurements.
|
|
305
305
|
|
|
306
|
+
`readFileStream(fs, path, options)` reads through the caller's native stream or retained range handle without calling `readFile`. It accepts the stream range/window options above, defaults to a 64 KiB read window, and closes owned readers on completion, failure or cancellation. `skipStream: true` selects retained ranges after an already-attempted stream reports `ENOTSUP`. Chunks are borrowed until the iterator advances. Native adapters must honor the requested window and backpressure. Whole-file-only backends receive `ENOTSUP`; use a streaming or retained-range backend for sequential Worker operations. This helper bounds its I/O window, not the consuming command's parser or output capture.
|
|
307
|
+
|
|
306
308
|
`collectBytes(source, { maxBytes, maxMemoryBytes, signal })` snapshots streamed chunks into one growing buffer. `maxBytes` and `maxMemoryBytes` accept explicit `Infinity`. `maxMemoryBytes` limits owned capacity, the current input's full backing buffer, and overlapping allocations during growth; exhaustion throws `EFBIG`. Collection limits are disabled by default on Node, browser, and Worker targets. Each call owns its budget; concurrent collections do not consume one another’s allowance. The returned view may retain geometric spare capacity. Configured budgets cover collection, not caller-retained results, transport buffering, archive decoding, strings, or the rest of the runtime; use streaming APIs and limit concurrent workloads for larger inputs.
|
|
307
309
|
|
|
308
310
|
<details>
|
|
@@ -17,3 +17,4 @@ export * from "./fs/s3/http/index.js";
|
|
|
17
17
|
export { createFileSystem, readConfigRecord, validateFileSystemConfig } from "./config.js";
|
|
18
18
|
export type { FileSystemConfig, FileSystemAdapterDescriptor, FileSystemAdapterRegistry } from "./config.js";
|
|
19
19
|
export { createPortableFileSystemAdapterRegistry } from "./config.portable.js";
|
|
20
|
+
export { readFileStream } from "./fs/read-file-stream.js";
|
|
@@ -15,3 +15,4 @@ export * from "./fs/s3/index.js";
|
|
|
15
15
|
export * from "./fs/s3/http/index.js";
|
|
16
16
|
export { createFileSystem, readConfigRecord, validateFileSystemConfig } from "./config.js";
|
|
17
17
|
export { createPortableFileSystemAdapterRegistry } from "./config.portable.js";
|
|
18
|
+
export { readFileStream } from "./fs/read-file-stream.js";
|
|
@@ -219,7 +219,7 @@ export class MountFileSystem {
|
|
|
219
219
|
&& await this.supportsDirectoryValidation(location.path.slice(0, location.path.lastIndexOf("/")) || "/", options, true)
|
|
220
220
|
: this.capabilities.conditionalChmod;
|
|
221
221
|
const { synchronousDirectoryValidation: ignoredValidation, synchronousStagingResolution: ignoredResolution, ...ordinary } = resize;
|
|
222
|
-
const withOpen = { ...ordinary,
|
|
222
|
+
const withOpen = { ...ordinary, ...(conditionalChmod === undefined ? {} : { conditionalChmod }), ...(resolution === undefined ? {} : { synchronousStagingResolution: resolution }), ...(validation === undefined ? {} : { synchronousDirectoryValidation: validation }), atomicStagingAncestry: ancestry, ...(typeof location.mount.backend.open === "function" ? {} : { open: false }) };
|
|
223
223
|
const capabilities = location.synthetic ? { ...withOpen, open: false, retainedRead: false }
|
|
224
224
|
: retainedResizeCapabilities(location.mount.backend, retainedReadCapabilities(location.mount.backend, withOpen));
|
|
225
225
|
if (location.synthetic)
|
|
@@ -973,7 +973,11 @@ export class MountFileSystem {
|
|
|
973
973
|
return Object.freeze(staging);
|
|
974
974
|
const backendCleanup = receipt.cleanup;
|
|
975
975
|
const cleanup = createStagingCleanup(staging.directory.path, controls => this.operation("removeStagedFile", staging.directory.path, controls, () => backendCleanup.remove(controls), undefined, true), () => backendCleanup.close());
|
|
976
|
-
|
|
976
|
+
const writer = receipt.writer;
|
|
977
|
+
return Object.freeze({ ...staging, cleanup, ...(writer ? { writer: Object.freeze({
|
|
978
|
+
write: (bytes, controls = {}) => this.operation("stagedWrite", staging.file.path, controls, () => writer.write(bytes, controls), undefined, true),
|
|
979
|
+
finish: (controls = {}) => this.operation("stagedFinish", staging.file.path, controls, async () => snapshotStat(await writer.finish(controls)), undefined, true),
|
|
980
|
+
}) } : {}) });
|
|
977
981
|
}
|
|
978
982
|
catch (error) {
|
|
979
983
|
await finishCleanup(() => receipt.cleanup?.close(), true);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { FileSystem, ReadStreamOptions } from "../contracts/filesystem.js";
|
|
2
|
+
/** Sequential payload access without a whole-file fallback. The injected backend
|
|
3
|
+
* must supply streaming reads or retained range reads; no private storage is used.
|
|
4
|
+
* Chunks are borrowed until the consumer advances the iterator. */
|
|
5
|
+
export declare function readFileStream(fs: FileSystem, path: string, options?: ReadStreamOptions & {
|
|
6
|
+
readonly skipStream?: boolean;
|
|
7
|
+
}): AsyncGenerator<Uint8Array>;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { FsError } from "../contracts/errors.js";
|
|
2
|
+
import { finishCleanup } from "../contracts/cleanup.js";
|
|
3
|
+
import { openRetainedReadFile } from "./capabilities.js";
|
|
4
|
+
const byteLength = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(Uint8Array.prototype), "byteLength").get;
|
|
5
|
+
const byteKind = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(Uint8Array.prototype), Symbol.toStringTag).get;
|
|
6
|
+
/** Sequential payload access without a whole-file fallback. The injected backend
|
|
7
|
+
* must supply streaming reads or retained range reads; no private storage is used.
|
|
8
|
+
* Chunks are borrowed until the consumer advances the iterator. */
|
|
9
|
+
export async function* readFileStream(fs, path, options = {}) {
|
|
10
|
+
const { signal } = options;
|
|
11
|
+
signal?.throwIfAborted();
|
|
12
|
+
const chunkSize = options.chunkSize ?? 65536;
|
|
13
|
+
let position = options.start ?? 0;
|
|
14
|
+
const end = options.endExclusive ?? Number.MAX_SAFE_INTEGER;
|
|
15
|
+
if (!Number.isSafeInteger(chunkSize) || chunkSize <= 0 || !Number.isSafeInteger(position) || position < 0
|
|
16
|
+
|| !Number.isSafeInteger(end) || end < position)
|
|
17
|
+
throw new FsError("EINVAL", { path, syscall: "readStream" });
|
|
18
|
+
const capabilities = await fs.capabilitiesFor?.(path, options) ?? fs.capabilities;
|
|
19
|
+
signal?.throwIfAborted();
|
|
20
|
+
if (!options.skipStream && fs.readStream && fs.capabilities?.streamingRead !== false && capabilities?.streamingRead !== false) {
|
|
21
|
+
let emitted = false;
|
|
22
|
+
let reading = true;
|
|
23
|
+
try {
|
|
24
|
+
const source = fs.readStream(path, { ...options, chunkSize });
|
|
25
|
+
const iterator = source[Symbol.asyncIterator]();
|
|
26
|
+
let done = false, failed = true;
|
|
27
|
+
try {
|
|
28
|
+
while (true) {
|
|
29
|
+
signal?.throwIfAborted();
|
|
30
|
+
const item = await iterator.next();
|
|
31
|
+
signal?.throwIfAborted();
|
|
32
|
+
if (item.done) {
|
|
33
|
+
done = true;
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
reading = false;
|
|
37
|
+
if (byteLength.call(item.value))
|
|
38
|
+
emitted = true;
|
|
39
|
+
yield item.value;
|
|
40
|
+
reading = true;
|
|
41
|
+
}
|
|
42
|
+
failed = false;
|
|
43
|
+
}
|
|
44
|
+
finally {
|
|
45
|
+
if (!done)
|
|
46
|
+
await finishCleanup(() => iterator.return?.(), failed);
|
|
47
|
+
}
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
signal?.throwIfAborted();
|
|
52
|
+
if (!reading || emitted || !(error instanceof FsError) || error.code !== "ENOTSUP")
|
|
53
|
+
throw error;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
const handle = await openRetainedReadFile(fs, path, options);
|
|
57
|
+
let failed = true;
|
|
58
|
+
try {
|
|
59
|
+
while (position < end) {
|
|
60
|
+
signal?.throwIfAborted();
|
|
61
|
+
const maximum = Math.min(chunkSize, end - position);
|
|
62
|
+
const bytes = await handle.read(position, maximum, options);
|
|
63
|
+
signal?.throwIfAborted();
|
|
64
|
+
if (byteKind.call(bytes) !== "Uint8Array" || byteLength.call(bytes) > maximum)
|
|
65
|
+
throw new FsError("EIO", { path, syscall: "read" });
|
|
66
|
+
const length = byteLength.call(bytes);
|
|
67
|
+
if (!length)
|
|
68
|
+
break;
|
|
69
|
+
position += length;
|
|
70
|
+
yield bytes;
|
|
71
|
+
}
|
|
72
|
+
failed = false;
|
|
73
|
+
}
|
|
74
|
+
finally {
|
|
75
|
+
await finishCleanup(() => handle.close(), failed);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -23,3 +23,4 @@ export { createFileSystem, readConfigRecord, validateFileSystemConfig } from "./
|
|
|
23
23
|
export type { FileSystemConfig, FileSystemAdapterDescriptor, FileSystemAdapterRegistry } from "./config.js";
|
|
24
24
|
export { createNodeFileSystemAdapterRegistry } from "./config.node.js";
|
|
25
25
|
export { createPortableFileSystemAdapterRegistry } from "./config.portable.js";
|
|
26
|
+
export { readFileStream } from "./fs/read-file-stream.js";
|
|
@@ -19,3 +19,4 @@ export * from "./node/index.js";
|
|
|
19
19
|
export { createFileSystem, readConfigRecord, validateFileSystemConfig } from "./config.js";
|
|
20
20
|
export { createNodeFileSystemAdapterRegistry } from "./config.node.js";
|
|
21
21
|
export { createPortableFileSystemAdapterRegistry } from "./config.portable.js";
|
|
22
|
+
export { readFileStream } from "./fs/read-file-stream.js";
|
|
@@ -25,3 +25,4 @@ export declare function tryWriteMemoryFileSync(fs: FileSystem, path: string, dat
|
|
|
25
25
|
export declare function tryMkdirMemorySync(fs: FileSystem, path: string, recursive: boolean, mode: number, signal?: AbortSignal, dirPrefixHint?: string): boolean;
|
|
26
26
|
export declare function tryRmRfMemorySync(fs: FileSystem, path: string, signal?: AbortSignal): boolean;
|
|
27
27
|
export declare function tryWriteMemoryFileInDirSync(fs: FileSystem, dirPrefix: string, name: string, data: Uint8Array, append: boolean, mode: number, signal?: AbortSignal): boolean;
|
|
28
|
+
export { readFileStream } from "./fs/read-file-stream.js";
|
|
@@ -55,3 +55,4 @@ export function tryRmRfMemorySync(fs, path, signal) {
|
|
|
55
55
|
export function tryWriteMemoryFileInDirSync(fs, dirPrefix, name, data, append, mode, signal) {
|
|
56
56
|
return Boolean((fs && _getMemHooks()?.byProto?.get(Object.getPrototypeOf(fs))?.tryWriteMemoryFileInDirSync)?.(fs, dirPrefix, name, data, append, mode, signal));
|
|
57
57
|
}
|
|
58
|
+
export { readFileStream } from "./fs/read-file-stream.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "toolcraft",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.761",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -175,7 +175,7 @@
|
|
|
175
175
|
"@poe-code/terminal-text"
|
|
176
176
|
],
|
|
177
177
|
"optionalDependencies": {
|
|
178
|
-
"toolcraft-schema": "0.0.
|
|
178
|
+
"toolcraft-schema": "0.0.761",
|
|
179
179
|
"toolcraft-design": "*",
|
|
180
180
|
"@poe-code/frontmatter": "*",
|
|
181
181
|
"@poe-code/agent-mcp-config": "*",
|