idea-manager 0.2.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -41
- package/next.config.ts +0 -1
- package/package.json +2 -2
- package/{src/app/icon.svg → public/favicon.svg} +2 -2
- package/src/app/api/filesystem/route.ts +49 -0
- package/src/app/api/projects/[id]/cleanup/route.ts +32 -0
- package/src/app/api/projects/[id]/items/[itemId]/refine/route.ts +36 -0
- package/src/app/api/projects/[id]/items/[itemId]/route.ts +23 -1
- package/src/app/api/projects/[id]/items/route.ts +51 -1
- package/src/app/api/projects/[id]/scan/route.ts +73 -0
- package/src/app/api/projects/[id]/scan/stream/route.ts +112 -0
- package/src/app/api/projects/[id]/structure/route.ts +34 -3
- package/src/app/api/projects/[id]/structure/stream/route.ts +157 -0
- package/src/app/api/projects/[id]/sub-projects/[subId]/route.ts +39 -0
- package/src/app/api/projects/[id]/sub-projects/[subId]/tasks/[taskId]/chat/route.ts +60 -0
- package/src/app/api/projects/[id]/sub-projects/[subId]/tasks/[taskId]/prompt/route.ts +26 -0
- package/src/app/api/projects/[id]/sub-projects/[subId]/tasks/[taskId]/route.ts +39 -0
- package/src/app/api/projects/[id]/sub-projects/[subId]/tasks/route.ts +33 -0
- package/src/app/api/projects/[id]/sub-projects/route.ts +31 -0
- package/src/app/api/projects/route.ts +1 -1
- package/src/app/globals.css +465 -5
- package/src/app/layout.tsx +3 -0
- package/src/app/page.tsx +260 -88
- package/src/app/projects/[id]/page.tsx +366 -183
- package/src/cli.ts +10 -10
- package/src/components/DirectoryPicker.tsx +137 -0
- package/src/components/ScanPanel.tsx +743 -0
- package/src/components/brainstorm/Editor.tsx +20 -4
- package/src/components/brainstorm/MemoPin.tsx +91 -5
- package/src/components/dashboard/SubProjectCard.tsx +76 -0
- package/src/components/dashboard/TabBar.tsx +42 -0
- package/src/components/task/ProjectTree.tsx +223 -0
- package/src/components/task/PromptEditor.tsx +107 -0
- package/src/components/task/StatusFlow.tsx +43 -0
- package/src/components/task/TaskChat.tsx +134 -0
- package/src/components/task/TaskDetail.tsx +205 -0
- package/src/components/task/TaskList.tsx +119 -0
- package/src/components/tree/CardView.tsx +206 -0
- package/src/components/tree/RefinePopover.tsx +157 -0
- package/src/components/tree/TreeNode.tsx +147 -38
- package/src/components/tree/TreeView.tsx +270 -26
- package/src/components/ui/ConfirmDialog.tsx +88 -0
- package/src/lib/ai/chat-responder.ts +4 -2
- package/src/lib/ai/cleanup.ts +87 -0
- package/src/lib/ai/client.ts +175 -58
- package/src/lib/ai/prompter.ts +19 -24
- package/src/lib/ai/refiner.ts +128 -0
- package/src/lib/ai/structurer.ts +340 -11
- package/src/lib/db/queries/context.ts +76 -0
- package/src/lib/db/queries/items.ts +133 -12
- package/src/lib/db/queries/projects.ts +12 -8
- package/src/lib/db/queries/sub-projects.ts +122 -0
- package/src/lib/db/queries/task-conversations.ts +27 -0
- package/src/lib/db/queries/task-prompts.ts +32 -0
- package/src/lib/db/queries/tasks.ts +133 -0
- package/src/lib/db/schema.ts +75 -0
- package/src/lib/mcp/server.ts +38 -39
- package/src/lib/mcp/tools.ts +47 -45
- package/src/lib/scanner.ts +573 -0
- package/src/lib/task-store.ts +97 -0
- package/src/types/index.ts +65 -0
package/src/lib/mcp/tools.ts
CHANGED
|
@@ -1,82 +1,84 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
// Re-export query functions for MCP tools
|
|
4
|
-
// These are imported from DB queries when the MCP server initializes
|
|
1
|
+
import type { ITask, ITaskPrompt, ISubProject } from '@/types';
|
|
5
2
|
|
|
6
3
|
export interface McpToolContext {
|
|
7
4
|
listProjects: () => { id: string; name: string; description: string; created_at: string; updated_at: string }[];
|
|
8
5
|
getProject: (id: string) => { id: string; name: string; description: string } | undefined;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
getSubProjects: (projectId: string) => ISubProject[];
|
|
7
|
+
getTasksByProject: (projectId: string) => ITask[];
|
|
8
|
+
getTaskPrompt: (taskId: string) => ITaskPrompt | undefined;
|
|
9
|
+
updateTask: (id: string, data: Record<string, unknown>) => ITask | undefined;
|
|
13
10
|
}
|
|
14
11
|
|
|
15
12
|
export function getNextTask(ctx: McpToolContext, projectId: string): {
|
|
16
|
-
|
|
17
|
-
prompt?:
|
|
13
|
+
task: ITask;
|
|
14
|
+
prompt?: ITaskPrompt;
|
|
18
15
|
} | null {
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
// Find unlocked + pending items (ready to execute)
|
|
22
|
-
const ready = items.filter(i => !i.is_locked && i.status === 'pending');
|
|
16
|
+
const tasks = ctx.getTasksByProject(projectId);
|
|
23
17
|
|
|
18
|
+
// Find submitted tasks with prompts (ready to execute)
|
|
19
|
+
const ready = tasks.filter(t => t.status === 'submitted');
|
|
24
20
|
if (ready.length === 0) return null;
|
|
25
21
|
|
|
26
|
-
// Sort by sort_order
|
|
27
22
|
ready.sort((a, b) => a.sort_order - b.sort_order);
|
|
28
|
-
const
|
|
29
|
-
const prompt = ctx.
|
|
23
|
+
const task = ready[0];
|
|
24
|
+
const prompt = ctx.getTaskPrompt(task.id);
|
|
30
25
|
|
|
31
|
-
return {
|
|
26
|
+
return { task, prompt };
|
|
32
27
|
}
|
|
33
28
|
|
|
34
29
|
export function getProjectContext(ctx: McpToolContext, projectId: string): {
|
|
35
30
|
project: { id: string; name: string; description: string } | undefined;
|
|
36
|
-
|
|
37
|
-
|
|
31
|
+
subProjects: ISubProject[];
|
|
32
|
+
tasks: ITask[];
|
|
33
|
+
stats: { total: number; idea: number; writing: number; submitted: number; testing: number; done: number; problem: number };
|
|
38
34
|
} {
|
|
39
35
|
const project = ctx.getProject(projectId);
|
|
40
|
-
const
|
|
41
|
-
const
|
|
36
|
+
const subProjects = ctx.getSubProjects(projectId);
|
|
37
|
+
const tasks = ctx.getTasksByProject(projectId);
|
|
42
38
|
|
|
43
39
|
const stats = {
|
|
44
|
-
total:
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
40
|
+
total: tasks.length,
|
|
41
|
+
idea: tasks.filter(t => t.status === 'idea').length,
|
|
42
|
+
writing: tasks.filter(t => t.status === 'writing').length,
|
|
43
|
+
submitted: tasks.filter(t => t.status === 'submitted').length,
|
|
44
|
+
testing: tasks.filter(t => t.status === 'testing').length,
|
|
45
|
+
done: tasks.filter(t => t.status === 'done').length,
|
|
46
|
+
problem: tasks.filter(t => t.status === 'problem').length,
|
|
49
47
|
};
|
|
50
48
|
|
|
51
|
-
return { project,
|
|
49
|
+
return { project, subProjects, tasks, stats };
|
|
52
50
|
}
|
|
53
51
|
|
|
54
|
-
export function
|
|
52
|
+
export function formatTaskForMcp(task: ITask, prompt?: ITaskPrompt): string {
|
|
55
53
|
const lines = [
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
`상태: ${item.status}`,
|
|
61
|
-
`잠금: ${item.is_locked ? '잠금' : '해제'}`,
|
|
54
|
+
`Title: ${task.title}`,
|
|
55
|
+
`Description: ${task.description}`,
|
|
56
|
+
`Status: ${task.status}`,
|
|
57
|
+
`Priority: ${task.priority}`,
|
|
62
58
|
];
|
|
63
59
|
|
|
64
|
-
if (prompt) {
|
|
65
|
-
lines.push('', '---
|
|
60
|
+
if (prompt?.content) {
|
|
61
|
+
lines.push('', '--- Prompt ---', prompt.content);
|
|
66
62
|
}
|
|
67
63
|
|
|
68
64
|
return lines.join('\n');
|
|
69
65
|
}
|
|
70
66
|
|
|
71
|
-
export function
|
|
67
|
+
export function formatProjectForMcp(
|
|
68
|
+
subProjects: ISubProject[],
|
|
69
|
+
tasks: ITask[],
|
|
70
|
+
): string {
|
|
72
71
|
const lines: string[] = [];
|
|
73
|
-
for (const
|
|
74
|
-
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
72
|
+
for (const sp of subProjects) {
|
|
73
|
+
lines.push(`[${sp.name}]`);
|
|
74
|
+
const spTasks = tasks.filter(t => t.sub_project_id === sp.id);
|
|
75
|
+
if (spTasks.length === 0) {
|
|
76
|
+
lines.push(' (no tasks)');
|
|
77
|
+
} else {
|
|
78
|
+
for (const t of spTasks) {
|
|
79
|
+
const icon = t.status === 'done' ? 'v' : t.status === 'submitted' ? '>' : t.status === 'testing' ? '~' : t.status === 'problem' ? '!' : '-';
|
|
80
|
+
lines.push(` ${icon} ${t.title} [${t.status}]`);
|
|
81
|
+
}
|
|
80
82
|
}
|
|
81
83
|
}
|
|
82
84
|
return lines.join('\n');
|