@xihe-lab/tapd-core 2.0.0-rc.1 → 2.0.0-rc.3

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 (158) hide show
  1. package/README.md +23 -0
  2. package/dist/advisor/index.d.ts.map +1 -1
  3. package/dist/advisor/index.js +2 -0
  4. package/dist/advisor/index.js.map +1 -1
  5. package/dist/cache/read-cache.d.ts +136 -0
  6. package/dist/cache/read-cache.d.ts.map +1 -0
  7. package/dist/cache/read-cache.js +322 -0
  8. package/dist/cache/read-cache.js.map +1 -0
  9. package/dist/cache/read-cache.test.d.ts +2 -0
  10. package/dist/cache/read-cache.test.d.ts.map +1 -0
  11. package/dist/cache/read-cache.test.js +429 -0
  12. package/dist/cache/read-cache.test.js.map +1 -0
  13. package/dist/errors/index.d.ts +120 -0
  14. package/dist/errors/index.d.ts.map +1 -0
  15. package/dist/errors/index.js +429 -0
  16. package/dist/errors/index.js.map +1 -0
  17. package/dist/index.d.ts +3 -0
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +2 -0
  20. package/dist/index.js.map +1 -1
  21. package/dist/registry/registry.d.ts +7 -0
  22. package/dist/registry/registry.d.ts.map +1 -1
  23. package/dist/registry/registry.js +9 -3
  24. package/dist/registry/registry.js.map +1 -1
  25. package/dist/registry/registry.test.js +293 -2
  26. package/dist/registry/registry.test.js.map +1 -1
  27. package/dist/registry/richtext-manifests.generated.d.ts +1 -1
  28. package/dist/registry/richtext-manifests.generated.d.ts.map +1 -1
  29. package/dist/registry/richtext-manifests.generated.js +1 -1
  30. package/dist/registry/richtext-manifests.generated.js.map +1 -1
  31. package/dist/registry/richtext.d.ts +9 -0
  32. package/dist/registry/richtext.d.ts.map +1 -1
  33. package/dist/registry/richtext.js +33 -15
  34. package/dist/registry/richtext.js.map +1 -1
  35. package/dist/registry/richtext.test.js +70 -7
  36. package/dist/registry/richtext.test.js.map +1 -1
  37. package/dist/richtext/attachment-anchor.d.ts +58 -0
  38. package/dist/richtext/attachment-anchor.d.ts.map +1 -0
  39. package/dist/richtext/attachment-anchor.js +221 -0
  40. package/dist/richtext/attachment-anchor.js.map +1 -0
  41. package/dist/richtext/attachment-anchor.test.d.ts +2 -0
  42. package/dist/richtext/attachment-anchor.test.d.ts.map +1 -0
  43. package/dist/richtext/attachment-anchor.test.js +149 -0
  44. package/dist/richtext/attachment-anchor.test.js.map +1 -0
  45. package/dist/richtext/escape.d.ts +7 -0
  46. package/dist/richtext/escape.d.ts.map +1 -0
  47. package/dist/richtext/escape.js +60 -0
  48. package/dist/richtext/escape.js.map +1 -0
  49. package/dist/richtext/index.d.ts +15 -0
  50. package/dist/richtext/index.d.ts.map +1 -0
  51. package/dist/richtext/index.js +35 -0
  52. package/dist/richtext/index.js.map +1 -0
  53. package/dist/richtext/mention.d.ts +49 -0
  54. package/dist/richtext/mention.d.ts.map +1 -0
  55. package/dist/richtext/mention.js +179 -0
  56. package/dist/richtext/mention.js.map +1 -0
  57. package/dist/richtext/mention.test.d.ts +2 -0
  58. package/dist/richtext/mention.test.d.ts.map +1 -0
  59. package/dist/richtext/mention.test.js +123 -0
  60. package/dist/richtext/mention.test.js.map +1 -0
  61. package/dist/richtext/pipeline.d.ts +5 -0
  62. package/dist/richtext/pipeline.d.ts.map +1 -0
  63. package/dist/richtext/pipeline.js +199 -0
  64. package/dist/richtext/pipeline.js.map +1 -0
  65. package/dist/richtext/round-trip.test.d.ts +2 -0
  66. package/dist/richtext/round-trip.test.d.ts.map +1 -0
  67. package/dist/richtext/round-trip.test.js +105 -0
  68. package/dist/richtext/round-trip.test.js.map +1 -0
  69. package/dist/sdk-routes.d.ts.map +1 -1
  70. package/dist/sdk-routes.js +4 -0
  71. package/dist/sdk-routes.js.map +1 -1
  72. package/dist/tapd-client.d.ts +79 -2
  73. package/dist/tapd-client.d.ts.map +1 -1
  74. package/dist/tapd-client.js +177 -24
  75. package/dist/tapd-client.js.map +1 -1
  76. package/dist/tools/attachment.d.ts +47 -0
  77. package/dist/tools/attachment.d.ts.map +1 -1
  78. package/dist/tools/attachment.js +278 -32
  79. package/dist/tools/attachment.js.map +1 -1
  80. package/dist/tools/attachment.test.d.ts +2 -0
  81. package/dist/tools/attachment.test.d.ts.map +1 -0
  82. package/dist/tools/attachment.test.js +432 -0
  83. package/dist/tools/attachment.test.js.map +1 -0
  84. package/dist/tools/board.js +22 -22
  85. package/dist/tools/board.js.map +1 -1
  86. package/dist/tools/bug.d.ts.map +1 -1
  87. package/dist/tools/bug.js +262 -259
  88. package/dist/tools/bug.js.map +1 -1
  89. package/dist/tools/changes.js +20 -20
  90. package/dist/tools/changes.js.map +1 -1
  91. package/dist/tools/comment.d.ts.map +1 -1
  92. package/dist/tools/comment.js +26 -23
  93. package/dist/tools/comment.js.map +1 -1
  94. package/dist/tools/custom-fields.js +16 -16
  95. package/dist/tools/custom-fields.js.map +1 -1
  96. package/dist/tools/image.js +2 -2
  97. package/dist/tools/image.js.map +1 -1
  98. package/dist/tools/index.d.ts.map +1 -1
  99. package/dist/tools/index.js +2 -0
  100. package/dist/tools/index.js.map +1 -1
  101. package/dist/tools/iteration.js +50 -50
  102. package/dist/tools/iteration.js.map +1 -1
  103. package/dist/tools/media.d.ts +9 -0
  104. package/dist/tools/media.d.ts.map +1 -0
  105. package/dist/tools/media.js +45 -0
  106. package/dist/tools/media.js.map +1 -0
  107. package/dist/tools/mini-comment.js +27 -27
  108. package/dist/tools/mini-comment.js.map +1 -1
  109. package/dist/tools/mini-item.js +83 -83
  110. package/dist/tools/mini-item.js.map +1 -1
  111. package/dist/tools/mini-workspace.js +5 -5
  112. package/dist/tools/mini-workspace.js.map +1 -1
  113. package/dist/tools/program.js +7 -7
  114. package/dist/tools/program.js.map +1 -1
  115. package/dist/tools/relations.js +14 -14
  116. package/dist/tools/relations.js.map +1 -1
  117. package/dist/tools/release.js +53 -53
  118. package/dist/tools/release.js.map +1 -1
  119. package/dist/tools/report.js +8 -8
  120. package/dist/tools/report.js.map +1 -1
  121. package/dist/tools/richtext-wiring.test.d.ts +2 -0
  122. package/dist/tools/richtext-wiring.test.d.ts.map +1 -0
  123. package/dist/tools/richtext-wiring.test.js +302 -0
  124. package/dist/tools/richtext-wiring.test.js.map +1 -0
  125. package/dist/tools/settings.js +77 -77
  126. package/dist/tools/settings.js.map +1 -1
  127. package/dist/tools/source.js +14 -14
  128. package/dist/tools/source.js.map +1 -1
  129. package/dist/tools/story.d.ts.map +1 -1
  130. package/dist/tools/story.js +123 -120
  131. package/dist/tools/story.js.map +1 -1
  132. package/dist/tools/task.d.ts.map +1 -1
  133. package/dist/tools/task.js +126 -123
  134. package/dist/tools/task.js.map +1 -1
  135. package/dist/tools/test.js +117 -117
  136. package/dist/tools/test.js.map +1 -1
  137. package/dist/tools/timesheet.js +23 -23
  138. package/dist/tools/timesheet.js.map +1 -1
  139. package/dist/tools/user.js +8 -8
  140. package/dist/tools/user.js.map +1 -1
  141. package/dist/tools/utility.d.ts +17 -0
  142. package/dist/tools/utility.d.ts.map +1 -1
  143. package/dist/tools/utility.js +204 -88
  144. package/dist/tools/utility.js.map +1 -1
  145. package/dist/tools/wiki.d.ts.map +1 -1
  146. package/dist/tools/wiki.js +71 -56
  147. package/dist/tools/wiki.js.map +1 -1
  148. package/dist/tools/workflow.js +26 -26
  149. package/dist/tools/workflow.js.map +1 -1
  150. package/dist/tools/workspace.js +16 -16
  151. package/dist/tools/workspace.js.map +1 -1
  152. package/dist/types.d.ts +5 -0
  153. package/dist/types.d.ts.map +1 -1
  154. package/package.json +15 -11
  155. package/dist/tools/zz-acceptance-echo.d.ts +0 -3
  156. package/dist/tools/zz-acceptance-echo.d.ts.map +0 -1
  157. package/dist/tools/zz-acceptance-echo.js +0 -9
  158. package/dist/tools/zz-acceptance-echo.js.map +0 -1
