@cydm/pie 1.0.4 → 1.0.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.
- package/dist/builtin/extensions/plan-mode/index.js +27 -0
- package/dist/builtin/extensions/todo/index.js +2732 -143
- package/dist/cli.js +158 -192
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -65783,8 +65783,8 @@ function createExtensionContext2(extension, cwd, uiContext, abortFn, isIdleFn, h
|
|
|
65783
65783
|
sendUserMessage(content) {
|
|
65784
65784
|
actions?.sendUserMessage(content);
|
|
65785
65785
|
},
|
|
65786
|
-
setPlanMode(enabled) {
|
|
65787
|
-
actions?.setPlanMode(enabled);
|
|
65786
|
+
setPlanMode(enabled, options) {
|
|
65787
|
+
actions?.setPlanMode(enabled, options);
|
|
65788
65788
|
},
|
|
65789
65789
|
// Extended properties for subagent creation
|
|
65790
65790
|
get apiKey() {
|
|
@@ -65799,6 +65799,15 @@ function createExtensionContext2(extension, cwd, uiContext, abortFn, isIdleFn, h
|
|
|
65799
65799
|
getAllTools() {
|
|
65800
65800
|
return actions?.getAllTools ? actions.getAllTools() : actions?.getActiveTools()?.map((name) => ({ name, description: "" })) ?? [];
|
|
65801
65801
|
},
|
|
65802
|
+
getMessages() {
|
|
65803
|
+
return actions?.getMessages?.() ?? [];
|
|
65804
|
+
},
|
|
65805
|
+
getSessionMetadata() {
|
|
65806
|
+
return actions?.getSessionMetadata?.() ?? {};
|
|
65807
|
+
},
|
|
65808
|
+
setSessionMetadata(key, value) {
|
|
65809
|
+
actions?.setSessionMetadata?.(key, value);
|
|
65810
|
+
},
|
|
65802
65811
|
get yoloMode() {
|
|
65803
65812
|
return actions?.yoloMode ?? false;
|
|
65804
65813
|
}
|
|
@@ -66190,7 +66199,7 @@ var ExtensionRunner = class {
|
|
|
66190
66199
|
setActiveTools: (toolNames) => this.actions.setActiveTools(toolNames),
|
|
66191
66200
|
getActiveTools: () => this.actions.getActiveTools(),
|
|
66192
66201
|
sendUserMessage: (content) => this.actions.sendUserMessage(content),
|
|
66193
|
-
setPlanMode: (enabled) => this.actions.setPlanMode(enabled),
|
|
66202
|
+
setPlanMode: (enabled, options) => this.actions.setPlanMode(enabled, options),
|
|
66194
66203
|
get apiKey() {
|
|
66195
66204
|
return runner.actions.apiKey;
|
|
66196
66205
|
},
|
|
@@ -66201,6 +66210,9 @@ var ExtensionRunner = class {
|
|
|
66201
66210
|
return runner.actions.skills ?? [];
|
|
66202
66211
|
},
|
|
66203
66212
|
getAllTools: () => runner.actions.getAllTools(),
|
|
66213
|
+
getMessages: () => runner.actions.getMessages(),
|
|
66214
|
+
getSessionMetadata: () => runner.actions.getSessionMetadata(),
|
|
66215
|
+
setSessionMetadata: (key, value) => runner.actions.setSessionMetadata(key, value),
|
|
66204
66216
|
get yoloMode() {
|
|
66205
66217
|
return runner.actions.yoloMode ?? false;
|
|
66206
66218
|
}
|
|
@@ -74805,6 +74817,70 @@ function createFileCommandHandlers(fileManager, ui) {
|
|
|
74805
74817
|
};
|
|
74806
74818
|
}
|
|
74807
74819
|
|
|
74820
|
+
// src/todo/state-manager.ts
|
|
74821
|
+
var TodoStateManager = class {
|
|
74822
|
+
todos = [];
|
|
74823
|
+
read() {
|
|
74824
|
+
return this.todos.map((todo) => ({ ...todo }));
|
|
74825
|
+
}
|
|
74826
|
+
write(todos) {
|
|
74827
|
+
this.todos = todos.map((todo) => ({ ...todo }));
|
|
74828
|
+
}
|
|
74829
|
+
clear() {
|
|
74830
|
+
this.todos = [];
|
|
74831
|
+
}
|
|
74832
|
+
getStats() {
|
|
74833
|
+
const total = this.todos.length;
|
|
74834
|
+
const completed = this.todos.filter((todo) => todo.status === "completed").length;
|
|
74835
|
+
const inProgress = this.todos.filter((todo) => todo.status === "in-progress").length;
|
|
74836
|
+
return {
|
|
74837
|
+
total,
|
|
74838
|
+
completed,
|
|
74839
|
+
inProgress,
|
|
74840
|
+
notStarted: total - completed - inProgress
|
|
74841
|
+
};
|
|
74842
|
+
}
|
|
74843
|
+
validate(todos) {
|
|
74844
|
+
const errors = [];
|
|
74845
|
+
if (!Array.isArray(todos)) {
|
|
74846
|
+
return { valid: false, errors: ["todoList must be an array"] };
|
|
74847
|
+
}
|
|
74848
|
+
const validStatuses = /* @__PURE__ */ new Set(["not-started", "in-progress", "completed"]);
|
|
74849
|
+
for (let index = 0; index < todos.length; index++) {
|
|
74850
|
+
const item = todos[index];
|
|
74851
|
+
const prefix = `Item ${index + 1}`;
|
|
74852
|
+
if (typeof item?.id !== "number" || !Number.isInteger(item.id) || item.id < 1) {
|
|
74853
|
+
errors.push(`${prefix}: 'id' must be a positive integer`);
|
|
74854
|
+
}
|
|
74855
|
+
if (typeof item?.title !== "string" || item.title.trim().length === 0) {
|
|
74856
|
+
errors.push(`${prefix}: 'title' is required`);
|
|
74857
|
+
}
|
|
74858
|
+
if (typeof item?.description !== "string") {
|
|
74859
|
+
errors.push(`${prefix}: 'description' must be a string`);
|
|
74860
|
+
}
|
|
74861
|
+
if (!validStatuses.has(item?.status)) {
|
|
74862
|
+
errors.push(`${prefix}: 'status' must be one of: not-started, in-progress, completed`);
|
|
74863
|
+
}
|
|
74864
|
+
if (item?.id !== index + 1) {
|
|
74865
|
+
errors.push(`${prefix}: ids must be sequential starting from 1`);
|
|
74866
|
+
}
|
|
74867
|
+
}
|
|
74868
|
+
return { valid: errors.length === 0, errors };
|
|
74869
|
+
}
|
|
74870
|
+
restoreFromMessages(messages) {
|
|
74871
|
+
this.todos = [];
|
|
74872
|
+
for (const message of messages) {
|
|
74873
|
+
if (message.role !== "toolResult" || message.toolName !== "manage_todo_list") {
|
|
74874
|
+
continue;
|
|
74875
|
+
}
|
|
74876
|
+
const details = message.details;
|
|
74877
|
+
if (details?.todos) {
|
|
74878
|
+
this.todos = details.todos.map((todo) => ({ ...todo }));
|
|
74879
|
+
}
|
|
74880
|
+
}
|
|
74881
|
+
}
|
|
74882
|
+
};
|
|
74883
|
+
|
|
74808
74884
|
// src/interactive-mode.ts
|
|
74809
74885
|
var InteractiveMode = class {
|
|
74810
74886
|
agent;
|
|
@@ -74816,6 +74892,7 @@ var InteractiveMode = class {
|
|
|
74816
74892
|
editorContainer;
|
|
74817
74893
|
todoWidgetContainer;
|
|
74818
74894
|
todoWidget;
|
|
74895
|
+
todoState = new TodoStateManager();
|
|
74819
74896
|
keybindings;
|
|
74820
74897
|
sessionManager;
|
|
74821
74898
|
skills;
|
|
@@ -74837,8 +74914,25 @@ var InteractiveMode = class {
|
|
|
74837
74914
|
toolOutputExpanded = false;
|
|
74838
74915
|
// Plan mode state
|
|
74839
74916
|
planModeEnabled = false;
|
|
74840
|
-
|
|
74841
|
-
|
|
74917
|
+
pendingPlanModeTransition = null;
|
|
74918
|
+
planModeEnterPrefix = `<system-reminder>
|
|
74919
|
+
# Plan Mode - System Reminder
|
|
74920
|
+
|
|
74921
|
+
CRITICAL: Plan mode ACTIVE - you are in READ-ONLY phase. STRICTLY FORBIDDEN:
|
|
74922
|
+
ANY file edits, modifications, or system changes. Do NOT use write/edit or bash to manipulate files.
|
|
74923
|
+
Commands may ONLY read or inspect. This overrides all other instructions.
|
|
74924
|
+
|
|
74925
|
+
Your responsibility is to analyze, read, search, and produce a clear execution plan.
|
|
74926
|
+
</system-reminder>
|
|
74927
|
+
|
|
74928
|
+
`;
|
|
74929
|
+
planModeExitPrefix = `<system-reminder>
|
|
74930
|
+
Your operational mode has changed from plan to build.
|
|
74931
|
+
You are no longer in read-only mode.
|
|
74932
|
+
You may now make file changes, run shell commands, and use your tools as needed.
|
|
74933
|
+
</system-reminder>
|
|
74934
|
+
|
|
74935
|
+
`;
|
|
74842
74936
|
// File manager for multi-modal input
|
|
74843
74937
|
fileManager;
|
|
74844
74938
|
mentionHandler;
|
|
@@ -74930,6 +75024,16 @@ var InteractiveMode = class {
|
|
|
74930
75024
|
this.todoWidgetContainer.invalidate?.();
|
|
74931
75025
|
this.safeRequestRender();
|
|
74932
75026
|
}
|
|
75027
|
+
syncSessionScopedState(messages) {
|
|
75028
|
+
const sessionMessages = messages ?? this.sessionManager.getMessages();
|
|
75029
|
+
this.todoState.restoreFromMessages(sessionMessages);
|
|
75030
|
+
this.refreshTodoWidget();
|
|
75031
|
+
this.emitExtensionEvent({
|
|
75032
|
+
type: "session:changed",
|
|
75033
|
+
sessionId: this.sessionManager.getActiveSession()?.id ?? null,
|
|
75034
|
+
metadata: { ...this.sessionManager.getActiveSession()?.metadata ?? {} }
|
|
75035
|
+
});
|
|
75036
|
+
}
|
|
74933
75037
|
async init() {
|
|
74934
75038
|
const savedLevel = this.options.settingsManager.getDefaultThinkingLevel();
|
|
74935
75039
|
if (savedLevel) {
|
|
@@ -74950,14 +75054,14 @@ var InteractiveMode = class {
|
|
|
74950
75054
|
});
|
|
74951
75055
|
this.updateTerminalTitle();
|
|
74952
75056
|
this.setupUI();
|
|
74953
|
-
this.
|
|
74954
|
-
this.refreshTodoWidget();
|
|
75057
|
+
this.syncSessionScopedState();
|
|
74955
75058
|
this.setupAutocomplete();
|
|
74956
75059
|
this.setupAgentSubscription();
|
|
74957
75060
|
this.setupEditorSubmitHandler();
|
|
74958
75061
|
this.setupKeybindings();
|
|
74959
75062
|
this.registerBuiltinCommands();
|
|
74960
75063
|
await this.loadExtensions();
|
|
75064
|
+
this.syncSessionScopedState();
|
|
74961
75065
|
this.emitExtensionEvent({ type: "agent:start" });
|
|
74962
75066
|
this.setupAutocomplete();
|
|
74963
75067
|
this.registerExtensionShortcuts();
|
|
@@ -75003,7 +75107,10 @@ var InteractiveMode = class {
|
|
|
75003
75107
|
void this.editor.onSubmit(content);
|
|
75004
75108
|
}
|
|
75005
75109
|
},
|
|
75006
|
-
setPlanMode: (enabled) => {
|
|
75110
|
+
setPlanMode: (enabled, options) => {
|
|
75111
|
+
if (this.planModeEnabled !== enabled || options?.forcePromptInjection) {
|
|
75112
|
+
this.pendingPlanModeTransition = enabled ? "enter" : "exit";
|
|
75113
|
+
}
|
|
75007
75114
|
this.planModeEnabled = enabled;
|
|
75008
75115
|
if (process.env.PIE_VERBOSE) {
|
|
75009
75116
|
console.error(`[Extension] Plan mode ${enabled ? "enabled" : "disabled"}`);
|
|
@@ -75016,6 +75123,14 @@ var InteractiveMode = class {
|
|
|
75016
75123
|
parameters: t.parameters
|
|
75017
75124
|
}));
|
|
75018
75125
|
},
|
|
75126
|
+
getMessages: () => this.agent.state.messages,
|
|
75127
|
+
getSessionMetadata: () => ({ ...this.sessionManager.getActiveSession()?.metadata ?? {} }),
|
|
75128
|
+
setSessionMetadata: (key, value) => {
|
|
75129
|
+
const activeSession = this.sessionManager.getActiveSession();
|
|
75130
|
+
if (!activeSession) return;
|
|
75131
|
+
activeSession.metadata[key] = value;
|
|
75132
|
+
activeSession.isDirty = true;
|
|
75133
|
+
},
|
|
75019
75134
|
// YOLO mode status for subagent sandbox inheritance
|
|
75020
75135
|
// Note: Using arrow function to capture correct 'this'
|
|
75021
75136
|
yoloMode: this.yoloMode
|
|
@@ -75533,7 +75648,10 @@ var InteractiveMode = class {
|
|
|
75533
75648
|
void this.editor.onSubmit(content);
|
|
75534
75649
|
}
|
|
75535
75650
|
},
|
|
75536
|
-
setPlanMode: (enabled) => {
|
|
75651
|
+
setPlanMode: (enabled, options) => {
|
|
75652
|
+
if (this.planModeEnabled !== enabled || options?.forcePromptInjection) {
|
|
75653
|
+
this.pendingPlanModeTransition = enabled ? "enter" : "exit";
|
|
75654
|
+
}
|
|
75537
75655
|
this.planModeEnabled = enabled;
|
|
75538
75656
|
if (process.env.PIE_VERBOSE) {
|
|
75539
75657
|
console.error(`[Extension] Plan mode ${enabled ? "enabled" : "disabled"}`);
|
|
@@ -75553,6 +75671,14 @@ var InteractiveMode = class {
|
|
|
75553
75671
|
parameters: t.parameters
|
|
75554
75672
|
}));
|
|
75555
75673
|
},
|
|
75674
|
+
getMessages: () => this.agent.state.messages,
|
|
75675
|
+
getSessionMetadata: () => ({ ...this.sessionManager.getActiveSession()?.metadata ?? {} }),
|
|
75676
|
+
setSessionMetadata: (key, value) => {
|
|
75677
|
+
const activeSession = this.sessionManager.getActiveSession();
|
|
75678
|
+
if (!activeSession) return;
|
|
75679
|
+
activeSession.metadata[key] = value;
|
|
75680
|
+
activeSession.isDirty = true;
|
|
75681
|
+
},
|
|
75556
75682
|
// Provide YOLO mode status for subagent sandbox inheritance
|
|
75557
75683
|
yoloMode: this.yoloMode
|
|
75558
75684
|
};
|
|
@@ -75850,7 +75976,7 @@ ${newToolsSection}`
|
|
|
75850
75976
|
});
|
|
75851
75977
|
this.editorContainer = new Container();
|
|
75852
75978
|
this.todoWidgetContainer = new Container();
|
|
75853
|
-
this.todoWidget = new TodoWidgetComponent(this.
|
|
75979
|
+
this.todoWidget = new TodoWidgetComponent(this.todoState);
|
|
75854
75980
|
this.todoWidgetContainer.addChild(this.todoWidget);
|
|
75855
75981
|
const editorTheme = getEditorTheme();
|
|
75856
75982
|
this.editor = new Editor(this.ui, editorTheme, { paddingX: 1 });
|
|
@@ -76205,6 +76331,10 @@ ${newToolsSection}`
|
|
|
76205
76331
|
}
|
|
76206
76332
|
}
|
|
76207
76333
|
if (event.toolName === "manage_todo_list") {
|
|
76334
|
+
const details = event.result?.details;
|
|
76335
|
+
if (details?.todos) {
|
|
76336
|
+
this.todoState.write(details.todos);
|
|
76337
|
+
}
|
|
76208
76338
|
this.refreshTodoWidget();
|
|
76209
76339
|
}
|
|
76210
76340
|
this.footer.setState({ lifecycleEvent: "tool_execution_end" });
|
|
@@ -76775,15 +76905,14 @@ ${newToolsSection}`
|
|
|
76775
76905
|
this.ui.requestRender();
|
|
76776
76906
|
await new Promise((resolve5) => setImmediate(resolve5));
|
|
76777
76907
|
let finalContent = messageContent;
|
|
76778
|
-
|
|
76908
|
+
const planPrefix = this.pendingPlanModeTransition === "enter" ? this.planModeEnterPrefix : this.pendingPlanModeTransition === "exit" ? this.planModeExitPrefix : null;
|
|
76909
|
+
if (planPrefix) {
|
|
76779
76910
|
if (typeof messageContent === "string") {
|
|
76780
|
-
finalContent =
|
|
76911
|
+
finalContent = planPrefix + messageContent;
|
|
76781
76912
|
} else if (Array.isArray(messageContent)) {
|
|
76782
|
-
finalContent = [
|
|
76783
|
-
{ type: "text", text: this.planModeEnterPrefix },
|
|
76784
|
-
...messageContent
|
|
76785
|
-
];
|
|
76913
|
+
finalContent = [{ type: "text", text: planPrefix }, ...messageContent];
|
|
76786
76914
|
}
|
|
76915
|
+
this.pendingPlanModeTransition = null;
|
|
76787
76916
|
}
|
|
76788
76917
|
this.agent.prompt(finalContent).catch((err) => {
|
|
76789
76918
|
this.showError(`Agent error: ${err.message}`);
|
|
@@ -77215,6 +77344,8 @@ ${newToolsSection}`
|
|
|
77215
77344
|
this.agent.sessionId = activeSession.id;
|
|
77216
77345
|
}
|
|
77217
77346
|
this.syncSessionModelMetadata();
|
|
77347
|
+
this.planModeEnabled = false;
|
|
77348
|
+
this.pendingPlanModeTransition = null;
|
|
77218
77349
|
this.updateTerminalTitle();
|
|
77219
77350
|
this.chatContainer.clear();
|
|
77220
77351
|
this.streamingComponent = void 0;
|
|
@@ -77225,6 +77356,7 @@ ${newToolsSection}`
|
|
|
77225
77356
|
this.updatePendingMessagesDisplay();
|
|
77226
77357
|
this.chatContainer.addChild(new Spacer(1));
|
|
77227
77358
|
this.chatContainer.addChild(new Text(theme.fg("accent", "\u2713 New session started"), 1, 0));
|
|
77359
|
+
this.syncSessionScopedState();
|
|
77228
77360
|
this.ui.requestRender();
|
|
77229
77361
|
}
|
|
77230
77362
|
handleCtrlC() {
|
|
@@ -77555,9 +77687,10 @@ ${newToolsSection}`
|
|
|
77555
77687
|
this.agent.resetProcessingState();
|
|
77556
77688
|
this.agent.replaceMessages(conversationMessages);
|
|
77557
77689
|
this.lastSyncedMessageCount = this.agent.state.messages.length;
|
|
77558
|
-
this.
|
|
77559
|
-
this.refreshTodoWidget();
|
|
77690
|
+
this.syncSessionScopedState(messages);
|
|
77560
77691
|
this.chatContainer.clear();
|
|
77692
|
+
this.streamingComponent = void 0;
|
|
77693
|
+
this.pendingTools.clear();
|
|
77561
77694
|
this.lastStatusSpacer = void 0;
|
|
77562
77695
|
this.lastStatusText = void 0;
|
|
77563
77696
|
this.messageQueue = [];
|
|
@@ -77739,7 +77872,10 @@ ${newToolsSection}`
|
|
|
77739
77872
|
const messages = this.sessionManager.getMessages();
|
|
77740
77873
|
this.agent.replaceMessages(messages);
|
|
77741
77874
|
this.lastSyncedMessageCount = this.agent.state.messages.length;
|
|
77875
|
+
this.syncSessionScopedState(messages);
|
|
77742
77876
|
this.chatContainer.clear();
|
|
77877
|
+
this.streamingComponent = void 0;
|
|
77878
|
+
this.pendingTools.clear();
|
|
77743
77879
|
this.lastStatusSpacer = void 0;
|
|
77744
77880
|
this.lastStatusText = void 0;
|
|
77745
77881
|
this.messageQueue = [];
|
|
@@ -77767,7 +77903,10 @@ ${newToolsSection}`
|
|
|
77767
77903
|
const messages = this.sessionManager.getMessages();
|
|
77768
77904
|
this.agent.replaceMessages(messages);
|
|
77769
77905
|
this.lastSyncedMessageCount = this.agent.state.messages.length;
|
|
77906
|
+
this.syncSessionScopedState(messages);
|
|
77770
77907
|
this.chatContainer.clear();
|
|
77908
|
+
this.streamingComponent = void 0;
|
|
77909
|
+
this.pendingTools.clear();
|
|
77771
77910
|
this.lastStatusSpacer = void 0;
|
|
77772
77911
|
this.lastStatusText = void 0;
|
|
77773
77912
|
this.messageQueue = [];
|
|
@@ -78864,177 +79003,6 @@ var ModelRegistry = class {
|
|
|
78864
79003
|
}
|
|
78865
79004
|
};
|
|
78866
79005
|
|
|
78867
|
-
// src/todo/state-manager.ts
|
|
78868
|
-
var TodoStateManager = class {
|
|
78869
|
-
todos = [];
|
|
78870
|
-
read() {
|
|
78871
|
-
return this.todos.map((todo) => ({ ...todo }));
|
|
78872
|
-
}
|
|
78873
|
-
write(todos) {
|
|
78874
|
-
this.todos = todos.map((todo) => ({ ...todo }));
|
|
78875
|
-
}
|
|
78876
|
-
clear() {
|
|
78877
|
-
this.todos = [];
|
|
78878
|
-
}
|
|
78879
|
-
getStats() {
|
|
78880
|
-
const total = this.todos.length;
|
|
78881
|
-
const completed = this.todos.filter((todo) => todo.status === "completed").length;
|
|
78882
|
-
const inProgress = this.todos.filter((todo) => todo.status === "in-progress").length;
|
|
78883
|
-
return {
|
|
78884
|
-
total,
|
|
78885
|
-
completed,
|
|
78886
|
-
inProgress,
|
|
78887
|
-
notStarted: total - completed - inProgress
|
|
78888
|
-
};
|
|
78889
|
-
}
|
|
78890
|
-
validate(todos) {
|
|
78891
|
-
const errors = [];
|
|
78892
|
-
if (!Array.isArray(todos)) {
|
|
78893
|
-
return { valid: false, errors: ["todoList must be an array"] };
|
|
78894
|
-
}
|
|
78895
|
-
const validStatuses = /* @__PURE__ */ new Set(["not-started", "in-progress", "completed"]);
|
|
78896
|
-
for (let index = 0; index < todos.length; index++) {
|
|
78897
|
-
const item = todos[index];
|
|
78898
|
-
const prefix = `Item ${index + 1}`;
|
|
78899
|
-
if (typeof item?.id !== "number" || !Number.isInteger(item.id) || item.id < 1) {
|
|
78900
|
-
errors.push(`${prefix}: 'id' must be a positive integer`);
|
|
78901
|
-
}
|
|
78902
|
-
if (typeof item?.title !== "string" || item.title.trim().length === 0) {
|
|
78903
|
-
errors.push(`${prefix}: 'title' is required`);
|
|
78904
|
-
}
|
|
78905
|
-
if (typeof item?.description !== "string") {
|
|
78906
|
-
errors.push(`${prefix}: 'description' must be a string`);
|
|
78907
|
-
}
|
|
78908
|
-
if (!validStatuses.has(item?.status)) {
|
|
78909
|
-
errors.push(`${prefix}: 'status' must be one of: not-started, in-progress, completed`);
|
|
78910
|
-
}
|
|
78911
|
-
if (item?.id !== index + 1) {
|
|
78912
|
-
errors.push(`${prefix}: ids must be sequential starting from 1`);
|
|
78913
|
-
}
|
|
78914
|
-
}
|
|
78915
|
-
return { valid: errors.length === 0, errors };
|
|
78916
|
-
}
|
|
78917
|
-
restoreFromMessages(messages) {
|
|
78918
|
-
this.todos = [];
|
|
78919
|
-
for (const message of messages) {
|
|
78920
|
-
if (message.role !== "toolResult" || message.toolName !== "manage_todo_list") {
|
|
78921
|
-
continue;
|
|
78922
|
-
}
|
|
78923
|
-
const details = message.details;
|
|
78924
|
-
if (details?.todos) {
|
|
78925
|
-
this.todos = details.todos.map((todo) => ({ ...todo }));
|
|
78926
|
-
}
|
|
78927
|
-
}
|
|
78928
|
-
}
|
|
78929
|
-
};
|
|
78930
|
-
|
|
78931
|
-
// src/todo/tool.ts
|
|
78932
|
-
init_esm();
|
|
78933
|
-
function stringEnum(values, description) {
|
|
78934
|
-
return Type.Union(values.map((value) => Type.Literal(value)), { description });
|
|
78935
|
-
}
|
|
78936
|
-
var TodoItemSchema = Type.Object({
|
|
78937
|
-
id: Type.Number({ description: "Unique identifier for the todo. Use sequential numbers starting from 1." }),
|
|
78938
|
-
title: Type.String({ description: "Concise action-oriented todo label (3-7 words). Displayed in the UI." }),
|
|
78939
|
-
description: Type.String({
|
|
78940
|
-
description: "Detailed context, requirements, or implementation notes for the todo item."
|
|
78941
|
-
}),
|
|
78942
|
-
status: stringEnum(
|
|
78943
|
-
["not-started", "in-progress", "completed"],
|
|
78944
|
-
"not-started: Not begun | in-progress: Currently working | completed: Fully finished with no blockers"
|
|
78945
|
-
)
|
|
78946
|
-
});
|
|
78947
|
-
var ManageTodoListParams = Type.Object({
|
|
78948
|
-
operation: stringEnum(
|
|
78949
|
-
["write", "read"],
|
|
78950
|
-
"write: Replace entire todo list with new content. read: Retrieve current todo list."
|
|
78951
|
-
),
|
|
78952
|
-
todoList: Type.Optional(
|
|
78953
|
-
Type.Array(TodoItemSchema, {
|
|
78954
|
-
description: "Complete array of all todo items. Required for write. Must include ALL items."
|
|
78955
|
-
})
|
|
78956
|
-
)
|
|
78957
|
-
});
|
|
78958
|
-
var MANAGE_TODO_LIST_DESCRIPTION = `Manage a structured todo list to track progress and plan tasks throughout your coding session.
|
|
78959
|
-
|
|
78960
|
-
Use this tool for complex multi-step work, especially when:
|
|
78961
|
-
- The task needs planning or progress tracking
|
|
78962
|
-
- The user provided multiple requests
|
|
78963
|
-
- You need to break a larger change into actionable steps
|
|
78964
|
-
- You are about to start or finish a tracked step
|
|
78965
|
-
|
|
78966
|
-
Workflow:
|
|
78967
|
-
1. Write the full todo list with clear action items
|
|
78968
|
-
2. Mark the current item as in-progress before starting it
|
|
78969
|
-
3. Complete the work for that item
|
|
78970
|
-
4. Mark it completed immediately
|
|
78971
|
-
5. Continue until all items are done
|
|
78972
|
-
|
|
78973
|
-
Always send the full list on write. Partial updates are not supported.`;
|
|
78974
|
-
function successMessage(todos) {
|
|
78975
|
-
const total = todos.length;
|
|
78976
|
-
const completed = todos.filter((todo) => todo.status === "completed").length;
|
|
78977
|
-
let message = `Todos have been modified successfully. ${completed}/${total} completed. Ensure that you continue to use the todo list to track your progress. Please proceed with the current tasks if applicable.`;
|
|
78978
|
-
if (total < 3) {
|
|
78979
|
-
message += "\n\nWarning: Small todo list (<3 items). This task might not need a todo list.";
|
|
78980
|
-
}
|
|
78981
|
-
return message;
|
|
78982
|
-
}
|
|
78983
|
-
function createManageTodoListTool(state) {
|
|
78984
|
-
return {
|
|
78985
|
-
name: "manage_todo_list",
|
|
78986
|
-
label: "manage_todo_list",
|
|
78987
|
-
description: MANAGE_TODO_LIST_DESCRIPTION,
|
|
78988
|
-
parameters: ManageTodoListParams,
|
|
78989
|
-
execute: async (_toolCallId, params) => {
|
|
78990
|
-
if (params.operation === "read") {
|
|
78991
|
-
const todos2 = state.read();
|
|
78992
|
-
return {
|
|
78993
|
-
content: [
|
|
78994
|
-
{
|
|
78995
|
-
type: "text",
|
|
78996
|
-
text: todos2.length ? JSON.stringify(todos2, null, 2) : "No todos. Use write operation to create a todo list."
|
|
78997
|
-
}
|
|
78998
|
-
],
|
|
78999
|
-
details: { operation: "read", todos: todos2 }
|
|
79000
|
-
};
|
|
79001
|
-
}
|
|
79002
|
-
if (!params.todoList || !Array.isArray(params.todoList)) {
|
|
79003
|
-
return {
|
|
79004
|
-
content: [{ type: "text", text: "Error: todoList is required for write operation." }],
|
|
79005
|
-
details: { operation: "write", todos: state.read(), error: "todoList required" },
|
|
79006
|
-
isError: true
|
|
79007
|
-
};
|
|
79008
|
-
}
|
|
79009
|
-
const todoList = params.todoList;
|
|
79010
|
-
const validation = state.validate(todoList);
|
|
79011
|
-
if (!validation.valid) {
|
|
79012
|
-
return {
|
|
79013
|
-
content: [
|
|
79014
|
-
{
|
|
79015
|
-
type: "text",
|
|
79016
|
-
text: `Validation failed:
|
|
79017
|
-
${validation.errors.map((error) => ` - ${error}`).join("\n")}`
|
|
79018
|
-
}
|
|
79019
|
-
],
|
|
79020
|
-
details: {
|
|
79021
|
-
operation: "write",
|
|
79022
|
-
todos: state.read(),
|
|
79023
|
-
error: validation.errors.join("; ")
|
|
79024
|
-
},
|
|
79025
|
-
isError: true
|
|
79026
|
-
};
|
|
79027
|
-
}
|
|
79028
|
-
state.write(todoList);
|
|
79029
|
-
const todos = state.read();
|
|
79030
|
-
return {
|
|
79031
|
-
content: [{ type: "text", text: successMessage(todos) }],
|
|
79032
|
-
details: { operation: "write", todos }
|
|
79033
|
-
};
|
|
79034
|
-
}
|
|
79035
|
-
};
|
|
79036
|
-
}
|
|
79037
|
-
|
|
79038
79006
|
// src/cli.ts
|
|
79039
79007
|
enableEarlyLogBuffer();
|
|
79040
79008
|
var logError = (msg, err) => {
|
|
@@ -79126,8 +79094,7 @@ async function startChat(initialPrompt, testCommand) {
|
|
|
79126
79094
|
settingsManager.setDefaultModelAndProvider(provider, modelId);
|
|
79127
79095
|
const cwd = process.cwd();
|
|
79128
79096
|
const fsOptions = { allowlistedDirs: [CONFIG_DIR] };
|
|
79129
|
-
const
|
|
79130
|
-
const tools = [...createFileSystemTools(cwd, fsOptions), createBashTool(cwd), createManageTodoListTool(todoState)];
|
|
79097
|
+
const tools = [...createFileSystemTools(cwd, fsOptions), createBashTool(cwd)];
|
|
79131
79098
|
const sessionManager = createSessionManager({ sessionsDir: SESSIONS_DIR });
|
|
79132
79099
|
if (explicitSessionId) {
|
|
79133
79100
|
const loaded = await sessionManager.loadSession(explicitSessionId);
|
|
@@ -79245,7 +79212,6 @@ Current working directory: ${cwd}${skillsSection}`;
|
|
|
79245
79212
|
model,
|
|
79246
79213
|
apiKey,
|
|
79247
79214
|
tools,
|
|
79248
|
-
todoState,
|
|
79249
79215
|
sessionManager,
|
|
79250
79216
|
skills,
|
|
79251
79217
|
cwd,
|