openclaw-weiyuan-init 1.0.117 → 1.0.118
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/lib/downloader.js
CHANGED
|
@@ -12,6 +12,44 @@ function toZipFilename(downloadUrl) {
|
|
|
12
12
|
return parts[parts.length - 1] || 'weiyuan-openclaw-skill.zip';
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
function parseVersionFromZipFilename(zipFilename) {
|
|
16
|
+
const match = /-v(\d+\.\d+\.\d+)\.zip$/i.exec(String(zipFilename || '').trim());
|
|
17
|
+
return match ? match[1] : '';
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function buildFallbackReleaseNotes(version) {
|
|
21
|
+
const normalizedVersion = String(version || '').trim();
|
|
22
|
+
if (!normalizedVersion) return null;
|
|
23
|
+
return {
|
|
24
|
+
version: normalizedVersion,
|
|
25
|
+
summary: '本次更新已完成发布,请先阅读必读文件后再执行命令。',
|
|
26
|
+
changes: [
|
|
27
|
+
'已同步最新微元系统运行时与规则文件。',
|
|
28
|
+
'执行任何命令前,请先阅读 CHANGELOG_OPENCLAW.md、release-notes/latest.json、docs/OPENCLAW_WEIYUAN_CLI_QUICKSTART.md、docs/WEIYUAN_AGENT_RULES.md。'
|
|
29
|
+
],
|
|
30
|
+
releasedAt: new Date().toISOString()
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function normalizeReleaseNotesForResolvedVersion(releaseNotes, resolvedVersion) {
|
|
35
|
+
const version = String(resolvedVersion || '').trim();
|
|
36
|
+
if (!version) return releaseNotes || null;
|
|
37
|
+
const fallback = buildFallbackReleaseNotes(version);
|
|
38
|
+
if (!releaseNotes || typeof releaseNotes !== 'object') return fallback;
|
|
39
|
+
const notesVersion = String(releaseNotes.version || '').trim();
|
|
40
|
+
const summary = String(releaseNotes.summary || '').trim();
|
|
41
|
+
const changes = Array.isArray(releaseNotes.changes)
|
|
42
|
+
? releaseNotes.changes.map((item) => String(item || '').trim()).filter(Boolean)
|
|
43
|
+
: [];
|
|
44
|
+
return {
|
|
45
|
+
version,
|
|
46
|
+
summary: summary || fallback.summary,
|
|
47
|
+
changes: changes.length > 0 ? changes : fallback.changes,
|
|
48
|
+
releasedAt: String(releaseNotes.releasedAt || '').trim() || fallback.releasedAt,
|
|
49
|
+
sourceVersion: notesVersion || undefined
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
15
53
|
async function fetchLatestReleaseNotes(base, nonce) {
|
|
16
54
|
const notesUrl = `${base}/RELEASE_NOTES_LATEST.json?nocache=${nonce}`;
|
|
17
55
|
try {
|
|
@@ -34,7 +72,16 @@ async function fetchLatestReleaseNotes(base, nonce) {
|
|
|
34
72
|
|
|
35
73
|
async function resolvePackageSource({ downloadUrl, upgradeBaseUrl, spinner = null }) {
|
|
36
74
|
if (downloadUrl) {
|
|
37
|
-
|
|
75
|
+
const zipFilename = toZipFilename(downloadUrl);
|
|
76
|
+
const version = parseVersionFromZipFilename(zipFilename);
|
|
77
|
+
return {
|
|
78
|
+
downloadUrl,
|
|
79
|
+
zipFilename,
|
|
80
|
+
version: version || null,
|
|
81
|
+
sha256: '',
|
|
82
|
+
from: 'download_url',
|
|
83
|
+
releaseNotes: normalizeReleaseNotesForResolvedVersion(null, version)
|
|
84
|
+
};
|
|
38
85
|
}
|
|
39
86
|
|
|
40
87
|
const base = trimSlash(upgradeBaseUrl);
|
|
@@ -52,7 +99,14 @@ async function resolvePackageSource({ downloadUrl, upgradeBaseUrl, spinner = nul
|
|
|
52
99
|
if (spinner) {
|
|
53
100
|
spinner.text = `已解析最新版本: v${version}`;
|
|
54
101
|
}
|
|
55
|
-
return {
|
|
102
|
+
return {
|
|
103
|
+
downloadUrl: resolvedDownloadUrl,
|
|
104
|
+
zipFilename,
|
|
105
|
+
version,
|
|
106
|
+
sha256,
|
|
107
|
+
from: 'latest_json',
|
|
108
|
+
releaseNotes: normalizeReleaseNotesForResolvedVersion(releaseNotes, version)
|
|
109
|
+
};
|
|
56
110
|
}
|
|
57
111
|
} catch (_e) {
|
|
58
112
|
// fallback to txt
|
|
@@ -66,7 +120,14 @@ async function resolvePackageSource({ downloadUrl, upgradeBaseUrl, spinner = nul
|
|
|
66
120
|
if (spinner) {
|
|
67
121
|
spinner.text = `已解析最新版本: v${version}`;
|
|
68
122
|
}
|
|
69
|
-
return {
|
|
123
|
+
return {
|
|
124
|
+
downloadUrl: resolvedDownloadUrl,
|
|
125
|
+
zipFilename,
|
|
126
|
+
version,
|
|
127
|
+
sha256: '',
|
|
128
|
+
from: 'latest_version',
|
|
129
|
+
releaseNotes: normalizeReleaseNotesForResolvedVersion(releaseNotes, version)
|
|
130
|
+
};
|
|
70
131
|
}
|
|
71
132
|
|
|
72
133
|
async function downloadFile(url, outputPath, spinner = null, expectedSha256 = '') {
|
package/package.json
CHANGED
|
@@ -145,7 +145,7 @@ npm run weiyuan -- doc sync-check --project <projectId>
|
|
|
145
145
|
|
|
146
146
|
说明:
|
|
147
147
|
|
|
148
|
-
-
|
|
148
|
+
- 文件上传已恢复 CLI 直传能力,可使用 `doc upload --project <projectId> --file <路径>`;未显式提供 `--name` 或 `--type` 时会自动补默认值。
|
|
149
149
|
- 文件删除保留 CLI 能力,智能体 CLI 与小精灵 CLI 都支持删除文件。
|
|
150
150
|
|
|
151
151
|
Todo 行动清单:
|
|
@@ -803,7 +803,7 @@ async function repairIdentityForCurrentBinding(args: Argv): Promise<boolean> {
|
|
|
803
803
|
JSON.stringify(nextJoinedProjectIds) !== JSON.stringify(identity.joinedProjectIds ?? []) ||
|
|
804
804
|
nextCurrentProjectId !== String(identity.currentProjectId || "").trim() ||
|
|
805
805
|
JSON.stringify(nextProjectCursors) !== JSON.stringify(identity.projectCursors ?? {})
|
|
806
|
-
if (!changed) return
|
|
806
|
+
if (!changed) return true
|
|
807
807
|
await backupCurrentIdentityIfExists(filePath)
|
|
808
808
|
await writeIdentity(filePath, nextIdentity)
|
|
809
809
|
return true
|
|
@@ -5067,6 +5067,32 @@ function parseIssueAttachmentPaths(raw?: string): string[] {
|
|
|
5067
5067
|
.slice(0, ISSUE_ATTACHMENT_MAX_FILES)
|
|
5068
5068
|
}
|
|
5069
5069
|
|
|
5070
|
+
const DOC_UPLOAD_MIME_MAP: Record<string, string> = {
|
|
5071
|
+
".txt": "text/plain",
|
|
5072
|
+
".md": "text/markdown",
|
|
5073
|
+
".markdown": "text/markdown",
|
|
5074
|
+
".json": "application/json",
|
|
5075
|
+
".csv": "text/csv",
|
|
5076
|
+
".pdf": "application/pdf",
|
|
5077
|
+
".zip": "application/zip",
|
|
5078
|
+
".doc": "application/msword",
|
|
5079
|
+
".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
5080
|
+
".xls": "application/vnd.ms-excel",
|
|
5081
|
+
".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
5082
|
+
".ppt": "application/vnd.ms-powerpoint",
|
|
5083
|
+
".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
5084
|
+
".png": "image/png",
|
|
5085
|
+
".jpg": "image/jpeg",
|
|
5086
|
+
".jpeg": "image/jpeg",
|
|
5087
|
+
".gif": "image/gif",
|
|
5088
|
+
".webp": "image/webp",
|
|
5089
|
+
}
|
|
5090
|
+
|
|
5091
|
+
function guessDocMimeType(filePath: string): string {
|
|
5092
|
+
const ext = path.extname(String(filePath || "")).toLowerCase()
|
|
5093
|
+
return DOC_UPLOAD_MIME_MAP[ext] ?? "application/octet-stream"
|
|
5094
|
+
}
|
|
5095
|
+
|
|
5070
5096
|
async function loadIssueAttachments(attachmentPath?: string): Promise<Array<{ fileName: string; mimeType: string; contentBase64: string }>> {
|
|
5071
5097
|
const paths = parseIssueAttachmentPaths(attachmentPath)
|
|
5072
5098
|
if (!paths.length) return []
|
|
@@ -5760,8 +5786,93 @@ async function cmdDocList(args: Argv): Promise<void> {
|
|
|
5760
5786
|
}
|
|
5761
5787
|
|
|
5762
5788
|
async function cmdDocCreate(args: Argv): Promise<void> {
|
|
5763
|
-
|
|
5764
|
-
|
|
5789
|
+
const filePath = optString(args.flags, "identity") ?? DEFAULT_IDENTITY_PATH
|
|
5790
|
+
const identity = await readIdentity(filePath)
|
|
5791
|
+
const resolved = await resolveProjectRef(args.flags, identity)
|
|
5792
|
+
const interactive = Boolean(args.flags.interactive || args.flags.prompt)
|
|
5793
|
+
const sourceFileRaw = interactive
|
|
5794
|
+
? await askRequired("请选择要上传的文件路径: ", optString(args.flags, "file"))
|
|
5795
|
+
: mustString(args.flags, "file")
|
|
5796
|
+
const sourceFile = path.resolve(sourceFileRaw)
|
|
5797
|
+
let stat
|
|
5798
|
+
try {
|
|
5799
|
+
stat = await fs.stat(sourceFile)
|
|
5800
|
+
} catch {
|
|
5801
|
+
throw new Error(`invalid_doc_file_path: ${sourceFileRaw}`)
|
|
5802
|
+
}
|
|
5803
|
+
if (!stat.isFile()) throw new Error(`invalid_doc_file_path: ${sourceFileRaw}`)
|
|
5804
|
+
const bytes = await fs.readFile(sourceFile)
|
|
5805
|
+
const uploadNameFallback = path.basename(sourceFile)
|
|
5806
|
+
const uploadTypeFallback = guessDocMimeType(sourceFile)
|
|
5807
|
+
const docName = interactive
|
|
5808
|
+
? await askRequired("请输入上传后显示的文件名: ", optString(args.flags, "name") ?? optString(args.flags, "title") ?? uploadNameFallback)
|
|
5809
|
+
: String(optString(args.flags, "name") ?? optString(args.flags, "title") ?? uploadNameFallback).trim()
|
|
5810
|
+
const docType = interactive
|
|
5811
|
+
? await askRequired("请输入文件类型(可留空走自动识别): ", optString(args.flags, "type") ?? optString(args.flags, "docType") ?? uploadTypeFallback)
|
|
5812
|
+
: String(optString(args.flags, "type") ?? optString(args.flags, "docType") ?? uploadTypeFallback).trim()
|
|
5813
|
+
const fileSize = bytes.length
|
|
5814
|
+
if (fileSize > MAX_SHARED_DOC_FILE_BYTES) {
|
|
5815
|
+
throw new Error("doc_file_too_large: 单文件超过 10MB,请压缩后重试。")
|
|
5816
|
+
}
|
|
5817
|
+
const contentHash = sha256Hex(bytes)
|
|
5818
|
+
const storageType = optString(args.flags, "storageType")
|
|
5819
|
+
const storageProvider = optString(args.flags, "storageProvider")
|
|
5820
|
+
const storagePath = optString(args.flags, "storagePath") ?? sourceFile
|
|
5821
|
+
const tags = String(optString(args.flags, "tags") ?? "")
|
|
5822
|
+
.split(",")
|
|
5823
|
+
.map((x) => x.trim())
|
|
5824
|
+
.filter(Boolean)
|
|
5825
|
+
const relatedTaskIds = String(optString(args.flags, "tasks") ?? optString(args.flags, "task") ?? "")
|
|
5826
|
+
.split(",")
|
|
5827
|
+
.map((x) => x.trim())
|
|
5828
|
+
.filter(Boolean)
|
|
5829
|
+
const version = optString(args.flags, "version") ?? "v1"
|
|
5830
|
+
const description = optString(args.flags, "desc") ?? optString(args.flags, "description")
|
|
5831
|
+
const changeSummary = optString(args.flags, "summary")
|
|
5832
|
+
const idempotencyKey = createRequestId(`doc_upload_${path.basename(sourceFile)}`)
|
|
5833
|
+
const { status, json } = await signedRequest({
|
|
5834
|
+
serverBaseUrl: identity.serverBaseUrl,
|
|
5835
|
+
method: "POST",
|
|
5836
|
+
pathWithQuery: `/v1/projects/${resolved.projectId}/docs`,
|
|
5837
|
+
lobsterId: identity.lobsterId,
|
|
5838
|
+
secretKeyBase64: identity.secretKeyBase64,
|
|
5839
|
+
idempotencyKey,
|
|
5840
|
+
body: {
|
|
5841
|
+
docName,
|
|
5842
|
+
docType,
|
|
5843
|
+
fileSize,
|
|
5844
|
+
contentHash,
|
|
5845
|
+
contentBase64: bytes.toString("base64"),
|
|
5846
|
+
storageLocation: { type: storageType ?? undefined, provider: storageProvider, path: storagePath },
|
|
5847
|
+
version,
|
|
5848
|
+
relatedTaskIds,
|
|
5849
|
+
tags,
|
|
5850
|
+
description,
|
|
5851
|
+
changeSummary,
|
|
5852
|
+
},
|
|
5853
|
+
})
|
|
5854
|
+
if (status !== 200) {
|
|
5855
|
+
const msg = String((json as any)?.msg ?? (json as any)?.message ?? "")
|
|
5856
|
+
if (status === 409 && msg.includes("storage_quota_exceeded")) {
|
|
5857
|
+
throw new Error("storage_quota_exceeded: 存储空间已达上限,请联系 founder 升级容量后再上传。")
|
|
5858
|
+
}
|
|
5859
|
+
if (status === 409 && msg === "invalid_storage_profile") {
|
|
5860
|
+
throw new Error("invalid_storage_profile: 当前项目存储配置无效,请联系 founder 检查项目存储设置。")
|
|
5861
|
+
}
|
|
5862
|
+
throw new Error(JSON.stringify(json))
|
|
5863
|
+
}
|
|
5864
|
+
print({
|
|
5865
|
+
ok: true,
|
|
5866
|
+
projectId: resolved.projectId,
|
|
5867
|
+
projectName: resolved.projectName ?? "",
|
|
5868
|
+
docName,
|
|
5869
|
+
docType,
|
|
5870
|
+
sourceFile,
|
|
5871
|
+
fileSize,
|
|
5872
|
+
contentHash,
|
|
5873
|
+
uploadedAt: Date.now(),
|
|
5874
|
+
...(json.data && typeof json.data === "object" ? (json.data as Record<string, unknown>) : {}),
|
|
5875
|
+
})
|
|
5765
5876
|
}
|
|
5766
5877
|
|
|
5767
5878
|
async function cmdDocDetail(args: Argv): Promise<void> {
|
|
@@ -18,7 +18,9 @@ function toUserError(raw: string): string {
|
|
|
18
18
|
if (msg.includes("interactive_input_required")) return "必填内容不能为空,请补充参数后重试。"
|
|
19
19
|
if (msg.includes("missing_project_name")) return "项目名不能为空,请通过 --name 提供有效项目名。"
|
|
20
20
|
if (msg.includes("project_name_too_long")) return "项目名不能超过80个字符,请缩短后重试。"
|
|
21
|
-
if (msg.includes("doc_upload_board_only")) return "
|
|
21
|
+
if (msg.includes("doc_upload_board_only")) return "当前运行时版本过旧,文件上传仍被禁用。请先更新微元系统后再试。"
|
|
22
|
+
if (msg.includes("invalid_doc_file_path")) return "上传文件路径不存在,或该路径不是一个可读取的文件。请检查 --file 后重试。"
|
|
23
|
+
if (msg.includes("invalid_storage_profile")) return "当前项目的存储配置异常,暂时无法上传文件。请联系项目 founder 检查存储设置。"
|
|
22
24
|
if (msg.includes("invalid_project_name")) return "项目名仅支持中文/英文/数字/空格及 -_.()·,且不能包含HTML标签。"
|
|
23
25
|
if (msg.includes("task_title_contains_html")) return "任务标题不能包含HTML标签(如 <script>)。"
|
|
24
26
|
if (msg.includes("task_title_too_long")) return "任务标题不能超过120个字符,请缩短后重试。"
|
|
@@ -362,6 +362,90 @@ function extractNicknameFromText(text: string): string | undefined {
|
|
|
362
362
|
return v || undefined
|
|
363
363
|
}
|
|
364
364
|
|
|
365
|
+
function extractMemberProfileFieldFromText(
|
|
366
|
+
text: string,
|
|
367
|
+
field: "roleTitle" | "specialties" | "experienceSummary" | "strengthsSummary" | "taskPreferenceTags"
|
|
368
|
+
): string | undefined {
|
|
369
|
+
const patterns: RegExp[] =
|
|
370
|
+
field === "roleTitle"
|
|
371
|
+
? [
|
|
372
|
+
/(?:设置|修改|更改|更新)(?:我的)?(?:团队)?角色(?:与能力)?(?:为|叫|成)?\s*[“"']?([^”"'\n]+)[”"']?$/u,
|
|
373
|
+
/(?:我的)?(?:团队)?角色(?:是|为|叫|改成|改为)\s*[“"']?([^”"'\n]+)[”"']?$/u,
|
|
374
|
+
]
|
|
375
|
+
: field === "specialties"
|
|
376
|
+
? [
|
|
377
|
+
/(?:设置|修改|更改|更新)(?:我的)?(?:擅长方向|擅长|专长|特长方向)(?:为|成)?\s*[“"']?([^”"'\n]+)[”"']?$/u,
|
|
378
|
+
/(?:我的)?(?:擅长方向|擅长|专长|特长方向)(?:是|为|改成|改为)\s*[“"']?([^”"'\n]+)[”"']?$/u,
|
|
379
|
+
]
|
|
380
|
+
: field === "experienceSummary"
|
|
381
|
+
? [
|
|
382
|
+
/(?:设置|修改|更改|更新)(?:我的)?(?:经历概述|经历简介|经验概述|经验简介|经历)(?:为|成)?\s*[“"']?([^”"'\n]+)[”"']?$/u,
|
|
383
|
+
/(?:我的)?(?:经历概述|经历简介|经验概述|经验简介|经历)(?:是|为|改成|改为)\s*[“"']?([^”"'\n]+)[”"']?$/u,
|
|
384
|
+
]
|
|
385
|
+
: field === "strengthsSummary"
|
|
386
|
+
? [
|
|
387
|
+
/(?:设置|修改|更改|更新)(?:我的)?(?:特长概述|优势概述|优势简介|特长简介|特长)(?:为|成)?\s*[“"']?([^”"'\n]+)[”"']?$/u,
|
|
388
|
+
/(?:我的)?(?:特长概述|优势概述|优势简介|特长简介|特长)(?:是|为|改成|改为)\s*[“"']?([^”"'\n]+)[”"']?$/u,
|
|
389
|
+
]
|
|
390
|
+
: [
|
|
391
|
+
/(?:设置|修改|更改|更新)(?:我的)?(?:偏好任务标签|任务偏好标签|偏好标签|任务标签)(?:为|成)?\s*[“"']?([^”"'\n]+)[”"']?$/u,
|
|
392
|
+
/(?:我的)?(?:偏好任务标签|任务偏好标签|偏好标签|任务标签)(?:是|为|改成|改为)\s*[“"']?([^”"'\n]+)[”"']?$/u,
|
|
393
|
+
]
|
|
394
|
+
for (const pattern of patterns) {
|
|
395
|
+
const value = String(text.match(pattern)?.[1] ?? "").trim()
|
|
396
|
+
if (value) return value
|
|
397
|
+
}
|
|
398
|
+
return undefined
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
function hasMemberProfileCardIntent(text: string): boolean {
|
|
402
|
+
const compact = text.toLowerCase().replace(/\s+/g, "")
|
|
403
|
+
return (
|
|
404
|
+
compact.includes("成员角色卡片") ||
|
|
405
|
+
compact.includes("角色卡片") ||
|
|
406
|
+
compact.includes("成员卡片") ||
|
|
407
|
+
compact.includes("编辑成员信息") ||
|
|
408
|
+
compact.includes("修改成员信息") ||
|
|
409
|
+
compact.includes("设置角色卡片") ||
|
|
410
|
+
compact.includes("角色与能力") ||
|
|
411
|
+
compact.includes("我的角色") ||
|
|
412
|
+
compact.includes("修改角色") ||
|
|
413
|
+
compact.includes("更新角色") ||
|
|
414
|
+
compact.includes("团队角色") ||
|
|
415
|
+
compact.includes("擅长方向") ||
|
|
416
|
+
compact.includes("我的擅长") ||
|
|
417
|
+
compact.includes("我的专长") ||
|
|
418
|
+
compact.includes("经历概述") ||
|
|
419
|
+
compact.includes("经历简介") ||
|
|
420
|
+
compact.includes("经验概述") ||
|
|
421
|
+
compact.includes("我的经历") ||
|
|
422
|
+
compact.includes("特长概述") ||
|
|
423
|
+
compact.includes("优势概述") ||
|
|
424
|
+
compact.includes("我的特长") ||
|
|
425
|
+
compact.includes("我的优势") ||
|
|
426
|
+
compact.includes("偏好任务标签") ||
|
|
427
|
+
compact.includes("任务偏好标签")
|
|
428
|
+
)
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
function extractMemberRemarkIntent(text: string): { target?: string; remark?: string; clear?: boolean } | undefined {
|
|
432
|
+
const trimmed = String(text || "").trim()
|
|
433
|
+
if (!trimmed) return undefined
|
|
434
|
+
const clearMatch =
|
|
435
|
+
trimmed.match(/(?:清空|删除|移除|去掉)(?:我对)?\s*([^,,\s]+)\s*(?:的)?备注$/u) ??
|
|
436
|
+
trimmed.match(/(?:把)?\s*([^,,\s]+)\s*(?:的)?备注(?:清空|删除|移除|去掉)$/u)
|
|
437
|
+
if (clearMatch?.[1]) {
|
|
438
|
+
return { target: clearMatch[1].trim(), clear: true, remark: "-" }
|
|
439
|
+
}
|
|
440
|
+
const saveMatch =
|
|
441
|
+
trimmed.match(/(?:给|帮我给|把)?\s*([^,,\s]+)\s*(?:的)?备注(?:为|成)?\s*([^\n]+)$/u) ??
|
|
442
|
+
trimmed.match(/(?:把)?\s*([^,,\s]+)\s*(?:备注为|备注成)\s*([^\n]+)$/u)
|
|
443
|
+
if (saveMatch?.[1]) {
|
|
444
|
+
return { target: saveMatch[1].trim(), remark: String(saveMatch[2] ?? "").trim() }
|
|
445
|
+
}
|
|
446
|
+
return undefined
|
|
447
|
+
}
|
|
448
|
+
|
|
365
449
|
function extractProjectNameForCreate(text: string): string | undefined {
|
|
366
450
|
const m =
|
|
367
451
|
text.match(/(?:创建|新建)(?:一个|个)?[“"'《【((]?\s*([^”"'》】))\n]+?项目)\s*(?:吧|呀|呢|的)?$/) ??
|
|
@@ -1761,22 +1845,33 @@ function fromText(input: SkillInput): string[] {
|
|
|
1761
1845
|
if (!nickname) return ["member-profile-edit", "--identity", identity, "--project", input.projectId]
|
|
1762
1846
|
return ["member-profile-set", "--identity", identity, "--project", input.projectId, "--nickname", nickname]
|
|
1763
1847
|
}
|
|
1764
|
-
if (
|
|
1765
|
-
compact.includes("成员角色卡片") ||
|
|
1766
|
-
compact.includes("角色卡片") ||
|
|
1767
|
-
compact.includes("成员卡片") ||
|
|
1768
|
-
compact.includes("编辑成员信息") ||
|
|
1769
|
-
compact.includes("修改成员信息") ||
|
|
1770
|
-
compact.includes("设置角色卡片")
|
|
1771
|
-
) {
|
|
1848
|
+
if (hasMemberProfileCardIntent(text)) {
|
|
1772
1849
|
if (!input.projectId) return ["context", "candidates", "--identity", identity]
|
|
1773
|
-
|
|
1850
|
+
const roleTitle = extractMemberProfileFieldFromText(text, "roleTitle")
|
|
1851
|
+
const specialties = extractMemberProfileFieldFromText(text, "specialties")
|
|
1852
|
+
const experienceSummary = extractMemberProfileFieldFromText(text, "experienceSummary")
|
|
1853
|
+
const strengthsSummary = extractMemberProfileFieldFromText(text, "strengthsSummary")
|
|
1854
|
+
const taskPreferenceTags = extractMemberProfileFieldFromText(text, "taskPreferenceTags")
|
|
1855
|
+
const argv = ["member-profile-edit", "--identity", identity, "--project", input.projectId]
|
|
1856
|
+
if (roleTitle) argv.push("--roleTitle", roleTitle)
|
|
1857
|
+
if (specialties) argv.push("--specialties", specialties)
|
|
1858
|
+
if (experienceSummary) argv.push("--experienceSummary", experienceSummary)
|
|
1859
|
+
if (strengthsSummary) argv.push("--strengthsSummary", strengthsSummary)
|
|
1860
|
+
if (taskPreferenceTags) argv.push("--taskPreferenceTags", taskPreferenceTags)
|
|
1861
|
+
return argv
|
|
1774
1862
|
}
|
|
1775
|
-
if (
|
|
1863
|
+
if (
|
|
1864
|
+
compact.includes("成员备注") ||
|
|
1865
|
+
compact.includes("备注成员") ||
|
|
1866
|
+
compact.includes("给成员备注") ||
|
|
1867
|
+
compact.includes("修改备注") ||
|
|
1868
|
+
compact.includes("清空备注") ||
|
|
1869
|
+
compact.includes("删除备注")
|
|
1870
|
+
) {
|
|
1776
1871
|
if (!input.projectId) return ["context", "candidates", "--identity", identity]
|
|
1777
|
-
const
|
|
1778
|
-
const target = (
|
|
1779
|
-
const remark = (
|
|
1872
|
+
const remarkIntent = extractMemberRemarkIntent(text)
|
|
1873
|
+
const target = String(remarkIntent?.target ?? "").trim()
|
|
1874
|
+
const remark = String(remarkIntent?.remark ?? "").trim()
|
|
1780
1875
|
if (target && remark) {
|
|
1781
1876
|
return ["panel", "member-remark", "--identity", identity, "--project", input.projectId, "--target", target, "--remark", remark]
|
|
1782
1877
|
}
|
|
@@ -2385,8 +2480,20 @@ function fromText(input: SkillInput): string[] {
|
|
|
2385
2480
|
}
|
|
2386
2481
|
if (lower.includes("上传文件") || lower.includes("上传文档") || lower.includes("新增文档")) {
|
|
2387
2482
|
if (!input.projectId) return ["context", "candidates", "--identity", identity]
|
|
2388
|
-
if (!input.file
|
|
2389
|
-
return [
|
|
2483
|
+
if (!input.file) return ["doc", "upload", "--identity", identity, "--project", input.projectId, "--interactive"]
|
|
2484
|
+
return [
|
|
2485
|
+
"doc",
|
|
2486
|
+
"upload",
|
|
2487
|
+
"--identity",
|
|
2488
|
+
identity,
|
|
2489
|
+
"--project",
|
|
2490
|
+
input.projectId,
|
|
2491
|
+
"--file",
|
|
2492
|
+
input.file,
|
|
2493
|
+
...(input.title ? ["--name", input.title] : []),
|
|
2494
|
+
...(input.docType ? ["--type", input.docType] : []),
|
|
2495
|
+
...(input.desc ? ["--desc", input.desc] : []),
|
|
2496
|
+
]
|
|
2390
2497
|
}
|
|
2391
2498
|
if (lower.includes("老规矩") || lower.includes("上次那套")) {
|
|
2392
2499
|
if (input.projectId) return ["capsule", "recommend", "--identity", identity, "--project", input.projectId, "--query", input.query ?? ""]
|
|
@@ -2659,8 +2766,8 @@ function fromAction(input: SkillInput): string[] {
|
|
|
2659
2766
|
]
|
|
2660
2767
|
case "doc.upload":
|
|
2661
2768
|
if (!input.projectId) throw new Error("missing_projectId")
|
|
2662
|
-
if (!input.file
|
|
2663
|
-
return ["doc", "upload", "--identity", identity, "--project", input.projectId, "--interactive", ...(input.title ? ["--name", input.title] : []), ...(input.docType ? ["--type", input.docType] : [])
|
|
2769
|
+
if (!input.file) {
|
|
2770
|
+
return ["doc", "upload", "--identity", identity, "--project", input.projectId, "--interactive", ...(input.title ? ["--name", input.title] : []), ...(input.docType ? ["--type", input.docType] : [])]
|
|
2664
2771
|
}
|
|
2665
2772
|
return [
|
|
2666
2773
|
"doc",
|
|
@@ -2669,12 +2776,10 @@ function fromAction(input: SkillInput): string[] {
|
|
|
2669
2776
|
identity,
|
|
2670
2777
|
"--project",
|
|
2671
2778
|
input.projectId,
|
|
2672
|
-
"--name",
|
|
2673
|
-
input.title,
|
|
2674
|
-
"--type",
|
|
2675
|
-
input.docType,
|
|
2676
2779
|
"--file",
|
|
2677
2780
|
input.file,
|
|
2781
|
+
...(input.title ? ["--name", input.title] : []),
|
|
2782
|
+
...(input.docType ? ["--type", input.docType] : []),
|
|
2678
2783
|
...(input.desc ? ["--desc", input.desc] : []),
|
|
2679
2784
|
]
|
|
2680
2785
|
case "doc.delete":
|