@co0ontty/wand 1.2.2 → 1.3.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.
@@ -431,8 +431,23 @@ export class ClaudePtyBridge extends EventEmitter {
431
431
  }
432
432
  }
433
433
  isPermissionPromptDetected(normalized) {
434
- return hasPermissionActionContext(normalized)
435
- && (hasExplicitConfirmSyntax(normalized) || /\bdo you want to\b/i.test(normalized) || /\bwould you like to\b/i.test(normalized));
434
+ const hasIntent = /\bdo you want to\b/i.test(normalized)
435
+ || /\bwould you like to\b/i.test(normalized)
436
+ || /\benter to confirm\b/i.test(normalized)
437
+ || /\bgrant\b.*\bpermission\b/i.test(normalized)
438
+ || /\bhaven't granted\b/i.test(normalized);
439
+ const hasConfirmSyntax = hasExplicitConfirmSyntax(normalized);
440
+ const hasActionCtx = hasPermissionActionContext(normalized);
441
+ // Intent phrase + explicit confirm syntax (e.g. "Do you want to proceed? (yes/no)")
442
+ if (hasIntent && hasConfirmSyntax)
443
+ return true;
444
+ // Intent phrase + action keyword (e.g. "Do you want to execute this command?")
445
+ if (hasIntent && hasActionCtx)
446
+ return true;
447
+ // Standalone confirm syntax + action keyword (e.g. "[y/n] Allow bash command")
448
+ if (hasConfirmSyntax && hasActionCtx)
449
+ return true;
450
+ return false;
436
451
  }
