centaurus-cli 3.1.3 → 3.1.5

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 (138) hide show
  1. package/dist/cli-adapter.js +685 -153
  2. package/dist/cli-adapter.js.map +1 -1
  3. package/dist/config/defaultConfig.js +1 -4
  4. package/dist/config/defaultConfig.js.map +1 -1
  5. package/dist/config/models.js +4 -0
  6. package/dist/config/models.js.map +1 -1
  7. package/dist/config/slash-commands.js +66 -2
  8. package/dist/config/slash-commands.js.map +1 -1
  9. package/dist/config/types.js +4 -4
  10. package/dist/config/types.js.map +1 -1
  11. package/dist/index.js +36 -0
  12. package/dist/index.js.map +1 -1
  13. package/dist/services/ai-context-injector.js +109 -0
  14. package/dist/services/ai-context-injector.js.map +1 -1
  15. package/dist/services/api-client.js.map +1 -1
  16. package/dist/services/background-task-manager.js +59 -0
  17. package/dist/services/background-task-manager.js.map +1 -1
  18. package/dist/services/local-chat-storage.js +2 -0
  19. package/dist/services/local-chat-storage.js.map +1 -1
  20. package/dist/services/skill-storage.js +141 -0
  21. package/dist/services/skill-storage.js.map +1 -0
  22. package/dist/services/sub-agent-manager.js +49 -8
  23. package/dist/services/sub-agent-manager.js.map +1 -1
  24. package/dist/services/warpify-detector.js +17 -5
  25. package/dist/services/warpify-detector.js.map +1 -1
  26. package/dist/tools/background-command.js +5 -2
  27. package/dist/tools/background-command.js.map +1 -1
  28. package/dist/tools/command.js +367 -109
  29. package/dist/tools/command.js.map +1 -1
  30. package/dist/tools/file-ops.js +23 -6
  31. package/dist/tools/file-ops.js.map +1 -1
  32. package/dist/tools/plan-mode.js +184 -336
  33. package/dist/tools/plan-mode.js.map +1 -1
  34. package/dist/tools/sub-agent.js +24 -5
  35. package/dist/tools/sub-agent.js.map +1 -1
  36. package/dist/tools/todo-list.js +157 -0
  37. package/dist/tools/todo-list.js.map +1 -0
  38. package/dist/types/skill.js +30 -0
  39. package/dist/types/skill.js.map +1 -0
  40. package/dist/ui/components/App.js +956 -162
  41. package/dist/ui/components/App.js.map +1 -1
  42. package/dist/ui/components/AuthScreen.js +3 -1
  43. package/dist/ui/components/AuthScreen.js.map +1 -1
  44. package/dist/ui/components/AuthWelcomeScreen.js +3 -1
  45. package/dist/ui/components/AuthWelcomeScreen.js.map +1 -1
  46. package/dist/ui/components/CodeBlock.js +3 -1
  47. package/dist/ui/components/CodeBlock.js.map +1 -1
  48. package/dist/ui/components/CompactShellPreview.js +44 -0
  49. package/dist/ui/components/CompactShellPreview.js.map +1 -0
  50. package/dist/ui/components/ConfigViewer.js +3 -1
  51. package/dist/ui/components/ConfigViewer.js.map +1 -1
  52. package/dist/ui/components/ConfirmPrompt.js +3 -1
  53. package/dist/ui/components/ConfirmPrompt.js.map +1 -1
  54. package/dist/ui/components/ConnectionStatusMessage.js +3 -1
  55. package/dist/ui/components/ConnectionStatusMessage.js.map +1 -1
  56. package/dist/ui/components/DetailedPlanReviewScreen.js +84 -74
  57. package/dist/ui/components/DetailedPlanReviewScreen.js.map +1 -1
  58. package/dist/ui/components/DiffViewer.js +6 -3
  59. package/dist/ui/components/DiffViewer.js.map +1 -1
  60. package/dist/ui/components/FileCreationPreview.js.map +1 -1
  61. package/dist/ui/components/FileTagAutocomplete.js +4 -2
  62. package/dist/ui/components/FileTagAutocomplete.js.map +1 -1
  63. package/dist/ui/components/InputBox.js +243 -40
  64. package/dist/ui/components/InputBox.js.map +1 -1
  65. package/dist/ui/components/InteractiveShell.js +5 -3
  66. package/dist/ui/components/InteractiveShell.js.map +1 -1
  67. package/dist/ui/components/KeyboardHelp.js +4 -1
  68. package/dist/ui/components/KeyboardHelp.js.map +1 -1
  69. package/dist/ui/components/LoadingIndicator.js +3 -1
  70. package/dist/ui/components/LoadingIndicator.js.map +1 -1
  71. package/dist/ui/components/MCPAddScreen.js +63 -13
  72. package/dist/ui/components/MCPAddScreen.js.map +1 -1
  73. package/dist/ui/components/MarkdownRenderer.js +3 -1
  74. package/dist/ui/components/MarkdownRenderer.js.map +1 -1
  75. package/dist/ui/components/MessageDisplay.js +9 -7
  76. package/dist/ui/components/MessageDisplay.js.map +1 -1
  77. package/dist/ui/components/ModelPicker.js +170 -0
  78. package/dist/ui/components/ModelPicker.js.map +1 -0
  79. package/dist/ui/components/MonitorModeAIPanel.js +3 -1
  80. package/dist/ui/components/MonitorModeAIPanel.js.map +1 -1
  81. package/dist/ui/components/PlanAcceptedMessage.js +12 -6
  82. package/dist/ui/components/PlanAcceptedMessage.js.map +1 -1
  83. package/dist/ui/components/PlanQuestionMessage.js +37 -0
  84. package/dist/ui/components/PlanQuestionMessage.js.map +1 -0
  85. package/dist/ui/components/PlanQuestionScreen.js +138 -0
  86. package/dist/ui/components/PlanQuestionScreen.js.map +1 -0
  87. package/dist/ui/components/PlanReviewScreen.js +7 -9
  88. package/dist/ui/components/PlanReviewScreen.js.map +1 -1
  89. package/dist/ui/components/RulesEditorScreen.js +65 -28
  90. package/dist/ui/components/RulesEditorScreen.js.map +1 -1
  91. package/dist/ui/components/SelectPrompt.js +3 -1
  92. package/dist/ui/components/SelectPrompt.js.map +1 -1
  93. package/dist/ui/components/SkillCreatorScreen.js +217 -0
  94. package/dist/ui/components/SkillCreatorScreen.js.map +1 -0
  95. package/dist/ui/components/SlashCommandAutocomplete.js +4 -2
  96. package/dist/ui/components/SlashCommandAutocomplete.js.map +1 -1
  97. package/dist/ui/components/StatusBar.js +4 -2
  98. package/dist/ui/components/StatusBar.js.map +1 -1
  99. package/dist/ui/components/StreamingMessageDisplay.js +5 -3
  100. package/dist/ui/components/StreamingMessageDisplay.js.map +1 -1
  101. package/dist/ui/components/SubAgentListScreen.js +65 -0
  102. package/dist/ui/components/SubAgentListScreen.js.map +1 -0
  103. package/dist/ui/components/SubAgentViewScreen.js +123 -0
  104. package/dist/ui/components/SubAgentViewScreen.js.map +1 -0
  105. package/dist/ui/components/TaskCompletedMessage.js +40 -8
  106. package/dist/ui/components/TaskCompletedMessage.js.map +1 -1
  107. package/dist/ui/components/TaskProgressIndicator.js +6 -4
  108. package/dist/ui/components/TaskProgressIndicator.js.map +1 -1
  109. package/dist/ui/components/TextEditor.js +297 -0
  110. package/dist/ui/components/TextEditor.js.map +1 -0
  111. package/dist/ui/components/TodoListMessage.js +59 -0
  112. package/dist/ui/components/TodoListMessage.js.map +1 -0
  113. package/dist/ui/components/ToolExecutionMessage.js +134 -84
  114. package/dist/ui/components/ToolExecutionMessage.js.map +1 -1
  115. package/dist/ui/components/ToolExecutionStatus.js +3 -1
  116. package/dist/ui/components/ToolExecutionStatus.js.map +1 -1
  117. package/dist/ui/components/WelcomeBanner.js +33 -33
  118. package/dist/ui/components/WelcomeBanner.js.map +1 -1
  119. package/dist/ui/components/WorkflowCreatorScreen.js +5 -3
  120. package/dist/ui/components/WorkflowCreatorScreen.js.map +1 -1
  121. package/dist/ui/theme.js +97 -0
  122. package/dist/ui/theme.js.map +1 -0
  123. package/dist/ui/utils/chat-history-limit.js +247 -0
  124. package/dist/ui/utils/chat-history-limit.js.map +1 -0
  125. package/dist/utils/chat-formatter.js +22 -9
  126. package/dist/utils/chat-formatter.js.map +1 -1
  127. package/dist/utils/input-classifier.js +11 -1
  128. package/dist/utils/input-classifier.js.map +1 -1
  129. package/dist/utils/output-truncation.js +175 -0
  130. package/dist/utils/output-truncation.js.map +1 -0
  131. package/dist/utils/rule-reference-resolver.js +3 -3
  132. package/dist/utils/rule-reference-resolver.js.map +1 -1
  133. package/dist/utils/tunnel-commands-manager.js +134 -0
  134. package/dist/utils/tunnel-commands-manager.js.map +1 -0
  135. package/package.json +91 -90
  136. package/postinstall.js +4 -11
  137. package/dist/ui/components/MultiLineInput.js +0 -255
  138. package/dist/ui/components/MultiLineInput.js.map +0 -1
