@batalabs/virlow-mcp-core 3.80.0 → 3.81.1

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.
Files changed (45) hide show
  1. package/dist/api.d.ts +46 -0
  2. package/dist/api.d.ts.map +1 -1
  3. package/dist/api.js +26 -0
  4. package/dist/api.js.map +1 -1
  5. package/dist/attachment-format.d.ts +42 -0
  6. package/dist/attachment-format.d.ts.map +1 -0
  7. package/dist/attachment-format.js +205 -0
  8. package/dist/attachment-format.js.map +1 -0
  9. package/dist/attachments.d.ts +39 -0
  10. package/dist/attachments.d.ts.map +1 -0
  11. package/dist/attachments.js +166 -0
  12. package/dist/attachments.js.map +1 -0
  13. package/dist/cjs/api.d.ts +46 -0
  14. package/dist/cjs/api.js +26 -0
  15. package/dist/cjs/attachment-format.d.ts +41 -0
  16. package/dist/cjs/attachment-format.js +214 -0
  17. package/dist/cjs/attachments.d.ts +38 -0
  18. package/dist/cjs/attachments.js +169 -0
  19. package/dist/cjs/index.d.ts +3 -1
  20. package/dist/cjs/index.js +3 -1
  21. package/dist/cjs/local-paths.d.ts +26 -0
  22. package/dist/cjs/local-paths.js +53 -0
  23. package/dist/http/index.d.ts +1 -1
  24. package/dist/http/index.d.ts.map +1 -1
  25. package/dist/http/index.js +1 -1
  26. package/dist/http/index.js.map +1 -1
  27. package/dist/http/local-origin.d.ts +9 -0
  28. package/dist/http/local-origin.d.ts.map +1 -1
  29. package/dist/http/local-origin.js +19 -4
  30. package/dist/http/local-origin.js.map +1 -1
  31. package/dist/http/server.js +2 -2
  32. package/dist/http/server.js.map +1 -1
  33. package/dist/index.d.ts +3 -1
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +1 -0
  36. package/dist/index.js.map +1 -1
  37. package/dist/local-paths.d.ts +27 -0
  38. package/dist/local-paths.d.ts.map +1 -0
  39. package/dist/local-paths.js +51 -0
  40. package/dist/local-paths.js.map +1 -0
  41. package/dist/tools.d.ts +11 -2
  42. package/dist/tools.d.ts.map +1 -1
  43. package/dist/tools.js +297 -2
  44. package/dist/tools.js.map +1 -1
  45. package/package.json +3 -3
package/dist/api.d.ts CHANGED
@@ -80,6 +80,35 @@ export interface ApiFolder {
80
80
  /** Encrypted v2 blob of the folder's property and view definitions. */
81
81
  encryptedSchema: string | null;
82
82
  }
83
+ /** One attachment's metadata. The filename is only ever in encryptedTitle. */
84
+ export interface ApiFile {
85
+ id: string;
86
+ noteId: string;
87
+ filename: string;
88
+ /** Legacy plaintext filename; null for anything a current client uploaded. */
89
+ originalName: string | null;
90
+ encryptedTitle: string;
91
+ iv: string;
92
+ salt: string;
93
+ mimeType: string;
94
+ size: number;
95
+ uploadedAt: string;
96
+ /** Set while the file is in the note's Recently deleted. */
97
+ deletedAt: string | null;
98
+ }
99
+ export interface ApiFileWithData extends ApiFile {
100
+ /** "v2:<iv>:<ciphertext>"; anything else is legacy v1. */
101
+ encryptedData: string;
102
+ noteSalt: string | null;
103
+ }
104
+ export interface FileUpload {
105
+ encryptedTitle: string;
106
+ encryptedData: string;
107
+ iv: string;
108
+ salt: string;
109
+ mimeType: string;
110
+ size: number;
111
+ }
83
112
  export declare class VirlowApi {
84
113
  private readonly baseUrl;
85
114
  private tokens;
@@ -171,5 +200,22 @@ export declare class VirlowApi {
171
200
  mcpEnabled?: boolean;
172
201
  encryptedSchema?: string | null;
173
202
  }): Promise<ApiFolder>;
