@oneciel-ai/claude-any 0.1.78 → 0.1.80

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 (2) hide show
  1. package/claude_any.py +52 -7
  2. package/package.json +1 -1
package/claude_any.py CHANGED
@@ -104,7 +104,7 @@ OFFICIAL_CHANNEL_PLUGINS = {
104
104
  "fakechat": "plugin:fakechat@claude-plugins-official",
105
105
  }
106
106
  APP_NAME = "Claude Any"
107
- VERSION = "0.1.78"
107
+ VERSION = "0.1.80"
108
108
  CREDITS = "Credits: One Ciel LLC"
109
109
 
110
110
  LOG_LEVELS = {"SILENT": 0, "ERROR": 1, "WARN": 2, "INFO": 3, "DEBUG": 4, "TRACE": 5}
@@ -9106,8 +9106,8 @@ def _mcp_server_is_stdio(server: dict[str, Any]) -> bool:
9106
9106
  command = str(server.get("command") or "").strip()
9107
9107
  if not command:
9108
9108
  return False
9109
- joined = " ".join([command, *[str(item) for item in server.get("args", []) if item is not None]])
9110
- return "mcp-proxy" not in joined
9109
+ args = [str(item) for item in server.get("args", []) if item is not None] if isinstance(server.get("args", []), list) else []
9110
+ return "mcp-proxy" not in args
9111
9111
 
9112
9112
 
9113
9113
  def _mcp_config_passthrough_values(passthrough: list[str]) -> list[str]:
@@ -13620,6 +13620,39 @@ def format_channel_wake_prompt(message: dict[str, Any]) -> str:
13620
13620
  )
13621
13621
 
13622
13622
 
13623
+ def _channel_wake_message_is_noise(message: dict[str, Any]) -> bool:
13624
+ body = re.sub(r"\s+", " ", str(message.get("message") or "")).strip().lower()
13625
+ kind = str(message.get("kind") or "").strip().lower()
13626
+ if not body:
13627
+ return True
13628
+ if kind in {"connection", "connected", "heartbeat", "keepalive"}:
13629
+ return True
13630
+ return bool(re.fullmatch(r"[a-z0-9_.:-]{1,80}\.(ws|sse)\.connected", body))
13631
+
13632
+
13633
+ def format_channel_wake_batch_prompt(messages: list[dict[str, Any]]) -> str:
13634
+ if len(messages) == 1:
13635
+ return format_channel_wake_prompt(messages[0])
13636
+ parts: list[str] = []
13637
+ for message in messages:
13638
+ channel = str(message.get("channel") or "default")
13639
+ sender = str(message.get("sender_id") or "channel")
13640
+ mid = str(message.get("id") or "")
13641
+ meta = message.get("meta") if isinstance(message.get("meta"), dict) else {}
13642
+ room = str(meta.get("room_id") or meta.get("room") or channel)
13643
+ thread = str(message.get("thread_id") or meta.get("thread_id") or "")
13644
+ body = re.sub(r"\s+", " ", str(message.get("message") or "")).strip()
13645
+ fields = [f"id={mid}", f"room={room}", f"from={sender}"]
13646
+ if thread:
13647
+ fields.append(f"thread={thread}")
13648
+ parts.append("(" + " ".join(fields) + ") " + json.dumps(body, ensure_ascii=False))
13649
+ return (
13650
+ f"[claude-any external channel messages] {len(messages)} new messages: "
13651
+ + " ; ".join(parts)
13652
+ + ". If relevant to current work, respond or act now; otherwise keep working."
13653
+ )
13654
+
13655
+
13623
13656
  def _write_fd_all(fd: int, data: bytes) -> None:
13624
13657
  view = memoryview(data)
13625
13658
  while view:
@@ -13629,18 +13662,27 @@ def _write_fd_all(fd: int, data: bytes) -> None:
13629
13662
 
13630
13663
  def _channel_wake_input_bytes(prompt: str) -> bytes:
13631
13664
  # Ctrl-U clears any stale line editor text before submitting the synthetic prompt.
13632
- return b"\x15" + prompt.encode("utf-8", errors="replace") + b"\n"
13665
+ # Claude Code's interactive input is terminal-driven; send carriage return,
13666
+ # the same byte a TTY normally delivers for Enter in raw mode.
13667
+ return b"\x15" + prompt.encode("utf-8", errors="replace") + b"\r"
13633
13668
 
13634
13669
 
13635
13670
  def _inject_pending_channel_messages(master_fd: int, last_id: int) -> int:
13671
+ pending: list[dict[str, Any]] = []
13636
13672
  for message in read_chat_messages(last_id, None, None, 100):
13637
13673
  try:
13638
13674
  last_id = max(last_id, int(message.get("id") or 0))
13639
13675
  except Exception:
13640
13676
  continue
13641
- prompt = format_channel_wake_prompt(message)
13677
+ if _channel_wake_message_is_noise(message):
13678
+ continue
13679
+ pending.append(message)
13680
+ if pending:
13681
+ prompt = format_channel_wake_batch_prompt(pending)
13642
13682
  _write_fd_all(master_fd, _channel_wake_input_bytes(prompt))
13643
- router_log("INFO", f"channel_stdin_proxy_injected message_id={message.get('id')} channel={message.get('channel')}")
13683
+ ids = ",".join(str(message.get("id") or "") for message in pending)
13684
+ channels = ",".join(sorted({str(message.get("channel") or "default") for message in pending}))
13685
+ router_log("INFO", f"channel_stdin_proxy_injected count={len(pending)} message_ids={ids} channels={channels}")
13644
13686
  return last_id
13645
13687
 
13646
13688
 
@@ -13897,8 +13939,9 @@ class _McpStdoutObserver:
13897
13939
 
13898
13940
  def _mcp_proxy_forward_stdin(proc: subprocess.Popen[bytes]) -> None:
13899
13941
  try:
13942
+ stdin_fd = sys.stdin.fileno()
13900
13943
  while True:
13901
- chunk = sys.stdin.buffer.read(65536)
13944
+ chunk = os.read(stdin_fd, 65536)
13902
13945
  if not chunk:
13903
13946
  break
13904
13947
  if proc.stdin:
@@ -15124,6 +15167,8 @@ def build_parser() -> argparse.ArgumentParser:
15124
15167
 
15125
15168
 
15126
15169
  def main() -> None:
15170
+ if len(sys.argv) >= 2 and sys.argv[1] == "mcp-proxy":
15171
+ raise SystemExit(cmd_mcp_proxy(sys.argv[2:]))
15127
15172
  if len(sys.argv) >= 2 and sys.argv[1] == "cli":
15128
15173
  raise SystemExit(run_cli(sys.argv[2:]))
15129
15174
  if len(sys.argv) >= 2 and sys.argv[1] == "launch":
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oneciel-ai/claude-any",
3
- "version": "0.1.78",
3
+ "version": "0.1.80",
4
4
  "description": "Claude Code provider selector for Anthropic, Ollama, Ollama Cloud, vLLM, NVIDIA hosted, and self-hosted NIM.",
5
5
  "license": "MIT",
6
6
  "author": "One Ciel LLC",