superun-ai-cli 0.1.28 → 0.1.30

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.en.md CHANGED
@@ -78,9 +78,12 @@ superun-ai
78
78
  │ ├── login # Sign in and save a PAT
79
79
  │ ├── status # Check local PAT configuration
80
80
  │ └── logout # Remove the locally saved PAT
81
- ├── session # Query projects
81
+ ├── session # Query projects and conversation binding
82
82
  │ ├── list # List projects
83
- │ └── get <sessionId> # Get project details
83
+ │ ├── get <sessionId> # Get project details
84
+ │ ├── current # Read the saved project for this host conversation
85
+ │ ├── use <sessionId> # Select a project for this conversation
86
+ │ └── clear # Clear the local binding and keep the remote project
84
87
  ├── chat # Conversational creation
85
88
  │ ├── create # Create a project and send a request
86
89
  │ ├── send <sessionId> # Continue the conversation
@@ -116,6 +119,22 @@ superun-ai
116
119
 
117
120
  Run `npm run docs:sync` after changing command registration to update both command trees. `npm run docs:check` validates their completeness; `prepack` also checks them before packaging.
118
121
 
122
+ ## Restore the project for this conversation
123
+
124
+ In Codex and WorkBuddy / CodeBuddy environments with a verifiable conversation identity, the CLI remembers one project per conversation. Creating a project or explicitly operating on another project replaces the binding. Listing projects, reading details, and waiting for tasks do not change it.
125
+
126
+ ```bash
127
+ superun-ai session current
128
+ superun-ai session use <sessionId>
129
+ superun-ai session clear
130
+ ```
131
+
132
+ `current` returns the saved `sessionId`. Use existing commands to read project details or continue with `chat send <sessionId>`. Use `use` when switching projects without starting work; `clear` removes only the local binding and keeps the remote project. You do not need to run `use` before every command.
133
+
134
+ Bindings survive reopening the same host conversation and are isolated by conversation, superun account, and endpoint. WorkBuddy subagents share the main task binding when their ownership can be verified. Bindings are local to this device.
135
+
136
+ `UNBOUND` means no project is selected. `UNAVAILABLE` means the host conversation cannot be identified; continue passing an explicit `sessionId`. For `CREATING` or `CREATE_UNKNOWN`, check the original creation request before creating again. Once you have confirmed the project ID, restore the binding with `use`.
137
+
119
138
  ## PAT login
120
139
 
121
140
  ```bash
@@ -292,11 +311,29 @@ After the user explicitly asks to launch the site, use `chat publish status <ses
292
311
 
293
312
  `chat publish start --indexing allow|deny` controls search-engine indexing, not visitor access. Change site visibility with `chat publish visibility`. If the service requires acknowledgment of cloud costs, review them before explicitly passing `--acknowledge-cloud-fee`.
294
313
 
295
- ## Text input and result files
314
+ ## Text input and attachments
315
+
316
+ `chat create/send/test/review` supports repeated `--file <path>` options for local uploads. Supply text through mutually exclusive `--message <text>` or `--input <file>` / `--input -`. JSON accepts only `content` or `message`, not `attachments`, inline file data, or attachment URLs. `--input` reads request JSON; only `--file` uploads a file. create/send also accepts files without text.
317
+
318
+ ```bash
319
+ superun-ai chat create --message "Build a chat summary app using the attachment" --file ./feishu-group-digest.md
320
+ superun-ai chat send <sessionId> --input ./request.json --file ./design.png --file ./requirements.pdf
321
+ ```
322
+
323
+ The CLI loads Glow's current file extension and size rules before uploading. Current China production limits are listed below; the connected environment's response is authoritative.
324
+
325
+ | Category | Supported extensions | Current per-file limit |
326
+ | --- | --- | --- |
327
+ | Images | png, jpg, jpeg, webp, gif | 20 MB; try Glow's compression flow when exceeded |
328
+ | Text and code | txt, md, svg, js, ts, jsx, tsx, py, java, cpp, c, h, cs, php, rb, go, rs, swift, html, css, scss, less, json, xml, yaml, yml | 5 MB |
329
+ | Documents | pdf, docx | 50 MB |
330
+ | Spreadsheets | xlsx, xls; csv | Excel 30 MB; CSV 5 MB |
331
+ | Video | mp4, mov, webm, avi, wmv, flv, mkv | 15 MB; readable duration of at most 5 minutes plus 2 seconds tolerance |
332
+ | Audio and archives | mp3, wav, ogg, flac, m4a, aac, zip, rar | 15 MB |
296
333
 
