@mmmbuto/qwen-code-termux 0.6.4-termux → 0.6.402

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.
@@ -0,0 +1,206 @@
1
+ #!/data/data/com.termux/files/usr/bin/bash
2
+ # TERMUX PATCH: Termux-API Tool Call dispatcher for Qwen Code
3
+ # Usage: call.sh <tool_name> < params.json
4
+ # Author: DioNanos
5
+
6
+ TOOL_NAME="$1"
7
+
8
+ # Read JSON params from stdin
9
+ PARAMS=$(cat)
10
+
11
+ case "$TOOL_NAME" in
12
+ termux_battery_status)
13
+ termux-battery-status
14
+ ;;
15
+
16
+ termux_clipboard_get)
17
+ termux-clipboard-get
18
+ ;;
19
+
20
+ termux_clipboard_set)
21
+ TEXT=$(echo "$PARAMS" | jq -r '.text // empty')
22
+ if [ -n "$TEXT" ]; then
23
+ echo "$TEXT" | termux-clipboard-set
24
+ echo '{"status": "ok"}'
25
+ else
26
+ echo '{"error": "text parameter required"}'
27
+ exit 1
28
+ fi
29
+ ;;
30
+
31
+ termux_toast)
32
+ MSG=$(echo "$PARAMS" | jq -r '.message // empty')
33
+ SHORT=$(echo "$PARAMS" | jq -r '.short // false')
34
+ GRAVITY=$(echo "$PARAMS" | jq -r '.gravity // empty')
35
+ BG=$(echo "$PARAMS" | jq -r '.background_color // empty')
36
+ TC=$(echo "$PARAMS" | jq -r '.text_color // empty')
37
+
38
+ ARGS=""
39
+ [ "$SHORT" = "true" ] && ARGS="$ARGS -s"
40
+ [ -n "$GRAVITY" ] && ARGS="$ARGS -g $GRAVITY"
41
+ [ -n "$BG" ] && ARGS="$ARGS -c $BG"
42
+ [ -n "$TC" ] && ARGS="$ARGS -C $TC"
43
+
44
+ echo "$MSG" | termux-toast $ARGS
45
+ echo '{"status": "ok"}'
46
+ ;;
47
+
48
+ termux_notification)
49
+ TITLE=$(echo "$PARAMS" | jq -r '.title // empty')
50
+ CONTENT=$(echo "$PARAMS" | jq -r '.content // empty')
51
+ ID=$(echo "$PARAMS" | jq -r '.id // empty')
52
+ PRIORITY=$(echo "$PARAMS" | jq -r '.priority // empty')
53
+ SOUND=$(echo "$PARAMS" | jq -r '.sound // false')
54
+ VIBRATE=$(echo "$PARAMS" | jq -r '.vibrate // empty')
55
+ ONGOING=$(echo "$PARAMS" | jq -r '.ongoing // false')
56
+ GROUP=$(echo "$PARAMS" | jq -r '.group // empty')
57
+
58
+ ARGS="-t \"$TITLE\" -c \"$CONTENT\""
59
+ [ -n "$ID" ] && ARGS="$ARGS --id $ID"
60
+ [ -n "$PRIORITY" ] && ARGS="$ARGS --priority $PRIORITY"
61
+ [ "$SOUND" = "true" ] && ARGS="$ARGS --sound"
62
+ [ -n "$VIBRATE" ] && ARGS="$ARGS --vibrate $VIBRATE"
63
+ [ "$ONGOING" = "true" ] && ARGS="$ARGS --ongoing"
64
+ [ -n "$GROUP" ] && ARGS="$ARGS --group $GROUP"
65
+
66
+ eval "termux-notification $ARGS"
67
+ echo '{"status": "ok"}'
68
+ ;;
69
+
70
+ termux_notification_remove)
71
+ ID=$(echo "$PARAMS" | jq -r '.id // empty')
72
+ termux-notification-remove --id "$ID"
73
+ echo '{"status": "ok"}'
74
+ ;;
75
+
76
+ termux_tts_speak)
77
+ TEXT=$(echo "$PARAMS" | jq -r '.text // empty')
78
+ LANG=$(echo "$PARAMS" | jq -r '.language // empty')
79
+ PITCH=$(echo "$PARAMS" | jq -r '.pitch // empty')
80
+ RATE=$(echo "$PARAMS" | jq -r '.rate // empty')
81
+
82
+ ARGS=""
83
+ [ -n "$LANG" ] && ARGS="$ARGS -l $LANG"
84
+ [ -n "$PITCH" ] && ARGS="$ARGS -p $PITCH"
85
+ [ -n "$RATE" ] && ARGS="$ARGS -r $RATE"
86
+
87
+ echo "$TEXT" | termux-tts-speak $ARGS
88
+ echo '{"status": "ok"}'
89
+ ;;
90
+
91
+ termux_vibrate)
92
+ DUR=$(echo "$PARAMS" | jq -r '.duration // 1000')
93
+ FORCE=$(echo "$PARAMS" | jq -r '.force // false')
94
+
95
+ ARGS="-d $DUR"
96
+ [ "$FORCE" = "true" ] && ARGS="$ARGS -f"
97
+
98
+ termux-vibrate $ARGS
99
+ echo '{"status": "ok"}'
100
+ ;;
101
+
102
+ termux_torch)
103
+ STATE=$(echo "$PARAMS" | jq -r '.state // empty')
104
+ if [ "$STATE" = "on" ]; then
105
+ termux-torch on
106
+ echo '{"status": "torch_on"}'
107
+ elif [ "$STATE" = "off" ]; then
108
+ termux-torch off
109
+ echo '{"status": "torch_off"}'
110
+ else
111
+ termux-torch
112
+ echo '{"status": "ok"}'
113
+ fi
114
+ ;;
115
+
116
+ termux_wifi_scan)
117
+ termux-wifi-scan
118
+ ;;
119
+
120
+ termux_wifi_connection)
121
+ termux-wifi-connectioninfo
122
+ ;;
123
+
124
+ termux_location)
125
+ PROVIDER=$(echo "$PARAMS" | jq -r '.provider // "gps"')
126
+ termux-location -p "$PROVIDER"
127
+ ;;
128
+
129
+ termux_camera_info)
130
+ termux-camera-info
131
+ ;;
132
+
133
+ termux_camera_photo)
134
+ CAM_ID=$(echo "$PARAMS" | jq -r '.camera_id // "0"')
135
+ OUTPUT=$(echo "$PARAMS" | jq -r '.output_file // empty')
136
+ ARGS="-c $CAM_ID"
137
+ [ -n "$OUTPUT" ] && ARGS="$ARGS $OUTPUT"
138
+ termux-camera-photo $ARGS
139
+ ;;
140
+
141
+ termux_dialog)
142
+ TITLE=$(echo "$PARAMS" | jq -r '.title // empty')
143
+ MESSAGE=$(echo "$PARAMS" | jq -r '.message // empty')
144
+ HINT=$(echo "$PARAMS" | jq -r '.hint // empty')
145
+ ARGS="-t \"$TITLE\""
146
+ [ -n "$MESSAGE" ] && ARGS="$ARGS -m \"$MESSAGE\""
147
+ [ -n "$HINT" ] && ARGS="$ARGS -i \"$HINT\""
148
+ termux-dialog $ARGS
149
+ ;;
150
+
151
+ termux_share)
152
+ TEXT=$(echo "$PARAMS" | jq -r '.text // empty')
153
+ ACTION=$(echo "$PARAMS" | jq -r '.action // empty')
154
+ TITLE=$(echo "$PARAMS" | jq -r '.title // empty')
155
+ ARGS=""
156
+ [ -n "$TEXT" ] && ARGS="$ARGS -c \"$TEXT\""
157
+ [ -n "$ACTION" ] && ARGS="$ARGS -a \"$ACTION\""
158
+ [ -n "$TITLE" ] && ARGS="$ARGS -t \"$TITLE\""
159
+ eval "termux-share $ARGS"
160
+ echo '{"status": "ok"}'
161
+ ;;
162
+
163
+ termux_volume)
164
+ STREAM=$(echo "$PARAMS" | jq -r '.stream // empty')
165
+ VOLUME=$(echo "$PARAMS" | jq -r '.volume // empty')
166
+ termux-volume "$STREAM" "$VOLUME"
167
+ echo '{"status": "ok"}'
168
+ ;;
169
+
170
+ termux_telephony_call)
171
+ NUMBER=$(echo "$PARAMS" | jq -r '.number // empty')
172
+ termux-telephony-call "$NUMBER"
173
+ echo '{"status": "ok"}'
174
+ ;;
175
+
176
+ termux_telephony_cellinfo)
177
+ termux-telephony-cellinfo
178
+ ;;
179
+
180
+ termux_fingerprint)
181
+ TIMEOUT=$(echo "$PARAMS" | jq -r '.timeout // "30"')
182
+ termux-fingerprint -t "$TIMEOUT"
183
+ ;;
184
+
185
+ termux_sensor_info)
186
+ SENSOR_TYPE=$(echo "$PARAMS" | jq -r '.sensor_type // empty')
187
+ if [ -n "$SENSOR_TYPE" ]; then
188
+ termux-sensor -l "$SENSOR_TYPE"
189
+ else
190
+ termux-sensor -l
191
+ fi
192
+ ;;
193
+
194
+ termux_sensor_read)
195
+ SENSOR=$(echo "$PARAMS" | jq -r '.sensor_name // empty')
196
+ DELAY=$(echo "$PARAMS" | jq -r '.delay // "1000"')
197
+ LIMIT=$(echo "$PARAMS" | jq -r '.limit // "1"')
198
+ ARGS="-s $SENSOR -d $DELAY -n $LIMIT"
199
+ termux-sensor $ARGS
200
+ ;;
201
+
202
+ *)
203
+ echo '{"error": "Unknown tool: '"$TOOL_NAME"'"}'
204
+ exit 1
205
+ ;;
206
+ esac
@@ -0,0 +1,382 @@
1
+ #!/data/data/com.termux/files/usr/bin/bash
2
+ # TERMUX PATCH: Termux-API Tool Discovery for Qwen Code
3
+ # Returns FunctionDeclarations for Termux commands
4
+ # Author: DioNanos
5
+
6
+ cat << 'EOF'
7
+ [
8
+ {
9
+ "name": "termux_battery_status",
10
+ "description": "Get device battery status including percentage, health, temperature, and charging state. Returns JSON with: health (GOOD/OVERHEAT/DEAD/etc), percentage (0-100), plugged (AC/USB/WIRELESS/UNPLUGGED), status (CHARGING/DISCHARGING/FULL/NOT_CHARGING), temperature (Celsius), current (microamperes).",
11
+ "parametersJsonSchema": {
12
+ "type": "object",
13
+ "properties": {}
14
+ }
15
+ },
16
+ {
17
+ "name": "termux_clipboard_get",
18
+ "description": "Read the current content of the Android clipboard. Returns the clipboard text content to stdout.",
19
+ "parametersJsonSchema": {
20
+ "type": "object",
21
+ "properties": {}
22
+ }
23
+ },
24
+ {
25
+ "name": "termux_clipboard_set",
26
+ "description": "Set the Android clipboard content. The text parameter will be copied to the system clipboard.",
27
+ "parametersJsonSchema": {
28
+ "type": "object",
29
+ "properties": {
30
+ "text": {
31
+ "type": "string",
32
+ "description": "Text to copy to clipboard"
33
+ }
34
+ },
35
+ "required": ["text"]
36
+ }
37
+ },
38
+ {
39
+ "name": "termux_toast",
40
+ "description": "Show a toast notification message on screen. Optional parameters control appearance and duration.",
41
+ "parametersJsonSchema": {
42
+ "type": "object",
43
+ "properties": {
44
+ "message": {
45
+ "type": "string",
46
+ "description": "Message to display in toast"
47
+ },
48
+ "short": {
49
+ "type": "boolean",
50
+ "description": "Use short duration (default: false for long)"
51
+ },
52
+ "gravity": {
53
+ "type": "string",
54
+ "enum": ["top", "middle", "bottom"],
55
+ "description": "Toast position on screen"
56
+ },
57
+ "background_color": {
58
+ "type": "string",
59
+ "description": "Background color (e.g., 'red', '#FF0000')"
60
+ },
61
+ "text_color": {
62
+ "type": "string",
63
+ "description": "Text color (e.g., 'white', '#FFFFFF')"
64
+ }
65
+ },
66
+ "required": ["message"]
67
+ }
68
+ },
69
+ {
70
+ "name": "termux_notification",
71
+ "description": "Create a persistent notification in the Android notification shade. Supports title, content, icons, actions, buttons, LED, sound, and vibration.",
72
+ "parametersJsonSchema": {
73
+ "type": "object",
74
+ "properties": {
75
+ "title": {
76
+ "type": "string",
77
+ "description": "Notification title"
78
+ },
79
+ "content": {
80
+ "type": "string",
81
+ "description": "Notification body text"
82
+ },
83
+ "id": {
84
+ "type": "string",
85
+ "description": "Unique ID to update/remove notification later"
86
+ },
87
+ "priority": {
88
+ "type": "string",
89
+ "enum": ["high", "low", "default"],
90
+ "description": "Notification priority"
91
+ },
92
+ "sound": {
93
+ "type": "boolean",
94
+ "description": "Play notification sound"
95
+ },
96
+ "vibrate": {
97
+ "type": "string",
98
+ "description": "Vibration pattern (e.g., '500,500,500')"
99
+ },
100
+ "ongoing": {
101
+ "type": "boolean",
102
+ "description": "Make notification ongoing (not dismissible)"
103
+ },
104
+ "group": {
105
+ "type": "string",
106
+ "description": "Notification group key"
107
+ }
108
+ },
109
+ "required": []
110
+ }
111
+ },
112
+ {
113
+ "name": "termux_notification_remove",
114
+ "description": "Remove a previously created notification by ID.",
115
+ "parametersJsonSchema": {
116
+ "type": "object",
117
+ "properties": {
118
+ "id": {
119
+ "type": "string",
120
+ "description": "Notification ID to remove"
121
+ }
122
+ },
123
+ "required": ["id"]
124
+ }
125
+ },
126
+ {
127
+ "name": "termux_tts_speak",
128
+ "description": "Speak text aloud using Android text-to-speech engine. Supports language, pitch, and rate parameters.",
129
+ "parametersJsonSchema": {
130
+ "type": "object",
131
+ "properties": {
132
+ "text": {
133
+ "type": "string",
134
+ "description": "Text to speak"
135
+ },
136
+ "language": {
137
+ "type": "string",
138
+ "description": "Language code (e.g., 'en-US', 'it-IT', 'ja-JP')"
139
+ },
140
+ "pitch": {
141
+ "type": "string",
142
+ "description": "Pitch adjustment (e.g., '1.0' for normal)"
143
+ },
144
+ "rate": {
145
+ "type": "string",
146
+ "description": "Speech rate (e.g., '1.0' for normal)"
147
+ }
148
+ },
149
+ "required": ["text"]
150
+ }
151
+ },
152
+ {
153
+ "name": "termux_vibrate",
154
+ "description": "Vibrate the device for specified duration. Can force vibration even if silent mode.",
155
+ "parametersJsonSchema": {
156
+ "type": "object",
157
+ "properties": {
158
+ "duration": {
159
+ "type": "string",
160
+ "description": "Vibration duration in milliseconds (default: 1000)"
161
+ },
162
+ "force": {
163
+ "type": "boolean",
164
+ "description": "Force vibration even in silent mode"
165
+ }
166
+ },
167
+ "required": []
168
+ }
169
+ },
170
+ {
171
+ "name": "termux_torch",
172
+ "description": "Control the camera flash/torch. Turn on, off, or query current state.",
173
+ "parametersJsonSchema": {
174
+ "type": "object",
175
+ "properties": {
176
+ "state": {
177
+ "type": "string",
178
+ "enum": ["on", "off"],
179
+ "description": "Torch state: on or off"
180
+ }
181
+ },
182
+ "required": ["state"]
183
+ }
184
+ },
185
+ {
186
+ "name": "termux_wifi_scan",
187
+ "description": "Scan for WiFi networks and return information about nearby access points.",
188
+ "parametersJsonSchema": {
189
+ "type": "object",
190
+ "properties": {},
191
+ "required": []
192
+ }
193
+ },
194
+ {
195
+ "name": "termux_wifi_connection",
196
+ "description": "Get current WiFi connection information including SSID, BSSID, frequency, and signal strength.",
197
+ "parametersJsonSchema": {
198
+ "type": "object",
199
+ "properties": {},
200
+ "required": []
201
+ }
202
+ },
203
+ {
204
+ "name": "termux_location",
205
+ "description": "Get current device location including latitude, longitude, altitude, accuracy, and bearing.",
206
+ "parametersJsonSchema": {
207
+ "type": "object",
208
+ "properties": {
209
+ "provider": {
210
+ "type": "string",
211
+ "enum": ["gps", "network", "passive"],
212
+ "description": "Location provider (default: gps)"
213
+ }
214
+ },
215
+ "required": []
216
+ }
217
+ },
218
+ {
219
+ "name": "termux_camera_info",
220
+ "description": "Get information about device cameras including IDs, focal lengths, and orientations.",
221
+ "parametersJsonSchema": {
222
+ "type": "object",
223
+ "properties": {},
224
+ "required": []
225
+ }
226
+ },
227
+ {
228
+ "name": "termux_camera_photo",
229
+ "description": "Take a photo with the specified camera. Returns file path to saved image.",
230
+ "parametersJsonSchema": {
231
+ "type": "object",
232
+ "properties": {
233
+ "camera_id": {
234
+ "type": "string",
235
+ "description": "Camera ID (from termux_camera_info)"
236
+ },
237
+ "output_file": {
238
+ "type": "string",
239
+ "description": "Output file path for saved photo"
240
+ }
241
+ },
242
+ "required": ["camera_id"]
243
+ }
244
+ },
245
+ {
246
+ "name": "termux_dialog",
247
+ "description": "Show a dialog with text input. Returns user input or empty if cancelled.",
248
+ "parametersJsonSchema": {
249
+ "type": "object",
250
+ "properties": {
251
+ "title": {
252
+ "type": "string",
253
+ "description": "Dialog title"
254
+ },
255
+ "message": {
256
+ "type": "string",
257
+ "description": "Dialog message/prompt"
258
+ },
259
+ "hint": {
260
+ "type": "string",
261
+ "description": "Input hint text"
262
+ }
263
+ },
264
+ "required": ["title"]
265
+ }
266
+ },
267
+ {
268
+ "name": "termux_share",
269
+ "description": "Share text or file via Android share sheet.",
270
+ "parametersJsonSchema": {
271
+ "type": "object",
272
+ "properties": {
273
+ "text": {
274
+ "type": "string",
275
+ "description": "Text content to share"
276
+ },
277
+ "action": {
278
+ "type": "string",
279
+ "description": "Optional action to handle shared content"
280
+ },
281
+ "title": {
282
+ "type": "string",
283
+ "description": "Title for share sheet"
284
+ }
285
+ },
286
+ "required": []
287
+ }
288
+ },
289
+ {
290
+ "name": "termux_volume",
291
+ "description": "Control device volume levels for different streams.",
292
+ "parametersJsonSchema": {
293
+ "type": "object",
294
+ "properties": {
295
+ "stream": {
296
+ "type": "string",
297
+ "enum": ["alarm", "music", "notification", "ring", "system"],
298
+ "description": "Audio stream to control"
299
+ },
300
+ "volume": {
301
+ "type": "string",
302
+ "description": "Volume level (0-100 or 'mute', 'raise', 'lower')"
303
+ }
304
+ },
305
+ "required": ["stream"]
306
+ }
307
+ },
308
+ {
309
+ "name": "termux_telephony_call",
310
+ "description": "Initiate a phone call to the specified number.",
311
+ "parametersJsonSchema": {
312
+ "type": "object",
313
+ "properties": {
314
+ "number": {
315
+ "type": "string",
316
+ "description": "Phone number to call"
317
+ }
318
+ },
319
+ "required": ["number"]
320
+ }
321
+ },
322
+ {
323
+ "name": "termux_telephony_cellinfo",
324
+ "description": "Get cellular network information including operator, MCC, MNC, and LAC.",
325
+ "parametersJsonSchema": {
326
+ "type": "object",
327
+ "properties": {},
328
+ "required": []
329
+ }
330
+ },
331
+ {
332
+ "name": "termux_fingerprint",
333
+ "description": "Authenticate with fingerprint sensor or check availability.",
334
+ "parametersJsonSchema": {
335
+ "type": "object",
336
+ "properties": {
337
+ "timeout": {
338
+ "type": "string",
339
+ "description": "Timeout in seconds (default: 30)"
340
+ }
341
+ },
342
+ "required": []
343
+ }
344
+ },
345
+ {
346
+ "name": "termux_sensor_info",
347
+ "description": "Get information about available sensors on the device.",
348
+ "parametersJsonSchema": {
349
+ "type": "object",
350
+ "properties": {
351
+ "sensor_type": {
352
+ "type": "string",
353
+ "description": "Filter by sensor type (e.g., 'accelerometer', 'gyroscope')"
354
+ }
355
+ },
356
+ "required": []
357
+ }
358
+ },
359
+ {
360
+ "name": "termux_sensor_read",
361
+ "description": "Read current values from the specified sensor.",
362
+ "parametersJsonSchema": {
363
+ "type": "object",
364
+ "properties": {
365
+ "sensor_name": {
366
+ "type": "string",
367
+ "description": "Sensor name (from termux_sensor_info)"
368
+ },
369
+ "delay": {
370
+ "type": "string",
371
+ "description": "Sampling delay in milliseconds (default: 1000)"
372
+ },
373
+ "limit": {
374
+ "type": "string",
375
+ "description": "Number of readings to return (default: 1, -1 for unlimited)"
376
+ }
377
+ },
378
+ "required": ["sensor_name"]
379
+ }
380
+ }
381
+ ]
382
+ EOF
@@ -0,0 +1,51 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ import path from 'node:path';
8
+ import { fileURLToPath } from 'node:url';
9
+
10
+ // Test how paths are normalized
11
+ function testPathNormalization() {
12
+ // Use platform-agnostic path construction instead of hardcoded paths
13
+ const testPath = path.join('test', 'project', 'src', 'file.md');
14
+ const absoluteTestPath = path.resolve('test', 'project', 'src', 'file.md');
15
+
16
+ console.log('Testing path normalization:');
17
+ console.log('Relative path:', testPath);
18
+ console.log('Absolute path:', absoluteTestPath);
19
+
20
+ // Test path.join with different segments
21
+ const joinedPath = path.join('test', 'project', 'src', 'file.md');
22
+ console.log('Joined path:', joinedPath);
23
+
24
+ // Test path.normalize
25
+ console.log('Normalized relative path:', path.normalize(testPath));
26
+ console.log('Normalized absolute path:', path.normalize(absoluteTestPath));
27
+
28
+ // Test how the test would see these paths
29
+ const testContent = `--- File: ${absoluteTestPath} ---\nContent\n--- End of File: ${absoluteTestPath} ---`;
30
+ console.log('\nTest content with platform-agnostic paths:');
31
+ console.log(testContent);
32
+
33
+ // Try to match with different patterns
34
+ const marker = `--- File: ${absoluteTestPath} ---`;
35
+ console.log('\nTrying to match:', marker);
36
+ console.log('Direct match:', testContent.includes(marker));
37
+
38
+ // Test with normalized path in marker
39
+ const normalizedMarker = `--- File: ${path.normalize(absoluteTestPath)} ---`;
40
+ console.log(
41
+ 'Normalized marker match:',
42
+ testContent.includes(normalizedMarker),
43
+ );
44
+
45
+ // Test path resolution
46
+ const __filename = fileURLToPath(import.meta.url);
47
+ console.log('\nCurrent file path:', __filename);
48
+ console.log('Directory name:', path.dirname(__filename));
49
+ }
50
+
51
+ testPathNormalization();