@inetafrica/open-claudia 1.11.0 → 1.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5 -0
- package/bot-agent.js +42 -1
- package/bot.js +44 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v1.12.0
|
|
4
|
+
- Cursor Agent tool progress: Shell, Read, Edit, Write, Grep, Glob calls now show in real-time Telegram updates
|
|
5
|
+
- Plan output surfaced to Telegram: when Cursor creates a plan (`--mode plan`), the full plan markdown and task list are sent to the user
|
|
6
|
+
- Handles all Cursor tool_call event types with fallback for unknown tools
|
|
7
|
+
|
|
3
8
|
## v1.11.0
|
|
4
9
|
- Backend-aware plan mode: /plan passes `--mode plan` to Cursor Agent, `--permission-mode plan` to Claude
|
|
5
10
|
- New /ask command: read-only Q&A mode (Cursor Agent only, `--mode ask`)
|
package/bot-agent.js
CHANGED
|
@@ -845,7 +845,6 @@ async function runClaude(prompt, cwd, replyToMsgId, opts = {}) {
|
|
|
845
845
|
else if (block.type === "tool_use") {
|
|
846
846
|
currentTool = block.name;
|
|
847
847
|
toolUses.push(block.name);
|
|
848
|
-
// Extract useful detail from tool input
|
|
849
848
|
const input = block.input || {};
|
|
850
849
|
if (block.name === "Bash" && input.command) currentToolDetail = input.command.slice(0, 80);
|
|
851
850
|
else if (block.name === "Read" && input.file_path) currentToolDetail = input.file_path.split("/").slice(-2).join("/");
|
|
@@ -857,6 +856,48 @@ async function runClaude(prompt, cwd, replyToMsgId, opts = {}) {
|
|
|
857
856
|
}
|
|
858
857
|
}
|
|
859
858
|
}
|
|
859
|
+
// Cursor Agent tool_call events (different format from Claude's tool_use blocks)
|
|
860
|
+
if (evt.type === "tool_call" && evt.subtype === "started" && evt.tool_call) {
|
|
861
|
+
const tc = evt.tool_call;
|
|
862
|
+
if (tc.shellToolCall) {
|
|
863
|
+
const a = tc.shellToolCall.args || {};
|
|
864
|
+
currentTool = "Shell"; toolUses.push("Shell");
|
|
865
|
+
currentToolDetail = (a.description || a.command || "").slice(0, 80);
|
|
866
|
+
} else if (tc.readToolCall) {
|
|
867
|
+
currentTool = "Read"; toolUses.push("Read");
|
|
868
|
+
currentToolDetail = (tc.readToolCall.args?.path || "").split("/").slice(-2).join("/");
|
|
869
|
+
} else if (tc.editToolCall) {
|
|
870
|
+
currentTool = "Edit"; toolUses.push("Edit");
|
|
871
|
+
currentToolDetail = (tc.editToolCall.args?.filePath || "").split("/").slice(-2).join("/");
|
|
872
|
+
} else if (tc.writeToolCall) {
|
|
873
|
+
currentTool = "Write"; toolUses.push("Write");
|
|
874
|
+
currentToolDetail = (tc.writeToolCall.args?.filePath || "").split("/").slice(-2).join("/");
|
|
875
|
+
} else if (tc.grepToolCall) {
|
|
876
|
+
currentTool = "Grep"; toolUses.push("Grep");
|
|
877
|
+
currentToolDetail = (tc.grepToolCall.args?.pattern || "").slice(0, 40);
|
|
878
|
+
} else if (tc.globToolCall) {
|
|
879
|
+
currentTool = "Glob"; toolUses.push("Glob");
|
|
880
|
+
currentToolDetail = (tc.globToolCall.args?.globPattern || "").slice(0, 40);
|
|
881
|
+
} else if (tc.createPlanToolCall) {
|
|
882
|
+
currentTool = "Plan"; toolUses.push("Plan");
|
|
883
|
+
const plan = tc.createPlanToolCall.args || {};
|
|
884
|
+
let planText = "";
|
|
885
|
+
if (plan.name) planText += `**${plan.name}**\n\n`;
|
|
886
|
+
if (plan.plan) planText += plan.plan + "\n";
|
|
887
|
+
if (plan.todos && plan.todos.length) {
|
|
888
|
+
planText += "\n**Tasks:**\n";
|
|
889
|
+
for (const todo of plan.todos) {
|
|
890
|
+
planText += `• ${todo.content || todo.id}\n`;
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
if (planText) assistantText = planText;
|
|
894
|
+
currentToolDetail = plan.name || "creating plan";
|
|
895
|
+
} else {
|
|
896
|
+
const toolKey = Object.keys(tc)[0] || "unknown";
|
|
897
|
+
currentTool = toolKey.replace("ToolCall", ""); toolUses.push(currentTool);
|
|
898
|
+
currentToolDetail = "";
|
|
899
|
+
}
|
|
900
|
+
}
|
|
860
901
|
if (evt.type === "result" && evt.session_id) {
|
|
861
902
|
if (settings.backend === "cursor") { cursorSessionId = evt.session_id; }
|
|
862
903
|
else { lastSessionId = evt.session_id; }
|
package/bot.js
CHANGED
|
@@ -861,7 +861,6 @@ async function runClaude(prompt, cwd, replyToMsgId, opts = {}) {
|
|
|
861
861
|
else if (block.type === "tool_use") {
|
|
862
862
|
currentTool = block.name;
|
|
863
863
|
toolUses.push(block.name);
|
|
864
|
-
// Extract useful detail from tool input
|
|
865
864
|
const input = block.input || {};
|
|
866
865
|
if (block.name === "Bash" && input.command) currentToolDetail = input.command.slice(0, 80);
|
|
867
866
|
else if (block.name === "Read" && input.file_path) currentToolDetail = input.file_path.split("/").slice(-2).join("/");
|
|
@@ -873,6 +872,48 @@ async function runClaude(prompt, cwd, replyToMsgId, opts = {}) {
|
|
|
873
872
|
}
|
|
874
873
|
}
|
|
875
874
|
}
|
|
875
|
+
// Cursor Agent tool_call events (different format from Claude's tool_use blocks)
|
|
876
|
+
if (evt.type === "tool_call" && evt.subtype === "started" && evt.tool_call) {
|
|
877
|
+
const tc = evt.tool_call;
|
|
878
|
+
if (tc.shellToolCall) {
|
|
879
|
+
const a = tc.shellToolCall.args || {};
|
|
880
|
+
currentTool = "Shell"; toolUses.push("Shell");
|
|
881
|
+
currentToolDetail = (a.description || a.command || "").slice(0, 80);
|
|
882
|
+
} else if (tc.readToolCall) {
|
|
883
|
+
currentTool = "Read"; toolUses.push("Read");
|
|
884
|
+
currentToolDetail = (tc.readToolCall.args?.path || "").split("/").slice(-2).join("/");
|
|
885
|
+
} else if (tc.editToolCall) {
|
|
886
|
+
currentTool = "Edit"; toolUses.push("Edit");
|
|
887
|
+
currentToolDetail = (tc.editToolCall.args?.filePath || "").split("/").slice(-2).join("/");
|
|
888
|
+
} else if (tc.writeToolCall) {
|
|
889
|
+
currentTool = "Write"; toolUses.push("Write");
|
|
890
|
+
currentToolDetail = (tc.writeToolCall.args?.filePath || "").split("/").slice(-2).join("/");
|
|
891
|
+
} else if (tc.grepToolCall) {
|
|
892
|
+
currentTool = "Grep"; toolUses.push("Grep");
|
|
893
|
+
currentToolDetail = (tc.grepToolCall.args?.pattern || "").slice(0, 40);
|
|
894
|
+
} else if (tc.globToolCall) {
|
|
895
|
+
currentTool = "Glob"; toolUses.push("Glob");
|
|
896
|
+
currentToolDetail = (tc.globToolCall.args?.globPattern || "").slice(0, 40);
|
|
897
|
+
} else if (tc.createPlanToolCall) {
|
|
898
|
+
currentTool = "Plan"; toolUses.push("Plan");
|
|
899
|
+
const plan = tc.createPlanToolCall.args || {};
|
|
900
|
+
let planText = "";
|
|
901
|
+
if (plan.name) planText += `**${plan.name}**\n\n`;
|
|
902
|
+
if (plan.plan) planText += plan.plan + "\n";
|
|
903
|
+
if (plan.todos && plan.todos.length) {
|
|
904
|
+
planText += "\n**Tasks:**\n";
|
|
905
|
+
for (const todo of plan.todos) {
|
|
906
|
+
planText += `• ${todo.content || todo.id}\n`;
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
if (planText) assistantText = planText;
|
|
910
|
+
currentToolDetail = plan.name || "creating plan";
|
|
911
|
+
} else {
|
|
912
|
+
const toolKey = Object.keys(tc)[0] || "unknown";
|
|
913
|
+
currentTool = toolKey.replace("ToolCall", ""); toolUses.push(currentTool);
|
|
914
|
+
currentToolDetail = "";
|
|
915
|
+
}
|
|
916
|
+
}
|
|
876
917
|
if (evt.type === "result" && evt.session_id) {
|
|
877
918
|
if (settings.backend === "cursor") { cursorSessionId = evt.session_id; }
|
|
878
919
|
else { lastSessionId = evt.session_id; }
|
|
@@ -1204,7 +1245,8 @@ bot.onText(/\/plan$/, (msg) => {
|
|
|
1204
1245
|
const p = settings.permissionMode === "plan";
|
|
1205
1246
|
settings.permissionMode = p ? null : "plan";
|
|
1206
1247
|
const label = settings.backend === "cursor" ? "read-only planning, no edits" : "plan permission mode";
|
|
1207
|
-
|
|
1248
|
+
if (p) cursorSessionId = null; // reset session so next message doesn't resume plan-mode session
|
|
1249
|
+
send(p ? "Plan mode off (session reset)." : `Plan mode on (${label}).`);
|
|
1208
1250
|
});
|
|
1209
1251
|
bot.onText(/\/ask$/, (msg) => {
|
|
1210
1252
|
if (!isAuthorized(msg)) return;
|