@inetafrica/open-claudia 1.10.1 → 1.11.0

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 CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## v1.11.0
4
+ - Backend-aware plan mode: /plan passes `--mode plan` to Cursor Agent, `--permission-mode plan` to Claude
5
+ - New /ask command: read-only Q&A mode (Cursor Agent only, `--mode ask`)
6
+ - /effort and /budget now warn when on Cursor backend (unsupported flags)
7
+ - Worktree flag (`--worktree`) wired into Cursor Agent args
8
+ - buildCursorArgs now forwards plan/ask/worktree settings
9
+
3
10
  ## v1.10.0
4
11
  - Cursor Agent backend: switch between Claude Code and Cursor Agent CLI
5
12
  - New commands: /cursor, /claude, /backend with inline keyboard
package/README.md CHANGED
@@ -126,7 +126,8 @@ When you select a project, the last conversation is automatically resumed. Tap "
126
126
  | `/model` | Switch model (opus / sonnet / haiku for Claude; any model flag for Cursor) |
127
127
  | `/effort` | Set effort level (low / medium / high / max) |
128
128
  | `/budget` | Set max spend for next task (e.g. `/budget 0.50`) — Claude only |
129
- | `/plan` | Toggle plan mode — Claude only |
129
+ | `/plan` | Toggle plan mode — `--permission-mode plan` (Claude) / `--mode plan` (Cursor) |
130
+ | `/ask` | Toggle ask mode — read-only Q&A, no edits (Cursor Agent only) |
130
131
  | `/compact` | Summarize conversation context |
131
132
  | `/worktree` | Toggle isolated git branch — Claude only |
132
133
  | `/mode` | Switch between direct and agent bot modes |
@@ -158,9 +159,10 @@ When you select a project, the last conversation is automatically resumed. Tap "
158
159
  | Session flag | `--resume <id>` | `--resume <id>` |
159
160
  | Auth | `claude auth` | `agent login` |
160
161
  | Plan mode | Yes (`--permission-mode plan`) | Yes (`--mode plan`) |
162
+ | Ask mode | No | Yes (`--mode ask`) |
161
163
  | Budget control | Yes (`--max-budget-usd`) | No |
162
164
  | Effort levels | Yes | No |
163
- | Worktree | Yes | No |
165
+ | Worktree | Yes (`--worktree`) | Yes (`--worktree`) |
164
166
  | Model switching | Yes | Yes |
165
167
  | Dangerously skip permissions | Yes | Yes (`--trust`) |
166
168
 