@@ -1,23 +1,141 @@
1
+ import { createReadStream, existsSync, statSync } from 'node:fs';
2
+ import { writeFile } from 'node:fs/promises';
3
+ import { createHash } from 'node:crypto';
4
+ import path from 'node:path';
5
+ import os from 'node:os';
1
6
  import { z } from 'zod';
2
7
  import { TapdClient } from '../tapd-client.js';
8
+ // Wave 2 接线收敛(需求 1139814312001001548):file-type 词汇表以 core/richtext 的
9
+ // R6 四桶映射(FILE_TYPE_BY_EXTENSION)为准,本文件不再另设一套已知类型判断;
10
+ // 未知扩展名保留 A 侧「直通」契约(前端取回退图标,data-name/size 仍可渲染)。
11
+ import { FILE_TYPE_BY_EXTENSION } from '../richtext/index.js';
12
+ // ---------------------------------------------------------------------------
13
+ // Shared file/anchor helpers (reused by tools/media.ts and Wave 2 richtext lib)
14
+ // ---------------------------------------------------------------------------
15
+ /** TAPD upload limit — mirrors the SDK axios maxBodyLength (300MB). */
16
+ export const MAX_UPLOAD_BYTES = 300 * 1024 * 1024;
17
+ /** FSD §6: files above 50MB get a size warning in the tool result. */
18
+ export const LARGE_FILE_WARN_BYTES = 50 * 1024 * 1024;
19
+ function expandTilde(p) {
20
+ if (p === '~')
21
+ return os.homedir();
22
+ if (p === '~/' || p.startsWith('~/'))
23
+ return path.join(os.homedir(), p.slice(2));
24
+ return p;
25
+ }
26
+ /**
27
+ * Resolve a user-supplied local file path to an absolute path and verify it is
28
+ * an existing regular file within the 300MB upload limit.
29
+ * - `~` expansion is a defense for direct (MCP) callers; the CLI flags layer
30
+ * normalizes paths before invoking core (FSD §2).
31
+ * - Throws a descriptive Error for ENOENT / directory / oversize.
32
+ */
33
+ export function resolveLocalFile(fileArg) {
34
+ const absolutePath = path.resolve(expandTilde(fileArg));
35
+ if (!existsSync(absolutePath)) {
36
+ throw new Error(`file not found: ${fileArg} (resolved: ${absolutePath})`);
37
+ }
38
+ const stat = statSync(absolutePath);
39
+ if (!stat.isFile()) {
40
+ throw new Error(`not a regular file: ${absolutePath}`);
41
+ }
42
+ if (stat.size > MAX_UPLOAD_BYTES) {
43
+ throw new Error(`file too large: ${fileArg} is ${(stat.size / 1024 / 1024).toFixed(1)}MB, TAPD upload limit is 300MB`);
44
+ }
45
+ return { absolutePath, size: stat.size };
46
+ }
47
+ /**
48
+ * Zod refine helper: turn a missing/oversized local file into an INVALID_ARGS
49
+ * schema error (CLI maps INVALID_ARGS to usage exit 2 per FSD §3.1) instead of
50
+ * a runtime API error. The file is re-validated in the handler for direct
51
+ * callers that bypass registry parsing.
52
+ */
53
+ export function localFileRefine() {
54
+ return (v) => {
55
+ try {
56
+ resolveLocalFile(v);
57
+ return true;
58
+ }
59
+ catch {
60
+ return false;
61
+ }
62
+ };
63
+ }
64
+ /** Strip path separators / control chars — an uploaded filename is a label, never a path. */
65
+ export function sanitizeFilename(name) {
66
+ const base = name.split(/[/\\]/).pop() ?? '';
67
+ const cleaned = base.replace(/[\r\n\t\0]/g, ' ').trim();
68
+ return cleaned.length > 0 ? cleaned.slice(0, 255) : 'attachment';
69
+ }
70
+ function escapeHtml(s) {
71
+ return s
72
+ .replace(/&/g, '&')
73
+ .replace(/</g, '&lt;')
74
+ .replace(/>/g, '&gt;')
75
+ .replace(/"/g, '&quot;');
76
+ }
77
+ /**
78
+ * TAPD front-end file-type vocabulary. Only the plain-text family is
79
+ * evidenced end-to-end (research R6: data-file-type="text" renders perfectly);
80
+ * unknown extensions pass through as-is and the front-end picks its fallback
81
+ * icon while still showing name/size from the data attributes.
82
+ */
83
+ const TEXT_LIKE_EXTENSIONS = new Set(['txt', 'text', 'log', 'md', 'csv', 'json', 'xml', 'yml', 'yaml']);
84
+ /**
85
+ * Build the R6 data五件套 attachment anchor for TAPD rich-text fields
86
+ * (comments / description). Verified minimal template (research comment 369):
87
+ * the front-end rebuilds its attachment component purely from the data
88
+ * attributes, so inner spans can be omitted.
89
+ *
90
+ * Exported for the Wave 2 richtext conversion library
91
+ * (`[📎 name](attach:<ws>/<id>)` → anchor), not a tool itself (FSD §2 ruling 2).
92
+ */
93
+ export function buildAttachmentAnchor(input) {
94
+ const dot = input.filename.lastIndexOf('.');
95
+ const ext = dot > -1 && dot < input.filename.length - 1 ? input.filename.slice(dot + 1).toLowerCase() : '';
96
+ const fileType = input.file_type
97
+ ?? (FILE_TYPE_BY_EXTENSION[ext]) // richtext R6 四桶优先(text/image/pdf)
98
+ ?? (TEXT_LIKE_EXTENSIONS.has(ext) ? 'text' : ext || 'other'); // 未收录:A 侧文本族 → text,其余扩展名直通
99
+ const name = escapeHtml(input.filename);
100
+ const size = Math.max(0, Math.round(input.size));
101
+ return (`<a data-is-tapd-attachment="true" data-can-preview="true" data-file-type="${escapeHtml(fileType)}"` +
102
+ ` data-name="${name}" data-size="${size}" target="_blank" rel="noopener"` +
103
+ ` href="/${input.workspace_id}/attachments/preview_attachments/${input.id}/story_description_attachment">${name}</a>`);
104
+ }
105
+ /** `[📎 <name>](attach:<ws>/<id>)` — md 管道场景的附件引用(P3 语法接线用)。 */
106
+ export function buildAttachmentMarkdown(workspaceId, id, filename) {
107
+ return `[📎 ${filename}](attach:${workspaceId}/${id})`;
108
+ }
109
+ function optionalSizeWarning(size) {
110
+ return size > LARGE_FILE_WARN_BYTES
111
+ ? { warning: `file is ${(size / 1024 / 1024).toFixed(1)}MB (>50MB), upload/download may be slow` }
112
+ : {};
113
+ }
114
+ function requireWorkspaceId(params) {
115
+ const workspaceId = params.workspace_id ?? TapdClient.getDefaultWorkspaceId();
116
+ if (!workspaceId) {
117
+ throw new Error('workspace_id is required (either provide it or set TAPD_DEFAULT_WORKSPACE_ID env)');
118
+ }
119
+ return workspaceId;
120
+ }
3
121
  export const attachmentTools = [
4
122
  // Standard TAPD API attachment tools
5
123
  {
6
124
  name: 'tapd_get_attachments',
7
- description: 'Get attachment list from TAPD',
125
+ description: '查询附件列表(可按实体、文件名、上传人过滤)。单个附件详情用单附件查询工具;下载用附件下载工具。读操作;limit 最大 200。返回附件数组。',
8
126
  inputSchema: z.object({
9
- workspace_id: z.number().optional().describe('项目ID(可省略,使用默认配置)'),
10
- id: z.string().optional().describe('Attachment ID, supports multiple IDs;必须以字符串(带引号)传递,禁止传数值,20 位 ID 超出 JS 安全整数范围会丢精度'),
11
- entity_id: z.string().optional().describe('Related entity ID (story/task/bug/wiki ID);必须以字符串(带引号)传递,禁止传数值,20 位 ID 超出 JS 安全整数范围会丢精度'),
12
- entity_type: z.string().optional().describe('Entity type (story, task, bug, wiki)'),
13
- filename: z.string().optional().describe('Filename'),
14
- owner: z.string().optional().describe('Uploader'),
15
- created: z.string().optional().describe('Creation time, supports time query'),
16
- modified: z.string().optional().describe('Last modification time, supports time query'),
17
- fields: z.string().optional().describe('Comma-separated list of fields to return'),
18
- limit: z.number().optional().describe('Number of results to return, max 200'),
19
- page: z.number().optional().describe('Page number, default 1'),
20
- order: z.string().optional().describe('Sort order, e.g., "created desc"'),
127
+ workspace_id: z.number().optional().describe('项目 ID,可省略(默认取环境变量 TAPD_DEFAULT_WORKSPACE_ID)'),
128
+ id: z.string().optional().describe('附件 ID,支持多 ID 查询;必须以字符串(带引号)传递,禁止传数值,20 位 ID 超出 JS 安全整数范围会丢精度'),
129
+ entity_id: z.string().optional().describe('关联实体 ID(需求/任务/缺陷/知识库页面的 ID);必须以字符串(带引号)传递,禁止传数值,20 位 ID 超出 JS 安全整数范围会丢精度'),
130
+ entity_type: z.string().optional().describe('实体类型(story/task/bug/wiki)'),
131
+ filename: z.string().optional().describe('文件名'),
132
+ owner: z.string().optional().describe('上传人'),
133
+ created: z.string().optional().describe('创建时间,支持时间查询'),
134
+ modified: z.string().optional().describe('最后修改时间,支持时间查询'),
135
+ fields: z.string().optional().describe('返回字段,多个以逗号分隔'),
136
+ limit: z.number().optional().describe('返回数量,最大 200'),
137
+ page: z.number().optional().describe('页码,默认 1'),
138
+ order: z.string().optional().describe('排序,如 created desc'),
21
139
  }),
22
140
  handler: async (client, params) => {
23
141
  const workspaceId = params.workspace_id ?? TapdClient.getDefaultWorkspaceId();
@@ -29,11 +147,11 @@ export const attachmentTools = [
29
147
  },
30
148
  {
31
149
  name: 'tapd_get_attachment',
32
- description: 'Get a single attachment from TAPD',
150
+ description: '按 ID 查询单个附件元数据。列表用附件列表查询工具;下载用附件下载工具。读操作;id 必填。返回附件详情。',
33
151
  inputSchema: z.object({
34
- workspace_id: z.number().optional().describe('项目ID(可省略,使用默认配置)'),
35
- id: z.string().describe('Attachment ID (required);必须以字符串(带引号)传递,禁止传数值,20 位 ID 超出 JS 安全整数范围会丢精度'),
36
- fields: z.string().optional().describe('Comma-separated list of fields to return'),
152
+ workspace_id: z.number().optional().describe('项目 ID,可省略(默认取环境变量 TAPD_DEFAULT_WORKSPACE_ID)'),
153
+ id: z.string().describe('附件 ID(必填);必须以字符串(带引号)传递,禁止传数值,20 位 ID 超出 JS 安全整数范围会丢精度'),
154
+ fields: z.string().optional().describe('返回字段,多个以逗号分隔'),
37
155
  }),
38
156
  handler: async (client, params) => {
39
157
  const workspaceId = params.workspace_id ?? TapdClient.getDefaultWorkspaceId();
@@ -45,11 +163,11 @@ export const attachmentTools = [
45
163
  },
46
164
  {
47
165
  name: 'tapd_get_attachment_download_url',
48
- description: 'Get download URL for a single attachment (valid for 300s)',
166
+ description: '获取单个附件的临时下载 URL(300s 有效)。注意:本工具走 documents_down 端点需要 attachments::documents_down 授权;推荐改用附件下载工具(走通用下载端点,无需额外权限)。读操作;id 必填。返回下载 URL。',
49
167
  inputSchema: z.object({
50
- workspace_id: z.number().optional().describe('项目ID(可省略,使用默认配置)'),
51
- id: z.string().describe('Attachment ID (required);必须以字符串(带引号)传递,禁止传数值,20 位 ID 超出 JS 安全整数范围会丢精度'),
52
- filename: z.string().optional().describe('Filename for download'),
168
+ workspace_id: z.number().optional().describe('项目 ID,可省略(默认取环境变量 TAPD_DEFAULT_WORKSPACE_ID)'),
169
+ id: z.string().describe('附件 ID(必填);必须以字符串(带引号)传递,禁止传数值,20 位 ID 超出 JS 安全整数范围会丢精度'),
170
+ filename: z.string().optional().describe('下载时使用的文件名'),
53
171
  }),
54
172
  handler: async (client, params) => {
55
173
  const workspaceId = params.workspace_id ?? TapdClient.getDefaultWorkspaceId();
@@ -59,18 +177,146 @@ export const attachmentTools = [
59
177
  return client.get('/attachments/documents_down', { ...params, workspace_id: workspaceId });
60
178
  },
61
179
  },
180
+ // ---------------------------------------------------------------------
181
+ // rc.2 rich-media collaboration tools (FSD §3.1-3.3, requirement 1139814312001001546)
182
+ // ---------------------------------------------------------------------
183
+ {
184
+ name: 'tapd_upload_attachment',
185
+ description: '上传本地文件为 TAPD 附件并绑定到实体(需求/缺陷/任务一次调用完成上传+绑定)。仅登记第三方链接用外部文件挂接工具。返回附件元数据、embed_html(R6 data 五件套锚点,可原样拼入评论/描述富文本)与 embed_md([📎 文件名](attach:<ws>/<id>));附件可再用附件下载工具取回。写操作(文件上传);上限 300MB,超 50MB 返回 warning。',
186
+ inputSchema: z.object({
187
+ workspace_id: z.number().optional().describe('项目 ID,可省略(默认取环境变量 TAPD_DEFAULT_WORKSPACE_ID)'),
188
+ file_path: z.string().min(1).refine(localFileRefine(), { message: '本地文件不存在(或超过 300MB 上限)' }).describe('本地文件路径(绝对路径,或相对当前工作目录)'),
189
+ entity_type: z.enum(['story', 'bug', 'task']).describe('绑定实体类型;entity_id 必须是该类型实体的真实 ID(严格同体型,不做跨表侥幸绑定)'),
190
+ entity_id: z.string().describe('目标实体长 ID;必须以字符串(带引号)传递,禁止传数值,20 位 ID 超出 JS 安全整数范围会丢精度'),
191
+ filename: z.string().optional().describe('上传后显示的文件名,缺省取 file_path 的 basename'),
192
+ }),
193
+ handler: async (client, params) => {
194
+ const workspaceId = requireWorkspaceId(params);
195
+ const { absolutePath, size } = resolveLocalFile(params.file_path);
196
+ const filename = sanitizeFilename(params.filename ?? path.basename(absolutePath));
197
+ const data = await client.postFile('/files/upload_attachment', {
198
+ workspace_id: workspaceId,
199
+ filename,
200
+ type: params.entity_type,
201
+ entry_id: params.entity_id,
202
+ file: createReadStream(absolutePath),
203
+ });
204
+ const attachment = (data?.Attachment ?? data ?? {});
205
+ const id = typeof attachment.id === 'string' || typeof attachment.id === 'number'
206
+ ? String(attachment.id)
207
+ : '';
208
+ if (id === '') {
209
+ throw new Error(`unexpected uploadAttachment response (no Attachment.id): ${JSON.stringify(data).slice(0, 200)}`);
210
+ }
211
+ const finalName = typeof attachment.filename === 'string' && attachment.filename !== ''
212
+ ? attachment.filename
213
+ : filename;
214
+ const finalSize = Number(attachment.size ?? size) || size;
215
+ return {
216
+ ...attachment,
217
+ embed_html: buildAttachmentAnchor({ workspace_id: workspaceId, id, filename: finalName, size: finalSize }),
218
+ embed_md: buildAttachmentMarkdown(workspaceId, id, finalName),
219
+ ...optionalSizeWarning(size),
220
+ };
221
+ },
222
+ cli: { resource: 'attachment', action: 'upload', positional: 'file_path' },
223
+ },
224
+ {
225
+ name: 'tapd_download_attachment',
226
+ description: '下载 TAPD 附件:走通用下载端点(无需额外授权)拿到 file.tapd.cn 签名 URL(300s 有效)。不带 out_path 仅返回 {download_url, filename, content_type};带 out_path(必须位于当前工作目录内)直接落盘并返回 {saved_to, bytes, sha1}。读操作。',
227
+ inputSchema: z.object({
228
+ workspace_id: z.number().optional().describe('项目 ID,可省略(默认取环境变量 TAPD_DEFAULT_WORKSPACE_ID)'),
229
+ id: z.string().describe('附件 ID(必填);必须以字符串(带引号)传递,禁止传数值,20 位 ID 超出 JS 安全整数范围会丢精度'),
230
+ out_path: z.string().optional().describe('保存路径(已存在的目录则取附件名落盘;否则视为完整文件路径)。必须在当前工作目录内。省略时仅返回下载元数据'),
231
+ }),
232
+ handler: async (client, params) => {
233
+ const workspaceId = requireWorkspaceId(params);
234
+ const data = await client.get('/attachments/down', {
235
+ workspace_id: workspaceId,
236
+ id: params.id,
237
+ });
238
+ const attachment = ((data?.Attachment ?? data) ?? {});
239
+ const downloadUrl = typeof attachment.download_url === 'string' ? attachment.download_url : undefined;
240
+ if (!downloadUrl) {
241
+ throw new Error(`no download_url returned for attachment ${params.id}: ${JSON.stringify(data).slice(0, 200)}`);
242
+ }
243
+ const filename = typeof attachment.filename === 'string' && attachment.filename !== ''
244
+ ? attachment.filename
245
+ : `attachment-${params.id}`;
246
+ const meta = {
247
+ id: params.id,
248
+ filename,
249
+ download_url: downloadUrl,
250
+ ...(typeof attachment.content_type === 'string' ? { content_type: attachment.content_type } : {}),
251
+ };
252
+ if (!params.out_path) {
253
+ return meta;
254
+ }
255
+ // Path traversal guard: the resolved target must stay inside process.cwd().
256
+ const cwd = process.cwd();
257
+ const resolvedOut = path.resolve(expandTilde(params.out_path));
258
+ if (resolvedOut !== cwd && !resolvedOut.startsWith(cwd + path.sep)) {
259
+ throw new Error(`out_path must stay within the working directory (${cwd}): ${params.out_path}`);
260
+ }
261
+ const stat = existsSync(resolvedOut) ? statSync(resolvedOut) : undefined;
262
+ const target = stat?.isDirectory() ? path.join(resolvedOut, sanitizeFilename(filename)) : resolvedOut;
263
+ // The signature URL points at file.tapd.cn — plain GET, no TAPD API auth.
264
+ const response = await fetch(downloadUrl);
265
+ if (!response.ok) {
266
+ throw new Error(`failed to download attachment bytes: HTTP ${response.status} ${response.statusText}`);
267
+ }
268
+ const bytes = Buffer.from(await response.arrayBuffer());
269
+ await writeFile(target, bytes);
270
+ const sha1 = createHash('sha1').update(bytes).digest('hex');
271
+ return {
272
+ ...meta,
273
+ saved_to: target,
274
+ bytes: bytes.length,
275
+ sha1,
276
+ ...optionalSizeWarning(bytes.length),
277
+ };
278
+ },
279
+ cli: { resource: 'attachment', action: 'download', positional: 'id' },
280
+ },
281
+ {
282
+ name: 'tapd_attach_external_file',
283
+ description: '把第三方系统文件挂接到 TAPD 实体(不传输文件本体,仅登记标题+链接)。上传真实文件用附件上传工具。写操作;type 服务端目前仅支持 png/psd。返回挂接结果。',
284
+ write: true,
285
+ inputSchema: z.object({
286
+ workspace_id: z.number().optional().describe('项目 ID,可省略(默认取环境变量 TAPD_DEFAULT_WORKSPACE_ID)'),
287
+ title: z.string().min(1).describe('第三方附件标题'),
288
+ source_url: z.string().min(1).describe('第三方附件链接'),
289
+ entity_type: z.enum(['story', 'bug', 'task']).describe('挂接实体类型(story/bug/task)'),
290
+ entity_id: z.string().describe('目标实体长 ID;必须以字符串(带引号)传递,禁止传数值,20 位 ID 超出 JS 安全整数范围会丢精度'),
291
+ type: z.enum(['png', 'psd']).default('png').describe('附件类型,目前服务端只支持 png/psd'),
292
+ creator: z.string().optional().describe('创建人(缺省取当前授权用户)'),
293
+ }),
294
+ handler: async (client, params) => {
295
+ const workspaceId = requireWorkspaceId(params);
296
+ return client.post('/open_app_obj_attachment', {
297
+ workspace_id: workspaceId,
298
+ title: params.title,
299
+ type: params.type ?? 'png',
300
+ entry_type: params.entity_type,
301
+ entry_id: params.entity_id,
302
+ source_url: params.source_url,
303
+ ...(params.creator !== undefined ? { creator: params.creator } : {}),
304
+ });
305
+ },
306
+ cli: { resource: 'attachment', action: 'attach-external' },
307
+ },
62
308
  // Mini (轻协作) API attachment tools
63
309
  {
64
310
  name: 'tapd_mini_get_attachments',
65
- description: 'Get attachments from mini workspace',
311
+ description: '查询轻协作项目附件列表。标准项目用标准附件列表查询工具。读操作。返回附件数组。',
66
312
  inputSchema: z.object({
67
- workspace_id: z.number().optional().describe('项目ID(可省略,使用默认配置)'),
68
- id: z.string().optional().describe('Attachment ID;必须以字符串(带引号)传递,禁止传数值,20 位 ID 超出 JS 安全整数范围会丢精度'),
69
- entry_id: z.string().optional().describe('Item ID;必须以字符串(带引号)传递,禁止传数值,20 位 ID 超出 JS 安全整数范围会丢精度'),
70
- filename: z.string().optional().describe('Filename'),
71
- owner: z.string().optional().describe('Uploader'),
72
- limit: z.number().optional().describe('Return count, default 30, max 200'),
73
- page: z.number().optional().describe('Page number, default 1'),
313
+ workspace_id: z.number().optional().describe('项目 ID,可省略(默认取环境变量 TAPD_DEFAULT_WORKSPACE_ID)'),
314
+ id: z.string().optional().describe('附件 ID;必须以字符串(带引号)传递,禁止传数值,20 位 ID 超出 JS 安全整数范围会丢精度'),
315
+ entry_id: z.string().optional().describe('工作项 ID;必须以字符串(带引号)传递,禁止传数值,20 位 ID 超出 JS 安全整数范围会丢精度'),
316
+ filename: z.string().optional().describe('文件名'),
317
+ owner: z.string().optional().describe('上传人'),
318
+ limit: z.number().optional().describe('返回数量,默认 30,最大 200'),
319
+ page: z.number().optional().describe('页码,默认 1'),
74
320
  }),
75
321
  handler: async (client, params) => {
76
322
  const workspaceId = params.workspace_id ?? TapdClient.getDefaultWorkspaceId();
@@ -82,10 +328,10 @@ export const attachmentTools = [
82
328
  },
83
329
  {
84
330
  name: 'tapd_mini_get_attachment_download_url',
85
- description: 'Get download URL for a single mini workspace attachment (valid for 300s)',
331
+ description: '获取轻协作项目附件的临时下载 URL(300s 有效)。标准项目附件用标准附件下载工具。读操作;id 必填。返回下载 URL。',
86
332
  inputSchema: z.object({
87
- workspace_id: z.number().optional().describe('项目ID(可省略,使用默认配置)'),
88
- id: z.string().describe('Attachment ID (required);必须以字符串(带引号)传递,禁止传数值,20 位 ID 超出 JS 安全整数范围会丢精度'),
333
+ workspace_id: z.number().optional().describe('项目 ID,可省略(默认取环境变量 TAPD_DEFAULT_WORKSPACE_ID)'),
334
+ id: z.string().describe('附件 ID(必填);必须以字符串(带引号)传递,禁止传数值,20 位 ID 超出 JS 安全整数范围会丢精度'),
89
335
  }),
90
336
  handler: async (client, params) => {
91
337
  const workspaceId = params.workspace_id ?? TapdClient.getDefaultWorkspaceId();
@@ -1 +1 @@
1
- {"version":3,"file":"attachment.js","sourceRoot":"","sources":["../../src/tools/attachment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,MAAM,CAAC,MAAM,eAAe,GAAc;IACxC,qCAAqC;IACrC;QACE,IAAI,EAAE,sBAAsB;QAC5B,WAAW,EAAE,+BAA+B;QAC5C,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC;YAChE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mFAAmF,CAAC;YACvH,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,yFAAyF,CAAC;YACpI,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sCAAsC,CAAC;YACnF,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC;YACpD,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC;YACjD,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oCAAoC,CAAC;YAC7E,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,6CAA6C,CAAC;YACvF,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,0CAA0C,CAAC;YAClF,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sCAAsC,CAAC;YAC7E,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC;YAC9D,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC;SAC1E,CAAC;QACF,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;YAChC,MAAM,WAAW,GAAG,MAAM,CAAC,YAAY,IAAI,UAAU,CAAC,qBAAqB,EAAE,CAAC;YAC9E,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,MAAM,IAAI,KAAK,CAAC,mFAAmF,CAAC,CAAC;YACvG,CAAC;YACD,OAAO,MAAM,CAAC,GAAG,CAAC,cAAc,EAAE,EAAE,GAAG,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC,CAAC;QAC9E,CAAC;KACF;IACD;QACE,IAAI,EAAE,qBAAqB;QAC3B,WAAW,EAAE,mCAAmC;QAChD,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC;YAChE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,uEAAuE,CAAC;YAChG,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,0CAA0C,CAAC;SACnF,CAAC;QACF,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;YAChC,MAAM,WAAW,GAAG,MAAM,CAAC,YAAY,IAAI,UAAU,CAAC,qBAAqB,EAAE,CAAC;YAC9E,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,MAAM,IAAI,KAAK,CAAC,mFAAmF,CAAC,CAAC;YACvG,CAAC;YACD,OAAO,MAAM,CAAC,GAAG,CAAC,sBAAsB,EAAE,EAAE,GAAG,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC,CAAC;QACtF,CAAC;KACF;IACD;QACE,IAAI,EAAE,kCAAkC;QACxC,WAAW,EAAE,2DAA2D;QACxE,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC;YAChE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,uEAAuE,CAAC;YAChG,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,uBAAuB,CAAC;SAClE,CAAC;QACF,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;YAChC,MAAM,WAAW,GAAG,MAAM,CAAC,YAAY,IAAI,UAAU,CAAC,qBAAqB,EAAE,CAAC;YAC9E,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,MAAM,IAAI,KAAK,CAAC,mFAAmF,CAAC,CAAC;YACvG,CAAC;YACD,OAAO,MAAM,CAAC,GAAG,CAAC,6BAA6B,EAAE,EAAE,GAAG,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC,CAAC;QAC7F,CAAC;KACF;IACD,kCAAkC;IAClC;QACE,IAAI,EAAE,2BAA2B;QACjC,WAAW,EAAE,qCAAqC;QAClD,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC;YAChE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,4DAA4D,CAAC;YAChG,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sDAAsD,CAAC;YAChG,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC;YACpD,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC;YACjD,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mCAAmC,CAAC;YAC1E,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC;SAC/D,CAAC;QACF,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;YAChC,MAAM,WAAW,GAAG,MAAM,CAAC,YAAY,IAAI,UAAU,CAAC,qBAAqB,EAAE,CAAC;YAC9E,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,MAAM,IAAI,KAAK,CAAC,mFAAmF,CAAC,CAAC;YACvG,CAAC;YACD,OAAO,MAAM,CAAC,GAAG,CAAC,cAAc,EAAE,EAAE,GAAG,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC,CAAC;QAC9E,CAAC;KACF;IACD;QACE,IAAI,EAAE,uCAAuC;QAC7C,WAAW,EAAE,0EAA0E;QACvF,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC;YAChE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,uEAAuE,CAAC;SACjG,CAAC;QACF,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;YAChC,MAAM,WAAW,GAAG,MAAM,CAAC,YAAY,IAAI,UAAU,CAAC,qBAAqB,EAAE,CAAC;YAC9E,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,MAAM,IAAI,KAAK,CAAC,mFAAmF,CAAC,CAAC;YACvG,CAAC;YACD,OAAO,MAAM,CAAC,GAAG,CAAC,mBAAmB,EAAE,EAAE,GAAG,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC,CAAC;QACnF,CAAC;KACF;CACF,CAAC"}
1
+ {"version":3,"file":"attachment.js","sourceRoot":"","sources":["../../src/tools/attachment.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=attachment.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attachment.test.d.ts","sourceRoot":"","sources":["../../src/tools/attachment.test.ts"],"names":[],"mappings":""}