clawless 0.1.2
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/.env.example +48 -0
- package/LICENSE +21 -0
- package/QUICKSTART-SCHEDULER.md +226 -0
- package/QUICKSTART.md +98 -0
- package/README.md +404 -0
- package/SCHEDULER.md +255 -0
- package/TESTING.md +239 -0
- package/acp/clientHelpers.ts +23 -0
- package/acp/tempAcpRunner.ts +320 -0
- package/agent-bridge.config.example.json +19 -0
- package/bin/cli.ts +255 -0
- package/dist/acp/clientHelpers.js +19 -0
- package/dist/acp/tempAcpRunner.js +263 -0
- package/dist/bin/cli.js +217 -0
- package/dist/index.js +1115 -0
- package/dist/messaging/telegramClient.js +109 -0
- package/dist/scheduler/cronScheduler.js +272 -0
- package/dist/scheduler/scheduledJobHandler.js +34 -0
- package/dist/utils/error.js +12 -0
- package/dist/utils/telegramMarkdown.js +128 -0
- package/ecosystem.config.json +23 -0
- package/index.ts +1272 -0
- package/messaging/telegramClient.ts +132 -0
- package/package.json +43 -0
- package/scheduler/cronScheduler.ts +355 -0
- package/scheduler/scheduledJobHandler.ts +55 -0
- package/scripts/callback-health.sh +6 -0
- package/scripts/callback-post-chat.sh +25 -0
- package/scripts/callback-post.sh +19 -0
- package/scripts/gemini-scheduler-examples.sh +162 -0
- package/scripts/test-scheduler.sh +78 -0
- package/tsconfig.json +23 -0
- package/utils/error.ts +12 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Example: How Gemini CLI can interact with the Scheduler API
|
|
4
|
+
# This demonstrates the curl commands that Gemini would execute when asked to create schedules
|
|
5
|
+
|
|
6
|
+
BASE_URL="http://127.0.0.1:8788"
|
|
7
|
+
TOKEN="" # Set this if CALLBACK_AUTH_TOKEN is configured
|
|
8
|
+
|
|
9
|
+
# Helper function to add auth header if token is set
|
|
10
|
+
auth_header() {
|
|
11
|
+
if [ -n "$TOKEN" ]; then
|
|
12
|
+
echo "-H x-callback-token:$TOKEN"
|
|
13
|
+
fi
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
echo "=== Gemini CLI Scheduler Integration Examples ==="
|
|
17
|
+
echo ""
|
|
18
|
+
|
|
19
|
+
# Example 1: User asks "Remind me to take a break in 30 minutes"
|
|
20
|
+
echo "Example 1: One-time reminder in 30 minutes"
|
|
21
|
+
echo "User: 'Remind me to take a break in 30 minutes'"
|
|
22
|
+
echo ""
|
|
23
|
+
RUN_AT=$(date -u -d "+30 minutes" +"%Y-%m-%dT%H:%M:%SZ" 2>/dev/null || date -u -v+30M +"%Y-%m-%dT%H:%M:%SZ")
|
|
24
|
+
echo "Gemini executes:"
|
|
25
|
+
cat <<EOF
|
|
26
|
+
curl -X POST ${BASE_URL}/api/schedule \\
|
|
27
|
+
-H "Content-Type: application/json" \\
|
|
28
|
+
$(auth_header) \\
|
|
29
|
+
-d '{
|
|
30
|
+
"message": "Remind: Take a break! It has been 30 minutes.",
|
|
31
|
+
"description": "Break reminder",
|
|
32
|
+
"oneTime": true,
|
|
33
|
+
"runAt": "${RUN_AT}"
|
|
34
|
+
}'
|
|
35
|
+
EOF
|
|
36
|
+
echo ""
|
|
37
|
+
echo "---"
|
|
38
|
+
echo ""
|
|
39
|
+
|
|
40
|
+
# Example 2: User asks "Check my calendar every morning at 9am"
|
|
41
|
+
echo "Example 2: Daily calendar check at 9am"
|
|
42
|
+
echo "User: 'Check my calendar every morning at 9am and send me a summary'"
|
|
43
|
+
echo ""
|
|
44
|
+
echo "Gemini executes:"
|
|
45
|
+
cat <<EOF
|
|
46
|
+
curl -X POST ${BASE_URL}/api/schedule \\
|
|
47
|
+
-H "Content-Type: application/json" \\
|
|
48
|
+
$(auth_header) \\
|
|
49
|
+
-d '{
|
|
50
|
+
"message": "Check my calendar for today and provide a summary of all events",
|
|
51
|
+
"description": "Daily calendar summary at 9am",
|
|
52
|
+
"cronExpression": "0 9 * * *"
|
|
53
|
+
}'
|
|
54
|
+
EOF
|
|
55
|
+
echo ""
|
|
56
|
+
echo "---"
|
|
57
|
+
echo ""
|
|
58
|
+
|
|
59
|
+
# Example 3: User asks "Every Friday at 5pm, remind me to review my weekly goals"
|
|
60
|
+
echo "Example 3: Weekly reminder on Fridays at 5pm"
|
|
61
|
+
echo "User: 'Every Friday at 5pm, remind me to review my weekly goals'"
|
|
62
|
+
echo ""
|
|
63
|
+
echo "Gemini executes:"
|
|
64
|
+
cat <<EOF
|
|
65
|
+
curl -X POST ${BASE_URL}/api/schedule \\
|
|
66
|
+
-H "Content-Type: application/json" \\
|
|
67
|
+
$(auth_header) \\
|
|
68
|
+
-d '{
|
|
69
|
+
"message": "Weekly reminder: Review your goals for this week. What did you accomplish? What needs more work?",
|
|
70
|
+
"description": "Weekly goals review - Friday 5pm",
|
|
71
|
+
"cronExpression": "0 17 * * 5"
|
|
72
|
+
}'
|
|
73
|
+
EOF
|
|
74
|
+
echo ""
|
|
75
|
+
echo "---"
|
|
76
|
+
echo ""
|
|
77
|
+
|
|
78
|
+
# Example 4: User asks "What schedules do I have?"
|
|
79
|
+
echo "Example 4: List all schedules"
|
|
80
|
+
echo "User: 'What schedules do I have?'"
|
|
81
|
+
echo ""
|
|
82
|
+
echo "Gemini executes:"
|
|
83
|
+
cat <<EOF
|
|
84
|
+
curl ${BASE_URL}/api/schedule \\
|
|
85
|
+
$(auth_header)
|
|
86
|
+
EOF
|
|
87
|
+
echo ""
|
|
88
|
+
echo "Then Gemini formats the response in a human-readable way."
|
|
89
|
+
echo ""
|
|
90
|
+
echo "---"
|
|
91
|
+
echo ""
|
|
92
|
+
|
|
93
|
+
# Example 5: User asks "Cancel my daily calendar check"
|
|
94
|
+
echo "Example 5: Cancel a specific schedule"
|
|
95
|
+
echo "User: 'Cancel my daily calendar check'"
|
|
96
|
+
echo ""
|
|
97
|
+
echo "Gemini first lists schedules, finds the one matching 'daily calendar', then:"
|
|
98
|
+
cat <<EOF
|
|
99
|
+
curl -X DELETE ${BASE_URL}/api/schedule/SCHEDULE_ID \\
|
|
100
|
+
$(auth_header)
|
|
101
|
+
EOF
|
|
102
|
+
echo ""
|
|
103
|
+
echo "---"
|
|
104
|
+
echo ""
|
|
105
|
+
|
|
106
|
+
# Example 6: More complex recurring schedules
|
|
107
|
+
echo "Example 6: Complex recurring schedules"
|
|
108
|
+
echo ""
|
|
109
|
+
|
|
110
|
+
echo "Every 5 minutes:"
|
|
111
|
+
echo " cronExpression: '*/5 * * * *'"
|
|
112
|
+
echo ""
|
|
113
|
+
|
|
114
|
+
echo "Every weekday at 8am:"
|
|
115
|
+
echo " cronExpression: '0 8 * * 1-5'"
|
|
116
|
+
echo ""
|
|
117
|
+
|
|
118
|
+
echo "First day of every month at midnight:"
|
|
119
|
+
echo " cronExpression: '0 0 1 * *'"
|
|
120
|
+
echo ""
|
|
121
|
+
|
|
122
|
+
echo "Every hour during work hours (9am-5pm) on weekdays:"
|
|
123
|
+
echo " cronExpression: '0 9-17 * * 1-5'"
|
|
124
|
+
echo ""
|
|
125
|
+
|
|
126
|
+
echo "---"
|
|
127
|
+
echo ""
|
|
128
|
+
|
|
129
|
+
echo "=== Cron Expression Guide ==="
|
|
130
|
+
echo ""
|
|
131
|
+
echo "Format: minute hour day month weekday"
|
|
132
|
+
echo ""
|
|
133
|
+
echo "Field Values"
|
|
134
|
+
echo "------- ----------------"
|
|
135
|
+
echo "minute 0-59"
|
|
136
|
+
echo "hour 0-23"
|
|
137
|
+
echo "day 1-31"
|
|
138
|
+
echo "month 1-12"
|
|
139
|
+
echo "weekday 0-7 (0 or 7 is Sunday)"
|
|
140
|
+
echo ""
|
|
141
|
+
echo "Special characters:"
|
|
142
|
+
echo " * any value"
|
|
143
|
+
echo " , value list separator (e.g., 1,3,5)"
|
|
144
|
+
echo " - range of values (e.g., 1-5)"
|
|
145
|
+
echo " / step values (e.g., */15 for every 15 minutes)"
|
|
146
|
+
echo ""
|
|
147
|
+
|
|
148
|
+
echo "=== Integration Notes ==="
|
|
149
|
+
echo ""
|
|
150
|
+
echo "1. Gemini CLI has access to the scheduler API endpoints through system prompts"
|
|
151
|
+
echo "2. When users ask to schedule something, Gemini:"
|
|
152
|
+
echo " - Parses the natural language request"
|
|
153
|
+
echo " - Determines if it's one-time (runAt) or recurring (cronExpression)"
|
|
154
|
+
echo " - Converts time expressions to appropriate format"
|
|
155
|
+
echo " - Calls the API with proper JSON payload"
|
|
156
|
+
echo " - Confirms schedule creation to the user"
|
|
157
|
+
echo ""
|
|
158
|
+
echo "3. When scheduled jobs run:"
|
|
159
|
+
echo " - The message is executed through a new Gemini CLI session"
|
|
160
|
+
echo " - Gemini can use all its tools (calendar, file access, web search, etc.)"
|
|
161
|
+
echo " - The response is automatically sent to Telegram"
|
|
162
|
+
echo ""
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Test script for scheduler API
|
|
4
|
+
# This script tests the scheduler API endpoints
|
|
5
|
+
|
|
6
|
+
BASE_URL="http://127.0.0.1:8788"
|
|
7
|
+
|
|
8
|
+
echo "=== Scheduler API Test ==="
|
|
9
|
+
echo ""
|
|
10
|
+
|
|
11
|
+
# Test 1: Health check
|
|
12
|
+
echo "1. Testing health check..."
|
|
13
|
+
curl -s "${BASE_URL}/healthz" | jq .
|
|
14
|
+
echo ""
|
|
15
|
+
|
|
16
|
+
# Test 2: Create a recurring schedule (every minute)
|
|
17
|
+
echo "2. Creating a recurring schedule (every minute)..."
|
|
18
|
+
RECURRING_RESPONSE=$(curl -s -X POST "${BASE_URL}/api/schedule" \
|
|
19
|
+
-H "Content-Type: application/json" \
|
|
20
|
+
-d '{
|
|
21
|
+
"message": "What time is it now?",
|
|
22
|
+
"description": "Test recurring schedule - every minute",
|
|
23
|
+
"cronExpression": "* * * * *"
|
|
24
|
+
}')
|
|
25
|
+
echo "$RECURRING_RESPONSE" | jq .
|
|
26
|
+
SCHEDULE_ID=$(echo "$RECURRING_RESPONSE" | jq -r '.schedule.id')
|
|
27
|
+
echo "Created schedule ID: $SCHEDULE_ID"
|
|
28
|
+
echo ""
|
|
29
|
+
|
|
30
|
+
# Test 3: Create a one-time schedule (30 seconds from now)
|
|
31
|
+
echo "3. Creating a one-time schedule (30 seconds from now)..."
|
|
32
|
+
if ! RUN_AT=$(date -u -d "+30 seconds" +"%Y-%m-%dT%H:%M:%SZ" 2>/dev/null); then
|
|
33
|
+
# Fallback for macOS/BSD date
|
|
34
|
+
RUN_AT=$(date -u -v+30S +"%Y-%m-%dT%H:%M:%SZ")
|
|
35
|
+
fi
|
|
36
|
+
ONE_TIME_RESPONSE=$(curl -s -X POST "${BASE_URL}/api/schedule" \
|
|
37
|
+
-H "Content-Type: application/json" \
|
|
38
|
+
-d "{
|
|
39
|
+
\"message\": \"This is a one-time scheduled message\",
|
|
40
|
+
\"description\": \"Test one-time schedule\",
|
|
41
|
+
\"oneTime\": true,
|
|
42
|
+
\"runAt\": \"${RUN_AT}\"
|
|
43
|
+
}")
|
|
44
|
+
echo "$ONE_TIME_RESPONSE" | jq .
|
|
45
|
+
ONE_TIME_ID=$(echo "$ONE_TIME_RESPONSE" | jq -r '.schedule.id')
|
|
46
|
+
echo "Created one-time schedule ID: $ONE_TIME_ID"
|
|
47
|
+
echo ""
|
|
48
|
+
|
|
49
|
+
# Test 4: List all schedules
|
|
50
|
+
echo "4. Listing all schedules..."
|
|
51
|
+
curl -s "${BASE_URL}/api/schedule" | jq .
|
|
52
|
+
echo ""
|
|
53
|
+
|
|
54
|
+
# Test 5: Get a specific schedule
|
|
55
|
+
echo "5. Getting schedule by ID..."
|
|
56
|
+
curl -s "${BASE_URL}/api/schedule/${SCHEDULE_ID}" | jq .
|
|
57
|
+
echo ""
|
|
58
|
+
|
|
59
|
+
# Test 6: Wait for 65 seconds to see recurring job execute
|
|
60
|
+
echo "6. Waiting 65 seconds to observe recurring job execution..."
|
|
61
|
+
echo " (Check the bridge logs to see the job execute)"
|
|
62
|
+
sleep 65
|
|
63
|
+
echo ""
|
|
64
|
+
|
|
65
|
+
# Test 7: Delete the recurring schedule
|
|
66
|
+
echo "7. Deleting recurring schedule..."
|
|
67
|
+
curl -s -X DELETE "${BASE_URL}/api/schedule/${SCHEDULE_ID}" | jq .
|
|
68
|
+
echo ""
|
|
69
|
+
|
|
70
|
+
# Test 8: List schedules again (should only have one-time if it hasn't run yet)
|
|
71
|
+
echo "8. Listing schedules after deletion..."
|
|
72
|
+
curl -s "${BASE_URL}/api/schedule" | jq .
|
|
73
|
+
echo ""
|
|
74
|
+
|
|
75
|
+
echo "=== Test Complete ==="
|
|
76
|
+
echo ""
|
|
77
|
+
echo "Note: Make sure the bridge is running before executing this script."
|
|
78
|
+
echo "To run the bridge: npm run dev"
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "NodeNext",
|
|
5
|
+
"moduleResolution": "NodeNext",
|
|
6
|
+
"outDir": "dist",
|
|
7
|
+
"rootDir": ".",
|
|
8
|
+
"strict": false,
|
|
9
|
+
"skipLibCheck": true,
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"resolveJsonModule": true,
|
|
12
|
+
"forceConsistentCasingInFileNames": true
|
|
13
|
+
},
|
|
14
|
+
"include": [
|
|
15
|
+
"index.ts",
|
|
16
|
+
"bin/**/*.ts",
|
|
17
|
+
"messaging/**/*.ts"
|
|
18
|
+
],
|
|
19
|
+
"exclude": [
|
|
20
|
+
"dist",
|
|
21
|
+
"node_modules"
|
|
22
|
+
]
|
|
23
|
+
}
|
package/utils/error.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function getErrorMessage(error: unknown, fallback = 'Unknown error'): string {
|
|
2
|
+
if (error instanceof Error) {
|
|
3
|
+
return error.message;
|
|
4
|
+
}
|
|
5
|
+
if (typeof error === 'string') {
|
|
6
|
+
return error;
|
|
7
|
+
}
|
|
8
|
+
if (error === null || error === undefined) {
|
|
9
|
+
return fallback;
|
|
10
|
+
}
|
|
11
|
+
return String(error);
|
|
12
|
+
}
|