package/bot-agent.js CHANGED
@@ -178,6 +178,7 @@ bot.setMyCommands([
178
178
  { command: "effort", description: "Set effort level" },
179
179
  { command: "budget", description: "Set max spend for next task" },
180
180
  { command: "plan", description: "Toggle plan mode" },
181
+ { command: "ask", description: "Toggle ask mode (Cursor only)" },
181
182
  { command: "sessions", description: "List conversations for this project" },
182
183
  { command: "compact", description: "Summarize conversation context" },
183
184
  { command: "continue", description: "Resume last conversation" },
@@ -696,6 +697,9 @@ function buildCursorArgs(prompt, opts = {}) {
696
697
  if (opts.continueSession) args.push("--continue");
697
698
  else if (cursorSessionId && !opts.fresh) args.push("--resume", cursorSessionId);
698
699
  if (settings.model) args.push("--model", settings.model);
700
+ if (settings.permissionMode === "plan") args.push("--mode", "plan");
701
+ else if (settings.permissionMode === "ask") args.push("--mode", "ask");
702
+ if (settings.worktree) args.push("--worktree");
699
703
  args.push(prompt);
700
704
  return args;
701
705
  }
@@ -1126,23 +1130,46 @@ bot.onText(/\/model (.+)/, (msg, match) => { if (!isAuthorized(msg)) return; set
1126
1130
 
1127
1131
  bot.onText(/\/effort$/, (msg) => {
1128
1132
  if (!isAuthorized(msg)) return;
1133
+ if (settings.backend === "cursor") return send("Effort levels are not supported on Cursor Agent.\nSwitch to Claude with /claude to use this.");
1129
1134
  send(`Effort: ${settings.effort || "default"}`, { keyboard: { inline_keyboard: [
1130
1135
  [{ text: "Low", callback_data: "e:low" }, { text: "Med", callback_data: "e:medium" }, { text: "High", callback_data: "e:high" }, { text: "Max", callback_data: "e:max" }],
1131
1136
  [{ text: "Default", callback_data: "e:default" }],
1132
1137
  ] } });
1133
1138
  });
1134
- bot.onText(/\/effort (.+)/, (msg, match) => { if (!isAuthorized(msg)) return; const e = match[1].trim().toLowerCase(); settings.effort = ["low","medium","high","max"].includes(e) ? e : null; send(`Effort: ${settings.effort || "default"}`); });
1139
+ bot.onText(/\/effort (.+)/, (msg, match) => {
1140
+ if (!isAuthorized(msg)) return;
1141
+ if (settings.backend === "cursor") return send("Effort levels are not supported on Cursor Agent.");
1142
+ const e = match[1].trim().toLowerCase(); settings.effort = ["low","medium","high","max"].includes(e) ? e : null; send(`Effort: ${settings.effort || "default"}`);
1143
+ });
1135
1144
 
1136
1145
  bot.onText(/\/budget$/, (msg) => {
1137
1146
  if (!isAuthorized(msg)) return;
1147
+ if (settings.backend === "cursor") return send("Budget limits are not supported on Cursor Agent.\nSwitch to Claude with /claude to use this.");
1138
1148
  send(`Budget: ${settings.budget ? "$" + settings.budget : "none"}`, { keyboard: { inline_keyboard: [
1139
1149
  [{ text: "$1", callback_data: "b:1" }, { text: "$5", callback_data: "b:5" }, { text: "$10", callback_data: "b:10" }, { text: "$25", callback_data: "b:25" }],
1140
1150
  [{ text: "No limit", callback_data: "b:none" }],
1141
1151
  ] } });
1142
1152
  });
1143
- bot.onText(/\/budget (.+)/, (msg, match) => { if (!isAuthorized(msg)) return; const v = parseFloat(match[1].replace("$","")); settings.budget = v > 0 ? v : null; send(`Budget: ${settings.budget ? "$"+settings.budget : "none"}`); });
1153
+ bot.onText(/\/budget (.+)/, (msg, match) => {
1154
+ if (!isAuthorized(msg)) return;
1155
+ if (settings.backend === "cursor") return send("Budget limits are not supported on Cursor Agent.");
1156
+ const v = parseFloat(match[1].replace("$","")); settings.budget = v > 0 ? v : null; send(`Budget: ${settings.budget ? "$"+settings.budget : "none"}`);
1157
+ });
1144
1158
 
1145
- bot.onText(/\/plan$/, (msg) => { if (!isAuthorized(msg)) return; const p = settings.permissionMode === "plan"; settings.permissionMode = p ? null : "plan"; send(p ? "Plan mode off." : "Plan mode on."); });
1159
+ bot.onText(/\/plan$/, (msg) => {
1160
+ if (!isAuthorized(msg)) return;
1161
+ const p = settings.permissionMode === "plan";
1162
+ settings.permissionMode = p ? null : "plan";
1163
+ const label = settings.backend === "cursor" ? "read-only planning, no edits" : "plan permission mode";
1164
+ send(p ? "Plan mode off." : `Plan mode on (${label}).`);
1165
+ });
1166
+ bot.onText(/\/ask$/, (msg) => {
1167
+ if (!isAuthorized(msg)) return;
1168
+ if (settings.backend !== "cursor") return send("Ask mode is only available on Cursor Agent.\nUse /cursor to switch.");
1169
+ const a = settings.permissionMode === "ask";
1170
+ settings.permissionMode = a ? null : "ask";
1171
+ send(a ? "Ask mode off." : "Ask mode on (read-only Q&A, no edits).");
1172
+ });
1146
1173
  bot.onText(/\/compact/, async (msg) => { if (!isAuthorized(msg)) return; if (!requireSession(msg)) return; if (!getActiveSessionId()) return send("No conversation."); await runClaude("Summarize: key decisions, code state, next steps.", currentSession.dir, msg.message_id); });
1147
1174
  bot.onText(/\/continue$/, async (msg) => { if (!isAuthorized(msg)) return; if (!requireSession(msg)) return; await runClaude("continue where we left off", currentSession.dir, msg.message_id, { continueSession: true }); });
1148
1175
  bot.onText(/\/worktree$/, (msg) => { if (!isAuthorized(msg)) return; settings.worktree = !settings.worktree; send(settings.worktree ? "Worktree on." : "Worktree off."); });
package/bot.js CHANGED
@@ -236,6 +236,7 @@ bot.setMyCommands([
236
236
  { command: "effort", description: "Set effort level" },
237
237
  { command: "budget", description: "Set max spend for next task" },
238
238
  { command: "plan", description: "Toggle plan mode" },
239
+ { command: "ask", description: "Toggle ask mode (Cursor only)" },
239
240
  { command: "sessions", description: "List conversations for this project" },
240
241
  { command: "compact", description: "Summarize conversation context" },
241
242
  { command: "continue", description: "Resume last conversation" },
@@ -757,6 +758,9 @@ function buildCursorArgs(prompt, opts = {}) {
757
758
  if (opts.continueSession) args.push("--continue");
758
759
  else if (cursorSessionId && !opts.fresh) args.push("--resume", cursorSessionId);
759
760
  if (settings.model) args.push("--model", settings.model);
761
+ if (settings.permissionMode === "plan") args.push("--mode", "plan");
762
+ else if (settings.permissionMode === "ask") args.push("--mode", "ask");
763
+ if (settings.worktree) args.push("--worktree");
760
764
  args.push(prompt);
761
765
  return args;
762
766
  }
@@ -1169,23 +1173,46 @@ bot.onText(/\/model (.+)/, (msg, match) => { if (!isAuthorized(msg)) return; set
1169
1173
 
1170
1174
  bot.onText(/\/effort$/, (msg) => {
1171
1175
  if (!isAuthorized(msg)) return;
1176
+ if (settings.backend === "cursor") return send("Effort levels are not supported on Cursor Agent.\nSwitch to Claude with /claude to use this.");
1172
1177
  send(`Effort: ${settings.effort || "default"}`, { keyboard: { inline_keyboard: [
1173
1178
  [{ text: "Low", callback_data: "e:low" }, { text: "Med", callback_data: "e:medium" }, { text: "High", callback_data: "e:high" }, { text: "Max", callback_data: "e:max" }],
1174
1179
  [{ text: "Default", callback_data: "e:default" }],
1175
1180
  ] } });
1176
1181
  });
1177
- bot.onText(/\/effort (.+)/, (msg, match) => { if (!isAuthorized(msg)) return; const e = match[1].trim().toLowerCase(); settings.effort = ["low","medium","high","max"].includes(e) ? e : null; send(`Effort: ${settings.effort || "default"}`); });
1182
+ bot.onText(/\/effort (.+)/, (msg, match) => {
1183
+ if (!isAuthorized(msg)) return;
1184
+ if (settings.backend === "cursor") return send("Effort levels are not supported on Cursor Agent.");
1185
+ const e = match[1].trim().toLowerCase(); settings.effort = ["low","medium","high","max"].includes(e) ? e : null; send(`Effort: ${settings.effort || "default"}`);
1186
+ });
1178
1187
 
1179
1188
  bot.onText(/\/budget$/, (msg) => {
1180
1189
  if (!isAuthorized(msg)) return;
1190
+ if (settings.backend === "cursor") return send("Budget limits are not supported on Cursor Agent.\nSwitch to Claude with /claude to use this.");
1181
1191
  send(`Budget: ${settings.budget ? "$" + settings.budget : "none"}`, { keyboard: { inline_keyboard: [
1182
1192
  [{ text: "$1", callback_data: "b:1" }, { text: "$5", callback_data: "b:5" }, { text: "$10", callback_data: "b:10" }, { text: "$25", callback_data: "b:25" }],
1183
1193
  [{ text: "No limit", callback_data: "b:none" }],
1184
1194
  ] } });
1185
1195
  });
1186
- bot.onText(/\/budget (.+)/, (msg, match) => { if (!isAuthorized(msg)) return; const v = parseFloat(match[1].replace("$","")); settings.budget = v > 0 ? v : null; send(`Budget: ${settings.budget ? "$"+settings.budget : "none"}`); });
1196
+ bot.onText(/\/budget (.+)/, (msg, match) => {
1197
+ if (!isAuthorized(msg)) return;
1198
+ if (settings.backend === "cursor") return send("Budget limits are not supported on Cursor Agent.");
1199
+ const v = parseFloat(match[1].replace("$","")); settings.budget = v > 0 ? v : null; send(`Budget: ${settings.budget ? "$"+settings.budget : "none"}`);
1200
+ });
1187
1201
 
1188
- bot.onText(/\/plan$/, (msg) => { if (!isAuthorized(msg)) return; const p = settings.permissionMode === "plan"; settings.permissionMode = p ? null : "plan"; send(p ? "Plan mode off." : "Plan mode on."); });
1202
+ bot.onText(/\/plan$/, (msg) => {
1203
+ if (!isAuthorized(msg)) return;
1204
+ const p = settings.permissionMode === "plan";
1205
+ settings.permissionMode = p ? null : "plan";
1206
+ const label = settings.backend === "cursor" ? "read-only planning, no edits" : "plan permission mode";
1207
+ send(p ? "Plan mode off." : `Plan mode on (${label}).`);
1208
+ });
1209
+ bot.onText(/\/ask$/, (msg) => {
1210
+ if (!isAuthorized(msg)) return;
1211
+ if (settings.backend !== "cursor") return send("Ask mode is only available on Cursor Agent.\nUse /cursor to switch.");
1212
+ const a = settings.permissionMode === "ask";
1213
+ settings.permissionMode = a ? null : "ask";
1214
+ send(a ? "Ask mode off." : "Ask mode on (read-only Q&A, no edits).");
1215
+ });
1189
1216
  bot.onText(/\/compact/, async (msg) => { if (!isAuthorized(msg)) return; if (!requireSession(msg)) return; if (!getActiveSessionId()) return send("No conversation."); await runClaude("Summarize: key decisions, code state, next steps.", currentSession.dir, msg.message_id); });
1190
1217
  bot.onText(/\/continue$/, async (msg) => { if (!isAuthorized(msg)) return; if (!requireSession(msg)) return; await runClaude("continue where we left off", currentSession.dir, msg.message_id, { continueSession: true }); });
1191
1218
  bot.onText(/\/worktree$/, (msg) => { if (!isAuthorized(msg)) return; settings.worktree = !settings.worktree; send(settings.worktree ? "Worktree on." : "Worktree off."); });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inetafrica/open-claudia",
3
- "version": "1.10.1",
3
+ "version": "1.11.0",
4
4
  "description": "Your always-on AI coding assistant — Claude Code via Telegram",
5
5
  "main": "bot.js",
6
6
  "bin": {