claude-code-telegrammer 0.1.0__tar.gz → 0.2.0__tar.gz
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.
- {claude_code_telegrammer-0.1.0 → claude_code_telegrammer-0.2.0}/PKG-INFO +1 -1
- claude_code_telegrammer-0.2.0/bin/telegrammer-relay +55 -0
- {claude_code_telegrammer-0.1.0 → claude_code_telegrammer-0.2.0}/config/telegram-master.yaml +5 -0
- claude_code_telegrammer-0.2.0/lib/orochi-relay.sh +149 -0
- {claude_code_telegrammer-0.1.0 → claude_code_telegrammer-0.2.0}/pyproject.toml +2 -1
- {claude_code_telegrammer-0.1.0 → claude_code_telegrammer-0.2.0}/src/claude_code_telegrammer/__init__.py +1 -1
- {claude_code_telegrammer-0.1.0 → claude_code_telegrammer-0.2.0}/src/claude_code_telegrammer/cli.py +4 -0
- {claude_code_telegrammer-0.1.0 → claude_code_telegrammer-0.2.0}/.github/workflows/publish-pypi.yml +0 -0
- {claude_code_telegrammer-0.1.0 → claude_code_telegrammer-0.2.0}/.github/workflows/test.yml +0 -0
- {claude_code_telegrammer-0.1.0 → claude_code_telegrammer-0.2.0}/LICENSE +0 -0
- {claude_code_telegrammer-0.1.0 → claude_code_telegrammer-0.2.0}/README.md +0 -0
- {claude_code_telegrammer-0.1.0 → claude_code_telegrammer-0.2.0}/bin/telegrammer +0 -0
- {claude_code_telegrammer-0.1.0 → claude_code_telegrammer-0.2.0}/bin/telegrammer-guard +0 -0
- {claude_code_telegrammer-0.1.0 → claude_code_telegrammer-0.2.0}/bin/telegrammer-init +0 -0
- {claude_code_telegrammer-0.1.0 → claude_code_telegrammer-0.2.0}/bin/telegrammer-watchdog +0 -0
- {claude_code_telegrammer-0.1.0 → claude_code_telegrammer-0.2.0}/docs/scitex-icon-navy-inverted.png +0 -0
- {claude_code_telegrammer-0.1.0 → claude_code_telegrammer-0.2.0}/docs/scitex-logo-blue-cropped.png +0 -0
- {claude_code_telegrammer-0.1.0 → claude_code_telegrammer-0.2.0}/hooks/enforce_background_subagents.sh +0 -0
- {claude_code_telegrammer-0.1.0 → claude_code_telegrammer-0.2.0}/lib/auto-response.sh +0 -0
- {claude_code_telegrammer-0.1.0 → claude_code_telegrammer-0.2.0}/lib/common.sh +0 -0
- {claude_code_telegrammer-0.1.0 → claude_code_telegrammer-0.2.0}/lib/lock.sh +0 -0
- {claude_code_telegrammer-0.1.0 → claude_code_telegrammer-0.2.0}/lib/state-detection.sh +0 -0
- {claude_code_telegrammer-0.1.0 → claude_code_telegrammer-0.2.0}/src/claude_code_telegrammer.egg-info/PKG-INFO +0 -0
- {claude_code_telegrammer-0.1.0 → claude_code_telegrammer-0.2.0}/src/claude_code_telegrammer.egg-info/SOURCES.txt +0 -0
- {claude_code_telegrammer-0.1.0 → claude_code_telegrammer-0.2.0}/src/claude_code_telegrammer.egg-info/dependency_links.txt +0 -0
- {claude_code_telegrammer-0.1.0 → claude_code_telegrammer-0.2.0}/src/claude_code_telegrammer.egg-info/entry_points.txt +0 -0
- {claude_code_telegrammer-0.1.0 → claude_code_telegrammer-0.2.0}/src/claude_code_telegrammer.egg-info/top_level.txt +0 -0
- {claude_code_telegrammer-0.1.0 → claude_code_telegrammer-0.2.0}/tests/test-state-detection.sh +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: claude-code-telegrammer
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: Screen-based auto-responder watchdog for Claude Code TUI
|
|
5
5
|
Project-URL: Homepage, https://github.com/ywatanabe1989/claude-code-telegrammer
|
|
6
6
|
Project-URL: Repository, https://github.com/ywatanabe1989/claude-code-telegrammer.git
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# telegrammer-relay — Send messages to Orochi from telegrammer
|
|
3
|
+
# Usage: telegrammer-relay send "message" [--channel '#telegram']
|
|
4
|
+
# telegrammer-relay health
|
|
5
|
+
# telegrammer-relay who
|
|
6
|
+
# telegrammer-relay --self-test
|
|
7
|
+
|
|
8
|
+
set -uo pipefail
|
|
9
|
+
|
|
10
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
11
|
+
source "${SCRIPT_DIR}/../lib/orochi-relay.sh"
|
|
12
|
+
|
|
13
|
+
case "${1:-}" in
|
|
14
|
+
send)
|
|
15
|
+
shift
|
|
16
|
+
message="${1:?Usage: telegrammer-relay send \"message\" [--channel '#channel']}"
|
|
17
|
+
channel="${OROCHI_CHANNEL}"
|
|
18
|
+
# Parse optional --channel flag
|
|
19
|
+
if [[ "${2:-}" == "--channel" && -n "${3:-}" ]]; then
|
|
20
|
+
channel="$3"
|
|
21
|
+
fi
|
|
22
|
+
result=$(orochi_relay "$message" "$channel")
|
|
23
|
+
case "$result" in
|
|
24
|
+
rest)
|
|
25
|
+
echo "Sent via REST API"
|
|
26
|
+
;;
|
|
27
|
+
screen)
|
|
28
|
+
echo "WARNING: REST unavailable, sent via screen fallback"
|
|
29
|
+
;;
|
|
30
|
+
failed)
|
|
31
|
+
echo "ERROR: Both REST and screen delivery failed" >&2
|
|
32
|
+
exit 1
|
|
33
|
+
;;
|
|
34
|
+
esac
|
|
35
|
+
;;
|
|
36
|
+
health)
|
|
37
|
+
orochi_health
|
|
38
|
+
;;
|
|
39
|
+
who)
|
|
40
|
+
orochi_who
|
|
41
|
+
;;
|
|
42
|
+
--self-test)
|
|
43
|
+
orochi_self_test
|
|
44
|
+
;;
|
|
45
|
+
*)
|
|
46
|
+
echo "Usage: telegrammer-relay {send|health|who|--self-test}"
|
|
47
|
+
echo ""
|
|
48
|
+
echo "Commands:"
|
|
49
|
+
echo " send \"message\" [--channel '#channel'] Send message to Orochi"
|
|
50
|
+
echo " health Check Orochi connectivity"
|
|
51
|
+
echo " who List connected agents"
|
|
52
|
+
echo " --self-test Run self-tests"
|
|
53
|
+
exit 1
|
|
54
|
+
;;
|
|
55
|
+
esac
|
|
@@ -24,6 +24,11 @@ spec:
|
|
|
24
24
|
waiting: "/speak-and-call"
|
|
25
25
|
lock:
|
|
26
26
|
path: ~/.claude/channels/telegram/telegram.lock
|
|
27
|
+
orochi:
|
|
28
|
+
host: 192.168.0.102
|
|
29
|
+
dashboard_port: 8559
|
|
30
|
+
channel: "#telegram"
|
|
31
|
+
master_screen: "orochi-agent:master"
|
|
27
32
|
restart:
|
|
28
33
|
enabled: false
|
|
29
34
|
max_retries: 3
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# orochi-relay.sh — Relay messages from telegrammer to Orochi hub
|
|
3
|
+
# Multi-route: tries all available routes, reports results honestly (no silent fallbacks)
|
|
4
|
+
|
|
5
|
+
# Configuration (from env or defaults)
|
|
6
|
+
OROCHI_HOST="${SCITEX_OROCHI_HOST:-192.168.0.102}"
|
|
7
|
+
OROCHI_DASHBOARD_PORT="${SCITEX_OROCHI_DASHBOARD_PORT:-8559}"
|
|
8
|
+
OROCHI_CHANNEL="${TELEGRAMMER_OROCHI_CHANNEL:-#telegram}"
|
|
9
|
+
OROCHI_MASTER_SCREEN="${TELEGRAMMER_OROCHI_MASTER_SCREEN:-orochi-agent:master}"
|
|
10
|
+
|
|
11
|
+
# Send message to Orochi via all available routes
|
|
12
|
+
# Returns JSON-like status: "rest:OK screen:OK" / "rest:FAIL(503) screen:OK" / etc.
|
|
13
|
+
# No silent fallbacks — every route's result is reported
|
|
14
|
+
orochi_relay() {
|
|
15
|
+
local message="$1"
|
|
16
|
+
local channel="${2:-$OROCHI_CHANNEL}"
|
|
17
|
+
local results=""
|
|
18
|
+
|
|
19
|
+
# Route 1: REST API
|
|
20
|
+
local rest_response
|
|
21
|
+
rest_response=$(curl -s -o /dev/null -w "%{http_code}" \
|
|
22
|
+
-X POST "http://${OROCHI_HOST}:${OROCHI_DASHBOARD_PORT}/api/messages" \
|
|
23
|
+
-H "Content-Type: application/json" \
|
|
24
|
+
-d "{\"channel\": \"${channel}\", \"content\": \"${message}\", \"sender\": \"telegrammer\"}" \
|
|
25
|
+
--connect-timeout 3 --max-time 5 2>/dev/null) || rest_response="000"
|
|
26
|
+
|
|
27
|
+
if [[ "$rest_response" =~ ^2 ]]; then
|
|
28
|
+
results="rest:OK"
|
|
29
|
+
else
|
|
30
|
+
results="rest:FAIL(${rest_response})"
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
# Route 2: Screen stuff
|
|
34
|
+
if screen -ls "$OROCHI_MASTER_SCREEN" 2>/dev/null | grep -q "$OROCHI_MASTER_SCREEN"; then
|
|
35
|
+
screen -S "$OROCHI_MASTER_SCREEN" -X stuff "${message}\r"
|
|
36
|
+
results="${results} screen:OK"
|
|
37
|
+
else
|
|
38
|
+
results="${results} screen:FAIL(no-session)"
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
echo "$results"
|
|
42
|
+
|
|
43
|
+
# Return success if at least one route worked
|
|
44
|
+
if echo "$results" | grep -q "OK"; then
|
|
45
|
+
return 0
|
|
46
|
+
fi
|
|
47
|
+
return 1
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
# Check if Orochi is reachable
|
|
51
|
+
orochi_health() {
|
|
52
|
+
local response
|
|
53
|
+
response=$(curl -s -o /dev/null -w "%{http_code}" \
|
|
54
|
+
"http://${OROCHI_HOST}:${OROCHI_DASHBOARD_PORT}/api/stats" \
|
|
55
|
+
--connect-timeout 3 --max-time 5 2>/dev/null) || response="000"
|
|
56
|
+
|
|
57
|
+
if [[ "$response" =~ ^2 ]]; then
|
|
58
|
+
echo "healthy"
|
|
59
|
+
return 0
|
|
60
|
+
else
|
|
61
|
+
echo "unreachable (HTTP ${response})"
|
|
62
|
+
return 1
|
|
63
|
+
fi
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
# Get connected agents from Orochi
|
|
67
|
+
orochi_who() {
|
|
68
|
+
curl -s "http://${OROCHI_HOST}:${OROCHI_DASHBOARD_PORT}/api/agents" \
|
|
69
|
+
--connect-timeout 3 --max-time 5 2>/dev/null || echo "[]"
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
# Self-test with mocked curl
|
|
73
|
+
orochi_self_test() {
|
|
74
|
+
local pass=0
|
|
75
|
+
local fail=0
|
|
76
|
+
|
|
77
|
+
echo "=== orochi-relay self-test ==="
|
|
78
|
+
|
|
79
|
+
# Test 1: REST relay (mocked 200, screen unavailable)
|
|
80
|
+
echo -n "Test 1: REST success... "
|
|
81
|
+
curl() { echo "200"; }
|
|
82
|
+
export -f curl
|
|
83
|
+
local result
|
|
84
|
+
result=$(orochi_relay "test message" "#test")
|
|
85
|
+
local rc=$?
|
|
86
|
+
unset -f curl
|
|
87
|
+
if echo "$result" | grep -q "rest:OK" && [[ "$rc" -eq 0 ]]; then
|
|
88
|
+
echo "PASS"
|
|
89
|
+
((pass++))
|
|
90
|
+
else
|
|
91
|
+
echo "FAIL (got: $result rc=$rc)"
|
|
92
|
+
((fail++))
|
|
93
|
+
fi
|
|
94
|
+
|
|
95
|
+
# Test 2: Both unavailable
|
|
96
|
+
echo -n "Test 2: Both unavailable... "
|
|
97
|
+
curl() { echo "000"; return 1; }
|
|
98
|
+
export -f curl
|
|
99
|
+
screen() { return 1; }
|
|
100
|
+
export -f screen
|
|
101
|
+
result=$(orochi_relay "test message" "#test")
|
|
102
|
+
rc=$?
|
|
103
|
+
unset -f curl
|
|
104
|
+
unset -f screen
|
|
105
|
+
if echo "$result" | grep -q "rest:FAIL" && [[ "$rc" -eq 1 ]]; then
|
|
106
|
+
echo "PASS"
|
|
107
|
+
((pass++))
|
|
108
|
+
else
|
|
109
|
+
echo "FAIL (got: $result rc=$rc)"
|
|
110
|
+
((fail++))
|
|
111
|
+
fi
|
|
112
|
+
|
|
113
|
+
# Test 3: orochi_health healthy case
|
|
114
|
+
echo -n "Test 3: Health check (mocked 200)... "
|
|
115
|
+
curl() { echo "200"; }
|
|
116
|
+
export -f curl
|
|
117
|
+
result=$(orochi_health)
|
|
118
|
+
unset -f curl
|
|
119
|
+
if [[ "$result" == "healthy" ]]; then
|
|
120
|
+
echo "PASS"
|
|
121
|
+
((pass++))
|
|
122
|
+
else
|
|
123
|
+
echo "FAIL (got: $result, expected: healthy)"
|
|
124
|
+
((fail++))
|
|
125
|
+
fi
|
|
126
|
+
|
|
127
|
+
# Test 4: orochi_health unreachable case
|
|
128
|
+
echo -n "Test 4: Health check (mocked 503)... "
|
|
129
|
+
curl() { echo "503"; }
|
|
130
|
+
export -f curl
|
|
131
|
+
result=$(orochi_health)
|
|
132
|
+
local rc=$?
|
|
133
|
+
unset -f curl
|
|
134
|
+
if [[ "$result" == "unreachable (HTTP 503)" && "$rc" -eq 1 ]]; then
|
|
135
|
+
echo "PASS"
|
|
136
|
+
((pass++))
|
|
137
|
+
else
|
|
138
|
+
echo "FAIL (got: '$result' rc=$rc)"
|
|
139
|
+
((fail++))
|
|
140
|
+
fi
|
|
141
|
+
|
|
142
|
+
echo "=== Results: ${pass} passed, ${fail} failed ==="
|
|
143
|
+
[[ "$fail" -eq 0 ]] && return 0 || return 1
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
# Run self-test if invoked directly (not sourced) with --self-test
|
|
147
|
+
if [[ "${BASH_SOURCE[0]}" == "${0}" && "${1:-}" == "--self-test" ]]; then
|
|
148
|
+
orochi_self_test
|
|
149
|
+
fi
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "claude-code-telegrammer"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.2.0"
|
|
8
8
|
description = "Screen-based auto-responder watchdog for Claude Code TUI"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "AGPL-3.0"
|
|
@@ -34,6 +34,7 @@ telegrammer = "claude_code_telegrammer.cli:telegrammer"
|
|
|
34
34
|
telegrammer-watchdog = "claude_code_telegrammer.cli:telegrammer_watchdog"
|
|
35
35
|
telegrammer-guard = "claude_code_telegrammer.cli:telegrammer_guard"
|
|
36
36
|
telegrammer-init = "claude_code_telegrammer.cli:telegrammer_init"
|
|
37
|
+
telegrammer-relay = "claude_code_telegrammer.cli:telegrammer_relay"
|
|
37
38
|
|
|
38
39
|
[project.urls]
|
|
39
40
|
Homepage = "https://github.com/ywatanabe1989/claude-code-telegrammer"
|
{claude_code_telegrammer-0.1.0 → claude_code_telegrammer-0.2.0}/.github/workflows/publish-pypi.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{claude_code_telegrammer-0.1.0 → claude_code_telegrammer-0.2.0}/docs/scitex-icon-navy-inverted.png
RENAMED
|
File without changes
|
{claude_code_telegrammer-0.1.0 → claude_code_telegrammer-0.2.0}/docs/scitex-logo-blue-cropped.png
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{claude_code_telegrammer-0.1.0 → claude_code_telegrammer-0.2.0}/tests/test-state-detection.sh
RENAMED
|
File without changes
|