203
+ listFiles(noteId: string, opts?: {
204
+ trashed?: boolean;
205
+ }): Promise<ApiFile[]>;
206
+ /** The full row, ciphertext included. Trashed files are served too. */
207
+ getFile(id: string): Promise<ApiFileWithData>;
208
+ /** Metadata only: what an exposure check needs, without up to 50 MB of ciphertext. */
209
+ getFileMeta(id: string): Promise<ApiFile>;
210
+ uploadFile(noteId: string, body: FileUpload): Promise<ApiFile>;
211
+ patchFile(id: string, body: {
212
+ encryptedTitle?: string;
213
+ iv?: string;
214
+ noteId?: string;
215
+ }): Promise<ApiFile>;
216
+ /** Moves the file to the note's Recently deleted. There is deliberately no
217
+ * way to hard-delete from here: Claude's deletes can always be undone. */
218
+ deleteFile(id: string): Promise<void>;
219
+ restoreFile(id: string): Promise<ApiFile>;
174
220
  }
175
221
  //# sourceMappingURL=api.d.ts.map
package/dist/api.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
package/dist/api.js CHANGED
@@ -218,5 +218,31 @@ export class VirlowApi {
218
218
  updateFolder(id, body) {
219
219
  return this.request('PUT', `/api/folders/${id}`, body);
220
220
  }
221
+ listFiles(noteId, opts = {}) {
222
+ const qs = opts.trashed ? '?trashed=true' : '';
223
+ return this.request('GET', `/api/notes/${encodeURIComponent(noteId)}/files${qs}`);
224
+ }
225
+ /** The full row, ciphertext included. Trashed files are served too. */
226
+ getFile(id) {
227
+ return this.request('GET', `/api/files/${encodeURIComponent(id)}`);
228
+ }
229
+ /** Metadata only: what an exposure check needs, without up to 50 MB of ciphertext. */
230
+ getFileMeta(id) {
231
+ return this.request('GET', `/api/files/${encodeURIComponent(id)}?metadata=true`);
232
+ }
233
+ uploadFile(noteId, body) {
234
+ return this.request('POST', `/api/notes/${encodeURIComponent(noteId)}/files`, body);
235
+ }
236
+ patchFile(id, body) {
237
+ return this.request('PATCH', `/api/files/${encodeURIComponent(id)}`, body);
238
+ }
239
+ /** Moves the file to the note's Recently deleted. There is deliberately no
240
+ * way to hard-delete from here: Claude's deletes can always be undone. */
241
+ deleteFile(id) {
242
+ return this.request('DELETE', `/api/files/${encodeURIComponent(id)}`);
243
+ }
244
+ restoreFile(id) {
245
+ return this.request('POST', `/api/files/${encodeURIComponent(id)}/restore`);
246
+ }
221
247
  }
222
248
  //# sourceMappingURL=api.js.map
