superplanners-mcp 0.1.0

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 (46) hide show
  1. package/README.md +160 -0
  2. package/dist/file-manager.d.ts +99 -0
  3. package/dist/file-manager.d.ts.map +1 -0
  4. package/dist/file-manager.js +364 -0
  5. package/dist/file-manager.js.map +1 -0
  6. package/dist/index.d.ts +3 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +65 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/renderer.d.ts +10 -0
  11. package/dist/renderer.d.ts.map +1 -0
  12. package/dist/renderer.js +170 -0
  13. package/dist/renderer.js.map +1 -0
  14. package/dist/server.d.ts +6 -0
  15. package/dist/server.d.ts.map +1 -0
  16. package/dist/server.js +438 -0
  17. package/dist/server.js.map +1 -0
  18. package/dist/task-engine/dependency-resolver.d.ts +43 -0
  19. package/dist/task-engine/dependency-resolver.d.ts.map +1 -0
  20. package/dist/task-engine/dependency-resolver.js +94 -0
  21. package/dist/task-engine/dependency-resolver.js.map +1 -0
  22. package/dist/task-engine/index.d.ts +6 -0
  23. package/dist/task-engine/index.d.ts.map +1 -0
  24. package/dist/task-engine/index.js +6 -0
  25. package/dist/task-engine/index.js.map +1 -0
  26. package/dist/task-engine/next-task-selector.d.ts +18 -0
  27. package/dist/task-engine/next-task-selector.d.ts.map +1 -0
  28. package/dist/task-engine/next-task-selector.js +99 -0
  29. package/dist/task-engine/next-task-selector.js.map +1 -0
  30. package/dist/task-engine/parser.d.ts +20 -0
  31. package/dist/task-engine/parser.d.ts.map +1 -0
  32. package/dist/task-engine/parser.js +77 -0
  33. package/dist/task-engine/parser.js.map +1 -0
  34. package/dist/task-engine/progress-calculator.d.ts +15 -0
  35. package/dist/task-engine/progress-calculator.d.ts.map +1 -0
  36. package/dist/task-engine/progress-calculator.js +58 -0
  37. package/dist/task-engine/progress-calculator.js.map +1 -0
  38. package/dist/task-engine/status-reducer.d.ts +18 -0
  39. package/dist/task-engine/status-reducer.d.ts.map +1 -0
  40. package/dist/task-engine/status-reducer.js +88 -0
  41. package/dist/task-engine/status-reducer.js.map +1 -0
  42. package/dist/types.d.ts +999 -0
  43. package/dist/types.d.ts.map +1 -0
  44. package/dist/types.js +228 -0
  45. package/dist/types.js.map +1 -0
  46. package/package.json +51 -0
