@telepath-computer/autofile 0.0.0-stage → 0.3.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Telepath Computer
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,75 @@
1
- # Temporary Holding Version
1
+ # Autofile
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Autofile makes it easy for agents to store information in a structured, unambiguous way, and makes that information available to the services and interfaces that want to use it and show it.
4
+
5
+ Autofile is designed for:
6
+
7
+ - **No ambiguity on input.** Every kind of information has one defined place and type, with clear instructions for how it is filed.
8
+ - **Efficient retrieval.** Agents find what they need by keyword search, by matching on typed properties, and by following links between records.
9
+ - **Plain files, no lock-in.** Records are JSON files you own, and any agent, MCP server or interface can read, use and show them.
10
+
11
+ Autofile is an [MCP](https://modelcontextprotocol.io) server. Agents use it through the tools and resources it serves.
12
+
13
+ ## Install
14
+
15
+ Autofile needs Node.js 24 or later.
16
+
17
+ ```sh
18
+ npm install -g @telepath-computer/autofile
19
+ ```
20
+
21
+ This installs the `autofile` command.
22
+
23
+ ## Connect an agent
24
+
25
+ An MCP client starts Autofile itself by running `autofile`, and talks to it over stdio. For Claude Code:
26
+
27
+ ```sh
28
+ claude mcp add autofile --scope user -- autofile
29
+ ```
30
+
31
+ For another client, add an MCP server whose command is `autofile`, with no arguments.
32
+
33
+ Autofile starts with no types. Ask your agent to file something: it proposes a type, such as `contact` with the fields a contact needs, and creates it once you agree. It then files records of that type, and finds them again by search, by field value, or by following links between records.
34
+
35
+ ## Where records are kept
36
+
37
+ Autofile keeps records in `~/.autofile/data`, as one JSON file per record in a folder for each type:
38
+
39
+ ```
40
+ ~/.autofile/data/
41
+ _types/contact.json the declaration of the type contact
42
+ contact/priya-narayan.json a record of that type
43
+ _blobs/9f86d081…0a08.pdf a file stored with a record
44
+ ```
45
+
46
+ The files are plain JSON, so you can read them, back them up, or edit them by hand. To keep them in another folder:
47
+
48
+ ```sh
49
+ autofile set storage ~/Documents/Autofile
50
+ ```
51
+
52
+ Setting `storage` moves no files. Clients use the new folder the next time they start Autofile, and `autofile serve` once it is restarted. [Commands](spec/index.md#commands) lists the other settings.
53
+
54
+ ## Serve over HTTP
55
+
56
+ For clients that connect over HTTP, such as a web page, run:
57
+
58
+ ```sh
59
+ autofile serve
60
+ ```
61
+
62
+ This serves the same tools and resources at `http://127.0.0.1:7319/mcp` until stopped. Autofile does not authenticate HTTP clients: anything that can reach the address can read and change every record. It therefore listens only on this machine by default, and accepts requests from web pages only when they are served from this machine. [Serving over HTTP](spec/index.md#serving-over-http) explains how to change the address, the port, and the web pages it accepts.
63
+
64
+ ## Specification
65
+
66
+ [spec/index.md](spec/index.md) describes Autofile in full: records, types, links, stored files, the MCP tools and resources, and the commands.
67
+
68
+ ## Development
69
+
70
+ ```sh
71
+ npm install
72
+ npm test
73
+ ```
74
+
75
+ `npm test` builds Autofile and runs the tests.
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Parses, checks, and persists blob-field inputs. Candidate preparation is
3
+ * deliberately separate from persistence so a refused record write cannot
4
+ * leave a blob behind.
5
+ */
6
+ /** Largest blob that fits in one MCP message after base64 encoding. */
7
+ export declare const MAX_BLOB_BYTES = 7340032;
8
+ /** Canonical names Autofile recognizes in its blob folder. */
9
+ export declare const BLOB_NAME_PATTERN: RegExp;
10
+ /** Canonical URIs Autofile recognizes for stored blobs. */
11
+ export declare const BLOB_URI_PATTERN: RegExp;
12
+ /** One checked blob which may still need to be copied into the store. */
13
+ export interface PreparedBlob {
14
+ uri: string;
15
+ name: string;
16
+ bytes?: Buffer;
17
+ }
18
+ /** A user-correctable refusal for one blob field. */
19
+ interface BlobRefusal {
20
+ message: string;
21
+ }
22
+ /** Returns whether the value has one of the three syntactic blob input forms. */
23
+ export declare function isBlobInput(value: unknown): value is string;
24
+ /** Checks and materializes one candidate without changing the blob folder. */
25
+ export declare function prepareBlob(value: string, blobFolder: string, allowLocalPaths: boolean): Promise<PreparedBlob | BlobRefusal>;
26
+ /** Stores checked blobs atomically, skipping any destination already present. */
27
+ export declare function writePreparedBlobs(blobFolder: string, blobs: Iterable<PreparedBlob>): Promise<void>;
28
+ /** Deletes the named canonical blob resources when they still exist. */
29
+ export declare function deleteBlobUris(blobFolder: string, uris: Iterable<string>): Promise<void>;
30
+ /** Returns the canonical blob name from a URI. */
31
+ export declare function blobNameFromUri(uri: string): string | undefined;
32
+ /** Builds the canonical URI for a recognized blob name. */
33
+ export declare function blobUri(name: string): string;
34
+ export {};
package/dist/blobs.js ADDED
@@ -0,0 +1,295 @@
1
+ /**
2
+ * Parses, checks, and persists blob-field inputs. Candidate preparation is
3
+ * deliberately separate from persistence so a refused record write cannot
4
+ * leave a blob behind.
5
+ */
6
+ import { createHash, randomUUID } from "node:crypto";
7
+ import { constants } from "node:fs";
8
+ import { lstat, mkdir, open, rename, unlink, writeFile } from "node:fs/promises";
9
+ import { basename, dirname, extname, isAbsolute, join } from "node:path";
10
+ import { extension as extensionForMimeType } from "mime-types";
11
+ const BLOB_EXTENSION_PATTERN_SOURCE = "[a-z0-9_-]+";
12
+ /** Largest blob that fits in one MCP message after base64 encoding. */
13
+ export const MAX_BLOB_BYTES = 7_340_032;
14
+ /** Canonical names Autofile recognizes in its blob folder. */
15
+ export const BLOB_NAME_PATTERN = new RegExp(`^[a-f0-9]{64}(?:\\.${BLOB_EXTENSION_PATTERN_SOURCE})?$`, "u");
16
+ /** Canonical URIs Autofile recognizes for stored blobs. */
17
+ export const BLOB_URI_PATTERN = new RegExp(`^autofile:///_blobs/([a-f0-9]{64}(?:\\.${BLOB_EXTENSION_PATTERN_SOURCE})?)$`, "u");
18
+ const SOURCE_READ_CHUNK_BYTES = 64 * 1024;
19
+ const blobExtensionPattern = new RegExp(`^${BLOB_EXTENSION_PATTERN_SOURCE}$`, "u");
20
+ /** Returns whether the value has one of the three syntactic blob input forms. */
21
+ export function isBlobInput(value) {
22
+ return typeof value === "string"
23
+ && (BLOB_URI_PATTERN.test(value) || isAbsolute(value) || parseDataUri(value) !== undefined);
24
+ }
25
+ /** Checks and materializes one candidate without changing the blob folder. */
26
+ export async function prepareBlob(value, blobFolder, allowLocalPaths) {
27
+ const blobName = blobNameFromUri(value);
28
+ if (blobName !== undefined) {
29
+ const details = await storedBlobDetails(blobFolder, blobName);
30
+ if (details === undefined)
31
+ return { message: `references a blob that does not exist: ${value}` };
32
+ if (details.size > MAX_BLOB_BYTES)
33
+ return sizeRefusal(details.size);
34
+ return { uri: value, name: blobName };
35
+ }
36
+ if (isAbsolute(value)) {
37
+ if (!allowLocalPaths) {
38
+ return { message: "local paths are accepted only over stdio, not HTTP" };
39
+ }
40
+ const source = await openRegularFile(value, false);
41
+ if (source === undefined)
42
+ return { message: `path does not exist or is not a file: ${value}` };
43
+ try {
44
+ if (source.size > MAX_BLOB_BYTES)
45
+ return sizeRefusal(source.size);
46
+ const bytes = await readSourceFile(source.handle);
47
+ if ("message" in bytes)
48
+ return bytes;
49
+ return preparedBytes(bytes, pathExtension(value));
50
+ }
51
+ finally {
52
+ await source.handle.close();
53
+ }
54
+ }
55
+ const data = parseDataUri(value);
56
+ if (data === undefined)
57
+ return { message: "must be a blob URI, an absolute path, or a base64 data URI" };
58
+ if (data.size > MAX_BLOB_BYTES)
59
+ return sizeRefusal(data.size);
60
+ return preparedBytes(Buffer.from(data.base64, "base64"), data.extension);
61
+ }
62
+ /** Stores checked blobs atomically, skipping any destination already present. */
63
+ export async function writePreparedBlobs(blobFolder, blobs) {
64
+ const pending = [...blobs].filter((blob) => blob.bytes !== undefined);
65
+ if (pending.length === 0)
66
+ return;
67
+ await mkdir(blobFolder, { recursive: true });
68
+ if (!await isDirectory(blobFolder)) {
69
+ throw Object.assign(new Error("blob folder is not a directory"), { code: "ENOTDIR" });
70
+ }
71
+ const written = new Set();
72
+ for (const blob of pending) {
73
+ if (written.has(blob.name))
74
+ continue;
75
+ written.add(blob.name);
76
+ const path = join(blobFolder, blob.name);
77
+ if (await isRegularFile(path))
78
+ continue;
79
+ await writeBlobAtomically(path, blob.bytes ?? Buffer.alloc(0));
80
+ }
81
+ }
82
+ /** Deletes the named canonical blob resources when they still exist. */
83
+ export async function deleteBlobUris(blobFolder, uris) {
84
+ if (!await isDirectory(blobFolder))
85
+ return;
86
+ for (const uri of uris) {
87
+ const name = blobNameFromUri(uri);
88
+ if (name === undefined)
89
+ continue;
90
+ try {
91
+ await unlink(join(blobFolder, name));
92
+ }
93
+ catch (error) {
94
+ if (!hasCode(error, "ENOENT") && !hasCode(error, "ENOTDIR"))
95
+ throw error;
96
+ }
97
+ }
98
+ }
99
+ /** Returns the canonical blob name from a URI. */
100
+ export function blobNameFromUri(uri) {
101
+ return BLOB_URI_PATTERN.exec(uri)?.[1];
102
+ }
103
+ /** Builds the canonical URI for a recognized blob name. */
104
+ export function blobUri(name) {
105
+ return `autofile:///_blobs/${name}`;
106
+ }
107
+ function preparedBytes(bytes, extension) {
108
+ const digest = createHash("sha256").update(bytes).digest("hex");
109
+ const name = `${digest}${extension === undefined ? "" : `.${extension}`}`;
110
+ return { uri: blobUri(name), name, bytes };
111
+ }
112
+ function parseDataUri(value) {
113
+ if (value.slice(0, "data:".length).toLowerCase() !== "data:")
114
+ return undefined;
115
+ const comma = value.indexOf(",", "data:".length);
116
+ if (comma === -1)
117
+ return undefined;
118
+ const header = value.slice("data:".length, comma);
119
+ const marker = ";base64";
120
+ if (header.slice(-marker.length).toLowerCase() !== marker)
121
+ return undefined;
122
+ const metadata = header.slice(0, -marker.length);
123
+ const base64 = value.slice(comma + 1);
124
+ if (!isCanonicalBase64(base64))
125
+ return undefined;
126
+ const [mediaType = "", ...parameters] = metadata.split(";");
127
+ if ((mediaType !== "" && !isMediaType(mediaType))
128
+ || parameters.some((parameter) => !isMediaTypeParameter(parameter))) {
129
+ return undefined;
130
+ }
131
+ const normalizedMediaType = mediaType === "" ? "text/plain" : mediaType.toLowerCase();
132
+ const usualExtension = extensionForMimeType(normalizedMediaType);
133
+ const extension = usualExtension === false ? undefined : normalizeExtension(usualExtension);
134
+ return {
135
+ base64,
136
+ ...(extension === undefined ? {} : { extension }),
137
+ size: decodedBase64Size(base64),
138
+ };
139
+ }
140
+ function isCanonicalBase64(value) {
141
+ if (value.length % 4 !== 0)
142
+ return false;
143
+ const padding = value.endsWith("==") ? 2 : value.endsWith("=") ? 1 : 0;
144
+ const contentLength = value.length - padding;
145
+ if (padding === 2 && contentLength % 4 !== 2)
146
+ return false;
147
+ if (padding === 1 && contentLength % 4 !== 3)
148
+ return false;
149
+ for (let index = 0; index < contentLength; index += 1) {
150
+ const code = value.charCodeAt(index);
151
+ if (!(code >= 0x41 && code <= 0x5a)
152
+ && !(code >= 0x61 && code <= 0x7a)
153
+ && !(code >= 0x30 && code <= 0x39)
154
+ && code !== 0x2b
155
+ && code !== 0x2f) {
156
+ return false;
157
+ }
158
+ }
159
+ if (padding > 0) {
160
+ const finalCode = value.charCodeAt(contentLength - 1);
161
+ const finalSextet = finalCode >= 0x41 && finalCode <= 0x5a
162
+ ? finalCode - 0x41
163
+ : finalCode >= 0x61 && finalCode <= 0x7a
164
+ ? finalCode - 0x61 + 26
165
+ : finalCode >= 0x30 && finalCode <= 0x39
166
+ ? finalCode - 0x30 + 52
167
+ : finalCode === 0x2b ? 62 : 63;
168
+ const unusedBits = padding === 2 ? 4 : 2;
169
+ if ((finalSextet & ((1 << unusedBits) - 1)) !== 0)
170
+ return false;
171
+ }
172
+ return true;
173
+ }
174
+ function decodedBase64Size(value) {
175
+ if (value.length === 0)
176
+ return 0;
177
+ const padding = value.endsWith("==") ? 2 : value.endsWith("=") ? 1 : 0;
178
+ return value.length / 4 * 3 - padding;
179
+ }
180
+ function isMediaType(value) {
181
+ const token = "[!#$%&'*+.^_`|~0-9A-Za-z-]+";
182
+ return new RegExp(`^${token}/${token}$`, "u").test(value);
183
+ }
184
+ function isMediaTypeParameter(value) {
185
+ return /^[!#$%&'*+.^_`|~0-9A-Za-z-]+=[^\s,;]+$/u.test(value);
186
+ }
187
+ function pathExtension(path) {
188
+ return normalizeExtension(extname(basename(path)).slice(1));
189
+ }
190
+ function normalizeExtension(extension) {
191
+ const normalized = extension.toLowerCase();
192
+ return blobExtensionPattern.test(normalized) ? normalized : undefined;
193
+ }
194
+ function sizeRefusal(size) {
195
+ return { message: `blob is ${String(size)} bytes; limit is ${String(MAX_BLOB_BYTES)} bytes` };
196
+ }
197
+ async function storedBlobDetails(blobFolder, name) {
198
+ if (!await isDirectory(blobFolder))
199
+ return undefined;
200
+ const file = await openRegularFile(join(blobFolder, name), true);
201
+ if (file === undefined)
202
+ return undefined;
203
+ try {
204
+ return { size: file.size };
205
+ }
206
+ finally {
207
+ await file.handle.close();
208
+ }
209
+ }
210
+ async function readSourceFile(handle) {
211
+ const chunks = [];
212
+ let size = 0;
213
+ while (true) {
214
+ // The extra byte proves the source is too large without allowing a file that grew after stat,
215
+ // or a regular special file with an inaccurate size, to make this read unbounded.
216
+ const remainingWithSentinel = MAX_BLOB_BYTES + 1 - size;
217
+ const buffer = Buffer.alloc(Math.min(SOURCE_READ_CHUNK_BYTES, remainingWithSentinel));
218
+ const { bytesRead } = await handle.read(buffer, 0, buffer.byteLength, null);
219
+ if (bytesRead === 0)
220
+ return Buffer.concat(chunks, size);
221
+ size += bytesRead;
222
+ if (size > MAX_BLOB_BYTES)
223
+ return sizeRefusal(size);
224
+ chunks.push(bytesRead === buffer.byteLength ? buffer : buffer.subarray(0, bytesRead));
225
+ }
226
+ }
227
+ async function openRegularFile(path, noFollow) {
228
+ let handle;
229
+ try {
230
+ handle = await open(path, constants.O_RDONLY | constants.O_NONBLOCK | (noFollow ? constants.O_NOFOLLOW : 0));
231
+ }
232
+ catch (error) {
233
+ if (hasCode(error, "ENOENT")
234
+ || hasCode(error, "ENOTDIR")
235
+ || hasCode(error, "ELOOP")
236
+ || hasCode(error, "ENXIO")
237
+ || hasCode(error, "ENODEV")) {
238
+ return undefined;
239
+ }
240
+ throw error;
241
+ }
242
+ try {
243
+ const details = await handle.stat();
244
+ if (!details.isFile()) {
245
+ await handle.close();
246
+ return undefined;
247
+ }
248
+ return { handle, size: details.size };
249
+ }
250
+ catch (error) {
251
+ await handle.close();
252
+ throw error;
253
+ }
254
+ }
255
+ async function writeBlobAtomically(path, bytes) {
256
+ const temporaryPath = join(dirname(path), `.${basename(path)}.${String(process.pid)}.${randomUUID()}`);
257
+ try {
258
+ await writeFile(temporaryPath, bytes, { flag: "wx" });
259
+ await rename(temporaryPath, path);
260
+ }
261
+ catch (error) {
262
+ try {
263
+ await unlink(temporaryPath);
264
+ }
265
+ catch (cleanupError) {
266
+ if (!hasCode(cleanupError, "ENOENT"))
267
+ throw cleanupError;
268
+ }
269
+ throw error;
270
+ }
271
+ }
272
+ async function isDirectory(path) {
273
+ try {
274
+ return (await lstat(path)).isDirectory();
275
+ }
276
+ catch (error) {
277
+ if (hasCode(error, "ENOENT") || hasCode(error, "ENOTDIR"))
278
+ return false;
279
+ throw error;
280
+ }
281
+ }
282
+ async function isRegularFile(path) {
283
+ try {
284
+ return (await lstat(path)).isFile();
285
+ }
286
+ catch (error) {
287
+ if (hasCode(error, "ENOENT") || hasCode(error, "ENOTDIR"))
288
+ return false;
289
+ throw error;
290
+ }
291
+ }
292
+ function hasCode(error, code) {
293
+ return error instanceof Error && "code" in error && error.code === code;
294
+ }
295
+ //# sourceMappingURL=blobs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blobs.js","sourceRoot":"","sources":["../src/blobs.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ /** Serves Autofile over stdio or HTTP and dispatches its settings commands. */
3
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,180 @@
1
+ #!/usr/bin/env node
2
+ /** Serves Autofile over stdio or HTTP and dispatches its settings commands. */
3
+ import { StdioServerTransport, serveStdio } from "@modelcontextprotocol/server/stdio";
4
+ import { getSetting, getSettings, isSettingName, parsePort, setSetting, unsetSetting, } from "./config.js";
5
+ import { startHttpServer } from "./http.js";
6
+ import { buildServer } from "./server.js";
7
+ import { openStore } from "./store.js";
8
+ import { resourceNotificationUris, watchStore, } from "./watch.js";
9
+ const usage = `Usage:
10
+ autofile
11
+ autofile serve [--host <host>] [--port <port>]
12
+ autofile set <setting> <value> [<value>...]
13
+ autofile get <setting>
14
+ autofile unset <setting>
15
+ `;
16
+ class UsageError extends Error {
17
+ }
18
+ try {
19
+ await main(process.argv.slice(2));
20
+ }
21
+ catch (error) {
22
+ if (error instanceof UsageError) {
23
+ process.stderr.write(usage);
24
+ }
25
+ else {
26
+ reportError(error);
27
+ }
28
+ process.exitCode = 1;
29
+ }
30
+ async function main(args) {
31
+ if (args.length === 0) {
32
+ await runStdio();
33
+ return;
34
+ }
35
+ const [command, setting, ...values] = args;
36
+ if (command === "serve") {
37
+ await serve(args.slice(1));
38
+ return;
39
+ }
40
+ if (command === "set") {
41
+ if (setting === undefined || !isSettingName(setting) || !hasValidSetArity(setting, values)) {
42
+ throw new UsageError();
43
+ }
44
+ await setSetting(setting, values);
45
+ return;
46
+ }
47
+ if (command === "get") {
48
+ if (setting === undefined || values.length !== 0 || !isSettingName(setting)) {
49
+ throw new UsageError();
50
+ }
51
+ const lines = await getSetting(setting);
52
+ if (lines.length > 0)
53
+ process.stdout.write(`${lines.join("\n")}\n`);
54
+ return;
55
+ }
56
+ if (command === "unset") {
57
+ if (setting === undefined || values.length !== 0 || !isSettingName(setting)) {
58
+ throw new UsageError();
59
+ }
60
+ await unsetSetting(setting);
61
+ return;
62
+ }
63
+ throw new UsageError();
64
+ }
65
+ async function runStdio() {
66
+ const settings = await getSettings();
67
+ const store = await openStore({ dataFolder: settings.storage });
68
+ let connectedServer;
69
+ let watcher;
70
+ let handle;
71
+ let stopping;
72
+ const stop = () => {
73
+ stopping ??= Promise.all([
74
+ watcher?.close() ?? Promise.resolve(),
75
+ handle?.close() ?? Promise.resolve(),
76
+ ]).then(() => undefined);
77
+ return stopping;
78
+ };
79
+ watcher = await watchStore(settings.storage, store, async (batch) => {
80
+ const server = connectedServer;
81
+ if (server === undefined || !server.isConnected())
82
+ return;
83
+ try {
84
+ const uris = new Set(batch.changes.flatMap(({ uri }) => resourceNotificationUris(uri)));
85
+ for (const uri of uris) {
86
+ await server.server.sendResourceUpdated({ uri });
87
+ }
88
+ if (batch.listChanged)
89
+ await server.server.sendResourceListChanged();
90
+ }
91
+ catch (error) {
92
+ // Closing the connection can race an event already queued by Chokidar.
93
+ if (server.isConnected())
94
+ throw error;
95
+ }
96
+ }, reportError);
97
+ handle = serveStdio(async () => {
98
+ const server = await buildServer(store);
99
+ connectedServer = server;
100
+ return server;
101
+ }, {
102
+ legacy: "reject",
103
+ transport: new StdioServerTransport(process.stdin, process.stdout, {
104
+ maxBufferSize: 64 * 1024 * 1024,
105
+ }),
106
+ onerror: reportError,
107
+ });
108
+ const requestStop = () => {
109
+ void stop().catch((error) => {
110
+ reportError(error);
111
+ process.exitCode = 1;
112
+ });
113
+ };
114
+ process.stdin.once("end", requestStop);
115
+ process.stdin.once("close", requestStop);
116
+ process.once("SIGINT", requestStop);
117
+ process.once("SIGTERM", requestStop);
118
+ }
119
+ async function serve(args) {
120
+ const overrides = parseServeOptions(args);
121
+ const settings = await getSettings();
122
+ const http = {
123
+ ...settings.http,
124
+ ...(overrides.host === undefined ? {} : { host: overrides.host }),
125
+ ...(overrides.port === undefined ? {} : { port: overrides.port }),
126
+ };
127
+ const store = await openStore({ dataFolder: settings.storage });
128
+ const running = await startHttpServer(store, settings.storage, http, reportError);
129
+ process.stderr.write(`autofile: listening on ${running.endpoint.href}\n`);
130
+ const stop = () => {
131
+ void running.close().catch((error) => {
132
+ reportError(error);
133
+ process.exitCode = 1;
134
+ });
135
+ };
136
+ process.once("SIGINT", stop);
137
+ process.once("SIGTERM", stop);
138
+ try {
139
+ await running.closed;
140
+ }
141
+ finally {
142
+ process.off("SIGINT", stop);
143
+ process.off("SIGTERM", stop);
144
+ }
145
+ }
146
+ function parseServeOptions(args) {
147
+ let host;
148
+ let port;
149
+ for (let index = 0; index < args.length; index += 2) {
150
+ const option = args[index];
151
+ const value = args[index + 1];
152
+ if (value === undefined)
153
+ throw new UsageError();
154
+ if (option === "--host" && host === undefined) {
155
+ if (value === "")
156
+ throw new Error("http.host must be a non-empty string");
157
+ host = value;
158
+ }
159
+ else if (option === "--port" && port === undefined) {
160
+ port = parsePort(value);
161
+ }
162
+ else {
163
+ throw new UsageError();
164
+ }
165
+ }
166
+ return {
167
+ ...(host === undefined ? {} : { host }),
168
+ ...(port === undefined ? {} : { port }),
169
+ };
170
+ }
171
+ function hasValidSetArity(setting, values) {
172
+ if (setting === "http.origins")
173
+ return values.length > 0;
174
+ return values.length === 1;
175
+ }
176
+ function reportError(error) {
177
+ const message = error instanceof Error ? error.message : String(error);
178
+ process.stderr.write(`autofile: ${message.replace(/[\r\n]+/gu, " ")}\n`);
179
+ }
180
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}