nterminal 1.2.88 → 1.2.89
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/README.md +2 -1
- package/dist/client/assets/MarkdownPreview-Bpy611pE.js +1 -0
- package/dist/client/assets/{TranscriptMarkdownBody-CvclqHm3.js → TranscriptMarkdownBody-Du5Pkx1T.js} +1 -1
- package/dist/client/assets/{index-yKhwlegq.css → index-BcPAKIRq.css} +1 -1
- package/dist/client/assets/index-Bm5iXlSq.js +57 -0
- package/dist/client/assets/{index-DcP0SS12.js → index-Cyt748r3.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/server/agent/agentProxy.d.ts +4 -0
- package/dist/server/agent/agentProxy.js +93 -0
- package/dist/server/agent/agentProxy.js.map +1 -1
- package/dist/server/agent/agentRoutes.js +15 -0
- package/dist/server/agent/agentRoutes.js.map +1 -1
- package/dist/server/config.d.ts +3 -0
- package/dist/server/config.js +6 -0
- package/dist/server/config.js.map +1 -1
- package/dist/server/routes/agentManagementRoutes.js +48 -1
- package/dist/server/routes/agentManagementRoutes.js.map +1 -1
- package/dist/server/routes/attachmentRoutes.d.ts +9 -0
- package/dist/server/routes/attachmentRoutes.js +123 -0
- package/dist/server/routes/attachmentRoutes.js.map +1 -0
- package/dist/server/routes/uploadRoutes.js +31 -0
- package/dist/server/routes/uploadRoutes.js.map +1 -1
- package/dist/server/uploads/attachmentService.d.ts +23 -0
- package/dist/server/uploads/attachmentService.js +194 -0
- package/dist/server/uploads/attachmentService.js.map +1 -0
- package/dist/server/uploads/uploadService.d.ts +2 -0
- package/dist/server/uploads/uploadService.js +7 -5
- package/dist/server/uploads/uploadService.js.map +1 -1
- package/dist/shared/protocol.d.ts +25 -0
- package/dist/shared/protocol.js.map +1 -1
- package/docs/configuration.md +3 -0
- package/docs/features.md +11 -0
- package/package.json +1 -1
- package/dist/client/assets/MarkdownPreview-BCyFRE6U.js +0 -1
- package/dist/client/assets/index-XrYKpFyQ.js +0 -57
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { attachmentRootForStatePath, createComposeAttachmentSession, defaultAttachmentMaxBatchBytes, defaultAttachmentMaxFileBytes, defaultAttachmentMaxFiles, deleteComposeAttachments } from '../uploads/attachmentService.js';
|
|
2
|
+
import { parseUploadManifest, UploadRequestError } from '../uploads/uploadService.js';
|
|
3
|
+
export function composeAttachmentLimits(config) {
|
|
4
|
+
return {
|
|
5
|
+
uploadMaxFiles: config.attachmentMaxFiles ?? defaultAttachmentMaxFiles,
|
|
6
|
+
uploadMaxFileBytes: config.attachmentMaxFileBytes ?? defaultAttachmentMaxFileBytes,
|
|
7
|
+
uploadMaxBatchBytes: config.attachmentMaxBatchBytes ?? defaultAttachmentMaxBatchBytes
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export function composeAttachmentLimitsResponse(config) {
|
|
11
|
+
const limits = composeAttachmentLimits(config);
|
|
12
|
+
return {
|
|
13
|
+
maxFiles: limits.uploadMaxFiles,
|
|
14
|
+
maxFileBytes: limits.uploadMaxFileBytes,
|
|
15
|
+
maxBatchBytes: limits.uploadMaxBatchBytes
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export async function handleComposeAttachmentUpload(request, reply, config, terminalManager) {
|
|
19
|
+
if (!request.isMultipart()) {
|
|
20
|
+
return reply.code(400).send({ error: 'multipart_required' });
|
|
21
|
+
}
|
|
22
|
+
const limits = composeAttachmentLimits(config);
|
|
23
|
+
let session = null;
|
|
24
|
+
let responseError = null;
|
|
25
|
+
try {
|
|
26
|
+
for await (const part of request.parts({
|
|
27
|
+
limits: {
|
|
28
|
+
files: limits.uploadMaxFiles,
|
|
29
|
+
fileSize: limits.uploadMaxFileBytes + 1,
|
|
30
|
+
parts: limits.uploadMaxFiles + 1,
|
|
31
|
+
fields: 1
|
|
32
|
+
}
|
|
33
|
+
})) {
|
|
34
|
+
if (responseError) {
|
|
35
|
+
if (part.type === 'file')
|
|
36
|
+
await drain(part.file);
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
if (part.type === 'field') {
|
|
40
|
+
if (part.fieldname !== 'manifest' || session) {
|
|
41
|
+
responseError = { statusCode: 400, code: 'invalid_attachment_manifest' };
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
const manifest = parseUploadManifest(parseManifestValue(part.value));
|
|
45
|
+
if (!manifest) {
|
|
46
|
+
responseError = { statusCode: 400, code: 'invalid_attachment_manifest' };
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
if (!await ensureComposeAttachmentTerminal(terminalManager, manifest.terminalId)) {
|
|
50
|
+
responseError = { statusCode: 404, code: 'terminal_not_found' };
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
session = await createComposeAttachmentSession({
|
|
54
|
+
attachmentRoot: attachmentRootForStatePath(config.statePath),
|
|
55
|
+
limits,
|
|
56
|
+
manifest
|
|
57
|
+
});
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
if (!session) {
|
|
61
|
+
responseError = { statusCode: 400, code: 'manifest_required' };
|
|
62
|
+
await drain(part.file);
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
await session.writeFile(part.fieldname, part.file);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
await session?.abort();
|
|
70
|
+
if (error instanceof UploadRequestError) {
|
|
71
|
+
return reply.code(error.statusCode).send({ error: error.code });
|
|
72
|
+
}
|
|
73
|
+
throw error;
|
|
74
|
+
}
|
|
75
|
+
if (responseError) {
|
|
76
|
+
await session?.abort();
|
|
77
|
+
return reply.code(responseError.statusCode).send({ error: responseError.code });
|
|
78
|
+
}
|
|
79
|
+
if (!session) {
|
|
80
|
+
return reply.code(400).send({ error: 'manifest_required' });
|
|
81
|
+
}
|
|
82
|
+
return reply.send(await session.finish());
|
|
83
|
+
}
|
|
84
|
+
export async function handleComposeAttachmentDelete(request, config, terminalManager) {
|
|
85
|
+
if (!request || typeof request.terminalId !== 'string' || !Array.isArray(request.attachmentIds) || request.attachmentIds.length === 0 || request.attachmentIds.length > composeAttachmentLimits(config).uploadMaxFiles || request.attachmentIds.some((id) => typeof id !== 'string')) {
|
|
86
|
+
throw new UploadRequestError(400, 'invalid_attachment_delete_request');
|
|
87
|
+
}
|
|
88
|
+
if (!await ensureComposeAttachmentTerminal(terminalManager, request.terminalId)) {
|
|
89
|
+
throw new UploadRequestError(404, 'terminal_not_found');
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
deleted: await deleteComposeAttachments(attachmentRootForStatePath(config.statePath), request.attachmentIds)
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
// A browser can retain a live tmux-backed pane across a server restart while
|
|
96
|
+
// the in-memory terminal catalog is still stale. Reconcile once before
|
|
97
|
+
// rejecting an authenticated attachment request; an actually missing pane
|
|
98
|
+
// remains a 404.
|
|
99
|
+
async function ensureComposeAttachmentTerminal(terminalManager, terminalId) {
|
|
100
|
+
if (terminalManager.getTerminal(terminalId))
|
|
101
|
+
return true;
|
|
102
|
+
const restoreSessions = terminalManager.restoreSessions;
|
|
103
|
+
if (typeof restoreSessions !== 'function')
|
|
104
|
+
return false;
|
|
105
|
+
await restoreSessions.call(terminalManager);
|
|
106
|
+
return terminalManager.getTerminal(terminalId) !== null;
|
|
107
|
+
}
|
|
108
|
+
function parseManifestValue(value) {
|
|
109
|
+
if (typeof value !== 'string')
|
|
110
|
+
return value;
|
|
111
|
+
try {
|
|
112
|
+
return JSON.parse(value);
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
async function drain(stream) {
|
|
119
|
+
for await (const _chunk of stream) {
|
|
120
|
+
// Consume multipart input before responding with a validation error.
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=attachmentRoutes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachmentRoutes.js","sourceRoot":"","sources":["../../../src/server/routes/attachmentRoutes.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { requireAllowedOrigin } from './authRoutes.js';
|
|
2
2
|
import { authenticateTerminalRequest } from './terminalRoutes.js';
|
|
3
3
|
import { createUploadSession, parseUploadManifest, UploadRequestError } from '../uploads/uploadService.js';
|
|
4
|
+
import { attachmentRootForStatePath, startComposeAttachmentCleanup } from '../uploads/attachmentService.js';
|
|
5
|
+
import { composeAttachmentLimitsResponse, handleComposeAttachmentDelete, handleComposeAttachmentUpload } from './attachmentRoutes.js';
|
|
4
6
|
export async function registerUploadRoutes(app, config, services) {
|
|
7
|
+
const stopAttachmentCleanup = startComposeAttachmentCleanup(attachmentRootForStatePath(config.statePath));
|
|
8
|
+
app.addHook('onClose', () => stopAttachmentCleanup());
|
|
5
9
|
app.post('/api/uploads', { preHandler: (request, reply) => requireAllowedOrigin(config, request, reply) }, async (request, reply) => {
|
|
6
10
|
const auth = await authenticateTerminalRequest(services.authService, request, reply);
|
|
7
11
|
if (!auth) {
|
|
@@ -57,6 +61,33 @@ export async function registerUploadRoutes(app, config, services) {
|
|
|
57
61
|
}
|
|
58
62
|
return session.finish();
|
|
59
63
|
});
|
|
64
|
+
app.post('/api/attachments', { preHandler: (request, reply) => requireAllowedOrigin(config, request, reply) }, async (request, reply) => {
|
|
65
|
+
const auth = await authenticateTerminalRequest(services.authService, request, reply);
|
|
66
|
+
if (!auth) {
|
|
67
|
+
return reply;
|
|
68
|
+
}
|
|
69
|
+
return handleComposeAttachmentUpload(request, reply, config, services.terminalManager);
|
|
70
|
+
});
|
|
71
|
+
app.get('/api/attachments/limits', async (request, reply) => {
|
|
72
|
+
const auth = await authenticateTerminalRequest(services.authService, request, reply);
|
|
73
|
+
if (!auth)
|
|
74
|
+
return reply;
|
|
75
|
+
return composeAttachmentLimitsResponse(config);
|
|
76
|
+
});
|
|
77
|
+
app.post('/api/attachments/delete', { preHandler: (request, reply) => requireAllowedOrigin(config, request, reply) }, async (request, reply) => {
|
|
78
|
+
const auth = await authenticateTerminalRequest(services.authService, request, reply);
|
|
79
|
+
if (!auth)
|
|
80
|
+
return reply;
|
|
81
|
+
try {
|
|
82
|
+
return await handleComposeAttachmentDelete(request.body, config, services.terminalManager);
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
if (error instanceof UploadRequestError) {
|
|
86
|
+
return reply.code(error.statusCode).send({ error: error.code });
|
|
87
|
+
}
|
|
88
|
+
throw error;
|
|
89
|
+
}
|
|
90
|
+
});
|
|
60
91
|
}
|
|
61
92
|
async function createSessionFromManifest(value, config, services) {
|
|
62
93
|
const manifest = parseUploadManifest(parseManifestValue(value));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uploadRoutes.js","sourceRoot":"","sources":["../../../src/server/routes/uploadRoutes.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,kBAAkB,EAAsB,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"uploadRoutes.js","sourceRoot":"","sources":["../../../src/server/routes/uploadRoutes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Readable } from 'node:stream';
|
|
2
|
+
import type { ComposeAttachmentUploadResponse, UploadManifest } from '../../shared/protocol.js';
|
|
3
|
+
import { type UploadLimits } from './uploadService.js';
|
|
4
|
+
export declare const defaultAttachmentMaxFiles = 10;
|
|
5
|
+
export declare const defaultAttachmentMaxFileBytes: number;
|
|
6
|
+
export declare const defaultAttachmentMaxBatchBytes: number;
|
|
7
|
+
export declare const attachmentRetentionMs: number;
|
|
8
|
+
export interface ComposeAttachmentLimits extends UploadLimits {
|
|
9
|
+
}
|
|
10
|
+
export interface ComposeAttachmentSession {
|
|
11
|
+
writeFile(fieldName: string, stream: Readable): Promise<void>;
|
|
12
|
+
finish(): Promise<ComposeAttachmentUploadResponse>;
|
|
13
|
+
abort(): Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
export declare function createComposeAttachmentSession(options: {
|
|
16
|
+
attachmentRoot: string;
|
|
17
|
+
limits: ComposeAttachmentLimits;
|
|
18
|
+
manifest: UploadManifest;
|
|
19
|
+
}): Promise<ComposeAttachmentSession>;
|
|
20
|
+
export declare function attachmentRootForStatePath(statePath: string): string;
|
|
21
|
+
export declare function startComposeAttachmentCleanup(root: string): () => void;
|
|
22
|
+
export declare function pruneExpiredComposeAttachments(root: string, now?: number): Promise<void>;
|
|
23
|
+
export declare function deleteComposeAttachments(root: string, attachmentIds: readonly string[]): Promise<string[]>;
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { chmod, mkdir, readdir, rm, stat } from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { createUploadSession, validateUploadManifest, UploadRequestError } from './uploadService.js';
|
|
5
|
+
export const defaultAttachmentMaxFiles = 10;
|
|
6
|
+
export const defaultAttachmentMaxFileBytes = 50 * 1024 * 1024;
|
|
7
|
+
export const defaultAttachmentMaxBatchBytes = 100 * 1024 * 1024;
|
|
8
|
+
export const attachmentRetentionMs = 7 * 24 * 60 * 60 * 1000;
|
|
9
|
+
const attachmentCleanupIntervalMs = 60 * 60 * 1000;
|
|
10
|
+
const attachmentIdPattern = /^([0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12})\/(attachment-[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}(?:\.[a-z0-9]{1,12})?)$/;
|
|
11
|
+
export async function createComposeAttachmentSession(options) {
|
|
12
|
+
validateUploadManifest(options.manifest, options.limits);
|
|
13
|
+
await mkdir(options.attachmentRoot, { recursive: true, mode: 0o700 });
|
|
14
|
+
await chmod(options.attachmentRoot, 0o700);
|
|
15
|
+
const sessionId = randomUUID();
|
|
16
|
+
const attachmentDir = path.join(options.attachmentRoot, sessionId);
|
|
17
|
+
await mkdir(attachmentDir, { recursive: true, mode: 0o700 });
|
|
18
|
+
await chmod(attachmentDir, 0o700);
|
|
19
|
+
const inputByField = new Map(options.manifest.entries.map((entry) => [entry.fieldName, entry]));
|
|
20
|
+
const attachmentsByField = new Map(options.manifest.entries.map((entry) => {
|
|
21
|
+
const filename = storedFilename(entry.relativePath);
|
|
22
|
+
return [entry.fieldName, { attachmentId: `${sessionId}/${filename}`, filename }];
|
|
23
|
+
}));
|
|
24
|
+
const storedManifest = {
|
|
25
|
+
terminalId: options.manifest.terminalId,
|
|
26
|
+
entries: options.manifest.entries.map((entry) => ({
|
|
27
|
+
fieldName: entry.fieldName,
|
|
28
|
+
// Never derive a stored filename from browser-controlled input. The
|
|
29
|
+
// original name stays in the response only as display metadata.
|
|
30
|
+
relativePath: attachmentsByField.get(entry.fieldName).filename,
|
|
31
|
+
size: entry.size
|
|
32
|
+
}))
|
|
33
|
+
};
|
|
34
|
+
const upload = await createUploadSession({
|
|
35
|
+
destinationCwd: attachmentDir,
|
|
36
|
+
limits: options.limits,
|
|
37
|
+
manifest: storedManifest,
|
|
38
|
+
fileMode: 0o600
|
|
39
|
+
});
|
|
40
|
+
return new StoredComposeAttachmentSession(attachmentDir, inputByField, attachmentsByField, storedManifest, upload);
|
|
41
|
+
}
|
|
42
|
+
export function attachmentRootForStatePath(statePath) {
|
|
43
|
+
return path.join(path.dirname(statePath), 'attachments');
|
|
44
|
+
}
|
|
45
|
+
// Cleanup also runs at server start and every hour. The interval is unref'd,
|
|
46
|
+
// so it cannot keep the process alive during shutdown.
|
|
47
|
+
export function startComposeAttachmentCleanup(root) {
|
|
48
|
+
let running = false;
|
|
49
|
+
const run = () => {
|
|
50
|
+
if (running)
|
|
51
|
+
return;
|
|
52
|
+
running = true;
|
|
53
|
+
void pruneExpiredComposeAttachments(root).catch(() => undefined).finally(() => {
|
|
54
|
+
running = false;
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
run();
|
|
58
|
+
const timer = setInterval(run, attachmentCleanupIntervalMs);
|
|
59
|
+
timer.unref();
|
|
60
|
+
return () => clearInterval(timer);
|
|
61
|
+
}
|
|
62
|
+
export async function pruneExpiredComposeAttachments(root, now = Date.now()) {
|
|
63
|
+
try {
|
|
64
|
+
const entries = await readdir(root, { withFileTypes: true });
|
|
65
|
+
await Promise.all(entries.filter((entry) => entry.isDirectory()).map(async (entry) => {
|
|
66
|
+
const candidate = path.join(root, entry.name);
|
|
67
|
+
try {
|
|
68
|
+
const metadata = await stat(candidate);
|
|
69
|
+
if (now - metadata.mtimeMs > attachmentRetentionMs) {
|
|
70
|
+
await rm(candidate, { recursive: true, force: true, maxRetries: 2 });
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
if (!isNotFound(error)) {
|
|
75
|
+
throw error;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}));
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
if (isNotFound(error)) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
throw error;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
export async function deleteComposeAttachments(root, attachmentIds) {
|
|
88
|
+
const targets = attachmentIds.map(parseAttachmentId);
|
|
89
|
+
if (targets.some((target) => target === null)) {
|
|
90
|
+
throw new UploadRequestError(400, 'invalid_attachment_id');
|
|
91
|
+
}
|
|
92
|
+
const deleted = [];
|
|
93
|
+
for (const target of targets) {
|
|
94
|
+
if (!target)
|
|
95
|
+
continue;
|
|
96
|
+
const directory = path.join(root, target.sessionId);
|
|
97
|
+
const filePath = path.join(directory, target.filename);
|
|
98
|
+
await rm(filePath, { force: true });
|
|
99
|
+
deleted.push(target.attachmentId);
|
|
100
|
+
try {
|
|
101
|
+
if ((await readdir(directory)).length === 0) {
|
|
102
|
+
await rm(directory, { recursive: true, force: true });
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
if (!isNotFound(error))
|
|
107
|
+
throw error;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return deleted;
|
|
111
|
+
}
|
|
112
|
+
class StoredComposeAttachmentSession {
|
|
113
|
+
attachmentDir;
|
|
114
|
+
inputByField;
|
|
115
|
+
attachmentsByField;
|
|
116
|
+
storedManifest;
|
|
117
|
+
upload;
|
|
118
|
+
constructor(attachmentDir, inputByField, attachmentsByField, storedManifest, upload) {
|
|
119
|
+
this.attachmentDir = attachmentDir;
|
|
120
|
+
this.inputByField = inputByField;
|
|
121
|
+
this.attachmentsByField = attachmentsByField;
|
|
122
|
+
this.storedManifest = storedManifest;
|
|
123
|
+
this.upload = upload;
|
|
124
|
+
}
|
|
125
|
+
writeFile(fieldName, stream) {
|
|
126
|
+
return this.upload.writeFile(fieldName, stream);
|
|
127
|
+
}
|
|
128
|
+
abort() {
|
|
129
|
+
return Promise.all([
|
|
130
|
+
this.upload.abort(),
|
|
131
|
+
rm(this.attachmentDir, { recursive: true, force: true })
|
|
132
|
+
]).then(() => undefined);
|
|
133
|
+
}
|
|
134
|
+
async finish() {
|
|
135
|
+
const response = await this.upload.finish();
|
|
136
|
+
const storedByField = new Map(this.storedManifest.entries.map((entry) => [entry.fieldName, entry]));
|
|
137
|
+
const results = response.results.map((result, index) => {
|
|
138
|
+
const stored = this.storedManifest.entries[index];
|
|
139
|
+
const original = stored ? this.inputByField.get(stored.fieldName) : undefined;
|
|
140
|
+
if (!original || !stored) {
|
|
141
|
+
return { relativePath: result.relativePath, status: 'failed', error: 'invalid_attachment_result' };
|
|
142
|
+
}
|
|
143
|
+
const storedAttachment = this.attachmentsByField.get(stored.fieldName);
|
|
144
|
+
if (!storedAttachment) {
|
|
145
|
+
return { relativePath: original.relativePath, status: 'failed', error: 'attachment_path_unavailable' };
|
|
146
|
+
}
|
|
147
|
+
if (result.status !== 'uploaded') {
|
|
148
|
+
return result.error
|
|
149
|
+
? { relativePath: original.relativePath, status: 'failed', error: result.error }
|
|
150
|
+
: { relativePath: original.relativePath, status: 'failed' };
|
|
151
|
+
}
|
|
152
|
+
const saved = result.savedRelativePath ?? storedByField.get(stored.fieldName)?.relativePath;
|
|
153
|
+
if (!saved) {
|
|
154
|
+
return { relativePath: original.relativePath, status: 'failed', error: 'attachment_path_unavailable' };
|
|
155
|
+
}
|
|
156
|
+
return result.size === undefined ? {
|
|
157
|
+
relativePath: original.relativePath,
|
|
158
|
+
attachmentId: storedAttachment.attachmentId,
|
|
159
|
+
path: path.join(this.attachmentDir, saved),
|
|
160
|
+
status: 'uploaded'
|
|
161
|
+
} : {
|
|
162
|
+
relativePath: original.relativePath,
|
|
163
|
+
attachmentId: storedAttachment.attachmentId,
|
|
164
|
+
path: path.join(this.attachmentDir, saved),
|
|
165
|
+
status: 'uploaded',
|
|
166
|
+
size: result.size
|
|
167
|
+
};
|
|
168
|
+
});
|
|
169
|
+
return {
|
|
170
|
+
uploaded: results.filter((result) => result.status === 'uploaded').length,
|
|
171
|
+
failed: results.filter((result) => result.status === 'failed').length,
|
|
172
|
+
results
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
function storedFilename(relativePath) {
|
|
177
|
+
const extension = safeExtension(relativePath);
|
|
178
|
+
return `attachment-${randomUUID()}${extension}`;
|
|
179
|
+
}
|
|
180
|
+
function safeExtension(relativePath) {
|
|
181
|
+
const base = path.posix.basename(relativePath);
|
|
182
|
+
const extension = path.posix.extname(base).toLowerCase();
|
|
183
|
+
return /^[.][a-z0-9]{1,12}$/.test(extension) ? extension : '';
|
|
184
|
+
}
|
|
185
|
+
function isNotFound(error) {
|
|
186
|
+
return typeof error === 'object' && error !== null && 'code' in error && error.code === 'ENOENT';
|
|
187
|
+
}
|
|
188
|
+
function parseAttachmentId(attachmentId) {
|
|
189
|
+
const match = attachmentIdPattern.exec(attachmentId);
|
|
190
|
+
if (!match)
|
|
191
|
+
return null;
|
|
192
|
+
return { attachmentId, sessionId: match[1], filename: match[2] };
|
|
193
|
+
}
|
|
194
|
+
//# sourceMappingURL=attachmentService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachmentService.js","sourceRoot":"","sources":["../../../src/server/uploads/attachmentService.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,6 +6,7 @@ export interface CreateUploadSessionOptions {
|
|
|
6
6
|
destinationCwd: string;
|
|
7
7
|
limits: UploadLimits;
|
|
8
8
|
manifest: UploadManifest;
|
|
9
|
+
fileMode?: number;
|
|
9
10
|
}
|
|
10
11
|
export declare class UploadRequestError extends Error {
|
|
11
12
|
readonly statusCode: number;
|
|
@@ -19,3 +20,4 @@ export interface UploadSession {
|
|
|
19
20
|
}
|
|
20
21
|
export declare function createUploadSession(options: CreateUploadSessionOptions): Promise<UploadSession>;
|
|
21
22
|
export declare function parseUploadManifest(value: unknown): UploadManifest | null;
|
|
23
|
+
export declare function validateUploadManifest(manifest: UploadManifest, limits: UploadLimits): void;
|
|
@@ -13,9 +13,9 @@ export class UploadRequestError extends Error {
|
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
export async function createUploadSession(options) {
|
|
16
|
-
|
|
16
|
+
validateUploadManifest(options.manifest, options.limits);
|
|
17
17
|
const pathPlan = await planUploadTargets(options.destinationCwd, options.manifest.entries);
|
|
18
|
-
return new StreamingUploadSession(options.destinationCwd, options.manifest.entries, options.limits, pathPlan.targets, pathPlan.failures);
|
|
18
|
+
return new StreamingUploadSession(options.destinationCwd, options.manifest.entries, options.limits, pathPlan.targets, pathPlan.failures, options.fileMode);
|
|
19
19
|
}
|
|
20
20
|
export function parseUploadManifest(value) {
|
|
21
21
|
if (!value || typeof value !== 'object') {
|
|
@@ -53,15 +53,17 @@ class StreamingUploadSession {
|
|
|
53
53
|
destinationCwd;
|
|
54
54
|
entries;
|
|
55
55
|
limits;
|
|
56
|
+
fileMode;
|
|
56
57
|
targetsByField = new Map();
|
|
57
58
|
failuresByField = new Map();
|
|
58
59
|
resultsByField = new Map();
|
|
59
60
|
createdFiles = new Set();
|
|
60
61
|
actualBatchBytes = 0;
|
|
61
|
-
constructor(destinationCwd, entries, limits, targets, failures) {
|
|
62
|
+
constructor(destinationCwd, entries, limits, targets, failures, fileMode) {
|
|
62
63
|
this.destinationCwd = destinationCwd;
|
|
63
64
|
this.entries = entries;
|
|
64
65
|
this.limits = limits;
|
|
66
|
+
this.fileMode = fileMode;
|
|
65
67
|
for (const target of targets) {
|
|
66
68
|
if (target.size > limits.uploadMaxFileBytes) {
|
|
67
69
|
this.failuresByField.set(target.fieldName, {
|
|
@@ -108,7 +110,7 @@ class StreamingUploadSession {
|
|
|
108
110
|
let createdPath = null;
|
|
109
111
|
let handle = null;
|
|
110
112
|
try {
|
|
111
|
-
handle = await open(target.absolutePath, 'wx');
|
|
113
|
+
handle = await open(target.absolutePath, 'wx', this.fileMode);
|
|
112
114
|
createdPath = target.absolutePath;
|
|
113
115
|
await pipeline(stream, counter, handle.createWriteStream());
|
|
114
116
|
this.createdFiles.add(target.absolutePath);
|
|
@@ -187,7 +189,7 @@ class StreamingUploadSession {
|
|
|
187
189
|
return counter;
|
|
188
190
|
}
|
|
189
191
|
}
|
|
190
|
-
function
|
|
192
|
+
export function validateUploadManifest(manifest, limits) {
|
|
191
193
|
if (manifest.entries.length > limits.uploadMaxFiles) {
|
|
192
194
|
throw new UploadRequestError(413, 'too_many_files');
|
|
193
195
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uploadService.js","sourceRoot":"","sources":["../../../src/server/uploads/uploadService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAiB,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAGhD,OAAO,EAAE,iBAAiB,EAAqB,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"uploadService.js","sourceRoot":"","sources":["../../../src/server/uploads/uploadService.ts"],"names":[],"mappings":"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"}
|
|
@@ -279,6 +279,31 @@ export interface UploadResponse {
|
|
|
279
279
|
failed: number;
|
|
280
280
|
results: UploadResultEntry[];
|
|
281
281
|
}
|
|
282
|
+
export interface ComposeAttachmentResult {
|
|
283
|
+
relativePath: string;
|
|
284
|
+
attachmentId?: string;
|
|
285
|
+
path?: string;
|
|
286
|
+
status: 'uploaded' | 'failed';
|
|
287
|
+
size?: number;
|
|
288
|
+
error?: string;
|
|
289
|
+
}
|
|
290
|
+
export interface ComposeAttachmentUploadResponse {
|
|
291
|
+
uploaded: number;
|
|
292
|
+
failed: number;
|
|
293
|
+
results: ComposeAttachmentResult[];
|
|
294
|
+
}
|
|
295
|
+
export interface ComposeAttachmentLimitsResponse {
|
|
296
|
+
maxFiles: number;
|
|
297
|
+
maxFileBytes: number;
|
|
298
|
+
maxBatchBytes: number;
|
|
299
|
+
}
|
|
300
|
+
export interface ComposeAttachmentDeleteRequest {
|
|
301
|
+
terminalId: TerminalId;
|
|
302
|
+
attachmentIds: string[];
|
|
303
|
+
}
|
|
304
|
+
export interface ComposeAttachmentDeleteResponse {
|
|
305
|
+
deleted: string[];
|
|
306
|
+
}
|
|
282
307
|
export interface NotificationAssetSummary {
|
|
283
308
|
id: string;
|
|
284
309
|
filename: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/shared/protocol.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,cAAc,GAAG,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/shared/protocol.ts"],"names":[],"mappings":"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"}
|
package/docs/configuration.md
CHANGED
|
@@ -38,6 +38,9 @@ Onboarding writes `.env` for you, including an absolute `NTERMINAL_STATE_PATH` s
|
|
|
38
38
|
| `NTERMINAL_UPLOAD_MAX_FILES` | `1024` | Maximum files accepted in one drag-and-drop upload. |
|
|
39
39
|
| `NTERMINAL_UPLOAD_MAX_FILE_BYTES` | `536870912` | Maximum bytes accepted for one uploaded file. |
|
|
40
40
|
| `NTERMINAL_UPLOAD_MAX_BATCH_BYTES` | `2147483648` | Maximum total bytes accepted for one upload batch. |
|
|
41
|
+
| `NTERMINAL_ATTACHMENT_MAX_FILES` | `10` | Maximum files attached to one compose upload. |
|
|
42
|
+
| `NTERMINAL_ATTACHMENT_MAX_FILE_BYTES` | `52428800` | Maximum size of one compose attachment (50 MB). |
|
|
43
|
+
| `NTERMINAL_ATTACHMENT_MAX_BATCH_BYTES` | `104857600` | Maximum total bytes in one compose attachment upload (100 MB). |
|
|
41
44
|
| `NTERMINAL_FILE_LIST_MAX_ENTRIES` | `2000` | Maximum entries returned in one file explorer directory listing. |
|
|
42
45
|
| `NTERMINAL_FILE_TEXT_MAX_BYTES` | `1048576` | Maximum bytes loaded for text or Markdown view/edit. |
|
|
43
46
|
| `NTERMINAL_FILE_PREVIEW_MAX_BYTES` | `52428800` | Maximum bytes served for browser file previews. |
|
package/docs/features.md
CHANGED
|
@@ -74,6 +74,17 @@ Drop files or folders onto the terminal workspace to upload them into the active
|
|
|
74
74
|
- Retrying a partial upload sends only failed files, avoiding duplicate renamed copies of successful uploads.
|
|
75
75
|
- Unsupported folder drops fail visibly instead of flattening the folder.
|
|
76
76
|
|
|
77
|
+
## Compose Attachments
|
|
78
|
+
|
|
79
|
+
Compose can attach source files, Markdown, images, and other files without writing them into the active project directory.
|
|
80
|
+
|
|
81
|
+
- Choose files, drop them on an open Compose drawer, or paste browser clipboard files.
|
|
82
|
+
- Attachments are written to a private `~/.nterminal/attachments` directory on the terminal's own server, including secondary servers.
|
|
83
|
+
- Send and Queue append the uploaded paths to the compose message so Codex, Claude, or another CLI agent can read them directly.
|
|
84
|
+
- Images show a thumbnail; other files show their name and upload state.
|
|
85
|
+
- Compose attachments default to 10 files, 50 MB each, and 100 MB per upload. The active server reports its configured limits to Compose.
|
|
86
|
+
- Removing an uploaded attachment or using Clear deletes it from private runtime storage before it is sent. Sent attachments expire automatically after seven days and are swept within an hour.
|
|
87
|
+
|
|
77
88
|
## Completion Notifications
|
|
78
89
|
|
|
79
90
|
NTerminal can show completion notifications when a background command transitions from busy to idle.
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{j as a}from"./index-XrYKpFyQ.js";import{M as e,r as o}from"./index-DcP0SS12.js";function s({content:r}){return a.jsx(e,{remarkPlugins:[o],children:r})}export{s as default};
|