nterminal 1.2.88 → 1.2.90
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-4fzY6p-f.js +1 -0
- package/dist/client/assets/{TranscriptMarkdownBody-CvclqHm3.js → TranscriptMarkdownBody-Bkq8AHtC.js} +1 -1
- package/dist/client/assets/{index-DcP0SS12.js → index-BI8o0HfA.js} +1 -1
- package/dist/client/assets/index-CiLqZsSA.css +1 -0
- package/dist/client/assets/index-Cr6EN3hl.js +57 -0
- 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
- package/dist/client/assets/index-yKhwlegq.css +0 -1
|
@@ -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":"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;AAWxE,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAEzB;IACA;IAFlB,YACkB,UAAkB,EAClB,IAAY;QAE5B,KAAK,CAAC,IAAI,CAAC,CAAC;QAHI,eAAU,GAAV,UAAU,CAAQ;QAClB,SAAI,GAAJ,IAAI,CAAQ;IAG9B,CAAC;CACF;AAQD,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,OAAmC;IAC3E,sBAAsB,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACzD,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,OAAO,CAAC,cAAc,EAAE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC3F,OAAO,IAAI,sBAAsB,CAC/B,OAAO,CAAC,cAAc,EACtB,OAAO,CAAC,QAAQ,CAAC,OAAO,EACxB,OAAO,CAAC,MAAM,EACd,QAAQ,CAAC,OAAO,EAChB,QAAQ,CAAC,QAAQ,EACjB,OAAO,CAAC,QAAQ,CACjB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,KAAc;IAChD,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACxC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,QAAQ,GAAG,KAAgC,CAAC;IAClD,IAAI,OAAO,QAAQ,CAAC,UAAU,KAAK,QAAQ,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAC/G,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,OAAO,GAA0B,EAAE,CAAC;IAC1C,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;QACrC,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YACxC,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,SAAS,GAAG,KAAqC,CAAC;QACxD,MAAM,SAAS,GAAG,SAAS,CAAC,SAAS,CAAC;QACtC,MAAM,YAAY,GAAG,SAAS,CAAC,YAAY,CAAC;QAC5C,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC;QAC5B,IACE,OAAO,SAAS,KAAK,QAAQ;YAC7B,OAAO,YAAY,KAAK,QAAQ;YAChC,OAAO,IAAI,KAAK,QAAQ;YACxB,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC;YAC3B,IAAI,GAAG,CAAC,EACR,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,CAAC,IAAI,CAAC;YACX,SAAS;YACT,YAAY;YACZ,IAAI;SACL,CAAC,CAAC;IACL,CAAC;IACD,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC,UAAU,EAAE,OAAO,EAAE,CAAC;AACtD,CAAC;AAED,MAAM,sBAAsB;IAQP;IACA;IACA;IAGA;IAZF,cAAc,GAAG,IAAI,GAAG,EAAwB,CAAC;IACjD,eAAe,GAAG,IAAI,GAAG,EAA6B,CAAC;IACvD,cAAc,GAAG,IAAI,GAAG,EAA6B,CAAC;IACtD,YAAY,GAAG,IAAI,GAAG,EAAU,CAAC;IAC1C,gBAAgB,GAAG,CAAC,CAAC;IAE7B,YACmB,cAAsB,EACtB,OAA8B,EAC9B,MAAoB,EACrC,OAAuB,EACvB,QAA2E,EAC1D,QAAiB;QALjB,mBAAc,GAAd,cAAc,CAAQ;QACtB,YAAO,GAAP,OAAO,CAAuB;QAC9B,WAAM,GAAN,MAAM,CAAc;QAGpB,aAAQ,GAAR,QAAQ,CAAS;QAElC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,IAAI,MAAM,CAAC,IAAI,GAAG,MAAM,CAAC,kBAAkB,EAAE,CAAC;gBAC5C,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE;oBACzC,YAAY,EAAE,MAAM,CAAC,YAAY;oBACjC,MAAM,EAAE,QAAQ;oBAChB,KAAK,EAAE,gBAAgB;iBACxB,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;YACpD,CAAC;QACH,CAAC;QACD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE;gBAC1C,YAAY,EAAE,OAAO,CAAC,YAAY;gBAClC,MAAM,EAAE,QAAQ;gBAChB,KAAK,EAAE,OAAO,CAAC,KAAK;aACrB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,SAAiB,EAAE,MAAgB;QACjD,IAAI,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YACvC,MAAM,KAAK,CAAC,MAAM,CAAC,CAAC;YACpB,OAAO;QACT,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAClD,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YACnD,MAAM,KAAK,CAAC,MAAM,CAAC,CAAC;YACpB,OAAO;QACT,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QACpD,MAAM,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5C,IAAI,CAAC,CAAC,MAAM,mBAAmB,CAAC,IAAI,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC;YACjE,MAAM,KAAK,CAAC,MAAM,CAAC,CAAC;YACpB,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,EAAE;gBACjC,YAAY,EAAE,MAAM,CAAC,YAAY;gBACjC,iBAAiB,EAAE,MAAM,CAAC,iBAAiB;gBAC3C,MAAM,EAAE,QAAQ;gBAChB,KAAK,EAAE,oBAAoB;aAC5B,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1C,IAAI,WAAW,GAAkB,IAAI,CAAC;QACtC,IAAI,MAAM,GAA4C,IAAI,CAAC;QAC3D,IAAI,CAAC;YACH,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC9D,WAAW,GAAG,MAAM,CAAC,YAAY,CAAC;YAClC,MAAM,QAAQ,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,iBAAiB,EAAE,CAAC,CAAC;YAC5D,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;YAC3C,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,EAAE;gBACjC,YAAY,EAAE,MAAM,CAAC,YAAY;gBACjC,iBAAiB,EAAE,MAAM,CAAC,iBAAiB;gBAC3C,MAAM,EAAE,UAAU;gBAClB,IAAI,EAAE,OAAO,CAAC,SAAS;aACxB,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,MAAM,KAAK,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;YAC7C,CAAC;YACD,MAAM,MAAM,EAAE,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;YAC7C,IAAI,WAAW,EAAE,CAAC;gBAChB,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;YACnD,CAAC;YACD,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,EAAE;gBACjC,YAAY,EAAE,MAAM,CAAC,YAAY;gBACjC,iBAAiB,EAAE,MAAM,CAAC,iBAAiB;gBAC3C,MAAM,EAAE,QAAQ;gBAChB,KAAK,EAAE,oBAAoB,CAAC,KAAK,CAAC;aACnC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACnD,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;QAC1B,MAAM,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAC7F,CAAC;IAED,KAAK,CAAC,MAAM;QACV,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAqB,EAAE;YAC5D,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;YACxD,IAAI,MAAM,EAAE,CAAC;gBACX,OAAO,MAAM,CAAC;YAChB,CAAC;YACD,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;YAC1D,IAAI,OAAO,EAAE,CAAC;gBACZ,OAAO,OAAO,CAAC;YACjB,CAAC;YACD,OAAO;gBACL,YAAY,EAAE,KAAK,CAAC,YAAY;gBAChC,MAAM,EAAE,QAAQ;gBAChB,KAAK,EAAE,cAAc;aACtB,CAAC;QACJ,CAAC,CAAC,CAAC;QACH,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,MAAM,CAAC;QACjF,OAAO;YACL,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,QAAQ;YACR,MAAM,EAAE,OAAO,CAAC,MAAM,GAAG,QAAQ;YACjC,OAAO;SACR,CAAC;IACJ,CAAC;IAEO,kBAAkB;QACxB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC3B,MAAM,OAAO,GAAG,IAAI,CAAC;QACrB,MAAM,OAAO,GAAG,IAAI,SAAS,CAAC;YAC5B,SAAS,CAAC,KAAsB,EAAE,SAAS,EAAE,QAAQ;gBACnD,MAAM,UAAU,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;gBACvF,OAAO,CAAC,SAAS,IAAI,UAAU,CAAC;gBAChC,OAAO,CAAC,gBAAgB,IAAI,UAAU,CAAC;gBACvC,IAAI,OAAO,CAAC,SAAS,GAAG,MAAM,CAAC,kBAAkB,EAAE,CAAC;oBAClD,QAAQ,CAAC,IAAI,kBAAkB,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC,CAAC;oBACxD,OAAO;gBACT,CAAC;gBACD,IAAI,OAAO,CAAC,gBAAgB,GAAG,MAAM,CAAC,mBAAmB,EAAE,CAAC;oBAC1D,QAAQ,CAAC,IAAI,kBAAkB,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC,CAAC;oBACzD,OAAO;gBACT,CAAC;gBACD,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YACxB,CAAC;SACF,CAAsC,CAAC;QACxC,OAAO,CAAC,SAAS,GAAG,CAAC,CAAC;QACtB,OAAO,OAAO,CAAC;IACjB,CAAC;CACF;AAED,MAAM,UAAU,sBAAsB,CAAC,QAAwB,EAAE,MAAoB;IACnF,IAAI,QAAQ,CAAC,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC,cAAc,EAAE,CAAC;QACpD,MAAM,IAAI,kBAAkB,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC;IACtD,CAAC;IACD,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IACrC,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;QACrC,IAAI,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;YACpC,MAAM,IAAI,kBAAkB,CAAC,GAAG,EAAE,wBAAwB,CAAC,CAAC;QAC9D,CAAC;QACD,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAClC,CAAC;IACD,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACpF,IAAI,UAAU,GAAG,MAAM,CAAC,mBAAmB,EAAE,CAAC;QAC5C,MAAM,IAAI,kBAAkB,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC;IACvD,CAAC;AACH,CAAC;AAED,KAAK,UAAU,KAAK,CAAC,MAAgB;IACnC,IAAI,KAAK,EAAE,MAAM,MAAM,IAAI,MAAM,EAAE,CAAC;QAClC,wDAAwD;IAC1D,CAAC;AACH,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAc;IAC1C,IAAI,mBAAmB,CAAC,KAAK,EAAE,QAAQ,CAAC,EAAE,CAAC;QACzC,OAAO,eAAe,CAAC;IACzB,CAAC;IACD,OAAO,KAAK,YAAY,kBAAkB,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC;AAC3E,CAAC;AAED,KAAK,UAAU,mBAAmB,CAAC,IAAY,EAAE,SAAiB;IAChE,IAAI,CAAC;QACH,MAAM,CAAC,YAAY,EAAE,iBAAiB,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QACnG,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE,iBAAiB,CAAC,CAAC;QAChE,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC;IACvF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAc,EAAE,IAAY;IACvD,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,MAAM,IAAI,KAAK,IAAK,KAA4B,CAAC,IAAI,KAAK,IAAI,CAAC;AACvH,CAAC"}
|
|
@@ -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};
|