mirror of
https://github.com/cjo4m06/mcp-shrimp-task-manager.git
synced 2025-07-27 00:12:26 +08:00
更新 API 參考文檔,新增目錄及詳細的核心任務管理 API 說明,包括任務規劃、分析、反思、拆分、列出、執行及驗證功能,並強化參數驗證規則以提升用戶體驗。同時,更新工具函數以加入錯誤處理,確保輸入的有效性與一致性。
This commit is contained in:
parent
611eb12534
commit
95628091fb
@ -2,7 +2,215 @@
|
|||||||
|
|
||||||
本文檔提供蝦米任務管理器的 API 參考,包含所有可用工具的詳細說明和參數列表。
|
本文檔提供蝦米任務管理器的 API 參考,包含所有可用工具的詳細說明和參數列表。
|
||||||
|
|
||||||
## 新增功能
|
## 目錄
|
||||||
|
|
||||||
|
- [核心任務管理 API](#核心任務管理-api)
|
||||||
|
- [任務管理 API](#任務管理-api)
|
||||||
|
- [工作日誌功能](#工作日誌功能)
|
||||||
|
|
||||||
|
## 核心任務管理 API
|
||||||
|
|
||||||
|
### 1. 任務規劃
|
||||||
|
|
||||||
|
#### `plan_task`
|
||||||
|
|
||||||
|
初始化並詳細規劃任務流程,建立明確的目標與成功標準。
|
||||||
|
|
||||||
|
**參數:**
|
||||||
|
|
||||||
|
| 參數名 | 類型 | 必填 | 描述 |
|
||||||
|
| ------------ | ------ | ---- | ------------------------------------------------------ |
|
||||||
|
| description | string | 是 | 完整詳細的任務問題描述,應包含任務目標、背景及預期成果 |
|
||||||
|
| requirements | string | 否 | 任務的特定技術要求、業務約束條件或品質標準(選填) |
|
||||||
|
|
||||||
|
**返回:**
|
||||||
|
|
||||||
|
- 成功:返回結構化的任務規劃結果
|
||||||
|
- 失敗:返回錯誤訊息,說明失敗原因
|
||||||
|
|
||||||
|
**使用範例:**
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const planResult = await mcp.mcp_shrimp_task_manager.plan_task({
|
||||||
|
description:
|
||||||
|
"開發一個用戶註冊功能,包含表單驗證、數據存儲和電子郵件確認流程。",
|
||||||
|
requirements: "必須符合GDPR數據保護規定,支持多語言,並通過所有安全測試。",
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 任務分析
|
||||||
|
|
||||||
|
#### `analyze_task`
|
||||||
|
|
||||||
|
深入分析任務需求並系統性檢查代碼庫,評估技術可行性與潛在風險。
|
||||||
|
|
||||||
|
**參數:**
|
||||||
|
|
||||||
|
| 參數名 | 類型 | 必填 | 描述 |
|
||||||
|
| ---------------- | ------ | ---- | ------------------------------------------------------------ |
|
||||||
|
| summary | string | 是 | 結構化的任務摘要,包含任務目標、範圍與關鍵技術挑戰 |
|
||||||
|
| initialConcept | string | 是 | 初步解答構想,包含技術方案、架構設計和實施策略 |
|
||||||
|
| previousAnalysis | string | 否 | 前次迭代的分析結果,用於持續改進方案(僅在重新分析時需提供) |
|
||||||
|
|
||||||
|
**返回:**
|
||||||
|
|
||||||
|
- 成功:返回詳細的任務分析結果
|
||||||
|
- 失敗:返回錯誤訊息,說明失敗原因
|
||||||
|
|
||||||
|
**使用範例:**
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const analysisResult = await mcp.mcp_shrimp_task_manager.analyze_task({
|
||||||
|
summary: "開發用戶身份驗證模塊,包含登入、註冊和密碼重設功能",
|
||||||
|
initialConcept: "計劃使用JWT進行身份驗證,實現無狀態API設計...",
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 方案反思
|
||||||
|
|
||||||
|
#### `reflect_task`
|
||||||
|
|
||||||
|
批判性審查分析結果,評估方案完整性並識別優化機會,確保解決方案符合最佳實踐。
|
||||||
|
|
||||||
|
**參數:**
|
||||||
|
|
||||||
|
| 參數名 | 類型 | 必填 | 描述 |
|
||||||
|
| -------- | ------ | ---- | ------------------------------------------------------------ |
|
||||||
|
| summary | string | 是 | 結構化的任務摘要,保持與分析階段一致以確保連續性 |
|
||||||
|
| analysis | string | 是 | 完整詳盡的技術分析結果,包括所有技術細節、依賴組件和實施方案 |
|
||||||
|
|
||||||
|
**返回:**
|
||||||
|
|
||||||
|
- 成功:返回方案改進建議和優化機會
|
||||||
|
- 失敗:返回錯誤訊息,說明失敗原因
|
||||||
|
|
||||||
|
**使用範例:**
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const reflectionResult = await mcp.mcp_shrimp_task_manager.reflect_task({
|
||||||
|
summary: "開發用戶身份驗證模塊,包含登入、註冊和密碼重設功能",
|
||||||
|
analysis: "詳細的技術分析結果,包括JWT實現方式、安全考量等...",
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. 任務拆分
|
||||||
|
|
||||||
|
#### `split_tasks`
|
||||||
|
|
||||||
|
將複雜任務分解為獨立且可追蹤的子任務,建立明確的依賴關係和優先順序。
|
||||||
|
|
||||||
|
**參數:**
|
||||||
|
|
||||||
|
| 參數名 | 類型 | 必填 | 描述 |
|
||||||
|
| ----------- | ------- | ---- | --------------------------------------------------------------------------- |
|
||||||
|
| isOverwrite | boolean | 是 | 任務覆蓋模式選擇(true:清除並覆蓋所有現有任務;false:保留現有任務並新增) |
|
||||||
|
| tasks | array | 是 | 結構化的任務清單,每個任務應保持原子性且有明確的完成標準 |
|
||||||
|
|
||||||
|
**tasks 對象屬性:**
|
||||||
|
|
||||||
|
| 屬性名 | 類型 | 必填 | 描述 |
|
||||||
|
| ------------ | ------ | ---- | ------------------------------------------------ |
|
||||||
|
| name | string | 是 | 簡潔明確的任務名稱,應能清晰表達任務目的 |
|
||||||
|
| description | string | 是 | 詳細的任務描述,包含實施要點、技術細節和驗收標準 |
|
||||||
|
| notes | string | 否 | 補充說明、特殊處理要求或實施建議(選填) |
|
||||||
|
| dependencies | array | 否 | 此任務依賴的前置任務 ID 或任務名稱列表 |
|
||||||
|
|
||||||
|
**返回:**
|
||||||
|
|
||||||
|
- 成功:返回創建的任務列表
|
||||||
|
- 失敗:返回錯誤訊息,說明失敗原因
|
||||||
|
|
||||||
|
**使用範例:**
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const tasksResult = await mcp.mcp_shrimp_task_manager.split_tasks({
|
||||||
|
isOverwrite: false,
|
||||||
|
tasks: [
|
||||||
|
{
|
||||||
|
name: "設計用戶數據模型",
|
||||||
|
description: "定義用戶實體的數據結構和驗證規則...",
|
||||||
|
notes: "參考現有的權限模型",
|
||||||
|
dependencies: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "實現用戶註冊API",
|
||||||
|
description: "開發註冊端點,處理表單驗證和數據存儲...",
|
||||||
|
dependencies: ["設計用戶數據模型"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. 任務列表
|
||||||
|
|
||||||
|
#### `list_tasks`
|
||||||
|
|
||||||
|
生成結構化任務清單,包含完整狀態追蹤、優先級和依賴關係。
|
||||||
|
|
||||||
|
**參數:** 無
|
||||||
|
|
||||||
|
**返回:**
|
||||||
|
|
||||||
|
- 成功:返回系統中所有任務的結構化清單
|
||||||
|
- 失敗:返回錯誤訊息,說明失敗原因
|
||||||
|
|
||||||
|
**使用範例:**
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const tasksList = await mcp.mcp_shrimp_task_manager.list_tasks();
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6. 任務執行
|
||||||
|
|
||||||
|
#### `execute_task`
|
||||||
|
|
||||||
|
按照預定義計劃執行特定任務,確保每個步驟的輸出符合質量標準。
|
||||||
|
|
||||||
|
**參數:**
|
||||||
|
|
||||||
|
| 參數名 | 類型 | 必填 | 描述 |
|
||||||
|
| ------ | ------ | ---- | ----------------------------------------------------- |
|
||||||
|
| taskId | string | 是 | 待執行任務的唯一標識符,必須是系統中存在的有效任務 ID |
|
||||||
|
|
||||||
|
**返回:**
|
||||||
|
|
||||||
|
- 成功:返回任務執行指南和上下文
|
||||||
|
- 失敗:返回錯誤訊息,說明失敗原因
|
||||||
|
|
||||||
|
**使用範例:**
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const executeResult = await mcp.mcp_shrimp_task_manager.execute_task({
|
||||||
|
taskId: "task-uuid-here",
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7. 任務驗證
|
||||||
|
|
||||||
|
#### `verify_task`
|
||||||
|
|
||||||
|
全面驗證任務完成度,確保所有需求與技術標準都已滿足,並無遺漏細節。
|
||||||
|
|
||||||
|
**參數:**
|
||||||
|
|
||||||
|
| 參數名 | 類型 | 必填 | 描述 |
|
||||||
|
| ------ | ------ | ---- | ----------------------------------------------------- |
|
||||||
|
| taskId | string | 是 | 待驗證任務的唯一標識符,必須是系統中存在的有效任務 ID |
|
||||||
|
|
||||||
|
**返回:**
|
||||||
|
|
||||||
|
- 成功:返回任務驗證評估結果
|
||||||
|
- 失敗:返回錯誤訊息,說明失敗原因
|
||||||
|
|
||||||
|
**使用範例:**
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const verifyResult = await mcp.mcp_shrimp_task_manager.verify_task({
|
||||||
|
taskId: "task-uuid-here",
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## 任務管理 API
|
||||||
|
|
||||||
### 1. 刪除任務功能
|
### 1. 刪除任務功能
|
||||||
|
|
||||||
@ -269,18 +477,4 @@ const clearResult = await mcp.mcp_shrimp_task_manager.clear_conversation_log({
|
|||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
## 完整 API 列表
|
## 實用工具函數
|
||||||
|
|
||||||
除了上述新增功能外,蝦米任務管理器還提供以下核心功能:
|
|
||||||
|
|
||||||
1. **開始規劃**:`plan_task`
|
|
||||||
2. **分析問題**:`analyze_task`
|
|
||||||
3. **反思構想**:`reflect_task`
|
|
||||||
4. **拆分任務**:`split_tasks`
|
|
||||||
5. **列出任務**:`list_tasks`
|
|
||||||
6. **執行任務**:`execute_task`
|
|
||||||
7. **檢驗任務**:`verify_task`
|
|
||||||
8. **完成任務**:`complete_task`
|
|
||||||
9. **刪除任務**:`delete_task`
|
|
||||||
10. **查詢日誌**:`list_conversation_log`
|
|
||||||
11. **清除日誌**:`clear_conversation_log`
|
|
||||||
|
39
src/index.ts
39
src/index.ts
@ -58,13 +58,17 @@ async function main() {
|
|||||||
version: "1.0.0",
|
version: "1.0.0",
|
||||||
});
|
});
|
||||||
|
|
||||||
// 註冊工具 - 使用已定義的schema物件
|
// 註冊工具 - 使用已定義的schema物件,並添加內嵌錯誤處理
|
||||||
server.tool(
|
server.tool(
|
||||||
"plan_task",
|
"plan_task",
|
||||||
"初始化並詳細規劃任務流程,建立明確的目標與成功標準",
|
"初始化並詳細規劃任務流程,建立明確的目標與成功標準",
|
||||||
{
|
{
|
||||||
description: z
|
description: z
|
||||||
.string()
|
.string()
|
||||||
|
.min(10, {
|
||||||
|
message:
|
||||||
|
"任務描述不能少於10個字符,請提供更詳細的描述以確保任務目標明確",
|
||||||
|
})
|
||||||
.describe("完整詳細的任務問題描述,應包含任務目標、背景及預期成果"),
|
.describe("完整詳細的任務問題描述,應包含任務目標、背景及預期成果"),
|
||||||
requirements: z
|
requirements: z
|
||||||
.string()
|
.string()
|
||||||
@ -82,9 +86,17 @@ async function main() {
|
|||||||
{
|
{
|
||||||
summary: z
|
summary: z
|
||||||
.string()
|
.string()
|
||||||
|
.min(20, {
|
||||||
|
message:
|
||||||
|
"任務摘要太短,請提供更詳細的摘要,包含任務目標、範圍與關鍵技術挑戰",
|
||||||
|
})
|
||||||
.describe("結構化的任務摘要,包含任務目標、範圍與關鍵技術挑戰"),
|
.describe("結構化的任務摘要,包含任務目標、範圍與關鍵技術挑戰"),
|
||||||
initialConcept: z
|
initialConcept: z
|
||||||
.string()
|
.string()
|
||||||
|
.min(50, {
|
||||||
|
message:
|
||||||
|
"初步解答構想過於簡短,請提供更完整的技術方案和實施策略詳情",
|
||||||
|
})
|
||||||
.describe("初步解答構想,包含技術方案、架構設計和實施策略"),
|
.describe("初步解答構想,包含技術方案、架構設計和實施策略"),
|
||||||
previousAnalysis: z
|
previousAnalysis: z
|
||||||
.string()
|
.string()
|
||||||
@ -104,9 +116,17 @@ async function main() {
|
|||||||
{
|
{
|
||||||
summary: z
|
summary: z
|
||||||
.string()
|
.string()
|
||||||
|
.min(20, {
|
||||||
|
message:
|
||||||
|
"任務摘要太短,請確保包含完整的任務目標和範圍以維持分析連續性",
|
||||||
|
})
|
||||||
.describe("結構化的任務摘要,保持與分析階段一致以確保連續性"),
|
.describe("結構化的任務摘要,保持與分析階段一致以確保連續性"),
|
||||||
analysis: z
|
analysis: z
|
||||||
.string()
|
.string()
|
||||||
|
.min(100, {
|
||||||
|
message:
|
||||||
|
"技術分析結果過於簡略,請提供更詳盡的技術細節、依賴組件和實施方案說明",
|
||||||
|
})
|
||||||
.describe(
|
.describe(
|
||||||
"完整詳盡的技術分析結果,包括所有技術細節、依賴組件和實施方案"
|
"完整詳盡的技術分析結果,包括所有技術細節、依賴組件和實施方案"
|
||||||
),
|
),
|
||||||
@ -130,9 +150,20 @@ async function main() {
|
|||||||
z.object({
|
z.object({
|
||||||
name: z
|
name: z
|
||||||
.string()
|
.string()
|
||||||
|
.min(5, {
|
||||||
|
message:
|
||||||
|
"任務名稱太短,請提供更清晰明確的名稱以便識別任務目的",
|
||||||
|
})
|
||||||
|
.max(100, {
|
||||||
|
message: "任務名稱過長,請保持簡潔,不超過100個字符",
|
||||||
|
})
|
||||||
.describe("簡潔明確的任務名稱,應能清晰表達任務目的"),
|
.describe("簡潔明確的任務名稱,應能清晰表達任務目的"),
|
||||||
description: z
|
description: z
|
||||||
.string()
|
.string()
|
||||||
|
.min(20, {
|
||||||
|
message:
|
||||||
|
"任務描述太短,請詳細說明實施要點、技術細節和驗收標準",
|
||||||
|
})
|
||||||
.describe("詳細的任務描述,包含實施要點、技術細節和驗收標準"),
|
.describe("詳細的任務描述,包含實施要點、技術細節和驗收標準"),
|
||||||
notes: z
|
notes: z
|
||||||
.string()
|
.string()
|
||||||
@ -157,7 +188,7 @@ async function main() {
|
|||||||
"list_tasks",
|
"list_tasks",
|
||||||
"生成結構化任務清單,包含完整狀態追蹤、優先級和依賴關係",
|
"生成結構化任務清單,包含完整狀態追蹤、優先級和依賴關係",
|
||||||
{},
|
{},
|
||||||
async () => {
|
async (args) => {
|
||||||
return await listTasks();
|
return await listTasks();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -347,7 +378,7 @@ async function main() {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// 註冊提示
|
// 註冊提示 - 使用同樣的錯誤處理模式
|
||||||
server.prompt(
|
server.prompt(
|
||||||
"plan_task_prompt",
|
"plan_task_prompt",
|
||||||
"生成結構化的新任務規劃,包含明確目標、評估標準與執行步驟",
|
"生成結構化的新任務規劃,包含明確目標、評估標準與執行步驟",
|
||||||
@ -364,7 +395,7 @@ async function main() {
|
|||||||
.describe("相關代碼片段或文件路徑(選填)"),
|
.describe("相關代碼片段或文件路徑(選填)"),
|
||||||
},
|
},
|
||||||
async (args) => {
|
async (args) => {
|
||||||
return planTaskPrompt(args);
|
return await planTaskPrompt(args);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -11,30 +11,70 @@ import { getTaskById } from "../models/taskModel.js";
|
|||||||
import { ListConversationLogArgs } from "../types/index.js";
|
import { ListConversationLogArgs } from "../types/index.js";
|
||||||
|
|
||||||
// 列出對話日誌工具
|
// 列出對話日誌工具
|
||||||
export const listConversationLogSchema = z.object({
|
export const listConversationLogSchema = z
|
||||||
taskId: z.string().optional().describe("按任務 ID 過濾對話記錄(選填)"),
|
.object({
|
||||||
startDate: z
|
taskId: z
|
||||||
.string()
|
.string()
|
||||||
.optional()
|
.uuid({ message: "任務ID格式無效,請提供有效的UUID格式" })
|
||||||
.describe("起始日期過濾,格式為 ISO 日期字串(選填)"),
|
.optional()
|
||||||
endDate: z
|
.describe("按任務 ID 過濾對話記錄(選填)"),
|
||||||
.string()
|
startDate: z
|
||||||
.optional()
|
.string()
|
||||||
.describe("結束日期過濾,格式為 ISO 日期字串(選填)"),
|
.refine(
|
||||||
limit: z
|
(val) => {
|
||||||
.number()
|
const date = new Date(val);
|
||||||
.int()
|
return !isNaN(date.getTime());
|
||||||
.positive()
|
},
|
||||||
.max(100)
|
{
|
||||||
.default(20)
|
message:
|
||||||
.describe("返回結果數量限制,最大 100(預設:20)"),
|
"起始日期格式無效,請使用ISO日期格式,例如:2025-04-11T12:13:49.751Z",
|
||||||
offset: z
|
}
|
||||||
.number()
|
)
|
||||||
.int()
|
.optional()
|
||||||
.nonnegative()
|
.describe("起始日期過濾,格式為 ISO 日期字串(選填)"),
|
||||||
.default(0)
|
endDate: z
|
||||||
.describe("分頁偏移量(預設:0)"),
|
.string()
|
||||||
});
|
.refine(
|
||||||
|
(val) => {
|
||||||
|
const date = new Date(val);
|
||||||
|
return !isNaN(date.getTime());
|
||||||
|
},
|
||||||
|
{
|
||||||
|
message:
|
||||||
|
"結束日期格式無效,請使用ISO日期格式,例如:2025-04-11T12:13:49.751Z",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.optional()
|
||||||
|
.describe("結束日期過濾,格式為 ISO 日期字串(選填)"),
|
||||||
|
limit: z
|
||||||
|
.number()
|
||||||
|
.int({ message: "限制必須是整數" })
|
||||||
|
.positive({ message: "限制必須是正數" })
|
||||||
|
.max(100, { message: "限制不能超過100條記錄" })
|
||||||
|
.default(20)
|
||||||
|
.describe("返回結果數量限制,最大 100(預設:20)"),
|
||||||
|
offset: z
|
||||||
|
.number()
|
||||||
|
.int({ message: "偏移量必須是整數" })
|
||||||
|
.nonnegative({ message: "偏移量不能為負數" })
|
||||||
|
.default(0)
|
||||||
|
.describe("分頁偏移量(預設:0)"),
|
||||||
|
})
|
||||||
|
.refine(
|
||||||
|
(data) => {
|
||||||
|
// 驗證起始日期和結束日期的順序
|
||||||
|
if (data.startDate && data.endDate) {
|
||||||
|
const start = new Date(data.startDate);
|
||||||
|
const end = new Date(data.endDate);
|
||||||
|
return start <= end;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
{
|
||||||
|
message: "起始日期必須早於或等於結束日期",
|
||||||
|
path: ["endDate"],
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
export async function listConversationLog({
|
export async function listConversationLog({
|
||||||
taskId,
|
taskId,
|
||||||
@ -171,7 +211,13 @@ export async function listConversationLog({
|
|||||||
|
|
||||||
// 清除所有對話日誌工具
|
// 清除所有對話日誌工具
|
||||||
export const clearConversationLogSchema = z.object({
|
export const clearConversationLogSchema = z.object({
|
||||||
confirm: z.boolean().describe("確認刪除所有日誌記錄(此操作不可逆)"),
|
confirm: z
|
||||||
|
.boolean()
|
||||||
|
.refine((val) => val === true, {
|
||||||
|
message:
|
||||||
|
"必須明確確認清除操作,請將 confirm 參數設置為 true 以確認此危險操作",
|
||||||
|
})
|
||||||
|
.describe("確認刪除所有日誌記錄(此操作不可逆)"),
|
||||||
});
|
});
|
||||||
|
|
||||||
export async function clearConversationLog({
|
export async function clearConversationLog({
|
||||||
@ -314,18 +360,23 @@ export async function listArchivedLogs({
|
|||||||
export const readArchivedLogSchema = z.object({
|
export const readArchivedLogSchema = z.object({
|
||||||
filename: z
|
filename: z
|
||||||
.string()
|
.string()
|
||||||
|
.min(1, { message: "文件名不能為空" })
|
||||||
|
.refine((val) => val.match(/^conversation_log_[\d-]+T[\d-]+\.json$/), {
|
||||||
|
message:
|
||||||
|
"無效的歸檔日誌文件名,正確格式為 'conversation_log_[timestamp].json'",
|
||||||
|
})
|
||||||
.describe("歸檔日誌文件名,格式為 'conversation_log_[timestamp].json'"),
|
.describe("歸檔日誌文件名,格式為 'conversation_log_[timestamp].json'"),
|
||||||
limit: z
|
limit: z
|
||||||
.number()
|
.number()
|
||||||
.int()
|
.int({ message: "限制必須是整數" })
|
||||||
.positive()
|
.positive({ message: "限制必須是正數" })
|
||||||
.max(100)
|
.max(100, { message: "限制不能超過100條記錄" })
|
||||||
.default(50)
|
.default(50)
|
||||||
.describe("返回結果數量限制,最大 100(預設:50)"),
|
.describe("返回結果數量限制,最大 100(預設:50)"),
|
||||||
offset: z
|
offset: z
|
||||||
.number()
|
.number()
|
||||||
.int()
|
.int({ message: "偏移量必須是整數" })
|
||||||
.nonnegative()
|
.nonnegative({ message: "偏移量不能為負數" })
|
||||||
.default(0)
|
.default(0)
|
||||||
.describe("分頁起始位置(預設:0)"),
|
.describe("分頁起始位置(預設:0)"),
|
||||||
});
|
});
|
||||||
|
@ -35,6 +35,9 @@ import { loadTaskRelatedFiles } from "../utils/fileLoader.js";
|
|||||||
export const planTaskSchema = z.object({
|
export const planTaskSchema = z.object({
|
||||||
description: z
|
description: z
|
||||||
.string()
|
.string()
|
||||||
|
.min(10, {
|
||||||
|
message: "任務描述不能少於10個字符,請提供更詳細的描述以確保任務目標明確",
|
||||||
|
})
|
||||||
.describe("完整詳細的任務問題描述,應包含任務目標、背景及預期成果"),
|
.describe("完整詳細的任務問題描述,應包含任務目標、背景及預期成果"),
|
||||||
requirements: z
|
requirements: z
|
||||||
.string()
|
.string()
|
||||||
@ -89,9 +92,16 @@ export async function planTask({
|
|||||||
export const analyzeTaskSchema = z.object({
|
export const analyzeTaskSchema = z.object({
|
||||||
summary: z
|
summary: z
|
||||||
.string()
|
.string()
|
||||||
|
.min(20, {
|
||||||
|
message:
|
||||||
|
"任務摘要太短,請提供更詳細的摘要,包含任務目標、範圍與關鍵技術挑戰",
|
||||||
|
})
|
||||||
.describe("結構化的任務摘要,包含任務目標、範圍與關鍵技術挑戰"),
|
.describe("結構化的任務摘要,包含任務目標、範圍與關鍵技術挑戰"),
|
||||||
initialConcept: z
|
initialConcept: z
|
||||||
.string()
|
.string()
|
||||||
|
.min(50, {
|
||||||
|
message: "初步解答構想過於簡短,請提供更完整的技術方案和實施策略詳情",
|
||||||
|
})
|
||||||
.describe("初步解答構想,包含技術方案、架構設計和實施策略"),
|
.describe("初步解答構想,包含技術方案、架構設計和實施策略"),
|
||||||
previousAnalysis: z
|
previousAnalysis: z
|
||||||
.string()
|
.string()
|
||||||
@ -147,14 +157,27 @@ export async function analyzeTask({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 反思構想工具
|
// 反思構想工具
|
||||||
export const reflectTaskSchema = z.object({
|
export const reflectTaskSchema = z
|
||||||
summary: z
|
.object({
|
||||||
.string()
|
summary: z
|
||||||
.describe("結構化的任務摘要,保持與分析階段一致以確保連續性"),
|
.string()
|
||||||
analysis: z
|
.min(20, {
|
||||||
.string()
|
message: "任務摘要太短,請確保包含完整的任務目標和範圍以維持分析連續性",
|
||||||
.describe("完整詳盡的技術分析結果,包括所有技術細節、依賴組件和實施方案"),
|
})
|
||||||
});
|
.describe("結構化的任務摘要,保持與分析階段一致以確保連續性"),
|
||||||
|
analysis: z
|
||||||
|
.string()
|
||||||
|
.min(100, {
|
||||||
|
message:
|
||||||
|
"技術分析結果過於簡略,請提供更詳盡的技術細節、依賴組件和實施方案說明",
|
||||||
|
})
|
||||||
|
.describe("完整詳盡的技術分析結果,包括所有技術細節、依賴組件和實施方案"),
|
||||||
|
})
|
||||||
|
.refine((data) => data.summary.length * 3 <= data.analysis.length, {
|
||||||
|
message:
|
||||||
|
"分析內容應該比摘要更詳細,建議分析部分至少是摘要長度的3倍以提供足夠的技術深度",
|
||||||
|
path: ["analysis"],
|
||||||
|
});
|
||||||
|
|
||||||
export async function reflectTask({
|
export async function reflectTask({
|
||||||
summary,
|
summary,
|
||||||
@ -204,33 +227,62 @@ export async function reflectTask({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 拆分任務工具
|
// 拆分任務工具
|
||||||
export const splitTasksSchema = z.object({
|
export const splitTasksSchema = z
|
||||||
isOverwrite: z
|
.object({
|
||||||
.boolean()
|
isOverwrite: z
|
||||||
.describe(
|
.boolean()
|
||||||
"任務覆蓋模式選擇(true:清除並覆蓋所有現有任務;false:保留現有任務並新增)"
|
.describe(
|
||||||
),
|
"任務覆蓋模式選擇(true:清除並覆蓋所有現有任務;false:保留現有任務並新增)"
|
||||||
tasks: z
|
),
|
||||||
.array(
|
tasks: z
|
||||||
z.object({
|
.array(
|
||||||
name: z.string().describe("簡潔明確的任務名稱,應能清晰表達任務目的"),
|
z.object({
|
||||||
description: z
|
name: z
|
||||||
.string()
|
.string()
|
||||||
.describe("詳細的任務描述,包含實施要點、技術細節和驗收標準"),
|
.min(5, {
|
||||||
notes: z
|
message: "任務名稱太短,請提供更清晰明確的名稱以便識別任務目的",
|
||||||
.string()
|
})
|
||||||
.optional()
|
.max(100, { message: "任務名稱過長,請保持簡潔,不超過100個字符" })
|
||||||
.describe("補充說明、特殊處理要求或實施建議(選填)"),
|
.describe("簡潔明確的任務名稱,應能清晰表達任務目的"),
|
||||||
dependencies: z
|
description: z
|
||||||
.array(z.string())
|
.string()
|
||||||
.optional()
|
.min(20, {
|
||||||
.describe(
|
message:
|
||||||
"此任務依賴的前置任務ID或任務名稱列表,支持兩種引用方式,名稱引用更直觀"
|
"任務描述太簡短,請提供更詳細的描述,包含實施要點和驗收標準",
|
||||||
),
|
})
|
||||||
})
|
.describe("詳細的任務描述,包含實施要點、技術細節和驗收標準"),
|
||||||
)
|
notes: z
|
||||||
.describe("結構化的任務清單,每個任務應保持原子性且有明確的完成標準"),
|
.string()
|
||||||
});
|
.optional()
|
||||||
|
.describe("補充說明、特殊處理要求或實施建議(選填)"),
|
||||||
|
dependencies: z
|
||||||
|
.array(z.string())
|
||||||
|
.optional()
|
||||||
|
.describe(
|
||||||
|
"此任務依賴的前置任務ID或任務名稱列表,支持兩種引用方式,名稱引用更直觀"
|
||||||
|
),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.min(1, { message: "至少需要提供一個任務,請確保任務列表不為空" })
|
||||||
|
.describe("結構化的任務清單,每個任務應保持原子性且有明確的完成標準"),
|
||||||
|
})
|
||||||
|
.refine(
|
||||||
|
(data) => {
|
||||||
|
// 檢查任務名稱是否有重複
|
||||||
|
const nameSet = new Set();
|
||||||
|
for (const task of data.tasks) {
|
||||||
|
if (nameSet.has(task.name)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
nameSet.add(task.name);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
{
|
||||||
|
message: "任務列表中存在重複的任務名稱,請確保每個任務名稱是唯一的",
|
||||||
|
path: ["tasks"],
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
export async function splitTasks({
|
export async function splitTasks({
|
||||||
isOverwrite,
|
isOverwrite,
|
||||||
@ -398,6 +450,7 @@ export async function listTasks() {
|
|||||||
export const executeTaskSchema = z.object({
|
export const executeTaskSchema = z.object({
|
||||||
taskId: z
|
taskId: z
|
||||||
.string()
|
.string()
|
||||||
|
.uuid({ message: "任務ID格式無效,請提供有效的UUID格式" })
|
||||||
.describe("待執行任務的唯一標識符,必須是系統中存在的有效任務ID"),
|
.describe("待執行任務的唯一標識符,必須是系統中存在的有效任務ID"),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -811,6 +864,7 @@ export async function executeTask({
|
|||||||
export const verifyTaskSchema = z.object({
|
export const verifyTaskSchema = z.object({
|
||||||
taskId: z
|
taskId: z
|
||||||
.string()
|
.string()
|
||||||
|
.uuid({ message: "任務ID格式無效,請提供有效的UUID格式" })
|
||||||
.describe("待驗證任務的唯一標識符,必須是狀態為「進行中」的有效任務ID"),
|
.describe("待驗證任務的唯一標識符,必須是狀態為「進行中」的有效任務ID"),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -911,11 +965,15 @@ export async function verifyTask({ taskId }: z.infer<typeof verifyTaskSchema>) {
|
|||||||
export const completeTaskSchema = z.object({
|
export const completeTaskSchema = z.object({
|
||||||
taskId: z
|
taskId: z
|
||||||
.string()
|
.string()
|
||||||
|
.uuid({ message: "任務ID格式無效,請提供有效的UUID格式" })
|
||||||
.describe(
|
.describe(
|
||||||
"待標記為完成的任務唯一標識符,必須是狀態為「進行中」的有效任務ID"
|
"待標記為完成的任務唯一標識符,必須是狀態為「進行中」的有效任務ID"
|
||||||
),
|
),
|
||||||
summary: z
|
summary: z
|
||||||
.string()
|
.string()
|
||||||
|
.min(30, {
|
||||||
|
message: "任務摘要太簡短,請提供更詳細的完成報告,包含實施結果和主要決策",
|
||||||
|
})
|
||||||
.optional()
|
.optional()
|
||||||
.describe(
|
.describe(
|
||||||
"任務完成摘要,簡潔描述實施結果和重要決策(選填,如未提供將自動生成)"
|
"任務完成摘要,簡潔描述實施結果和重要決策(選填,如未提供將自動生成)"
|
||||||
@ -1021,6 +1079,7 @@ export async function completeTask({
|
|||||||
export const deleteTaskSchema = z.object({
|
export const deleteTaskSchema = z.object({
|
||||||
taskId: z
|
taskId: z
|
||||||
.string()
|
.string()
|
||||||
|
.uuid({ message: "任務ID格式無效,請提供有效的UUID格式" })
|
||||||
.describe("待刪除任務的唯一標識符,必須是系統中存在且未完成的任務ID"),
|
.describe("待刪除任務的唯一標識符,必須是系統中存在且未完成的任務ID"),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1122,7 +1181,13 @@ export async function deleteTask({ taskId }: z.infer<typeof deleteTaskSchema>) {
|
|||||||
|
|
||||||
// 清除所有任務工具
|
// 清除所有任務工具
|
||||||
export const clearAllTasksSchema = z.object({
|
export const clearAllTasksSchema = z.object({
|
||||||
confirm: z.boolean().describe("確認刪除所有未完成的任務(此操作不可逆)"),
|
confirm: z
|
||||||
|
.boolean()
|
||||||
|
.refine((val) => val === true, {
|
||||||
|
message:
|
||||||
|
"必須明確確認清除操作,請將 confirm 參數設置為 true 以確認此危險操作",
|
||||||
|
})
|
||||||
|
.describe("確認刪除所有未完成的任務(此操作不可逆)"),
|
||||||
});
|
});
|
||||||
|
|
||||||
export async function clearAllTasks({
|
export async function clearAllTasks({
|
||||||
@ -1212,46 +1277,93 @@ export async function clearAllTasks({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 更新任務內容工具
|
// 更新任務內容工具
|
||||||
export const updateTaskContentSchema = z.object({
|
export const updateTaskContentSchema = z
|
||||||
taskId: z
|
.object({
|
||||||
.string()
|
taskId: z
|
||||||
.describe("待更新任務的唯一標識符,必須是系統中存在且未完成的任務ID"),
|
.string()
|
||||||
name: z.string().optional().describe("任務的新名稱(選填)"),
|
.uuid({ message: "任務ID格式無效,請提供有效的UUID格式" })
|
||||||
description: z.string().optional().describe("任務的新描述內容(選填)"),
|
.describe("待更新任務的唯一標識符,必須是系統中存在且未完成的任務ID"),
|
||||||
notes: z.string().optional().describe("任務的新補充說明(選填)"),
|
name: z
|
||||||
relatedFiles: z
|
.string()
|
||||||
.array(
|
.min(5, {
|
||||||
z.object({
|
message: "任務名稱太短,請提供更清晰明確的名稱以便識別任務目的",
|
||||||
path: z
|
|
||||||
.string()
|
|
||||||
.describe("文件路徑,可以是相對於項目根目錄的路徑或絕對路徑"),
|
|
||||||
type: z
|
|
||||||
.enum([
|
|
||||||
RelatedFileType.TO_MODIFY,
|
|
||||||
RelatedFileType.REFERENCE,
|
|
||||||
RelatedFileType.OUTPUT,
|
|
||||||
RelatedFileType.DEPENDENCY,
|
|
||||||
RelatedFileType.OTHER,
|
|
||||||
])
|
|
||||||
.describe("文件與任務的關係類型"),
|
|
||||||
description: z.string().optional().describe("文件的補充描述(選填)"),
|
|
||||||
lineStart: z
|
|
||||||
.number()
|
|
||||||
.int()
|
|
||||||
.positive()
|
|
||||||
.optional()
|
|
||||||
.describe("相關代碼區塊的起始行(選填)"),
|
|
||||||
lineEnd: z
|
|
||||||
.number()
|
|
||||||
.int()
|
|
||||||
.positive()
|
|
||||||
.optional()
|
|
||||||
.describe("相關代碼區塊的結束行(選填)"),
|
|
||||||
})
|
})
|
||||||
)
|
.max(100, { message: "任務名稱過長,請保持簡潔,不超過100個字符" })
|
||||||
.optional()
|
.optional()
|
||||||
.describe("與任務相關的文件列表(選填)"),
|
.describe("任務的新名稱(選填)"),
|
||||||
});
|
description: z
|
||||||
|
.string()
|
||||||
|
.min(20, {
|
||||||
|
message: "任務描述太簡短,請提供更詳細的描述,包含實施要點和驗收標準",
|
||||||
|
})
|
||||||
|
.optional()
|
||||||
|
.describe("任務的新描述內容(選填)"),
|
||||||
|
notes: z.string().optional().describe("任務的新補充說明(選填)"),
|
||||||
|
relatedFiles: z
|
||||||
|
.array(
|
||||||
|
z.object({
|
||||||
|
path: z
|
||||||
|
.string()
|
||||||
|
.min(1, { message: "文件路徑不能為空,請提供有效的文件路徑" })
|
||||||
|
.describe("文件路徑,可以是相對於項目根目錄的路徑或絕對路徑"),
|
||||||
|
type: z
|
||||||
|
.enum([
|
||||||
|
RelatedFileType.TO_MODIFY,
|
||||||
|
RelatedFileType.REFERENCE,
|
||||||
|
RelatedFileType.OUTPUT,
|
||||||
|
RelatedFileType.DEPENDENCY,
|
||||||
|
RelatedFileType.OTHER,
|
||||||
|
])
|
||||||
|
.describe("文件與任務的關係類型"),
|
||||||
|
description: z.string().optional().describe("文件的補充描述(選填)"),
|
||||||
|
lineStart: z
|
||||||
|
.number()
|
||||||
|
.int()
|
||||||
|
.positive()
|
||||||
|
.optional()
|
||||||
|
.describe("相關代碼區塊的起始行(選填)"),
|
||||||
|
lineEnd: z
|
||||||
|
.number()
|
||||||
|
.int()
|
||||||
|
.positive()
|
||||||
|
.optional()
|
||||||
|
.describe("相關代碼區塊的結束行(選填)"),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.optional()
|
||||||
|
.describe("與任務相關的文件列表(選填)"),
|
||||||
|
})
|
||||||
|
.refine(
|
||||||
|
(data) => {
|
||||||
|
// 確保行號有效:如果有起始行,就必須有結束行,反之亦然
|
||||||
|
if (data.relatedFiles) {
|
||||||
|
for (const file of data.relatedFiles) {
|
||||||
|
if (
|
||||||
|
(file.lineStart && !file.lineEnd) ||
|
||||||
|
(!file.lineStart && file.lineEnd)
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 確保起始行小於結束行
|
||||||
|
if (file.lineStart && file.lineEnd && file.lineStart > file.lineEnd) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 確保至少有一個字段被更新
|
||||||
|
return !!(
|
||||||
|
data.name ||
|
||||||
|
data.description ||
|
||||||
|
data.notes ||
|
||||||
|
(data.relatedFiles && data.relatedFiles.length > 0)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
{
|
||||||
|
message:
|
||||||
|
"更新請求無效:1. 行號設置必須同時包含起始行和結束行,且起始行必須小於結束行;2. 至少需要更新一個字段(名稱、描述、注記或相關文件)",
|
||||||
|
path: ["relatedFiles"],
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
export async function updateTaskContent({
|
export async function updateTaskContent({
|
||||||
taskId,
|
taskId,
|
||||||
@ -1385,42 +1497,86 @@ export async function updateTaskContent({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 更新任務相關文件工具
|
// 更新任務相關文件工具
|
||||||
export const updateTaskRelatedFilesSchema = z.object({
|
export const updateTaskRelatedFilesSchema = z
|
||||||
taskId: z
|
.object({
|
||||||
.string()
|
taskId: z
|
||||||
.describe("待更新任務的唯一標識符,必須是系統中存在且未完成的任務ID"),
|
.string()
|
||||||
relatedFiles: z
|
.uuid({ message: "任務ID格式無效,請提供有效的UUID格式" })
|
||||||
.array(
|
.describe("待更新任務的唯一標識符,必須是系統中存在且未完成的任務ID"),
|
||||||
z.object({
|
relatedFiles: z
|
||||||
path: z
|
.array(
|
||||||
.string()
|
z.object({
|
||||||
.describe("文件路徑,可以是相對於項目根目錄的路徑或絕對路徑"),
|
path: z
|
||||||
type: z
|
.string()
|
||||||
.enum([
|
.min(1, { message: "文件路徑不能為空,請提供有效的文件路徑" })
|
||||||
RelatedFileType.TO_MODIFY,
|
.describe("文件路徑,可以是相對於項目根目錄的路徑或絕對路徑"),
|
||||||
RelatedFileType.REFERENCE,
|
type: z
|
||||||
RelatedFileType.OUTPUT,
|
.enum([
|
||||||
RelatedFileType.DEPENDENCY,
|
RelatedFileType.TO_MODIFY,
|
||||||
RelatedFileType.OTHER,
|
RelatedFileType.REFERENCE,
|
||||||
])
|
RelatedFileType.OUTPUT,
|
||||||
.describe("文件與任務的關係類型"),
|
RelatedFileType.DEPENDENCY,
|
||||||
description: z.string().optional().describe("文件的補充描述(選填)"),
|
RelatedFileType.OTHER,
|
||||||
lineStart: z
|
])
|
||||||
.number()
|
.describe("文件與任務的關係類型"),
|
||||||
.int()
|
description: z.string().optional().describe("文件的補充描述(選填)"),
|
||||||
.positive()
|
lineStart: z
|
||||||
.optional()
|
.number()
|
||||||
.describe("相關代碼區塊的起始行(選填)"),
|
.int()
|
||||||
lineEnd: z
|
.positive()
|
||||||
.number()
|
.optional()
|
||||||
.int()
|
.describe("相關代碼區塊的起始行(選填)"),
|
||||||
.positive()
|
lineEnd: z
|
||||||
.optional()
|
.number()
|
||||||
.describe("相關代碼區塊的結束行(選填)"),
|
.int()
|
||||||
})
|
.positive()
|
||||||
)
|
.optional()
|
||||||
.describe("與任務相關的文件列表"),
|
.describe("相關代碼區塊的結束行(選填)"),
|
||||||
});
|
})
|
||||||
|
)
|
||||||
|
.min(1, { message: "至少需要提供一個相關文件,請確保文件列表不為空" })
|
||||||
|
.describe("與任務相關的文件列表"),
|
||||||
|
})
|
||||||
|
.refine(
|
||||||
|
(data) => {
|
||||||
|
// 檢查文件路徑是否有重複
|
||||||
|
const pathSet = new Set();
|
||||||
|
for (const file of data.relatedFiles) {
|
||||||
|
if (pathSet.has(file.path)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
pathSet.add(file.path);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
{
|
||||||
|
message: "文件列表中存在重複的文件路徑,請確保每個文件路徑是唯一的",
|
||||||
|
path: ["relatedFiles"],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.refine(
|
||||||
|
(data) => {
|
||||||
|
// 確保行號有效:如果有起始行,就必須有結束行,反之亦然
|
||||||
|
for (const file of data.relatedFiles) {
|
||||||
|
if (
|
||||||
|
(file.lineStart && !file.lineEnd) ||
|
||||||
|
(!file.lineStart && file.lineEnd)
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 確保起始行小於結束行
|
||||||
|
if (file.lineStart && file.lineEnd && file.lineStart > file.lineEnd) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
{
|
||||||
|
message:
|
||||||
|
"行號設置無效:必須同時設置起始行和結束行,且起始行必須小於結束行",
|
||||||
|
path: ["relatedFiles"],
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
export async function updateTaskRelatedFiles({
|
export async function updateTaskRelatedFiles({
|
||||||
taskId,
|
taskId,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user