@@ -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 create a detailed implementation plan.
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
- The plan should include:
9
- 1. A clear title describing what will be accomplished
10
- 2. A detailed design summary explaining your understanding of the codebase and approach
11
- 3. A brief summary of the overall approach
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
- IMPORTANT: Only use this tool when in planning mode. Each task should be:
15
- - Specific and actionable
16
- - Can have subtasks for more granular steps
17
- - Ordered in a logical sequence
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
- Example structure:
20
- - Task 1: Set up core infrastructure
21
- - 1.1: Create directory structure
22
- - 1.2: Define TypeScript interfaces
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
- designSummary: {
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: "Brief 1-2 sentence summary of the overall approach"
31
+ description: "The full markdown plan document with detailed analysis, tables, mappings, and implementation steps"
40
32
  },
41
- tasks: {
33
+ implementation_steps: {
42
34
  type: "array",
43
35
  items: {
44
- type: "object",
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: "List of main tasks to execute, in order"
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", "summary", "tasks"]
41
+ required: ["title", "document", "implementation_steps"]
84
42
  }
85
43
  },
86
44
  async execute(args, context) {
87
45
  const title = args.title;
88
- const designSummary = args.designSummary || "";
89
- const summary = args.summary;
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 (!tasks || tasks.length === 0) {
95
- throw new Error("Plan must have at least one task");
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
- designSummary: designSummary?.trim() || "",
100
- summary: summary?.trim() || "",
101
- steps: tasks.map((task, taskIndex) => ({
102
- id: `task_${taskIndex + 1}`,
103
- description: task.description.trim(),
104
- subtasks: (task.subtasks || []).map((subtask, subtaskIndex) => ({
105
- id: `${taskIndex + 1}.${subtaskIndex + 1}`,
106
- description: subtask.description.trim(),
107
- status: "pending",
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 a task or subtask as completed in the current plan.
128
- Call this after successfully completing each task/subtask in the plan.
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 task/subtask status to 'completed'
132
- 2. Show a completion message in the UI
133
- 3. Automatically advance to the next task/subtask
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 can mark:
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 subtasks complete as you finish them
142
- - After marking the LAST task/subtask complete, output your summary then call task_complete to end the session`,
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
- task_number: {
147
- type: "string",
148
- description: 'The task number to mark complete. Use integer for main task (e.g., "2") or dot notation for subtask (e.g., "2.1")'
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: ["task_number"]
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 tasks complete.");
113
+ throw new Error("Plan must be approved and active before marking steps complete.");
164
114
  }
165
- const taskNumberStr = String(args.task_number);
115
+ const stepNumber = Number(args.step_number);
166
116
  const completionNote = args.completion_note;
167
- const parts = taskNumberStr.split(".");
168
- const mainTaskNum = parseInt(parts[0], 10);
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
- task.status = "completed";
215
- task.completedAt = /* @__PURE__ */ new Date();
216
- task.subtasks.forEach((st) => {
217
- if (st.status !== "completed" && st.status !== "skipped") {
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
- const { completedCount, totalCount, allComplete } = calculateProgress();
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
- type: "task",
232
- taskNumber: mainTaskNum,
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
- nextTask: allComplete ? null : currentPlan.steps[currentPlan.currentTaskIndex]?.description
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
- function calculateProgress() {
244
- if (!currentPlan) {
245
- return { completedCount: 0, totalCount: 0, allComplete: false };
246
- }
247
- let completedCount = 0;
248
- let totalCount = 0;
249
- currentPlan.steps.forEach((step) => {
250
- if (step.subtasks.length > 0) {
251
- totalCount += step.subtasks.length;
252
- completedCount += step.subtasks.filter((st) => st.status === "completed").length;
253
- } else {
254
- totalCount += 1;
255
- if (step.status === "completed") completedCount += 1;
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
- return {
259
- completedCount,
260
- totalCount,
261
- allComplete: completedCount === totalCount && totalCount > 0
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 markTaskComplete(taskNumber) {
283
- if (!currentPlan || taskNumber < 1 || taskNumber > currentPlan.steps.length) {
284
- return null;
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.steps.every((step) => step.status === "completed" || step.status === "skipped");
229
+ return currentPlan.implementationSteps.every((step) => step.status === "completed");
338
230
  }
339
231
  function getPlanProgress() {
340
232
  if (!currentPlan) return null;
341
- const { completedCount, totalCount } = calculateProgress();
342
- const percentage = totalCount > 0 ? Math.round(completedCount / totalCount * 100) : 0;
343
- const completedTasks = currentPlan.steps.filter((s) => s.status === "completed").length;
344
- return {
345
- completed: completedCount,
346
- total: totalCount,
347
- percentage,
348
- currentTask: currentPlan.currentTaskIndex + 1,
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
- if (currentPlan.designSummary) {
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 += `### Tasks:
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
- step.subtasks.forEach((subtask, subIndex) => {
381
- const subStatusIcon = subtask.status === "completed" ? "\u2705" : subtask.status === "in_progress" ? "\u{1F504}" : "\u2B1C";
382
- context += ` ${index + 1}.${subIndex + 1}. ${subStatusIcon} ${subtask.description}
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 nextTask = getNextIncompleteTask();
387
- if (nextTask) {
261
+ const nextStep = currentPlan.implementationSteps.find((s) => s.status === "pending");
262
+ if (nextStep) {
388
263
  context += `
389
- **NEXT ACTION**: Complete task ${nextTask.taskNumber}: ${nextTask.task.description}
264
+ **NEXT ACTION**: Complete step ${nextStep.id}: ${nextStep.description}
390
265
  `;
391
- context += `After completing this task, call mark_task_complete with task_number=${nextTask.taskNumber}
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 TASKS COMPLETE**: Output your summary of what was accomplished, then call task_complete().
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
- if (!currentPlan || !currentPlan.isActive) return "";
402
- const currentPhase = getCurrentPhase();
403
- if (!currentPhase) {
404
- return `
405
- **ALL TASKS COMPLETE**: Output your summary of what was accomplished, then call task_complete().
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
- return context;
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
- markTaskComplete,
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