centaurus-cli 3.1.2 → 3.1.4
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/dist/cli-adapter.js +689 -155
- package/dist/cli-adapter.js.map +1 -1
- package/dist/config/defaultConfig.js +1 -4
- package/dist/config/defaultConfig.js.map +1 -1
- package/dist/config/models.js +6 -0
- package/dist/config/models.js.map +1 -1
- package/dist/config/slash-commands.js +66 -2
- package/dist/config/slash-commands.js.map +1 -1
- package/dist/config/types.js +4 -4
- package/dist/config/types.js.map +1 -1
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -1
- package/dist/services/ai-context-injector.js +109 -0
- package/dist/services/ai-context-injector.js.map +1 -1
- package/dist/services/ai-service-client.js +3 -2
- package/dist/services/ai-service-client.js.map +1 -1
- package/dist/services/api-client.js.map +1 -1
- package/dist/services/background-task-manager.js +59 -0
- package/dist/services/background-task-manager.js.map +1 -1
- package/dist/services/local-chat-storage.js +2 -0
- package/dist/services/local-chat-storage.js.map +1 -1
- package/dist/services/skill-storage.js +141 -0
- package/dist/services/skill-storage.js.map +1 -0
- package/dist/services/sub-agent-manager.js +49 -8
- package/dist/services/sub-agent-manager.js.map +1 -1
- package/dist/services/warpify-detector.js +17 -5
- package/dist/services/warpify-detector.js.map +1 -1
- package/dist/tools/background-command.js +5 -2
- package/dist/tools/background-command.js.map +1 -1
- package/dist/tools/command.js +367 -109
- package/dist/tools/command.js.map +1 -1
- package/dist/tools/file-ops.js +23 -6
- package/dist/tools/file-ops.js.map +1 -1
- package/dist/tools/plan-mode.js +184 -336
- package/dist/tools/plan-mode.js.map +1 -1
- package/dist/tools/sub-agent.js +24 -5
- package/dist/tools/sub-agent.js.map +1 -1
- package/dist/tools/todo-list.js +157 -0
- package/dist/tools/todo-list.js.map +1 -0
- package/dist/types/skill.js +30 -0
- package/dist/types/skill.js.map +1 -0
- package/dist/ui/components/App.js +956 -162
- package/dist/ui/components/App.js.map +1 -1
- package/dist/ui/components/AuthScreen.js +3 -1
- package/dist/ui/components/AuthScreen.js.map +1 -1
- package/dist/ui/components/AuthWelcomeScreen.js +3 -1
- package/dist/ui/components/AuthWelcomeScreen.js.map +1 -1
- package/dist/ui/components/CodeBlock.js +3 -1
- package/dist/ui/components/CodeBlock.js.map +1 -1
- package/dist/ui/components/CompactShellPreview.js +44 -0
- package/dist/ui/components/CompactShellPreview.js.map +1 -0
- package/dist/ui/components/ConfigViewer.js +3 -1
- package/dist/ui/components/ConfigViewer.js.map +1 -1
- package/dist/ui/components/ConfirmPrompt.js +3 -1
- package/dist/ui/components/ConfirmPrompt.js.map +1 -1
- package/dist/ui/components/ConnectionStatusMessage.js +3 -1
- package/dist/ui/components/ConnectionStatusMessage.js.map +1 -1
- package/dist/ui/components/DetailedPlanReviewScreen.js +84 -74
- package/dist/ui/components/DetailedPlanReviewScreen.js.map +1 -1
- package/dist/ui/components/DiffViewer.js +6 -3
- package/dist/ui/components/DiffViewer.js.map +1 -1
- package/dist/ui/components/FileCreationPreview.js.map +1 -1
- package/dist/ui/components/FileTagAutocomplete.js +4 -2
- package/dist/ui/components/FileTagAutocomplete.js.map +1 -1
- package/dist/ui/components/InputBox.js +243 -40
- package/dist/ui/components/InputBox.js.map +1 -1
- package/dist/ui/components/InteractiveShell.js +5 -3
- package/dist/ui/components/InteractiveShell.js.map +1 -1
- package/dist/ui/components/KeyboardHelp.js +4 -1
- package/dist/ui/components/KeyboardHelp.js.map +1 -1
- package/dist/ui/components/LoadingIndicator.js +3 -1
- package/dist/ui/components/LoadingIndicator.js.map +1 -1
- package/dist/ui/components/MCPAddScreen.js +63 -13
- package/dist/ui/components/MCPAddScreen.js.map +1 -1
- package/dist/ui/components/MarkdownRenderer.js +3 -1
- package/dist/ui/components/MarkdownRenderer.js.map +1 -1
- package/dist/ui/components/MessageDisplay.js +9 -7
- package/dist/ui/components/MessageDisplay.js.map +1 -1
- package/dist/ui/components/ModelPicker.js +170 -0
- package/dist/ui/components/ModelPicker.js.map +1 -0
- package/dist/ui/components/MonitorModeAIPanel.js +3 -1
- package/dist/ui/components/MonitorModeAIPanel.js.map +1 -1
- package/dist/ui/components/PlanAcceptedMessage.js +12 -6
- package/dist/ui/components/PlanAcceptedMessage.js.map +1 -1
- package/dist/ui/components/PlanQuestionMessage.js +37 -0
- package/dist/ui/components/PlanQuestionMessage.js.map +1 -0
- package/dist/ui/components/PlanQuestionScreen.js +138 -0
- package/dist/ui/components/PlanQuestionScreen.js.map +1 -0
- package/dist/ui/components/PlanReviewScreen.js +7 -9
- package/dist/ui/components/PlanReviewScreen.js.map +1 -1
- package/dist/ui/components/RulesEditorScreen.js +65 -28
- package/dist/ui/components/RulesEditorScreen.js.map +1 -1
- package/dist/ui/components/SelectPrompt.js +3 -1
- package/dist/ui/components/SelectPrompt.js.map +1 -1
- package/dist/ui/components/SkillCreatorScreen.js +217 -0
- package/dist/ui/components/SkillCreatorScreen.js.map +1 -0
- package/dist/ui/components/SlashCommandAutocomplete.js +4 -2
- package/dist/ui/components/SlashCommandAutocomplete.js.map +1 -1
- package/dist/ui/components/StatusBar.js +4 -2
- package/dist/ui/components/StatusBar.js.map +1 -1
- package/dist/ui/components/StreamingMessageDisplay.js +5 -3
- package/dist/ui/components/StreamingMessageDisplay.js.map +1 -1
- package/dist/ui/components/SubAgentListScreen.js +65 -0
- package/dist/ui/components/SubAgentListScreen.js.map +1 -0
- package/dist/ui/components/SubAgentViewScreen.js +123 -0
- package/dist/ui/components/SubAgentViewScreen.js.map +1 -0
- package/dist/ui/components/TaskCompletedMessage.js +40 -8
- package/dist/ui/components/TaskCompletedMessage.js.map +1 -1
- package/dist/ui/components/TaskProgressIndicator.js +6 -4
- package/dist/ui/components/TaskProgressIndicator.js.map +1 -1
- package/dist/ui/components/TextEditor.js +297 -0
- package/dist/ui/components/TextEditor.js.map +1 -0
- package/dist/ui/components/TodoListMessage.js +59 -0
- package/dist/ui/components/TodoListMessage.js.map +1 -0
- package/dist/ui/components/ToolExecutionMessage.js +134 -84
- package/dist/ui/components/ToolExecutionMessage.js.map +1 -1
- package/dist/ui/components/ToolExecutionStatus.js +3 -1
- package/dist/ui/components/ToolExecutionStatus.js.map +1 -1
- package/dist/ui/components/WelcomeBanner.js +33 -33
- package/dist/ui/components/WelcomeBanner.js.map +1 -1
- package/dist/ui/components/WorkflowCreatorScreen.js +5 -3
- package/dist/ui/components/WorkflowCreatorScreen.js.map +1 -1
- package/dist/ui/theme.js +97 -0
- package/dist/ui/theme.js.map +1 -0
- package/dist/ui/utils/chat-history-limit.js +247 -0
- package/dist/ui/utils/chat-history-limit.js.map +1 -0
- package/dist/utils/chat-formatter.js +22 -9
- package/dist/utils/chat-formatter.js.map +1 -1
- package/dist/utils/git-stats.js +7 -5
- package/dist/utils/git-stats.js.map +1 -1
- package/dist/utils/input-classifier.js +11 -1
- package/dist/utils/input-classifier.js.map +1 -1
- package/dist/utils/output-truncation.js +175 -0
- package/dist/utils/output-truncation.js.map +1 -0
- package/dist/utils/rule-reference-resolver.js +3 -3
- package/dist/utils/rule-reference-resolver.js.map +1 -1
- package/dist/utils/tunnel-commands-manager.js +134 -0
- package/dist/utils/tunnel-commands-manager.js.map +1 -0
- package/package.json +91 -90
- package/postinstall.js +4 -11
- package/dist/ui/components/MultiLineInput.js +0 -255
- package/dist/ui/components/MultiLineInput.js.map +0 -1
package/dist/tools/plan-mode.js
CHANGED
|
@@ -2,27 +2,23 @@ let currentPlan = null;
|
|
|
2
2
|
const createPlanTool = {
|
|
3
3
|
schema: {
|
|
4
4
|
name: "create_plan",
|
|
5
|
-
description: `Use this tool when in planning mode to
|
|
6
|
-
This will present the plan to the user for review and approval before execution begins.
|
|
5
|
+
description: `Use this tool when in planning mode to submit your detailed implementation plan.
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
1. A clear title
|
|
10
|
-
2. A
|
|
11
|
-
3.
|
|
12
|
-
4. A numbered list of main tasks, each optionally containing subtasks
|
|
7
|
+
You MUST provide:
|
|
8
|
+
1. A clear title for the plan
|
|
9
|
+
2. A comprehensive markdown document detailing the full plan (analysis, mappings, tables, etc.)
|
|
10
|
+
3. An array of implementation steps extracted from the document
|
|
13
11
|
|
|
14
|
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
12
|
+
The markdown document should be detailed and include sections like:
|
|
13
|
+
- Overview/summary of what will be done
|
|
14
|
+
- Analysis (current state, proposed changes, tables, mappings)
|
|
15
|
+
- Implementation Steps section with numbered steps
|
|
16
|
+
- Verification/testing notes
|
|
18
17
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
- Task 2: Implement main feature
|
|
24
|
-
- 2.1: Create component files
|
|
25
|
-
- 2.2: Add unit tests`,
|
|
18
|
+
The implementation_steps array should contain one string per step, matching the numbered steps in your document.
|
|
19
|
+
Each step should be a concise one-line description.
|
|
20
|
+
|
|
21
|
+
IMPORTANT: Only use this tool when in planning mode.`,
|
|
26
22
|
parameters: {
|
|
27
23
|
type: "object",
|
|
28
24
|
properties: {
|
|
@@ -30,92 +26,48 @@ Example structure:
|
|
|
30
26
|
type: "string",
|
|
31
27
|
description: "A clear, concise title for the plan"
|
|
32
28
|
},
|
|
33
|
-
|
|
34
|
-
type: "string",
|
|
35
|
-
description: "Detailed understanding of the codebase and how the changes will be implemented. Include architecture decisions, file structure understanding, and implementation approach."
|
|
36
|
-
},
|
|
37
|
-
summary: {
|
|
29
|
+
document: {
|
|
38
30
|
type: "string",
|
|
39
|
-
description: "
|
|
31
|
+
description: "The full markdown plan document with detailed analysis, tables, mappings, and implementation steps"
|
|
40
32
|
},
|
|
41
|
-
|
|
33
|
+
implementation_steps: {
|
|
42
34
|
type: "array",
|
|
43
35
|
items: {
|
|
44
|
-
type: "
|
|
45
|
-
properties: {
|
|
46
|
-
description: {
|
|
47
|
-
type: "string",
|
|
48
|
-
description: "Clear description of what this main task accomplishes"
|
|
49
|
-
},
|
|
50
|
-
subtasks: {
|
|
51
|
-
type: "array",
|
|
52
|
-
items: {
|
|
53
|
-
type: "object",
|
|
54
|
-
properties: {
|
|
55
|
-
description: {
|
|
56
|
-
type: "string",
|
|
57
|
-
description: "Specific subtask description"
|
|
58
|
-
},
|
|
59
|
-
requirements: {
|
|
60
|
-
type: "string",
|
|
61
|
-
description: "Optional traceability requirements"
|
|
62
|
-
}
|
|
63
|
-
},
|
|
64
|
-
required: ["description"]
|
|
65
|
-
},
|
|
66
|
-
description: "Optional list of subtasks within this main task"
|
|
67
|
-
},
|
|
68
|
-
complexity: {
|
|
69
|
-
type: "string",
|
|
70
|
-
enum: ["low", "medium", "high"],
|
|
71
|
-
description: "Estimated complexity of the task"
|
|
72
|
-
},
|
|
73
|
-
requirements: {
|
|
74
|
-
type: "string",
|
|
75
|
-
description: "Optional traceability requirements"
|
|
76
|
-
}
|
|
77
|
-
},
|
|
78
|
-
required: ["description"]
|
|
36
|
+
type: "string"
|
|
79
37
|
},
|
|
80
|
-
description: "
|
|
38
|
+
description: "Array of implementation step descriptions, one per step. These are the actionable items that will be tracked."
|
|
81
39
|
}
|
|
82
40
|
},
|
|
83
|
-
required: ["title", "
|
|
41
|
+
required: ["title", "document", "implementation_steps"]
|
|
84
42
|
}
|
|
85
43
|
},
|
|
86
44
|
async execute(args, context) {
|
|
87
45
|
const title = args.title;
|
|
88
|
-
const
|
|
89
|
-
const
|
|
90
|
-
const tasks = args.tasks;
|
|
46
|
+
const document = args.document;
|
|
47
|
+
const implementationSteps = args.implementation_steps;
|
|
91
48
|
if (!title || title.trim().length === 0) {
|
|
92
49
|
throw new Error("Plan title cannot be empty");
|
|
93
50
|
}
|
|
94
|
-
if (!
|
|
95
|
-
throw new Error("Plan
|
|
51
|
+
if (!document || document.trim().length === 0) {
|
|
52
|
+
throw new Error("Plan document cannot be empty");
|
|
53
|
+
}
|
|
54
|
+
if (!implementationSteps || implementationSteps.length === 0) {
|
|
55
|
+
throw new Error("Plan must have at least one implementation step");
|
|
96
56
|
}
|
|
97
57
|
const plan = {
|
|
98
58
|
title: title.trim(),
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
requirements: subtask.requirements?.trim()
|
|
109
|
-
})),
|
|
110
|
-
status: "pending",
|
|
111
|
-
estimatedComplexity: task.complexity,
|
|
112
|
-
requirements: task.requirements?.trim()
|
|
113
|
-
})),
|
|
59
|
+
document: document.trim(),
|
|
60
|
+
implementationSteps: implementationSteps.map((step, index) => {
|
|
61
|
+
const cleaned = step.trim().replace(/^\d+[\.\)\:\-]\s*/, "");
|
|
62
|
+
return {
|
|
63
|
+
id: index + 1,
|
|
64
|
+
description: cleaned,
|
|
65
|
+
status: "pending"
|
|
66
|
+
};
|
|
67
|
+
}),
|
|
114
68
|
createdAt: /* @__PURE__ */ new Date(),
|
|
115
69
|
approved: false,
|
|
116
|
-
isActive: false
|
|
117
|
-
currentTaskIndex: 0,
|
|
118
|
-
currentSubtaskIndex: -1
|
|
70
|
+
isActive: false
|
|
119
71
|
};
|
|
120
72
|
currentPlan = plan;
|
|
121
73
|
return `PLAN_CREATED:${JSON.stringify(plan)}`;
|
|
@@ -124,35 +76,33 @@ Example structure:
|
|
|
124
76
|
const markTaskCompleteTool = {
|
|
125
77
|
schema: {
|
|
126
78
|
name: "mark_task_complete",
|
|
127
|
-
description: `Use this tool to mark
|
|
128
|
-
Call this after successfully completing each
|
|
79
|
+
description: `Use this tool to mark an implementation step as completed in the current plan.
|
|
80
|
+
Call this after successfully completing each step in the plan.
|
|
129
81
|
|
|
130
82
|
This will:
|
|
131
|
-
1. Update the
|
|
132
|
-
2. Show a
|
|
133
|
-
3.
|
|
83
|
+
1. Update the step status to 'completed'
|
|
84
|
+
2. Show a tick mark next to the step in the UI
|
|
85
|
+
3. Report progress on all steps
|
|
134
86
|
|
|
135
|
-
You
|
|
136
|
-
- A main task: task_number=2
|
|
137
|
-
- A subtask: task_number="2.1" (marks subtask 1 of task 2)
|
|
87
|
+
You must provide the step number (1-indexed) matching the implementation steps list.
|
|
138
88
|
|
|
139
89
|
IMPORTANT:
|
|
140
90
|
- Must have an active approved plan
|
|
141
|
-
- Mark
|
|
142
|
-
- After marking the LAST
|
|
91
|
+
- Mark steps complete in order as you finish them
|
|
92
|
+
- After marking the LAST step complete, output your summary then call task_complete to end the session`,
|
|
143
93
|
parameters: {
|
|
144
94
|
type: "object",
|
|
145
95
|
properties: {
|
|
146
|
-
|
|
147
|
-
type: "
|
|
148
|
-
description:
|
|
96
|
+
step_number: {
|
|
97
|
+
type: "number",
|
|
98
|
+
description: "The step number to mark complete (1-indexed, e.g., 1, 2, 3...)"
|
|
149
99
|
},
|
|
150
100
|
completion_note: {
|
|
151
101
|
type: "string",
|
|
152
102
|
description: "Optional note about what was accomplished"
|
|
153
103
|
}
|
|
154
104
|
},
|
|
155
|
-
required: ["
|
|
105
|
+
required: ["step_number"]
|
|
156
106
|
}
|
|
157
107
|
},
|
|
158
108
|
async execute(args, context) {
|
|
@@ -160,107 +110,100 @@ IMPORTANT:
|
|
|
160
110
|
throw new Error("No active plan. Create a plan first using create_plan.");
|
|
161
111
|
}
|
|
162
112
|
if (!currentPlan.approved || !currentPlan.isActive) {
|
|
163
|
-
throw new Error("Plan must be approved and active before marking
|
|
113
|
+
throw new Error("Plan must be approved and active before marking steps complete.");
|
|
164
114
|
}
|
|
165
|
-
const
|
|
115
|
+
const stepNumber = Number(args.step_number);
|
|
166
116
|
const completionNote = args.completion_note;
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
const subtaskNum = parts.length > 1 ? parseInt(parts[1], 10) : null;
|
|
170
|
-
if (isNaN(mainTaskNum) || mainTaskNum < 1 || mainTaskNum > currentPlan.steps.length) {
|
|
171
|
-
throw new Error(`Invalid task number. Must be between 1 and ${currentPlan.steps.length}.`);
|
|
172
|
-
}
|
|
173
|
-
const taskIndex = mainTaskNum - 1;
|
|
174
|
-
const task = currentPlan.steps[taskIndex];
|
|
175
|
-
if (subtaskNum !== null) {
|
|
176
|
-
if (!task.subtasks || subtaskNum < 1 || subtaskNum > task.subtasks.length) {
|
|
177
|
-
throw new Error(`Invalid subtask number. Task ${mainTaskNum} has ${task.subtasks?.length || 0} subtasks.`);
|
|
178
|
-
}
|
|
179
|
-
const subtaskIndex = subtaskNum - 1;
|
|
180
|
-
const subtask = task.subtasks[subtaskIndex];
|
|
181
|
-
if (subtask.status === "completed") {
|
|
182
|
-
return `Subtask ${taskNumberStr} is already marked as completed.`;
|
|
183
|
-
}
|
|
184
|
-
subtask.status = "completed";
|
|
185
|
-
subtask.completedAt = /* @__PURE__ */ new Date();
|
|
186
|
-
const allSubtasksComplete = task.subtasks.every((st) => st.status === "completed" || st.status === "skipped");
|
|
187
|
-
if (allSubtasksComplete) {
|
|
188
|
-
task.status = "completed";
|
|
189
|
-
task.completedAt = /* @__PURE__ */ new Date();
|
|
190
|
-
} else {
|
|
191
|
-
task.status = "in_progress";
|
|
192
|
-
}
|
|
193
|
-
const nextPendingSubtaskIndex = task.subtasks.findIndex(
|
|
194
|
-
(st, idx) => idx > subtaskIndex && st.status === "pending"
|
|
195
|
-
);
|
|
196
|
-
currentPlan.currentSubtaskIndex = nextPendingSubtaskIndex;
|
|
197
|
-
const { completedCount: completedCount2, totalCount: totalCount2, allComplete: allComplete2 } = calculateProgress();
|
|
198
|
-
const result2 = {
|
|
199
|
-
type: "subtask",
|
|
200
|
-
taskNumber: taskNumberStr,
|
|
201
|
-
taskDescription: subtask.description,
|
|
202
|
-
completionNote: completionNote || null,
|
|
203
|
-
completedCount: completedCount2,
|
|
204
|
-
totalCount: totalCount2,
|
|
205
|
-
allComplete: allComplete2,
|
|
206
|
-
nextSubtask: nextPendingSubtaskIndex !== -1 ? task.subtasks[nextPendingSubtaskIndex].description : null,
|
|
207
|
-
mainTaskComplete: allSubtasksComplete
|
|
208
|
-
};
|
|
209
|
-
return `TASK_COMPLETED:${JSON.stringify(result2)}`;
|
|
210
|
-
}
|
|
211
|
-
if (task.status === "completed") {
|
|
212
|
-
return `Task ${mainTaskNum} is already marked as completed.`;
|
|
117
|
+
if (isNaN(stepNumber) || stepNumber < 1 || stepNumber > currentPlan.implementationSteps.length) {
|
|
118
|
+
throw new Error(`Invalid step number. Must be between 1 and ${currentPlan.implementationSteps.length}.`);
|
|
213
119
|
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
st.status = "completed";
|
|
219
|
-
st.completedAt = /* @__PURE__ */ new Date();
|
|
220
|
-
}
|
|
221
|
-
});
|
|
222
|
-
const nextPendingIndex = currentPlan.steps.findIndex(
|
|
223
|
-
(step, idx) => idx > taskIndex && step.status === "pending"
|
|
224
|
-
);
|
|
225
|
-
if (nextPendingIndex !== -1) {
|
|
226
|
-
currentPlan.currentTaskIndex = nextPendingIndex;
|
|
227
|
-
currentPlan.currentSubtaskIndex = -1;
|
|
120
|
+
const stepIndex = stepNumber - 1;
|
|
121
|
+
const step = currentPlan.implementationSteps[stepIndex];
|
|
122
|
+
if (step.status === "completed") {
|
|
123
|
+
return `Step ${stepNumber} is already marked as completed.`;
|
|
228
124
|
}
|
|
229
|
-
|
|
125
|
+
step.status = "completed";
|
|
126
|
+
step.completedAt = /* @__PURE__ */ new Date();
|
|
127
|
+
const completedCount = currentPlan.implementationSteps.filter((s) => s.status === "completed").length;
|
|
128
|
+
const totalCount = currentPlan.implementationSteps.length;
|
|
129
|
+
const allComplete = completedCount === totalCount;
|
|
130
|
+
const nextStep = currentPlan.implementationSteps.find((s) => s.status === "pending");
|
|
230
131
|
const result = {
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
taskDescription: task.description,
|
|
132
|
+
stepNumber,
|
|
133
|
+
stepDescription: step.description,
|
|
234
134
|
completionNote: completionNote || null,
|
|
235
135
|
completedCount,
|
|
236
136
|
totalCount,
|
|
237
137
|
allComplete,
|
|
238
|
-
|
|
138
|
+
nextStep: nextStep ? nextStep.description : null,
|
|
139
|
+
nextStepNumber: nextStep ? nextStep.id : null,
|
|
140
|
+
// Include all steps with their current status for UI rendering
|
|
141
|
+
allSteps: currentPlan.implementationSteps.map((s) => ({
|
|
142
|
+
id: s.id,
|
|
143
|
+
description: s.description,
|
|
144
|
+
status: s.status
|
|
145
|
+
}))
|
|
239
146
|
};
|
|
240
147
|
return `TASK_COMPLETED:${JSON.stringify(result)}`;
|
|
241
148
|
}
|
|
242
149
|
};
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
150
|
+
const planAskQuestionTool = {
|
|
151
|
+
schema: {
|
|
152
|
+
name: "plan_ask_question",
|
|
153
|
+
description: `Use this tool during planning mode to ask the user a clarifying question when you need more information before creating the plan.
|
|
154
|
+
|
|
155
|
+
Use this when:
|
|
156
|
+
- The user's request is ambiguous and could be interpreted in multiple ways
|
|
157
|
+
- You need to know about specific preferences (e.g., framework, architecture style)
|
|
158
|
+
- There are multiple valid approaches and you want the user to choose
|
|
159
|
+
- Important details are missing from the request
|
|
160
|
+
|
|
161
|
+
You provide:
|
|
162
|
+
1. The question text
|
|
163
|
+
2. An array of suggested answer options (2-4 options)
|
|
164
|
+
|
|
165
|
+
The user can select one of your suggested options, type a custom answer, or skip the question.
|
|
166
|
+
If the user skips, proceed with the most appropriate default approach.
|
|
167
|
+
|
|
168
|
+
IMPORTANT: Only use this during planning mode, before calling create_plan.
|
|
169
|
+
Do not ask too many questions \u2014 1-2 targeted questions maximum.`,
|
|
170
|
+
parameters: {
|
|
171
|
+
type: "object",
|
|
172
|
+
properties: {
|
|
173
|
+
question: {
|
|
174
|
+
type: "string",
|
|
175
|
+
description: "The clarifying question to ask the user"
|
|
176
|
+
},
|
|
177
|
+
options: {
|
|
178
|
+
type: "array",
|
|
179
|
+
items: {
|
|
180
|
+
type: "string"
|
|
181
|
+
},
|
|
182
|
+
description: "Array of 2-4 suggested answer options for the user to choose from"
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
required: ["question", "options"]
|
|
256
186
|
}
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
}
|
|
187
|
+
},
|
|
188
|
+
async execute(args, context) {
|
|
189
|
+
const question = args.question;
|
|
190
|
+
const options = args.options;
|
|
191
|
+
if (!question || question.trim().length === 0) {
|
|
192
|
+
throw new Error("Question cannot be empty");
|
|
193
|
+
}
|
|
194
|
+
if (!options || options.length < 2) {
|
|
195
|
+
throw new Error("Must provide at least 2 answer options");
|
|
196
|
+
}
|
|
197
|
+
if (options.length > 4) {
|
|
198
|
+
throw new Error("Maximum 4 answer options allowed");
|
|
199
|
+
}
|
|
200
|
+
const result = {
|
|
201
|
+
question: question.trim(),
|
|
202
|
+
options: options.map((o) => o.trim())
|
|
203
|
+
};
|
|
204
|
+
return `ASK_QUESTION:${JSON.stringify(result)}`;
|
|
205
|
+
}
|
|
206
|
+
};
|
|
264
207
|
function setPlan(plan) {
|
|
265
208
|
currentPlan = plan;
|
|
266
209
|
}
|
|
@@ -274,80 +217,27 @@ function approvePlan() {
|
|
|
274
217
|
if (currentPlan) {
|
|
275
218
|
currentPlan.approved = true;
|
|
276
219
|
currentPlan.isActive = true;
|
|
277
|
-
currentPlan.currentTaskIndex = 0;
|
|
278
|
-
currentPlan.currentSubtaskIndex = currentPlan.steps[0]?.subtasks?.length > 0 ? 0 : -1;
|
|
279
220
|
}
|
|
280
221
|
return currentPlan;
|
|
281
222
|
}
|
|
282
|
-
function
|
|
283
|
-
if (!currentPlan
|
|
284
|
-
|
|
285
|
-
}
|
|
286
|
-
const task = currentPlan.steps[taskNumber - 1];
|
|
287
|
-
task.status = "completed";
|
|
288
|
-
task.completedAt = /* @__PURE__ */ new Date();
|
|
289
|
-
task.subtasks.forEach((st) => {
|
|
290
|
-
st.status = "completed";
|
|
291
|
-
st.completedAt = /* @__PURE__ */ new Date();
|
|
292
|
-
});
|
|
293
|
-
return task;
|
|
294
|
-
}
|
|
295
|
-
function getCurrentPhase() {
|
|
296
|
-
if (!currentPlan || !currentPlan.isActive) return null;
|
|
297
|
-
const taskIndex = currentPlan.currentTaskIndex;
|
|
298
|
-
if (taskIndex < 0 || taskIndex >= currentPlan.steps.length) return null;
|
|
299
|
-
const task = currentPlan.steps[taskIndex];
|
|
300
|
-
if (task.status === "completed") {
|
|
301
|
-
const nextIndex = currentPlan.steps.findIndex(
|
|
302
|
-
(step, idx) => idx > taskIndex && step.status === "pending"
|
|
303
|
-
);
|
|
304
|
-
if (nextIndex === -1) return null;
|
|
305
|
-
return { taskNumber: nextIndex + 1, task: currentPlan.steps[nextIndex] };
|
|
306
|
-
}
|
|
307
|
-
return { taskNumber: taskIndex + 1, task };
|
|
308
|
-
}
|
|
309
|
-
function advanceToNextPhase() {
|
|
310
|
-
if (!currentPlan || !currentPlan.isActive) return null;
|
|
311
|
-
const currentTask = currentPlan.steps[currentPlan.currentTaskIndex];
|
|
312
|
-
if (currentTask && currentTask.status !== "completed") {
|
|
313
|
-
currentTask.status = "completed";
|
|
314
|
-
currentTask.completedAt = /* @__PURE__ */ new Date();
|
|
315
|
-
}
|
|
316
|
-
const nextIndex = currentPlan.steps.findIndex(
|
|
317
|
-
(step, idx) => idx > currentPlan.currentTaskIndex && step.status === "pending"
|
|
318
|
-
);
|
|
319
|
-
if (nextIndex === -1) {
|
|
320
|
-
return null;
|
|
321
|
-
}
|
|
322
|
-
currentPlan.currentTaskIndex = nextIndex;
|
|
323
|
-
currentPlan.currentSubtaskIndex = currentPlan.steps[nextIndex].subtasks.length > 0 ? 0 : -1;
|
|
324
|
-
return { taskNumber: nextIndex + 1, task: currentPlan.steps[nextIndex] };
|
|
325
|
-
}
|
|
326
|
-
function getNextIncompleteTask() {
|
|
327
|
-
if (!currentPlan) return null;
|
|
328
|
-
const index = currentPlan.steps.findIndex((step) => step.status === "pending" || step.status === "in_progress");
|
|
329
|
-
if (index === -1) return null;
|
|
330
|
-
return {
|
|
331
|
-
taskNumber: index + 1,
|
|
332
|
-
task: currentPlan.steps[index]
|
|
333
|
-
};
|
|
223
|
+
function getAllStepsStatus() {
|
|
224
|
+
if (!currentPlan) return [];
|
|
225
|
+
return currentPlan.implementationSteps.map((s) => ({ ...s }));
|
|
334
226
|
}
|
|
335
227
|
function areAllTasksComplete() {
|
|
336
228
|
if (!currentPlan) return false;
|
|
337
|
-
return currentPlan.
|
|
229
|
+
return currentPlan.implementationSteps.every((step) => step.status === "completed");
|
|
338
230
|
}
|
|
339
231
|
function getPlanProgress() {
|
|
340
232
|
if (!currentPlan) return null;
|
|
341
|
-
const
|
|
342
|
-
const
|
|
343
|
-
const
|
|
344
|
-
return {
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
totalTasks: currentPlan.steps.length
|
|
350
|
-
};
|
|
233
|
+
const completed = currentPlan.implementationSteps.filter((s) => s.status === "completed").length;
|
|
234
|
+
const total = currentPlan.implementationSteps.length;
|
|
235
|
+
const percentage = total > 0 ? Math.round(completed / total * 100) : 0;
|
|
236
|
+
return { completed, total, percentage };
|
|
237
|
+
}
|
|
238
|
+
function getPlanDocument() {
|
|
239
|
+
if (!currentPlan) return null;
|
|
240
|
+
return currentPlan.document;
|
|
351
241
|
}
|
|
352
242
|
function getPlanContextForPrompt() {
|
|
353
243
|
if (!currentPlan || !currentPlan.isActive) return "";
|
|
@@ -357,118 +247,73 @@ function getPlanContextForPrompt() {
|
|
|
357
247
|
|
|
358
248
|
## ACTIVE PLAN: ${currentPlan.title}
|
|
359
249
|
`;
|
|
360
|
-
|
|
361
|
-
context += `
|
|
362
|
-
### Design Summary:
|
|
363
|
-
${currentPlan.designSummary}
|
|
364
|
-
`;
|
|
365
|
-
}
|
|
366
|
-
context += `
|
|
367
|
-
Progress: ${progress.completed}/${progress.total} items completed (${progress.percentage}%)
|
|
368
|
-
`;
|
|
369
|
-
context += `Current Task: ${progress.currentTask}/${progress.totalTasks}
|
|
250
|
+
context += `Progress: ${progress.completed}/${progress.total} steps completed (${progress.percentage}%)
|
|
370
251
|
|
|
371
252
|
`;
|
|
372
|
-
context += `###
|
|
373
|
-
`;
|
|
374
|
-
currentPlan.steps.forEach((step, index) => {
|
|
375
|
-
const statusIcon = step.status === "completed" ? "\u2705" : step.status === "in_progress" ? "\u{1F504}" : step.status === "skipped" ? "\u23ED\uFE0F" : "\u23F3";
|
|
376
|
-
const isCurrent = index === currentPlan.currentTaskIndex && step.status !== "completed";
|
|
377
|
-
const marker = isCurrent ? " \u{1F448} CURRENT" : "";
|
|
378
|
-
context += `${index + 1}. ${statusIcon} ${step.description}${marker}
|
|
253
|
+
context += `### Implementation Steps:
|
|
379
254
|
`;
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
255
|
+
currentPlan.implementationSteps.forEach((step) => {
|
|
256
|
+
const statusIcon = step.status === "completed" ? "[x]" : "[ ]";
|
|
257
|
+
const marker = step.status === "pending" && !currentPlan.implementationSteps.slice(0, step.id - 1).some((s) => s.status === "pending") ? " <-- NEXT" : "";
|
|
258
|
+
context += `${step.id}. ${statusIcon} ${step.description}${marker}
|
|
383
259
|
`;
|
|
384
|
-
});
|
|
385
260
|
});
|
|
386
|
-
const
|
|
387
|
-
if (
|
|
261
|
+
const nextStep = currentPlan.implementationSteps.find((s) => s.status === "pending");
|
|
262
|
+
if (nextStep) {
|
|
388
263
|
context += `
|
|
389
|
-
**NEXT ACTION**: Complete
|
|
264
|
+
**NEXT ACTION**: Complete step ${nextStep.id}: ${nextStep.description}
|
|
390
265
|
`;
|
|
391
|
-
context += `After completing this
|
|
266
|
+
context += `After completing this step, call mark_task_complete with step_number=${nextStep.id}
|
|
392
267
|
`;
|
|
393
268
|
} else {
|
|
394
269
|
context += `
|
|
395
|
-
**ALL
|
|
270
|
+
**ALL STEPS COMPLETE**: Output your summary of what was accomplished, then call task_complete().
|
|
396
271
|
`;
|
|
397
272
|
}
|
|
398
273
|
return context;
|
|
399
274
|
}
|
|
275
|
+
function getCurrentPhase() {
|
|
276
|
+
if (!currentPlan || !currentPlan.isActive) return null;
|
|
277
|
+
const nextStep = currentPlan.implementationSteps.find((s) => s.status === "pending");
|
|
278
|
+
if (!nextStep) return null;
|
|
279
|
+
return { taskNumber: nextStep.id, task: nextStep };
|
|
280
|
+
}
|
|
281
|
+
function advanceToNextPhase() {
|
|
282
|
+
return getCurrentPhase();
|
|
283
|
+
}
|
|
284
|
+
function getNextIncompleteTask() {
|
|
285
|
+
return getCurrentPhase();
|
|
286
|
+
}
|
|
400
287
|
function getPhaseContextForPrompt() {
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
`;
|
|
407
|
-
}
|
|
408
|
-
const progress = getPlanProgress();
|
|
409
|
-
const { taskNumber, task } = currentPhase;
|
|
410
|
-
let context = `
|
|
411
|
-
|
|
412
|
-
## CURRENT TASK: ${currentPlan.title}
|
|
413
|
-
`;
|
|
414
|
-
if (currentPlan.designSummary) {
|
|
415
|
-
context += `
|
|
416
|
-
### Design Context:
|
|
417
|
-
${currentPlan.designSummary}
|
|
418
|
-
`;
|
|
419
|
-
}
|
|
420
|
-
context += `
|
|
421
|
-
### Overall Progress: Task ${taskNumber}/${currentPlan.steps.length}
|
|
422
|
-
`;
|
|
423
|
-
context += `${progress ? `(${progress.completed}/${progress.total} items completed - ${progress.percentage}%)` : ""}
|
|
424
|
-
|
|
425
|
-
`;
|
|
426
|
-
context += `### YOUR CURRENT TASK:
|
|
427
|
-
`;
|
|
428
|
-
context += `**Task ${taskNumber}: ${task.description}**
|
|
429
|
-
|
|
430
|
-
`;
|
|
431
|
-
if (task.subtasks.length > 0) {
|
|
432
|
-
context += `Subtasks to complete:
|
|
433
|
-
`;
|
|
434
|
-
task.subtasks.forEach((subtask, index) => {
|
|
435
|
-
const subStatusIcon = subtask.status === "completed" ? "\u2705" : subtask.status === "in_progress" ? "\u{1F504}" : "\u2B1C";
|
|
436
|
-
const isCurrentSubtask = index === currentPlan.currentSubtaskIndex;
|
|
437
|
-
const marker = isCurrentSubtask && subtask.status === "pending" ? " \u{1F448} CURRENT" : "";
|
|
438
|
-
context += ` ${taskNumber}.${index + 1}. ${subStatusIcon} ${subtask.description}${marker}
|
|
439
|
-
`;
|
|
440
|
-
});
|
|
441
|
-
context += `
|
|
442
|
-
**Instructions**: Complete each subtask in order.
|
|
443
|
-
`;
|
|
444
|
-
context += `After completing a subtask, call: mark_task_complete(task_number="${taskNumber}.X")
|
|
445
|
-
`;
|
|
446
|
-
context += `When all subtasks are done, the main task will be automatically marked complete.
|
|
447
|
-
`;
|
|
448
|
-
} else {
|
|
449
|
-
context += `
|
|
450
|
-
**Instructions**: Complete this task.
|
|
451
|
-
`;
|
|
452
|
-
context += `When done, call: mark_task_complete(task_number="${taskNumber}")
|
|
453
|
-
`;
|
|
288
|
+
return getPlanContextForPrompt();
|
|
289
|
+
}
|
|
290
|
+
function markTaskComplete(taskNumber) {
|
|
291
|
+
if (!currentPlan || taskNumber < 1 || taskNumber > currentPlan.implementationSteps.length) {
|
|
292
|
+
return null;
|
|
454
293
|
}
|
|
455
|
-
|
|
294
|
+
const step = currentPlan.implementationSteps[taskNumber - 1];
|
|
295
|
+
step.status = "completed";
|
|
296
|
+
step.completedAt = /* @__PURE__ */ new Date();
|
|
297
|
+
return step;
|
|
456
298
|
}
|
|
457
299
|
var plan_mode_default = {
|
|
458
300
|
createPlanTool,
|
|
459
301
|
markTaskCompleteTool,
|
|
302
|
+
planAskQuestionTool,
|
|
460
303
|
setPlan,
|
|
461
304
|
getCurrentPlan,
|
|
462
305
|
clearPlan,
|
|
463
306
|
approvePlan,
|
|
464
|
-
|
|
465
|
-
getCurrentPhase,
|
|
466
|
-
advanceToNextPhase,
|
|
467
|
-
getNextIncompleteTask,
|
|
307
|
+
getAllStepsStatus,
|
|
468
308
|
areAllTasksComplete,
|
|
469
309
|
getPlanProgress,
|
|
310
|
+
getPlanDocument,
|
|
470
311
|
getPlanContextForPrompt,
|
|
471
|
-
getPhaseContextForPrompt
|
|
312
|
+
getPhaseContextForPrompt,
|
|
313
|
+
getCurrentPhase,
|
|
314
|
+
advanceToNextPhase,
|
|
315
|
+
getNextIncompleteTask,
|
|
316
|
+
markTaskComplete
|
|
472
317
|
};
|
|
473
318
|
export {
|
|
474
319
|
advanceToNextPhase,
|
|
@@ -477,14 +322,17 @@ export {
|
|
|
477
322
|
clearPlan,
|
|
478
323
|
createPlanTool,
|
|
479
324
|
plan_mode_default as default,
|
|
325
|
+
getAllStepsStatus,
|
|
480
326
|
getCurrentPhase,
|
|
481
327
|
getCurrentPlan,
|
|
482
328
|
getNextIncompleteTask,
|
|
483
329
|
getPhaseContextForPrompt,
|
|
484
330
|
getPlanContextForPrompt,
|
|
331
|
+
getPlanDocument,
|
|
485
332
|
getPlanProgress,
|
|
486
333
|
markTaskComplete,
|
|
487
334
|
markTaskCompleteTool,
|
|
335
|
+
planAskQuestionTool,
|
|
488
336
|
setPlan
|
|
489
337
|
};
|
|
490
338
|
//# sourceMappingURL=plan-mode.js.map
|