@oneciel-ai/claude-any 0.1.92 → 0.1.94
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/claude_any.py +56 -6
- package/package.json +1 -1
package/claude_any.py
CHANGED
|
@@ -105,7 +105,7 @@ OFFICIAL_CHANNEL_PLUGINS = {
|
|
|
105
105
|
"fakechat": "plugin:fakechat@claude-plugins-official",
|
|
106
106
|
}
|
|
107
107
|
APP_NAME = "Claude Any"
|
|
108
|
-
VERSION = "0.1.
|
|
108
|
+
VERSION = "0.1.94"
|
|
109
109
|
CREDITS = "Credits: One Ciel LLC"
|
|
110
110
|
|
|
111
111
|
LOG_LEVELS = {"SILENT": 0, "ERROR": 1, "WARN": 2, "INFO": 3, "DEBUG": 4, "TRACE": 5}
|
|
@@ -5083,6 +5083,45 @@ def _channel_mcp_update_cursor(last_id: int) -> None:
|
|
|
5083
5083
|
router_log("WARN", f"channel_mcp_cursor_write_failed error={type(exc).__name__}: {exc}")
|
|
5084
5084
|
|
|
5085
5085
|
|
|
5086
|
+
def _channel_mcp_parse_event_id(value: Any) -> int | None:
|
|
5087
|
+
text = str(value or "").strip()
|
|
5088
|
+
if not text:
|
|
5089
|
+
return None
|
|
5090
|
+
try:
|
|
5091
|
+
return max(0, int(text))
|
|
5092
|
+
except Exception:
|
|
5093
|
+
return None
|
|
5094
|
+
|
|
5095
|
+
|
|
5096
|
+
def _channel_mcp_client_last_event_id(handler: BaseHTTPRequestHandler) -> int | None:
|
|
5097
|
+
try:
|
|
5098
|
+
event_id = _channel_mcp_parse_event_id(handler.headers.get("Last-Event-ID"))
|
|
5099
|
+
if event_id is not None:
|
|
5100
|
+
return event_id
|
|
5101
|
+
except Exception:
|
|
5102
|
+
pass
|
|
5103
|
+
try:
|
|
5104
|
+
params = _query_params(handler)
|
|
5105
|
+
for key in ("lastEventId", "last_event_id", "last_id"):
|
|
5106
|
+
event_id = _channel_mcp_parse_event_id(_first_param(params, key))
|
|
5107
|
+
if event_id is not None:
|
|
5108
|
+
return event_id
|
|
5109
|
+
except Exception:
|
|
5110
|
+
pass
|
|
5111
|
+
return None
|
|
5112
|
+
|
|
5113
|
+
|
|
5114
|
+
def _channel_mcp_session_start_last_id(handler: BaseHTTPRequestHandler) -> int:
|
|
5115
|
+
cursor_last_id = _channel_mcp_ensure_cursor_initialized()
|
|
5116
|
+
client_last_id = _channel_mcp_client_last_event_id(handler)
|
|
5117
|
+
if client_last_id is None:
|
|
5118
|
+
return cursor_last_id
|
|
5119
|
+
if client_last_id > cursor_last_id:
|
|
5120
|
+
_channel_mcp_update_cursor(client_last_id)
|
|
5121
|
+
router_log("INFO", f"channel_mcp_resume client_last_id={client_last_id} cursor_last_id={cursor_last_id}")
|
|
5122
|
+
return client_last_id
|
|
5123
|
+
|
|
5124
|
+
|
|
5086
5125
|
def _channel_mcp_notifications_for_messages(
|
|
5087
5126
|
messages: list[dict[str, Any]],
|
|
5088
5127
|
session: str = "",
|
|
@@ -5102,7 +5141,7 @@ def _channel_mcp_notifications_for_messages(
|
|
|
5102
5141
|
events.append((last_id, _channel_mcp_notification(message)))
|
|
5103
5142
|
router_log(
|
|
5104
5143
|
"INFO",
|
|
5105
|
-
f"
|
|
5144
|
+
f"channel_mcp_notification_prepared session={session or '-'} message_id={message.get('id')} channel={message.get('channel')}",
|
|
5106
5145
|
)
|
|
5107
5146
|
return last_id, events
|
|
5108
5147
|
|
|
@@ -5114,7 +5153,7 @@ def handle_channel_mcp_get(handler: BaseHTTPRequestHandler, path: str) -> bool:
|
|
|
5114
5153
|
if path != "/ca/mcp/sse":
|
|
5115
5154
|
return False
|
|
5116
5155
|
session = _channel_mcp_session_id()
|
|
5117
|
-
last_id =
|
|
5156
|
+
last_id = _channel_mcp_session_start_last_id(handler)
|
|
5118
5157
|
with _CHANNEL_MCP_LOCK:
|
|
5119
5158
|
_CHANNEL_MCP_SESSIONS[session] = {"created_at": time.time(), "last_id": last_id, "initialized": False, "outbox": []}
|
|
5120
5159
|
router_log("INFO", f"channel_mcp_session_started session={session} last_id={last_id}")
|
|
@@ -5149,7 +5188,9 @@ def handle_channel_mcp_get(handler: BaseHTTPRequestHandler, path: str) -> bool:
|
|
|
5149
5188
|
last_id = max(last_id, delivered_last_id)
|
|
5150
5189
|
for event_id, notification in events:
|
|
5151
5190
|
_write_sse_event(handler, "message", notification, event_id)
|
|
5152
|
-
|
|
5191
|
+
router_log("INFO", f"channel_mcp_notification_written session={session} message_id={event_id}")
|
|
5192
|
+
if not events:
|
|
5193
|
+
_channel_mcp_update_cursor(last_id)
|
|
5153
5194
|
with _CHANNEL_MCP_LOCK:
|
|
5154
5195
|
state = _CHANNEL_MCP_SESSIONS.get(session)
|
|
5155
5196
|
if state:
|
|
@@ -14137,6 +14178,15 @@ def _channel_enter_bytes_from_user_input(data: bytes) -> bytes | None:
|
|
|
14137
14178
|
return b"\r\n" if last_cr + 1 < len(data) and data[last_cr + 1 : last_cr + 2] == b"\n" else b"\r"
|
|
14138
14179
|
|
|
14139
14180
|
|
|
14181
|
+
def _channel_synthetic_enter_bytes_from_user_input(data: bytes) -> bytes | None:
|
|
14182
|
+
observed = _channel_enter_bytes_from_user_input(data)
|
|
14183
|
+
if observed == b"\r":
|
|
14184
|
+
# Bare CR is common from raw POSIX terminals, but synthetic CR-only
|
|
14185
|
+
# writes can sit in Claude Code's line editor on some PTY stacks.
|
|
14186
|
+
return b"\r\n"
|
|
14187
|
+
return observed
|
|
14188
|
+
|
|
14189
|
+
|
|
14140
14190
|
def _channel_enter_label(enter_bytes: bytes) -> str:
|
|
14141
14191
|
if enter_bytes == b"\r":
|
|
14142
14192
|
return "cr"
|
|
@@ -14217,8 +14267,8 @@ def subprocess_call_with_channel_wake_proxy(cmd: list[str], env: dict[str, str])
|
|
|
14217
14267
|
if stdin_fd in readable:
|
|
14218
14268
|
data = os.read(stdin_fd, 4096)
|
|
14219
14269
|
if data:
|
|
14220
|
-
observed_enter =
|
|
14221
|
-
if observed_enter:
|
|
14270
|
+
observed_enter = _channel_synthetic_enter_bytes_from_user_input(data)
|
|
14271
|
+
if observed_enter and not os.environ.get("CLAUDE_ANY_CHANNEL_WAKE_ENTER"):
|
|
14222
14272
|
channel_enter_bytes = observed_enter
|
|
14223
14273
|
_write_fd_all(master_fd, data)
|
|
14224
14274
|
if master_fd in readable:
|
package/package.json
CHANGED