437
452
  extractPromptText(normalized) {
438
453
  // Return a snippet around the permission prompt
@@ -1,6 +1,6 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import { EventEmitter } from "node:events";
3
- import { existsSync, unlinkSync, openSync, readSync, closeSync, readFileSync, readdirSync, statSync } from "node:fs";
3
+ import { existsSync, unlinkSync, rmSync, openSync, readSync, closeSync, readFileSync, readdirSync, statSync } from "node:fs";
4
4
  import path from "node:path";
5
5
  import process from "node:process";
6
6
  import os from "node:os";
@@ -957,6 +957,7 @@ export class ProcessManager extends EventEmitter {
957
957
  }
958
958
  deleteClaudeHistoryFiles(sessions) {
959
959
  let deleted = 0;
960
+ const claudeHome = path.join(os.homedir(), ".claude");
960
961
  for (const { claudeSessionId, cwd } of sessions) {
961
962
  if (!UUID_V4_PATTERN.test(claudeSessionId))
962
963
  continue;
@@ -968,6 +969,17 @@ export class ProcessManager extends EventEmitter {
968
969
  catch {
969
970
  // Best-effort — file may already be gone
970
971
  }
972
+ // Clean up related directories under ~/.claude/
973
+ for (const sub of ["session-env", "tasks", "todos"]) {
974
+ const dir = path.join(claudeHome, sub, claudeSessionId);
975
+ try {
976
+ if (existsSync(dir))
977
+ rmSync(dir, { recursive: true, force: true });
978
+ }
979
+ catch {
980
+ // Non-critical — best-effort
981
+ }
982
+ }
971
983
  }
972
984
  if (sessions.length > 0) {
973
985
  this.claudeHistoryCache = null;
@@ -1179,14 +1191,27 @@ export class ProcessManager extends EventEmitter {
1179
1191
  deleteClaudeCache(record) {
1180
1192
  if (!record.claudeSessionId)
1181
1193
  return;
1182
- const jsonlPath = path.join(getClaudeProjectDir(record.cwd), `${record.claudeSessionId}.jsonl`);
1194
+ const id = record.claudeSessionId;
1195
+ // 1. Delete the project JSONL file
1196
+ const jsonlPath = path.join(getClaudeProjectDir(record.cwd), `${id}.jsonl`);
1183
1197
  try {
1184
- if (existsSync(jsonlPath)) {
1198
+ if (existsSync(jsonlPath))
1185
1199
  unlinkSync(jsonlPath);
1186
- }
1187
1200
  }
1188
1201
  catch {
1189
- // Non-critical — Claude cache cleanup is best-effort
1202
+ // Non-critical — best-effort
1203
+ }
1204
+ // 2. Delete related directories under ~/.claude/
1205
+ const claudeHome = path.join(os.homedir(), ".claude");
1206
+ for (const sub of ["session-env", "tasks", "todos"]) {
1207
+ const dir = path.join(claudeHome, sub, id);
1208
+ try {
1209
+ if (existsSync(dir))
1210
+ rmSync(dir, { recursive: true, force: true });
1211
+ }
1212
+ catch {
1213
+ // Non-critical — best-effort
1214
+ }
1190
1215
  }
1191
1216
  }
1192
1217
  runStartupCommands() {
@@ -1445,12 +1470,10 @@ export class ProcessManager extends EventEmitter {
1445
1470
  const trustFolderPrompt = /\byes,\s*i\s*trust\s*this\s*folder\b/i.test(normalized) &&
1446
1471
  /\benter to confirm\b/i.test(normalized);
1447
1472
  const claudeConfirmPrompt = /\bdo you want to\b/i.test(normalized) &&
1448
- hasExplicitConfirmSyntax(normalized) &&
1449
- hasPermissionActionContext(normalized);
1473
+ (hasExplicitConfirmSyntax(normalized) || hasPermissionActionContext(normalized));
1450
1474
  // Check for Claude's tool permission prompt patterns
1451
1475
  const toolPermissionPrompt = /\bdo you want to\b/i.test(normalized) &&
1452
- /\(yes\b/i.test(normalized) &&
1453
- hasPermissionActionContext(normalized);
1476
+ /\(yes\b/i.test(normalized);
1454
1477
  // Reduced cooldown for faster response
1455
1478
  if (now - record.lastAutoConfirmAt < 500) {
1456
1479
  return;
@@ -94,8 +94,8 @@
94
94
  modalOpen: false,
95
95
  presetValue: "",
96
96
  cwdValue: "",
97
- modeValue: "full-access",
98
- chatMode: "full-access",
97
+ modeValue: "managed",
98
+ chatMode: "managed",
99
99
  sessionTool: "claude",
100
100
  preferredCommand: "claude",
101
101
  lastResize: { cols: 0, rows: 0 },
@@ -1659,11 +1659,11 @@
1659
1659
  }
1660
1660
  function renderModeCards(selectedMode) {
1661
1661
  var modes = [
1662
- { id: "default", label: "标准", desc: "逐步确认操作" },
1662
+ { id: "managed", label: "托管", desc: "全自动完成任务" },
1663
1663
  { id: "full-access", label: "全权限", desc: "自动确认权限" },
1664
1664
  { id: "auto-edit", label: "自动编辑", desc: "自动确认修改" },
1665
- { id: "native", label: "原生", desc: "结构化单轮输出" },
1666
- { id: "managed", label: "托管", desc: "全自动完成任务" }
1665
+ { id: "default", label: "标准", desc: "逐步确认操作" },
1666
+ { id: "native", label: "原生", desc: "结构化单轮输出" }
1667
1667
  ];
1668
1668
  return modes.map(function(m) {
1669
1669
  var active = m.id === selectedMode ? " active" : "";
@@ -4585,7 +4585,7 @@
4585
4585
  welcomeInput.value = "";
4586
4586
  welcomeInput.placeholder = "正在启动会话...";
4587
4587
  welcomeInput.disabled = true;
4588
- var mode = state.chatMode || "full-access";
4588
+ var mode = state.chatMode || "managed";
4589
4589
  var defaultCwd = getEffectiveCwd();
4590
4590
  var preferredTool = getPreferredTool();
4591
4591
  fetch("/api/commands", {
@@ -4645,7 +4645,7 @@
4645
4645
  }
4646
4646
 
4647
4647
  // No selected session, create a new one
4648
- var mode = state.chatMode || "full-access";
4648
+ var mode = state.chatMode || "managed";
4649
4649
  var defaultCwd = getEffectiveCwd();
4650
4650
  var preferredTool = getPreferredTool();
4651
4651
  fetch("/api/commands", {
@@ -5592,7 +5592,7 @@
5592
5592
  if (!welcomeInput) return;
5593
5593
  welcomeInput.placeholder = "Claude 正在思考,请稍候...";
5594
5594
  welcomeInput.disabled = true;
5595
- var mode = state.chatMode || "full-access";
5595
+ var mode = state.chatMode || "managed";
5596
5596
  var defaultCwd = getEffectiveCwd();
5597
5597
  var preferredTool = getPreferredTool();
5598
5598
  fetch("/api/commands", {
@@ -5628,7 +5628,7 @@
5628
5628
  }
5629
5629
 
5630
5630
  function createSessionFromInput(value, inputBox, welcomeInput) {
5631
- var mode = state.chatMode || "full-access";
5631
+ var mode = state.chatMode || "managed";
5632
5632
  var defaultCwd = getEffectiveCwd();
5633
5633
  var preferredTool = getPreferredTool();
5634
5634
  fetch("/api/commands", {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@co0ontty/wand",
3
- "version": "1.2.2",
3
+ "version": "1.3.0",
4
4
  "description": "A web terminal for local CLI tools like Claude.",
5
5
  "type": "module",
6
6
  "bin": {