@@ -0,0 +1,99 @@
1
+ import { areDependenciesMet } from './dependency-resolver.js';
2
+ /**
3
+ * 优先级权重映射
4
+ */
5
+ const PRIORITY_WEIGHT = {
6
+ critical: 4,
7
+ high: 3,
8
+ medium: 2,
9
+ low: 1,
10
+ };
11
+ /**
12
+ * 解析预估时间字符串,返回分钟数
13
+ * 支持格式: 1h, 30m, 2d
14
+ */
15
+ function parseEstimate(estimate) {
16
+ if (!estimate)
17
+ return Infinity;
18
+ const match = estimate.match(/^(\d+(?:\.\d+)?)(h|m|d)?$/i);
19
+ if (!match)
20
+ return Infinity;
21
+ const value = parseFloat(match[1]);
22
+ const unit = (match[2] || 'h').toLowerCase();
23
+ switch (unit) {
24
+ case 'm':
25
+ return value;
26
+ case 'h':
27
+ return value * 60;
28
+ case 'd':
29
+ return value * 60 * 8; // 假设一天 8 小时
30
+ default:
31
+ return value * 60;
32
+ }
33
+ }
34
+ /**
35
+ * 选择下一个可执行的任务
36
+ * 按优先级和预估时间排序,选择最优先且预估时间最短的任务
37
+ */
38
+ export function selectNextTask(tasks) {
39
+ // 筛选出待处理且依赖已满足的任务
40
+ const candidates = tasks.filter((task) => {
41
+ if (task.status !== 'pending')
42
+ return false;
43
+ return areDependenciesMet(tasks, task.id);
44
+ });
45
+ if (candidates.length === 0) {
46
+ return null;
47
+ }
48
+ // 按优先级降序、预估时间升序排序
49
+ candidates.sort((a, b) => {
50
+ const priorityDiff = PRIORITY_WEIGHT[b.priority] - PRIORITY_WEIGHT[a.priority];
51
+ if (priorityDiff !== 0)
52
+ return priorityDiff;
53
+ const estimateA = parseEstimate(a.estimate);
54
+ const estimateB = parseEstimate(b.estimate);
55
+ return estimateA - estimateB;
56
+ });
57
+ const selected = candidates[0];
58
+ return {
59
+ id: selected.id,
60
+ title: selected.title,
61
+ };
62
+ }
63
+ /**
64
+ * 获取无可执行任务的原因
65
+ */
66
+ export function getNextTaskReason(tasks) {
67
+ // 检查是否全部完成
68
+ const allCompleted = tasks.every((t) => t.status === 'completed' || t.status === 'skipped');
69
+ if (allCompleted) {
70
+ return '所有任务已完成';
71
+ }
72
+ // 检查阻塞任务
73
+ const blockedCount = tasks.filter((t) => t.status === 'blocked').length;
74
+ if (blockedCount > 0) {
75
+ return `存在 ${blockedCount} 个阻塞任务`;
76
+ }
77
+ // 检查依赖未满足的任务
78
+ const pendingWithUnmetDeps = tasks.filter((t) => t.status === 'pending' && !areDependenciesMet(tasks, t.id));
79
+ if (pendingWithUnmetDeps.length > 0) {
80
+ return `${pendingWithUnmetDeps.length} 个任务的依赖未完成`;
81
+ }
82
+ // 检查进行中的任务
83
+ const inProgressCount = tasks.filter((t) => t.status === 'in_progress').length;
84
+ if (inProgressCount > 0) {
85
+ return `${inProgressCount} 个任务正在进行中`;
86
+ }
87
+ return '无可执行任务';
88
+ }
89
+ /**
90
+ * 获取下一个任务或无法执行的原因
91
+ */
92
+ export function getNextTaskOrReason(tasks) {
93
+ const next = selectNextTask(tasks);
94
+ if (next) {
95
+ return { next };
96
+ }
97
+ return { next: null, reason: getNextTaskReason(tasks) };
98
+ }
99
+ //# sourceMappingURL=next-task-selector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"next-task-selector.js","sourceRoot":"","sources":["../../src/task-engine/next-task-selector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import { ProjectData, TaskPlan } from '../types.js';
2
+ export type ParseResult<T> = {
3
+ success: true;
4
+ data: T;
5
+ } | {
6
+ success: false;
7
+ error: string;
8
+ };
9
+ export declare function parseProjectData(yamlContent: string): ParseResult<ProjectData>;
10
+ export declare function parseTaskPlan(yamlContent: string): ParseResult<TaskPlan>;
11
+ import type { Task, SubTask } from '../types.js';
12
+ export type TaskLookupResult = {
13
+ task: Task | SubTask;
14
+ isSubtask: boolean;
15
+ parentId?: string;
16
+ };
17
+ export declare function findTaskById(tasks: Task[], taskId: string): TaskLookupResult | null;
18
+ export declare function traverseTasks(tasks: Task[], callback: (task: Task | SubTask, isSubtask: boolean, parentId?: string) => void): void;
19
+ export declare function getAllTasks(tasks: Task[]): (Task | SubTask)[];
20
+ //# sourceMappingURL=parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/task-engine/parser.ts"],"names":[],"mappings":"AACA,OAAO,EACL,WAAW,EAEX,QAAQ,EAET,MAAM,aAAa,CAAC;AAErB,MAAM,MAAM,WAAW,CAAC,CAAC,IACrB;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,CAAC,CAAA;CAAE,GAC1B;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtC,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,CAAC,WAAW,CAAC,CAmB9E;AAED,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,CAAC,QAAQ,CAAC,CAmBxE;AAED,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEjD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,wBAAgB,YAAY,CAC1B,KAAK,EAAE,IAAI,EAAE,EACb,MAAM,EAAE,MAAM,GACb,gBAAgB,GAAG,IAAI,CAgBzB;AAED,wBAAgB,aAAa,CAC3B,KAAK,EAAE,IAAI,EAAE,EACb,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,IAAI,GAC9E,IAAI,CAUN;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,GAAG,OAAO,CAAC,EAAE,CAQ7D"}
@@ -0,0 +1,77 @@
1
+ import YAML from 'yaml';
2
+ import { ProjectDataSchema, TaskPlanSchema, } from '../types.js';
3
+ export function parseProjectData(yamlContent) {
4
+ try {
5
+ const parsed = YAML.parse(yamlContent);
6
+ const result = ProjectDataSchema.safeParse(parsed);
7
+ if (result.success) {
8
+ return { success: true, data: result.data };
9
+ }
10
+ else {
11
+ return {
12
+ success: false,
13
+ error: 'Schema 校验失败: ' + result.error.message,
14
+ };
15
+ }
16
+ }
17
+ catch (e) {
18
+ return {
19
+ success: false,
20
+ error: 'YAML 解析失败: ' + (e instanceof Error ? e.message : String(e)),
21
+ };
22
+ }
23
+ }
24
+ export function parseTaskPlan(yamlContent) {
25
+ try {
26
+ const parsed = YAML.parse(yamlContent);
27
+ const result = TaskPlanSchema.safeParse(parsed);
28
+ if (result.success) {
29
+ return { success: true, data: result.data };
30
+ }
31
+ else {
32
+ return {
33
+ success: false,
34
+ error: 'Schema 校验失败: ' + result.error.message,
35
+ };
36
+ }
37
+ }
38
+ catch (e) {
39
+ return {
40
+ success: false,
41
+ error: 'YAML 解析失败: ' + (e instanceof Error ? e.message : String(e)),
42
+ };
43
+ }
44
+ }
45
+ export function findTaskById(tasks, taskId) {
46
+ for (const task of tasks) {
47
+ if (task.id === taskId) {
48
+ return { task, isSubtask: false };
49
+ }
50
+ if (task.subtasks) {
51
+ for (const subtask of task.subtasks) {
52
+ if (subtask.id === taskId) {
53
+ return { task: subtask, isSubtask: true, parentId: task.id };
54
+ }
55
+ }
56
+ }
57
+ }
58
+ return null;
59
+ }
60
+ export function traverseTasks(tasks, callback) {
61
+ for (const task of tasks) {
62
+ callback(task, false);
63
+ if (task.subtasks) {
64
+ for (const subtask of task.subtasks) {
65
+ callback(subtask, true, task.id);
66
+ }
67
+ }
68
+ }
69
+ }
70
+ export function getAllTasks(tasks) {
71
+ const result = [];
72
+ traverseTasks(tasks, (task) => {
73
+ result.push(task);
74
+ });
75
+ return result;
76
+ }
77
+ //# sourceMappingURL=parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/task-engine/parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { Task, TaskSummary, ProgressInfo } from '../types.js';
2
+ /**
3
+ * 计算任务统计摘要
4
+ * 递归统计所有任务(包括子任务)的状态
5
+ */
6
+ export declare function calculateTaskSummary(tasks: Task[]): TaskSummary;
7
+ /**
8
+ * 计算完成进度和百分比
9
+ */
10
+ export declare function calculateProgress(tasks: Task[]): ProgressInfo;
11
+ /**
12
+ * 生成进度字符串 (如 3/12)
13
+ */
14
+ export declare function formatProgressString(tasks: Task[]): string;
15
+ //# sourceMappingURL=progress-calculator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress-calculator.d.ts","sourceRoot":"","sources":["../../src/task-engine/progress-calculator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGnE;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,WAAW,CAiC/D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,YAAY,CAa7D;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,MAAM,CAG1D"}
@@ -0,0 +1,58 @@
1
+ import { traverseTasks } from './parser.js';
2
+ /**
3
+ * 计算任务统计摘要
4
+ * 递归统计所有任务(包括子任务)的状态
5
+ */
6
+ export function calculateTaskSummary(tasks) {
7
+ const summary = {
8
+ total: 0,
9
+ completed: 0,
10
+ in_progress: 0,
11
+ blocked: 0,
12
+ pending: 0,
13
+ skipped: 0,
14
+ };
15
+ traverseTasks(tasks, (task) => {
16
+ summary.total++;
17
+ switch (task.status) {
18
+ case 'completed':
19
+ summary.completed++;
20
+ break;
21
+ case 'in_progress':
22
+ summary.in_progress++;
23
+ break;
24
+ case 'blocked':
25
+ summary.blocked++;
26
+ break;
27
+ case 'pending':
28
+ summary.pending++;
29
+ break;
30
+ case 'skipped':
31
+ summary.skipped++;
32
+ break;
33
+ }
34
+ });
35
+ return summary;
36
+ }
37
+ /**
38
+ * 计算完成进度和百分比
39
+ */
40
+ export function calculateProgress(tasks) {
41
+ const summary = calculateTaskSummary(tasks);
42
+ const percentage = summary.total > 0
43
+ ? Math.round((summary.completed / summary.total) * 100)
44
+ : 0;
45
+ return {
46
+ completed: summary.completed,
47
+ total: summary.total,
48
+ percentage,
49
+ };
50
+ }
51
+ /**
52
+ * 生成进度字符串 (如 3/12)
53
+ */
54
+ export function formatProgressString(tasks) {
55
+ const summary = calculateTaskSummary(tasks);
56
+ return `${summary.completed}/${summary.total}`;
57
+ }
58
+ //# sourceMappingURL=progress-calculator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress-calculator.js","sourceRoot":"","sources":["../../src/task-engine/progress-calculator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAa;IAChD,MAAM,OAAO,GAAgB;QAC3B,KAAK,EAAE,CAAC;QACR,SAAS,EAAE,CAAC;QACZ,WAAW,EAAE,CAAC;QACd,OAAO,EAAE,CAAC;QACV,OAAO,EAAE,CAAC;QACV,OAAO,EAAE,CAAC;KACX,CAAC;IAEF,aAAa,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE;QAC5B,OAAO,CAAC,KAAK,EAAE,CAAC;QAEhB,QAAQ,IAAI,CAAC,MAAM,EAAE,CAAC;YACpB,KAAK,WAAW;gBACd,OAAO,CAAC,SAAS,EAAE,CAAC;gBACpB,MAAM;YACR,KAAK,aAAa;gBAChB,OAAO,CAAC,WAAW,EAAE,CAAC;gBACtB,MAAM;YACR,KAAK,SAAS;gBACZ,OAAO,CAAC,OAAO,EAAE,CAAC;gBAClB,MAAM;YACR,KAAK,SAAS;gBACZ,OAAO,CAAC,OAAO,EAAE,CAAC;gBAClB,MAAM;YACR,KAAK,SAAS;gBACZ,OAAO,CAAC,OAAO,EAAE,CAAC;gBAClB,MAAM;QACV,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAa;IAC7C,MAAM,OAAO,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;IAE5C,MAAM,UAAU,GACd,OAAO,CAAC,KAAK,GAAG,CAAC;QACf,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC;QACvD,CAAC,CAAC,CAAC,CAAC;IAER,OAAO;QACL,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,UAAU;KACX,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAa;IAChD,MAAM,OAAO,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;IAC5C,OAAO,GAAG,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;AACjD,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { Task, TaskStatus } from '../types.js';
2
+ export type UpdateResult = {
3
+ success: true;
4
+ tasks: Task[];
5
+ } | {
6
+ success: false;
7
+ error: string;
8
+ };
9
+ export declare function updateTaskStatus(tasks: Task[], taskId: string, newStatus: TaskStatus, notes?: string): UpdateResult;
10
+ export type ValidationResult = {
11
+ valid: true;
12
+ } | {
13
+ valid: false;
14
+ reason: string;
15
+ };
16
+ export declare function validateStatusTransition(currentStatus: TaskStatus, newStatus: TaskStatus): ValidationResult;
17
+ export declare function updateTaskStatusWithValidation(tasks: Task[], taskId: string, newStatus: TaskStatus, notes?: string): UpdateResult;
18
+ //# sourceMappingURL=status-reducer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status-reducer.d.ts","sourceRoot":"","sources":["../../src/task-engine/status-reducer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAW,UAAU,EAAE,MAAM,aAAa,CAAC;AAE7D,MAAM,MAAM,YAAY,GACpB;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,IAAI,EAAE,CAAA;CAAE,GAChC;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtC,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,IAAI,EAAE,EACb,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,UAAU,EACrB,KAAK,CAAC,EAAE,MAAM,GACb,YAAY,CAgCd;AAuCD,MAAM,MAAM,gBAAgB,GACxB;IAAE,KAAK,EAAE,IAAI,CAAA;CAAE,GACf;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAUrC,wBAAgB,wBAAwB,CACtC,aAAa,EAAE,UAAU,EACzB,SAAS,EAAE,UAAU,GACpB,gBAAgB,CAWlB;AAED,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,IAAI,EAAE,EACb,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,UAAU,EACrB,KAAK,CAAC,EAAE,MAAM,GACb,YAAY,CAad"}
@@ -0,0 +1,88 @@
1
+ export function updateTaskStatus(tasks, taskId, newStatus, notes) {
2
+ const now = new Date().toISOString();
3
+ let found = false;
4
+ const newTasks = tasks.map((task) => {
5
+ if (task.id === taskId) {
6
+ found = true;
7
+ return updateTask(task, newStatus, now, notes);
8
+ }
9
+ if (task.subtasks) {
10
+ const subtaskIndex = task.subtasks.findIndex((st) => st.id === taskId);
11
+ if (subtaskIndex !== -1) {
12
+ found = true;
13
+ const newSubtasks = [...task.subtasks];
14
+ newSubtasks[subtaskIndex] = updateSubtask(newSubtasks[subtaskIndex], newStatus, notes);
15
+ return { ...task, subtasks: newSubtasks };
16
+ }
17
+ }
18
+ return task;
19
+ });
20
+ if (!found) {
21
+ return { success: false, error: `任务 ${taskId} 不存在` };
22
+ }
23
+ return { success: true, tasks: newTasks };
24
+ }
25
+ function updateTask(task, newStatus, now, notes) {
26
+ const updated = { ...task, status: newStatus };
27
+ if (newStatus === 'in_progress' && !task.started_at) {
28
+ updated.started_at = now;
29
+ }
30
+ if (newStatus === 'completed' && !task.completed_at) {
31
+ updated.completed_at = now;
32
+ }
33
+ if (notes !== undefined) {
34
+ updated.notes = notes;
35
+ }
36
+ return updated;
37
+ }
38
+ function updateSubtask(subtask, newStatus, notes) {
39
+ const updated = { ...subtask, status: newStatus };
40
+ if (notes !== undefined) {
41
+ updated.notes = notes;
42
+ }
43
+ return updated;
44
+ }
45
+ const VALID_TRANSITIONS = {
46
+ pending: ['pending', 'in_progress', 'completed', 'blocked', 'skipped'],
47
+ in_progress: ['in_progress', 'completed', 'blocked', 'skipped'],
48
+ blocked: ['blocked', 'in_progress', 'skipped'],
49
+ completed: ['completed'],
50
+ skipped: ['skipped'],
51
+ };
52
+ export function validateStatusTransition(currentStatus, newStatus) {
53
+ const allowedTransitions = VALID_TRANSITIONS[currentStatus];
54
+ if (allowedTransitions.includes(newStatus)) {
55
+ return { valid: true };
56
+ }
57
+ return {
58
+ valid: false,
59
+ reason: `不允许从 ${currentStatus} 转换到 ${newStatus}`,
60
+ };
61
+ }
62
+ export function updateTaskStatusWithValidation(tasks, taskId, newStatus, notes) {
63
+ const found = findTaskForValidation(tasks, taskId);
64
+ if (!found) {
65
+ return { success: false, error: `任务 ${taskId} 不存在` };
66
+ }
67
+ const validation = validateStatusTransition(found.status, newStatus);
68
+ if (!validation.valid) {
69
+ return { success: false, error: validation.reason };
70
+ }
71
+ return updateTaskStatus(tasks, taskId, newStatus, notes);
72
+ }
73
+ function findTaskForValidation(tasks, taskId) {
74
+ for (const task of tasks) {
75
+ if (task.id === taskId) {
76
+ return { status: task.status };
77
+ }
78
+ if (task.subtasks) {
79
+ for (const subtask of task.subtasks) {
80
+ if (subtask.id === taskId) {
81
+ return { status: subtask.status };
82
+ }
83
+ }
84
+ }
85
+ }
86
+ return null;
87
+ }
88
+ //# sourceMappingURL=status-reducer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status-reducer.js","sourceRoot":"","sources":["../../src/task-engine/status-reducer.ts"],"names":[],"mappings":"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"}