package/dist/api.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Pure helpers for the attachment tools: names, types, sizes and how a file
3
+ * is shown to a model. No I/O, so every rule here is tested directly.
4
+ */
5
+ export declare const FILENAME_MAX = 255;
6
+ /** `text` and `content_base64`: what fits comfortably in one MCP message. */
7
+ export declare const INLINE_MAX_BYTES: number;
8
+ /** `path`: under the API's effective ceiling (~38 MB raw after the double base64). */
9
+ export declare const PATH_MAX_BYTES: number;
10
+ /** Largest non-text file read_attachment returns inline as base64. */
11
+ export declare const BINARY_INLINE_MAX_BYTES: number;
12
+ export declare const TEXT_MAX_CHARS = 200000;
13
+ /**
14
+ * The name shown and stored (encrypted). Basename only, so a model passing a
15
+ * full path does not leak the user's directory layout into the note; control
16
+ * characters out; capped at 255 with the extension kept.
17
+ */
18
+ export declare function sanitizeFilename(name: string): string;
19
+ export declare function inferMimeType(filename: string): string;
20
+ export declare function isTextLike(mimeType: string, filename: string): boolean;
21
+ export declare function formatSize(bytes: number): string;
22
+ /**
23
+ * atob accepts sloppy input on some runtimes; this does not. Bounded before
24
+ * anything is decoded: four characters carry three bytes, so input longer than
25
+ * ceil(max * 4 / 3) plus one padded group cannot fit in `max` and is refused
26
+ * without allocating its decoded form.
27
+ */
28
+ export declare function decodeBase64Strict(input: string, max?: number): Uint8Array;
29
+ /** Size gate shared by every add_attachment source. Returns the bytes so it can wrap a source inline. */
30
+ export declare function checkSize(bytes: Uint8Array, max: number, label: string): Uint8Array;
31
+ /**
32
+ * What read_attachment returns for a file it does not save: text as text,
33
+ * small binaries as base64 under a one-line header, and a clear refusal for
34
+ * anything bigger.
35
+ */
36
+ export declare function renderAttachment(info: {
37
+ filename: string;
38
+ mimeType: string;
39
+ }, bytes: Uint8Array, opts: {
40
+ canSave: boolean;
41
+ }): string;
42
+ //# sourceMappingURL=attachment-format.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attachment-format.d.ts","sourceRoot":"","sources":["../src/attachment-format.ts"],"names":[],"mappings":"AAEA;;;GAGG;AAEH,eAAO,MAAM,YAAY,MAAM,CAAC;AAChC,6EAA6E;AAC7E,eAAO,MAAM,gBAAgB,QAAkB,CAAC;AAChD,sFAAsF;AACtF,eAAO,MAAM,cAAc,QAAmB,CAAC;AAC/C,sEAAsE;AACtE,eAAO,MAAM,uBAAuB,QAAkB,CAAC;AACvD,eAAO,MAAM,cAAc,SAAU,CAAC;AAKtC;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAkBrD;AAqFD,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAKtD;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAQtE;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIhD;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,GAAE,MAAyB,GAAG,UAAU,CAW5F;AAED,yGAAyG;AACzG,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,UAAU,CAgBnF;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,EAC5C,KAAK,EAAE,UAAU,EACjB,IAAI,EAAE;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,GACzB,MAAM,CAqBR"}
@@ -0,0 +1,205 @@
1
+ import { base64ToBytes, bytesToBase64 } from '@batalabs/virlow-crypto';
2
+ /**
3
+ * Pure helpers for the attachment tools: names, types, sizes and how a file
4
+ * is shown to a model. No I/O, so every rule here is tested directly.
5
+ */
6
+ export const FILENAME_MAX = 255;
7
+ /** `text` and `content_base64`: what fits comfortably in one MCP message. */
8
+ export const INLINE_MAX_BYTES = 2 * 1024 * 1024;
9
+ /** `path`: under the API's effective ceiling (~38 MB raw after the double base64). */
10
+ export const PATH_MAX_BYTES = 35 * 1024 * 1024;
11
+ /** Largest non-text file read_attachment returns inline as base64. */
12
+ export const BINARY_INLINE_MAX_BYTES = 2 * 1024 * 1024;
13
+ export const TEXT_MAX_CHARS = 200_000;
14
+ const FALLBACK_NAME = 'attachment';
15
+ const FORMAT_CONTROL = /\p{Cf}/u;
16
+ /**
17
+ * The name shown and stored (encrypted). Basename only, so a model passing a
18
+ * full path does not leak the user's directory layout into the note; control
19
+ * characters out; capped at 255 with the extension kept.
20
+ */
21
+ export function sanitizeFilename(name) {
22
+ const base = name.split(/[\\/]/).pop() ?? '';
23
+ const cleaned = Array.from(base)
24
+ .filter((ch) => {
25
+ const c = ch.codePointAt(0) ?? 0;
26
+ if (c < 0x20 || c === 0x7f || (c >= 0x80 && c <= 0x9f))
27
+ return false;
28
+ // Line and paragraph separators break lines like a newline does; format
29
+ // controls (bidi overrides, zero-width characters, BOM) make a name
30
+ // read differently from what it is.
31
+ return c !== 0x2028 && c !== 0x2029 && !FORMAT_CONTROL.test(ch);
32
+ })
33
+ .join('')
34
+ .trim();
35
+ if (!cleaned || cleaned === '.' || cleaned === '..')
36
+ return FALLBACK_NAME;
37
+ if (cleaned.length <= FILENAME_MAX)
38
+ return cleaned;
39
+ const dot = cleaned.lastIndexOf('.');
40
+ const ext = dot > 0 && cleaned.length - dot <= 16 ? cleaned.slice(dot) : '';
41
+ return cleaned.slice(0, FILENAME_MAX - ext.length) + ext;
42
+ }
43
+ /** Every value here is on the API's MIME allowlist (virlow-api src/lib/validation.ts). */
44
+ const MIME_BY_EXT = {
45
+ txt: 'text/plain',
46
+ log: 'text/plain',
47
+ md: 'text/markdown',
48
+ markdown: 'text/markdown',
49
+ csv: 'text/csv',
50
+ json: 'application/json',
51
+ xml: 'application/xml',
52
+ html: 'text/html',
53
+ htm: 'text/html',
54
+ rtf: 'application/rtf',
55
+ pdf: 'application/pdf',
56
+ png: 'image/png',
57
+ jpg: 'image/jpeg',
58
+ jpeg: 'image/jpeg',
59
+ gif: 'image/gif',
60
+ webp: 'image/webp',
61
+ svg: 'image/svg+xml',
62
+ bmp: 'image/bmp',
63
+ tif: 'image/tiff',
64
+ tiff: 'image/tiff',
65
+ avif: 'image/avif',
66
+ heic: 'image/heic',
67
+ heif: 'image/heif',
68
+ ico: 'image/x-icon',
69
+ doc: 'application/msword',
70
+ docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
71
+ xls: 'application/vnd.ms-excel',
72
+ xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
73
+ ppt: 'application/vnd.ms-powerpoint',
74
+ pptx: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
75
+ pages: 'application/vnd.apple.pages',
76
+ numbers: 'application/vnd.apple.numbers',
77
+ zip: 'application/zip',
78
+ gz: 'application/gzip',
79
+ tar: 'application/x-tar',
80
+ '7z': 'application/x-7z-compressed',
81
+ rar: 'application/vnd.rar',
82
+ mp3: 'audio/mpeg',
83
+ m4a: 'audio/x-m4a',
84
+ wav: 'audio/wav',
85
+ ogg: 'audio/ogg',
86
+ aac: 'audio/aac',
87
+ mp4: 'video/mp4',
88
+ webm: 'video/webm',
89
+ mov: 'video/quicktime',
90
+ avi: 'video/x-msvideo',
91
+ woff: 'font/woff',
92
+ woff2: 'font/woff2',
93
+ ttf: 'font/ttf',
94
+ otf: 'font/otf',
95
+ wasm: 'application/wasm',
96
+ };
97
+ /**
98
+ * Source code. Stored as text/plain, because text/javascript and friends are
99
+ * not on the API allowlist; read back as text by extension.
100
+ */
101
+ const CODE_EXTENSIONS = new Set([
102
+ 'js', 'mjs', 'cjs', 'jsx', 'ts', 'tsx', 'py', 'rb', 'go', 'rs', 'java', 'kt', 'swift',
103
+ 'c', 'h', 'cpp', 'hpp', 'cs', 'php', 'sh', 'bash', 'zsh', 'ps1', 'sql', 'yaml', 'yml',
104
+ 'toml', 'ini', 'conf', 'env', 'css', 'scss', 'less', 'vue', 'svelte', 'lua', 'r', 'dart',
105
+ 'scala', 'gradle', 'dockerfile', 'makefile',
106
+ ]);
107
+ const TEXT_MIME = new Set([
108
+ 'application/json',
109
+ 'application/xml',
110
+ 'application/javascript',
111
+ 'application/x-javascript',
112
+ 'application/x-ndjson',
113
+ 'application/yaml',
114
+ 'application/x-yaml',
115
+ ]);
116
+ /** Lowercased extension, or the whole lowercased name when there is no dot (Dockerfile). */
117
+ function extOf(filename) {
118
+ const lower = filename.toLowerCase();
119
+ const dot = lower.lastIndexOf('.');
120
+ return dot === -1 ? lower : lower.slice(dot + 1);
121
+ }
122
+ export function inferMimeType(filename) {
123
+ const ext = extOf(filename);
124
+ if (MIME_BY_EXT[ext])
125
+ return MIME_BY_EXT[ext];
126
+ if (CODE_EXTENSIONS.has(ext))
127
+ return 'text/plain';
128
+ return 'application/octet-stream';
129
+ }
130
+ export function isTextLike(mimeType, filename) {
131
+ const mime = mimeType.split(';')[0].trim().toLowerCase();
132
+ if (mime.startsWith('text/') || TEXT_MIME.has(mime))
133
+ return true;
134
+ if (mime.endsWith('+json') || mime.endsWith('+xml'))
135
+ return true;
136
+ const ext = extOf(filename);
137
+ if (CODE_EXTENSIONS.has(ext))
138
+ return true;
139
+ const byExt = MIME_BY_EXT[ext];
140
+ return byExt !== undefined && (byExt.startsWith('text/') || TEXT_MIME.has(byExt));
141
+ }
142
+ export function formatSize(bytes) {
143
+ if (bytes < 1024)
144
+ return `${bytes} B`;
145
+ if (bytes < 1024 * 1024)
146
+ return `${(bytes / 1024).toFixed(1)} KB`;
147
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
148
+ }
149
+ /**
150
+ * atob accepts sloppy input on some runtimes; this does not. Bounded before
151
+ * anything is decoded: four characters carry three bytes, so input longer than
152
+ * ceil(max * 4 / 3) plus one padded group cannot fit in `max` and is refused
153
+ * without allocating its decoded form.
154
+ */
155
+ export function decodeBase64Strict(input, max = INLINE_MAX_BYTES) {
156
+ const compact = input.replace(/\s+/g, '');
157
+ if (compact.length > Math.ceil((max * 4) / 3) + 4) {
158
+ throw new Error(`content_base64 is about ${formatSize(Math.floor((compact.length * 3) / 4))}; the limit for inline content is ${formatSize(max)}.`);
159
+ }
160
+ if (compact.length % 4 !== 0 || !/^[A-Za-z0-9+/]*={0,2}$/.test(compact)) {
161
+ throw new Error('content_base64 is not valid base64.');
162
+ }
163
+ return base64ToBytes(compact);
164
+ }
165
+ /** Size gate shared by every add_attachment source. Returns the bytes so it can wrap a source inline. */
166
+ export function checkSize(bytes, max, label) {
167
+ if (bytes.byteLength === 0) {
168
+ throw new Error(`${label} is empty. There is nothing to attach.`);
169
+ }
170
+ if (bytes.byteLength > max) {
171
+ const where = max === INLINE_MAX_BYTES
172
+ ? 'the limit for inline content is'
173
+ : 'the limit for attaching from disk is';
174
+ const hint = max === INLINE_MAX_BYTES
175
+ ? ' Attach larger files from disk with path, using a local Virlow MCP server.'
176
+ : '';
177
+ throw new Error(`${label} is ${formatSize(bytes.byteLength)}; ${where} ${formatSize(max)}.${hint}`);
178
+ }
179
+ return bytes;
180
+ }
181
+ /**
182
+ * What read_attachment returns for a file it does not save: text as text,
183
+ * small binaries as base64 under a one-line header, and a clear refusal for
184
+ * anything bigger.
185
+ */
186
+ export function renderAttachment(info, bytes, opts) {
187
+ // The name is the one part of the header a file's author controls, so it is
188
+ // cleaned here too: a newline in it must not start a line of its own.
189
+ const filename = sanitizeFilename(info.filename);
190
+ if (isTextLike(info.mimeType, filename)) {
191
+ const text = new TextDecoder('utf-8').decode(bytes);
192
+ if (text.length <= TEXT_MAX_CHARS)
193
+ return text;
194
+ return (`${text.slice(0, TEXT_MAX_CHARS)}\n\n` +
195
+ `[truncated: showing the first ${TEXT_MAX_CHARS} of ${text.length} characters]`);
196
+ }
197
+ if (bytes.byteLength <= BINARY_INLINE_MAX_BYTES) {
198
+ return `${filename} · ${info.mimeType} · ${formatSize(bytes.byteLength)} · base64\n${bytesToBase64(bytes)}`;
199
+ }
200
+ const size = `${filename} is ${formatSize(bytes.byteLength)}, larger than the ${formatSize(BINARY_INLINE_MAX_BYTES)} that can be returned inline.`;
201
+ throw new Error(opts.canSave
202
+ ? `${size} Pass save_to with an absolute path to write it to disk.`
203
+ : `${size} Open it in the Virlow app, or read it through a local Virlow MCP server, which can save it to disk.`);
204
+ }
205
+ //# sourceMappingURL=attachment-format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attachment-format.js","sourceRoot":"","sources":["../src/attachment-format.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import { type VirlowApi } from './api.js';
2
+ import type { Vault } from './vault.js';
3
+ export interface AttachmentInfo {
4
+ id: string;
5
+ noteId: string;
6
+ filename: string;
7
+ mimeType: string;
8
+ size: number;
9
+ uploadedAt: string;
10
+ deletedAt: string | null;
11
+ }
12
+ export declare class AttachmentsService {
13
+ private readonly api;
14
+ private readonly vault;
15
+ constructor(api: VirlowApi, vault: Vault);
16
+ list(noteId: string, includeTrashed: boolean): Promise<AttachmentInfo[]>;
17
+ add(input: {
18
+ noteId: string;
19
+ filename: string;
20
+ mimeType?: string;
21
+ /** The bytes came from `text`: a name with no known extension is then text, not binary. */
22
+ fromText?: boolean;
23
+ bytes: Uint8Array;
24
+ }): Promise<AttachmentInfo>;
25
+ read(id: string): Promise<{
26
+ info: AttachmentInfo;
27
+ bytes: Uint8Array;
28
+ }>;
29
+ rename(id: string, newFilename: string): Promise<AttachmentInfo>;
30
+ move(id: string, toNoteId: string): Promise<AttachmentInfo>;
31
+ trash(id: string): Promise<void>;
32
+ restore(id: string): Promise<AttachmentInfo>;
33
+ /** Metadata with the filename decrypted. A legacy row's placeholder title
34
+ * does not decrypt; it falls back to its plaintext name, then a generic one. */
35
+ private describe;
36
+ private requireExposed;
37
+ private requireSession;
38
+ }
39
+ //# sourceMappingURL=attachments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attachments.d.ts","sourceRoot":"","sources":["../src/attachments.ts"],"names":[],"mappings":"AASA,OAAO,EAA0B,KAAK,SAAS,EAAE,MAAM,UAAU,CAAC;AAClE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAGxC,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAyCD,qBAAa,kBAAkB;IAE3B,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,KAAK;gBADL,GAAG,EAAE,SAAS,EACd,KAAK,EAAE,KAAK;IAGzB,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAQxE,GAAG,CAAC,KAAK,EAAE;QACf,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,2FAA2F;QAC3F,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,KAAK,EAAE,UAAU,CAAC;KACnB,GAAG,OAAO,CAAC,cAAc,CAAC;IAuBrB,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,cAAc,CAAC;QAAC,KAAK,EAAE,UAAU,CAAA;KAAE,CAAC;IAgBtE,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAahE,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAS3D,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOhC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAOlD;oFACgF;YAClE,QAAQ;YAUR,cAAc;IAe5B,OAAO,CAAC,cAAc;CAKvB"}
@@ -0,0 +1,166 @@
1
+ import { LegacyAttachmentError, bytesToBase64, decryptAttachment, decryptTitleField, encryptAttachment, encryptAttachmentName, } from '@batalabs/virlow-crypto';
2
+ import { computeExposure } from './exposure.js';
3
+ import { ApiError } from './api.js';
4
+ import { PATH_MAX_BYTES, formatSize, inferMimeType, sanitizeFilename } from './attachment-format.js';
5
+ /** A file this vault's key cannot open: encrypted before the account had a
6
+ * master password, under the web app's old per-device key. */
7
+ const WRONG_KEY_MESSAGE = 'Could not decrypt this file with your vault key. Open it in the Virlow app.';
8
+ /**
9
+ * The API's 409 for renaming a v1 file (virlow-api src/routes/files/crud.ts):
10
+ * its content shares the column IV with the filename, so the name cannot be
11
+ * re-encrypted on its own. Matched on the text, because the other 409 on that
12
+ * route ("Restore this file before changing it") must pass through as it is.
13
+ */
14
+ const API_LEGACY_RENAME_PREFIX = 'This file uses an older format.';
15
+ function renameFailure(err) {
16
+ if (err instanceof ApiError && err.status === 409 && err.message.startsWith(API_LEGACY_RENAME_PREFIX)) {
17
+ return new LegacyAttachmentError();
18
+ }
19
+ return err;
20
+ }
21
+ function decryptFailure(err) {
22
+ if (err instanceof LegacyAttachmentError)
23
+ return err;
24
+ if (err instanceof Error && err.name === 'OperationError')
25
+ return new Error(WRONG_KEY_MESSAGE);
26
+ return err instanceof Error ? err : new Error(String(err));
27
+ }
28
+ /**
29
+ * Attachments as the MCP tools see them. Holds no state of its own (no
30
+ * caches, no lock hook), so buildServer can make one per server without
31
+ * touching the shared ServerServices shape that virlow-api builds by hand.
32
+ *
33
+ * Every method checks exposure for every note it touches, the same rule as
34
+ * NotesService.requireExposed: knowing a file's id is not consent to reach
35
+ * into a folder the user has not opened to AI.
36
+ */
37
+ function inferredMimeType(filename, fromText) {
38
+ const inferred = inferMimeType(filename);
39
+ return fromText && inferred === 'application/octet-stream' ? 'text/plain' : inferred;
40
+ }
41
+ export class AttachmentsService {
42
+ api;
43
+ vault;
44
+ constructor(api, vault) {
45
+ this.api = api;
46
+ this.vault = vault;
47
+ }
48
+ async list(noteId, includeTrashed) {
49
+ const key = this.requireSession();
50
+ await this.requireExposed(noteId);
51
+ const live = await this.api.listFiles(noteId);
52
+ const trashed = includeTrashed ? await this.api.listFiles(noteId, { trashed: true }) : [];
53
+ return Promise.all([...live, ...trashed].map((file) => this.describe(key, file)));
54
+ }
55
+ async add(input) {
56
+ // A backstop under the tools' own per-source caps, so no caller can encrypt
57
+ // and send nothing, or more than the API could ever accept.
58
+ if (input.bytes.byteLength === 0)
59
+ throw new Error('The file is empty. There is nothing to attach.');
60
+ if (input.bytes.byteLength > PATH_MAX_BYTES) {
61
+ throw new Error(`The file is ${formatSize(input.bytes.byteLength)}; the most that can be attached is ${formatSize(PATH_MAX_BYTES)}.`);
62
+ }
63
+ const key = this.requireSession();
64
+ await this.requireExposed(input.noteId);
65
+ const filename = sanitizeFilename(input.filename);
66
+ const encrypted = await encryptAttachment(key, filename, input.bytes);
67
+ const row = await this.api.uploadFile(input.noteId, {
68
+ ...encrypted,
69
+ // Stored for the web app's legacy per-salt key; unused under a master key.
70
+ salt: bytesToBase64(crypto.getRandomValues(new Uint8Array(32))),
71
+ mimeType: input.mimeType ?? inferredMimeType(filename, input.fromText === true),
72
+ size: input.bytes.byteLength,
73
+ });
74
+ return { ...infoOf(row), filename };
75
+ }
76
+ async read(id) {
77
+ const key = this.requireSession();
78
+ // Metadata first, so a file in a closed folder is never downloaded at all.
79
+ const meta = await this.api.getFileMeta(id);
80
+ await this.requireExposed(meta.noteId);
81
+ const file = await this.api.getFile(id);
82
+ // Moved between the two calls: check where it is now, too.
83
+ if (file.noteId !== meta.noteId)
84
+ await this.requireExposed(file.noteId);
85
+ try {
86
+ const { filename, bytes } = await decryptAttachment(key, file);
87
+ return { info: { ...infoOf(file), filename: sanitizeFilename(filename) }, bytes };
88
+ }
89
+ catch (err) {
90
+ throw decryptFailure(err);
91
+ }
92
+ }
93
+ async rename(id, newFilename) {
94
+ const key = this.requireSession();
95
+ const file = await this.api.getFileMeta(id);
96
+ await this.requireExposed(file.noteId);
97
+ const filename = sanitizeFilename(newFilename);
98
+ const row = await this.api
99
+ .patchFile(id, await encryptAttachmentName(key, filename))
100
+ .catch((err) => {
101
+ throw renameFailure(err);
102
+ });
103
+ return { ...infoOf(row), filename };
104
+ }
105
+ async move(id, toNoteId) {
106
+ const key = this.requireSession();
107
+ const file = await this.api.getFileMeta(id);
108
+ // Both ends: out of a closed folder would reveal it, into one would hide
109
+ // a file where the user cannot expect Claude to have put it.
110
+ await this.requireExposed(file.noteId, toNoteId);
111
+ return this.describe(key, await this.api.patchFile(id, { noteId: toNoteId }));
112
+ }
113
+ async trash(id) {
114
+ this.requireSession();
115
+ const file = await this.api.getFileMeta(id);
116
+ await this.requireExposed(file.noteId);
117
+ await this.api.deleteFile(id);
118
+ }
119
+ async restore(id) {
120
+ const key = this.requireSession();
121
+ const file = await this.api.getFileMeta(id);
122
+ await this.requireExposed(file.noteId);
123
+ return this.describe(key, await this.api.restoreFile(id));
124
+ }
125
+ /** Metadata with the filename decrypted. A legacy row's placeholder title
126
+ * does not decrypt; it falls back to its plaintext name, then a generic one. */
127
+ async describe(key, file) {
128
+ try {
129
+ const filename = await decryptTitleField(key, file.encryptedTitle, file.iv);
130
+ // Names reach the model; one with a newline in it must not add a line.
131
+ return { ...infoOf(file), filename: sanitizeFilename(filename) };
132
+ }
133
+ catch {
134
+ return infoOf(file);
135
+ }
136
+ }
137
+ async requireExposed(...noteIds) {
138
+ const [{ folders }, ...rows] = await Promise.all([
139
+ this.api.listFolders(),
140
+ ...noteIds.map((id) => this.api.getNote(id)),
141
+ ]);
142
+ const exposure = computeExposure(folders);
143
+ for (const row of rows) {
144
+ if (!exposure.allows(row.folderId)) {
145
+ throw new Error(`Note ${row.id} is in a folder that is not exposed to MCP. Turn on "Expose to MCP" in that folder's settings in the Virlow app to access it here.`);
146
+ }
147
+ }
148
+ }
149
+ requireSession() {
150
+ const key = this.vault.session.key;
151
+ this.vault.touch();
152
+ return key;
153
+ }
154
+ }
155
+ function infoOf(file) {
156
+ return {
157
+ id: file.id,
158
+ noteId: file.noteId,
159
+ filename: sanitizeFilename(file.originalName ?? 'attachment'),
160
+ mimeType: file.mimeType,
161
+ size: file.size,
162
+ uploadedAt: file.uploadedAt,
163
+ deletedAt: file.deletedAt ?? null,
164
+ };
165
+ }
166
+ //# sourceMappingURL=attachments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attachments.js","sourceRoot":"","sources":["../src/attachments.ts"],"names":[],"mappings":"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"}