297
- `chat create/send/test/review` accepts plain text only. Neither `--file` nor JSON `attachments` (including an empty array) is supported. Use `--message <text>` or load JSON containing only `content` or `message` with `--input <file>` / `--input -`; the two text fields are mutually exclusive. `--input` reads request JSON and does not upload the file.
334
+ Each message allows at most 10 files, including at most 5 PDFs. Image dimensions/pixel count, PDF pages, and Word image counts follow the same rules as Glow. Current China production limits are 29900 pixels per image edge, 24999999 total pixels, and 800 PDF pages or Word images. Missing configuration, invalid files, audit failures, or preprocessing failures stop the entire message instead of silently dropping attachments.
298
335
 
299
- Put the complete requirements and text material in `content`, for example `{"content":"Full requirements\n\n## Reference material\nFull material text"}`. Hosts should read text files and include their contents in the text, rather than saying “see attachment” or passing only a local path. Report any material that cannot be read instead of claiming it was submitted.
336
+ Every file, including small Markdown/TXT files, is uploaded and audited before being sent as `name/url/mediaType/meta`. PDFs, Word documents, and Excel/CSV files use Glow's preprocessing services and retain their parsed metadata. File text and Base64 are never sent as attachment `content`. Progress goes to stderr; the creation message is sent once, after every attachment is ready. `--no-wait` still completes upload, audit, and preprocessing. Bundled dependencies read image dimensions and video duration locally without requiring FFmpeg. Do not upload `.env` or CLI credential files.
300
337
 
301
338
  `session get --include-attachments` returns visible attachments. `chat state --include-file <name>` reads a named visible file. System files and secret configuration are not returned as result attachments.
302
339
 
package/README.md CHANGED
@@ -80,9 +80,12 @@ superun-ai
80
80
  │ ├── login # 登录 superun 并保存 PAT
81
81
  │ ├── status # 查看本地 PAT 配置状态
82
82
  │ └── logout # 清除本地 PAT
83
- ├── session # 查询项目
83
+ ├── session # 查询项目与当前会话绑定
84
84
  │ ├── list # 查询项目列表
85
- │ └── get <sessionId> # 查询项目详情
85
+ │ ├── get <sessionId> # 查询项目详情
86
+ │ ├── current # 读取当前宿主会话保存的项目绑定
87
+ │ ├── use <sessionId> # 选择当前会话继续使用的项目
88
+ │ └── clear # 清除当前会话的项目绑定,保留远端项目
86
89
  ├── chat # 对话创作
87
90
  │ ├── create # 新建项目并发送需求
88
91
  │ ├── send <sessionId> # 继续项目创作
@@ -118,6 +121,22 @@ superun-ai
118
121
 
119
122
  命令树以源码注册为准。新增或调整命令后执行 `npm run docs:sync` 同步中英文命令树;`npm run docs:check` 校验完整性。发包前的 `prepack` 同样执行校验,发现遗漏或过期参数时停止发包准备。
120
123
 
124
+ ## 恢复当前会话的项目
125
+
126
+ 在可识别会话归属的 Codex、WorkBuddy / CodeBuddy 环境中,CLI 会自动记住当前会话正在创作的一个项目。新建项目会替换原绑定;显式操作另一个项目也会切换。列出项目、查询详情或等待任务不会改变绑定。
127
+
128
+ ```bash
129
+ superun-ai session current
130
+ superun-ai session use <sessionId>
131
+ superun-ai session clear
132
+ ```
133
+
134
+ `current` 返回已保存的 `sessionId`。需要项目详情时,用该 ID 调用已有查询命令;继续创作仍使用 `chat send <sessionId>`。`use` 适用于只切换项目、暂不创作的情况;`clear` 只解除本地绑定,保留远端项目。平时无需在每次命令前执行 `use`。
135
+
136
+ 同一宿主会话重开后可恢复绑定,不同会话、superun 账号和连接环境分别保存。WorkBuddy 子专家在能核对主任务归属时共用主任务绑定。该记录保存在本机,不跨设备同步。
137
+
138
+ `UNBOUND` 表示尚未绑定;`UNAVAILABLE` 表示无法识别宿主会话,此时继续显式传入 `sessionId`。若返回 `CREATING` 或 `CREATE_UNKNOWN`,先核对原创建请求,不要重复创建;确认已有项目后可用 `use` 恢复绑定。
139
+
121
140
  ## PAT 登录
122
141
 
123
142
  ```bash
@@ -420,11 +439,29 @@ superun-ai chat publish visibility <sessionId> private
420
439
 
421
440
  `chat publish start --indexing allow|deny` 控制搜索引擎索引,不限制用户访问;站点上下线使用 `chat publish visibility`。若服务端要求确认云服务费用,了解费用后可显式传入 `--acknowledge-cloud-fee`。
422
441
 
423
- ## 文本输入与结果文件
442
+ ## 文本输入与附件
443
+
444
+ `chat create/send/test/review` 支持重复使用 `--file <path>` 上传本地文件。文本仍通过互斥的 `--message <text>` 或 `--input <file>` / `--input -` 传入;JSON 只包含 `content` 或 `message`,不接受 `attachments`、内联文件内容或附件 URL。`--input` 读取的是请求 JSON,不会将该 JSON 文件上传;要上传文件必须显式使用 `--file`。create/send 也支持仅传文件。
445
+
446
+ ```bash
447
+ superun-ai chat create --message "根据附件制作聊天消息总结应用" --file ./feishu-group-digest.md
448
+ superun-ai chat send <sessionId> --input ./request.json --file ./design.png --file ./requirements.pdf
449
+ ```
450
+
451
+ CLI 每次上传前读取 Glow 同源的服务端格式和大小限制。当前主站配置如下,实际限制以当前连接环境返回为准:
452
+
453
+ | 文件类别 | 支持扩展名 | 当前单文件上限 |
454
+ | --- | --- | --- |
455
+ | 图片 | png、jpg、jpeg、webp、gif | 20MB,超限时按 Glow 流程尝试压缩 |
456
+ | 文本及代码 | txt、md、svg、js、ts、jsx、tsx、py、java、cpp、c、h、cs、php、rb、go、rs、swift、html、css、scss、less、json、xml、yaml、yml | 5MB |
457
+ | 文档 | pdf、docx | 50MB |
458
+ | 表格 | xlsx、xls;csv | Excel 30MB,CSV 5MB |
459
+ | 视频 | mp4、mov、webm、avi、wmv、flv、mkv | 15MB,必须能读取时长且不超过 5 分钟(含 2 秒容差) |
460
+ | 音频及压缩包 | mp3、wav、ogg、flac、m4a、aac、zip、rar | 15MB |
424
461
 
425
- `chat create/send/test/review` 只接受纯文本,不支持 `--file` 或 JSON `attachments`(包括空数组)。通过 `--message <text>` 传入文本,或通过 `--input <file>` / `--input -` 读取仅含 `content` 或 `message` 字段的 JSON,两个文本字段不能同时提供。`--input` 读取的是请求 JSON,不会上传该文件。
462
+ 每条消息最多 10 个文件,其中 PDF 最多 5 个;图片宽高、总像素、PDF 页数和 Word 图片数按同源规则校验。当前主站图片单边不超过 29900 像素,总像素不超过 24999999,PDF 页数和 Word 图片数上限为 800。格式配置不可用、文件不合法、审核失败或预处理失败时整条消息停止,不静默丢弃附件。
426
463
 
427
- 需求及文本素材应完整放入 `content`,例如 `{"content":"完整需求正文\n\n## 参考素材\n完整素材正文"}`。宿主读取文本文件后应将正文并入文本,不使用“正文见附件”或只传本地路径;不能读取的素材应明确告知用户,不能假装已经提交。
464
+ 所有文件(包括很小的 Markdown/TXT)都先上传、审核,再按 Glow 的 `name/url/mediaType/meta` 结构发送;PDF、Word、Excel/CSV 按同源服务预处理,保留解析元数据。不会把文件正文或 Base64 放入附件 `content`。上传过程写入 stderr,只有全部附件就绪后才发出一次创作消息;`--no-wait` 也会完成上传、审核和预处理。图片尺寸和视频时长由随包依赖在本机读取,无需安装 FFmpeg。不要上传 `.env` 或 CLI 凭据等敏感文件。
428
465
 
429
466
  `session get --include-attachments` 返回可见附件清单;`chat state --include-file <name>` 读取指定可见附件正文。系统文件和密钥配置文件不会作为结果附件返回。
430
467
 
@@ -1,9 +1,11 @@
1
1
  /** 对话创建、工具回复和项目内容更新。@author xiuyu.yi */
2
2
  import type { ApiClient } from '../transport/api-client.js';
3
3
  import type { JsonObject } from '../contracts/value.js';
4
+ import type { InputAttachment } from './upload-api.js';
4
5
  export type ChatInput = {
5
6
  sessionId?: string;
6
7
  content: string;
8
+ attachments?: InputAttachment[];
7
9
  model?: string;
8
10
  minDuration?: number;
9
11
  previewVersionId?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"agent-command-api.js","sourceRoot":"","sources":["../../src/api/agent-command-api.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agent-command-api.js","sourceRoot":"","sources":["../../src/api/agent-command-api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { CreationRuntime } from '../runtime.js';
2
+ import type { JsonObject } from '../contracts/value.js';
3
+ import type { PreparedFile } from './upload-files.js';
4
+ export type InputAttachment = {
5
+ name: string;
6
+ url: string;
7
+ mediaType: string;
8
+ meta?: JsonObject;
9
+ };
10
+ export declare function uploadAttachment(service: CreationRuntime, file: PreparedFile): Promise<InputAttachment>;
@@ -0,0 +1,205 @@
1
+ /** 复用 Glow 的七牛上传、审核和文档预处理,只发送 URL 附件。@author xiuyu.yi */
2
+ import { z } from 'zod';
3
+ import { pollOperation } from '../commands/shared.js';
4
+ import { list, object, requiredText } from '../contracts/value.js';
5
+ import { CliError } from '../output/exit-codes.js';
6
+ import { HttpClient } from '../transport/http-client.js';
7
+ import { getSuperunHostingDomain } from '../config/runtime-config.js';
8
+ import { MAX_PIXELS, MB } from './upload-files.js';
9
+ const urlSchema = z
10
+ .string()
11
+ .url()
12
+ .refine((value) => {
13
+ const url = new URL(value);
14
+ return ['http:', 'https:'].includes(url.protocol) && !url.username && !url.password;
15
+ });
16
+ const numberSchema = z.number().finite().nonnegative();
17
+ function parse(schema, value, label) {
18
+ const result = schema.safeParse(value);
19
+ if (!result.success)
20
+ throw new CliError('PROTOCOL_ERROR', `${label}返回的数据无效,尚未发送创作消息`);
21
+ return result.data;
22
+ }
23
+ async function uploadToCdn(service, file) {
24
+ const response = await service.client.request(`/api/uxa-center/support/FileUpload/getUploadToken?fileType=${encodeURIComponent(file.extension)}`, undefined, { method: 'GET' });
25
+ const token = object(response.data), credential = requiredText(token.token, '上传凭据');
26
+ service.output.registerSecret(credential);
27
+ const encryptedId = requiredText(token.encryptedId, '上传记录');
28
+ const form = new FormData();
29
+ form.append('token', credential);
30
+ form.append('file', file.blob, file.name);
31
+ const signal = service.client.signal;
32
+ let uploaded;
33
+ try {
34
+ uploaded = await fetch('https://upload-na0.qiniup.com', {
35
+ method: 'POST',
36
+ body: form,
37
+ redirect: 'error',
38
+ signal: signal ? AbortSignal.any([signal, AbortSignal.timeout(60_000)]) : AbortSignal.timeout(60_000),
39
+ });
40
+ }
41
+ catch {
42
+ throw new CliError(signal?.aborted ? 'INTERRUPTED' : 'OUTCOME_UNKNOWN', `${file.name}:上传已中断或结果不确定,尚未发送创作消息`);
43
+ }
44
+ await uploaded.body?.cancel();
45
+ if (!uploaded.ok)
46
+ throw new CliError('BUSINESS_ERROR', `${file.name}:附件上传失败,尚未发送创作消息`);
47
+ service.output.log(`${file.name}:上传完成,等待审核`);
48
+ return pollOperation(async () => {
49
+ const response = object(await service.client.call('/api/uxa-center/support/FileUpload/queryFileUrl', {
50
+ encryptedIds: [encryptedId],
51
+ }));
52
+ const item = object(list(response.items)[0]);
53
+ switch (item.auditStatus) {
54
+ case 0:
55
+ return undefined;
56
+ case 1:
57
+ case 4:
58
+ return parse(urlSchema, item.url, '附件审核');
59
+ case 2:
60
+ throw new CliError('BUSINESS_ERROR', `${file.name}:附件审核未通过,尚未发送创作消息`);
61
+ case 3:
62
+ throw new CliError('BUSINESS_ERROR', `${file.name}:附件审核结果存疑,尚未发送创作消息`);
63
+ default:
64
+ throw new CliError('BUSINESS_ERROR', `${file.name}:附件审核异常,尚未发送创作消息`);
65
+ }
66
+ }, (url) => url !== undefined, { timeout: 180, signal }).then((url) => url);
67
+ }
68
+ async function preprocess(service, path, payload) {
69
+ const domain = getSuperunHostingDomain(service.client.config.endpoint) === 'superun.yun' ? 'superun.com' : 'superun.ai';
70
+ const response = await new HttpClient().request({
71
+ url: `https://heavylift.${domain}/document/${path}/json`,
72
+ body: payload,
73
+ headers: { 'content-type': 'application/json' },
74
+ write: true,
75
+ timeoutMs: 300_000,
76
+ signal: service.client.signal,
77
+ });
78
+ const taskId = requiredText(object(response.data).taskId, '文件预处理任务');
79
+ return pollOperation(async () => {
80
+ const task = object(await service.client.call('/api/uxa-center/support/FileUpload/pollFileTask', { taskId }));
81
+ if (task.status === 0 || task.status === 1)
82
+ return undefined;
83
+ if (task.status === 3)
84
+ throw new CliError('BUSINESS_ERROR', '附件预处理失败,尚未发送创作消息');
85
+ if (task.status !== 2 || typeof task.result !== 'string')
86
+ throw new CliError('PROTOCOL_ERROR', '附件预处理返回未知状态,尚未发送创作消息');
87
+ let result;
88
+ try {
89
+ result = object(JSON.parse(task.result));
90
+ }
91
+ catch {
92
+ throw new CliError('PROTOCOL_ERROR', '无法读取附件预处理结果,尚未发送创作消息');
93
+ }
94
+ if (result.code !== 0)
95
+ throw new CliError('BUSINESS_ERROR', result.code === 10002 ? '不支持加密 PDF,尚未发送创作消息' : '附件预处理未通过,尚未发送创作消息');
96
+ return object(result.data);
97
+ }, (result) => result !== undefined, { timeout: 300, signal: service.client.signal }).then((result) => result);
98
+ }
99
+ function checkSize(file, bytes) {
100
+ if (bytes > file.rule.size * MB)
101
+ throw new CliError('INVALID_ARGUMENT', `${file.name}:处理后文件仍超过 ${file.rule.size}MB,尚未发送创作消息`);
102
+ }
103
+ function checkLimit(file, value, limit, label) {
104
+ if (limit !== undefined && value > limit)
105
+ throw new CliError('INVALID_ARGUMENT', `${file.name}:${label}超过 ${limit},尚未发送创作消息`);
106
+ }
107
+ const bytesToMb = (bytes) => Math.round((bytes / MB) * 100) / 100;
108
+ export async function uploadAttachment(service, file) {
109
+ service.output.log(`${file.name}:正在上传附件`);
110
+ const url = await uploadToCdn(service, file);
111
+ const attachment = { name: file.name, url, mediaType: file.mediaType };
112
+ const { extension, rule } = file;
113
+ if (file.image) {
114
+ let { width, height } = file.image;
115
+ let fileSize = file.blob.size;
116
+ const maxPixels = Math.min(rule.maxPixels ?? MAX_PIXELS, MAX_PIXELS);
117
+ if (fileSize > rule.size * MB || width * height > maxPixels) {
118
+ service.output.log(`${file.name}:正在压缩图片`);
119
+ const result = parse(z.object({
120
+ image_url: urlSchema,
121
+ width: numberSchema.positive(),
122
+ height: numberSchema.positive(),
123
+ file_size: numberSchema,
124
+ }), await preprocess(service, 'compress-image', {
125
+ image_url: url,
126
+ max_dimension: width * height > maxPixels
127
+ ? Math.floor(Math.max(width, height) * Math.sqrt(maxPixels / (width * height)))
128
+ : -1,
129
+ }), '图片压缩');
130
+ attachment.url = result.image_url;
131
+ width = result.width;
132
+ height = result.height;
133
+ fileSize = result.file_size;
134
+ }
135
+ checkSize(file, fileSize);
136
+ checkLimit(file, Math.max(width, height), rule.maxSize, '图片宽高');
137
+ checkLimit(file, width * height, maxPixels, '图片总像素');
138
+ attachment.meta = { image: { image_url: attachment.url, width, height, file_size: bytesToMb(fileSize) } };
139
+ }
140
+ else if (extension === 'pdf') {
141
+ service.output.log(`${file.name}:正在预处理 PDF`);
142
+ const result = parse(z.object({
143
+ url: urlSchema,
144
+ parsed_file_size: numberSchema,
145
+ parsed_page_count: numberSchema,
146
+ agent_representation: z.enum(['native_pdf', 'text_link']).optional(),
147
+ representation_reason: z.string().nullable().optional(),
148
+ }), await preprocess(service, 'compress-pdf', {
149
+ pdf_url: url,
150
+ compress_level: 'medium',
151
+ grayscale: false,
152
+ keep_pages: [],
153
+ }), 'PDF 预处理');
154
+ checkSize(file, result.parsed_file_size);
155
+ checkLimit(file, result.parsed_page_count, rule.visualCount, 'PDF 页数');
156
+ attachment.url = result.url;
157
+ attachment.meta = {
158
+ parsed_visual_count: result.parsed_page_count,
159
+ parsed_file_size: bytesToMb(result.parsed_file_size),
160
+ agent_representation: result.agent_representation ?? 'native_pdf',
161
+ representation_reason: result.representation_reason ?? null,
162
+ };
163
+ }
164
+ else if (extension === 'docx') {
165
+ service.output.log(`${file.name}:正在解析 Word 文档`);
166
+ const result = parse(z.object({
167
+ url: urlSchema.nullable().optional(),
168
+ parsed_url: urlSchema,
169
+ parsed_image_map: z.record(z.string()).default({}),
170
+ parsed_file_size: numberSchema,
171
+ parsed_text_length: numberSchema,
172
+ }), await preprocess(service, 'docx-to-md', { docx_url: url }), 'Word 预处理');
173
+ checkSize(file, result.parsed_file_size);
174
+ const count = Object.keys(result.parsed_image_map).length;
175
+ checkLimit(file, count, rule.visualCount, '文档图片数');
176
+ checkLimit(file, result.parsed_text_length, rule.textLimit, '文本长度');
177
+ attachment.url = result.url ?? result.parsed_url;
178
+ attachment.meta = {
179
+ parsed_url: result.parsed_url,
180
+ parsed_image_map: result.parsed_image_map,
181
+ parsed_visual_count: count,
182
+ parsed_file_size: bytesToMb(result.parsed_file_size),
183
+ parsed_text_length: result.parsed_text_length,
184
+ };
185
+ }
186
+ else if (['xlsx', 'xls', 'csv'].includes(extension)) {
187
+ service.output.log(`${file.name}:正在解析表格`);
188
+ const csv = extension === 'csv';
189
+ const result = parse(z.object({
190
+ url: urlSchema.nullable().optional(),
191
+ items: z.array(z
192
+ .object({
193
+ csv_url: urlSchema,
194
+ row_count: numberSchema,
195
+ rows: z.array(z.array(z.string())).optional(),
196
+ })
197
+ .passthrough()),
198
+ }), await preprocess(service, csv ? 'csv-parse' : 'xlsx-to-csv', csv ? { csv_url: url } : { xlsx_url: url }), '表格预处理');
199
+ attachment.url = result.url ?? url;
200
+ attachment.meta = { parsed_file_size: bytesToMb(file.blob.size), csvs: result.items };
201
+ }
202
+ service.output.log(`${file.name}:附件已就绪`);
203
+ return attachment;
204
+ }
205
+ //# sourceMappingURL=upload-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload-api.js","sourceRoot":"","sources":["../../src/api/upload-api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import { z } from 'zod';
2
+ import type { CreationRuntime } from '../runtime.js';
3
+ export declare const MB: number;
4
+ export declare const MAX_PIXELS = 24999999;
5
+ declare const ruleSchema: z.ZodObject<{
6
+ fileType: z.ZodEnum<["image", "text", "raw"]>;
7
+ ext: z.ZodString;
8
+ size: z.ZodNumber;
9
+ maxSize: z.ZodOptional<z.ZodNumber>;
10
+ maxPixels: z.ZodOptional<z.ZodNumber>;
11
+ visualCount: z.ZodOptional<z.ZodNumber>;
12
+ textLimit: z.ZodOptional<z.ZodNumber>;
13
+ }, "strip", z.ZodTypeAny, {
14
+ fileType: "image" | "text" | "raw";
15
+ ext: string;
16
+ size: number;
17
+ maxSize?: number | undefined;
18
+ maxPixels?: number | undefined;
19
+ visualCount?: number | undefined;
20
+ textLimit?: number | undefined;
21
+ }, {
22
+ fileType: "image" | "text" | "raw";
23
+ ext: string;
24
+ size: number;
25
+ maxSize?: number | undefined;
26
+ maxPixels?: number | undefined;
27
+ visualCount?: number | undefined;
28
+ textLimit?: number | undefined;
29
+ }>;
30
+ export type UploadRule = z.infer<typeof ruleSchema>;
31
+ export type PreparedFile = {
32
+ name: string;
33
+ extension: string;
34
+ mediaType: string;
35
+ rule: UploadRule;
36
+ blob: Blob;
37
+ image?: {
38
+ width: number;
39
+ height: number;
40
+ };
41
+ };
42
+ /** 整批完成本地校验后才申请上传凭据,避免静默丢弃附件或发送不完整需求。 */
43
+ export declare function prepareUploadFiles(service: CreationRuntime, paths: string[]): Promise<PreparedFile[]>;
44
+ export {};
@@ -0,0 +1,154 @@
1
+ /** 与 Glow 同源的上传白名单、数量、大小和媒体预检。@author xiuyu.yi */
2
+ import { openAsBlob } from 'node:fs';
3
+ import { stat } from 'node:fs/promises';
4
+ import { basename, extname } from 'node:path';
5
+ import { Worker } from 'node:worker_threads';
6
+ import { z } from 'zod';
7
+ import { CliError } from '../output/exit-codes.js';
8
+ export const MB = 1024 * 1024;
9
+ export const MAX_PIXELS = 24_999_999;
10
+ const ruleSchema = z.object({
11
+ fileType: z.enum(['image', 'text', 'raw']),
12
+ ext: z.string().min(1),
13
+ size: z.number().finite().positive(),
14
+ maxSize: z.number().finite().positive().optional(),
15
+ maxPixels: z.number().finite().positive().optional(),
16
+ visualCount: z.coerce.number().finite().positive().optional(),
17
+ textLimit: z.number().finite().positive().optional(),
18
+ });
19
+ const MIME = {
20
+ png: 'image/png',
21
+ jpg: 'image/jpeg',
22
+ jpeg: 'image/jpeg',
23
+ webp: 'image/webp',
24
+ gif: 'image/gif',
25
+ svg: 'image/svg+xml',
26
+ pdf: 'application/pdf',
27
+ docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
28
+ xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
29
+ xls: 'application/vnd.ms-excel',
30
+ csv: 'text/csv',
31
+ txt: 'text/plain',
32
+ md: 'text/markdown',
33
+ json: 'application/json',
34
+ js: 'text/javascript',
35
+ jsx: 'text/javascript',
36
+ ts: 'text/plain',
37
+ tsx: 'text/plain',
38
+ html: 'text/html',
39
+ css: 'text/css',
40
+ scss: 'text/plain',
41
+ less: 'text/plain',
42
+ xml: 'application/xml',
43
+ yaml: 'text/yaml',
44
+ yml: 'text/yaml',
45
+ mp4: 'video/mp4',
46
+ mov: 'video/quicktime',
47
+ webm: 'video/webm',
48
+ avi: 'video/x-msvideo',
49
+ wmv: 'video/x-ms-wmv',
50
+ flv: 'video/x-flv',
51
+ mkv: 'video/x-matroska',
52
+ mp3: 'audio/mpeg',
53
+ wav: 'audio/wav',
54
+ ogg: 'audio/ogg',
55
+ flac: 'audio/flac',
56
+ m4a: 'audio/mp4',
57
+ aac: 'audio/aac',
58
+ zip: 'application/zip',
59
+ rar: 'application/vnd.rar',
60
+ };
61
+ for (const ext of ['py', 'java', 'cpp', 'c', 'h', 'cs', 'php', 'rb', 'go', 'rs', 'swift'])
62
+ MIME[ext] = 'text/plain';
63
+ function readMedia(path, image, signal) {
64
+ return new Promise((resolve, reject) => {
65
+ const worker = new Worker(new URL('./upload-media-worker.js', import.meta.url), {
66
+ workerData: { path, image },
67
+ execArgv: [],
68
+ });
69
+ let finished = false;
70
+ const finish = (error, result) => {
71
+ if (finished)
72
+ return;
73
+ finished = true;
74
+ clearTimeout(timer);
75
+ signal?.removeEventListener('abort', abort);
76
+ void worker.terminate();
77
+ if (error)
78
+ reject(error);
79
+ else
80
+ resolve(result);
81
+ };
82
+ const abort = () => finish(new CliError('INTERRUPTED', '已取消附件预检,尚未发送创作消息'));
83
+ const timer = setTimeout(() => finish(new CliError('INVALID_ARGUMENT', `${basename(path)}:无法在 30 秒内读取媒体信息`)), 30_000);
84
+ worker.once('message', (result) => finish(undefined, result));
85
+ worker.once('error', () => finish(new CliError('INVALID_ARGUMENT', `${basename(path)}:无法读取媒体信息,请检查文件是否损坏`)));
86
+ worker.once('exit', () => {
87
+ if (!finished)
88
+ finish(new CliError('INVALID_ARGUMENT', `${basename(path)}:媒体预检未返回结果`));
89
+ });
90
+ signal?.addEventListener('abort', abort, { once: true });
91
+ if (signal?.aborted)
92
+ abort();
93
+ });
94
+ }
95
+ /** 整批完成本地校验后才申请上传凭据,避免静默丢弃附件或发送不完整需求。 */
96
+ export async function prepareUploadFiles(service, paths) {
97
+ if (!paths.length)
98
+ return [];
99
+ if (paths.length > 10)
100
+ throw new CliError('INVALID_ARGUMENT', '每条消息最多上传 10 个文件');
101
+ if (paths.filter((path) => extname(path).toLowerCase() === '.pdf').length > 5)
102
+ throw new CliError('INVALID_ARGUMENT', '每条消息最多上传 5 个 PDF');
103
+ const response = await service.client.request('/web-api/config/file-ext-config', undefined, {
104
+ method: 'GET',
105
+ });
106
+ const config = z.object({ fileExts: z.record(ruleSchema) }).safeParse(response.data);
107
+ if (!config.success || !Object.keys(config.data.fileExts).length)
108
+ throw new CliError('PROTOCOL_ERROR', '未取得有效的附件格式限制,尚未上传文件');
109
+ const prepared = [];
110
+ for (const path of paths) {
111
+ if (service.client.signal?.aborted)
112
+ throw new CliError('INTERRUPTED', '已取消附件预检');
113
+ const name = basename(path), extension = extname(name).slice(1).toLowerCase();
114
+ const rule = config.data.fileExts[extension], mediaType = MIME[extension];
115
+ if (!rule || !mediaType || rule.ext.toLowerCase() !== extension)
116
+ throw new CliError('INVALID_ARGUMENT', `${name}:不支持此文件格式`, {
117
+ supportedExtensions: Object.keys(config.data.fileExts).filter((ext) => MIME[ext]),
118
+ });
119
+ const info = await stat(path).catch(() => undefined);
120
+ if (!info?.isFile() || info.size === 0)
121
+ throw new CliError('INVALID_ARGUMENT', `${name}:附件必须是可读取的非空普通文件`);
122
+ // 图片允许先按 Glow 的流程压缩,其余格式在上传前检查原文件大小。
123
+ if (rule.fileType !== 'image' && info.size > rule.size * MB)
124
+ throw new CliError('INVALID_ARGUMENT', `${name}:文件不能超过 ${rule.size}MB`);
125
+ const item = {
126
+ name,
127
+ extension,
128
+ mediaType,
129
+ rule,
130
+ blob: await openAsBlob(path, { type: mediaType }),
131
+ };
132
+ if (rule.fileType === 'image' || mediaType.startsWith('video/')) {
133
+ const media = await readMedia(path, rule.fileType === 'image', service.client.signal);
134
+ if (rule.fileType === 'image') {
135
+ const { width, height } = media;
136
+ if (!width || !height || !Number.isFinite(width * height))
137
+ throw new CliError('INVALID_ARGUMENT', `${name}:无法读取图片尺寸`);
138
+ if (rule.maxSize && Math.max(width, height) > rule.maxSize)
139
+ throw new CliError('INVALID_ARGUMENT', `${name}:图片宽高不能超过 ${rule.maxSize} 像素`);
140
+ item.image = { width, height };
141
+ }
142
+ else if (!media.hasVideo ||
143
+ !media.duration ||
144
+ !Number.isFinite(media.duration) ||
145
+ media.duration <= 0 ||
146
+ media.duration > 302) {
147
+ throw new CliError('INVALID_ARGUMENT', `${name}:视频必须能读取时长且不超过 5 分钟(含 2 秒容差)`);
148
+ }
149
+ }
150
+ prepared.push(item);
151
+ }
152
+ return prepared;
153
+ }
154
+ //# sourceMappingURL=upload-files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload-files.js","sourceRoot":"","sources":["../../src/api/upload-files.ts"],"names":[],"mappings":"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"}