@mmmbuto/gemini-cli-termux 0.22.7-termux → 0.24.1-termux

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 (103) hide show
  1. package/README.md +18 -78
  2. package/bundle/docs/TERMUX.md +97 -0
  3. package/bundle/docs/architecture.md +80 -0
  4. package/bundle/docs/assets/connected_devtools.png +0 -0
  5. package/bundle/docs/assets/gemini-screenshot.png +0 -0
  6. package/bundle/docs/assets/release_patch.png +0 -0
  7. package/bundle/docs/assets/theme-ansi-light.png +0 -0
  8. package/bundle/docs/assets/theme-ansi.png +0 -0
  9. package/bundle/docs/assets/theme-atom-one.png +0 -0
  10. package/bundle/docs/assets/theme-ayu-light.png +0 -0
  11. package/bundle/docs/assets/theme-ayu.png +0 -0
  12. package/bundle/docs/assets/theme-custom.png +0 -0
  13. package/bundle/docs/assets/theme-default-light.png +0 -0
  14. package/bundle/docs/assets/theme-default.png +0 -0
  15. package/bundle/docs/assets/theme-dracula.png +0 -0
  16. package/bundle/docs/assets/theme-github-light.png +0 -0
  17. package/bundle/docs/assets/theme-github.png +0 -0
  18. package/bundle/docs/assets/theme-google-light.png +0 -0
  19. package/bundle/docs/assets/theme-xcode-light.png +0 -0
  20. package/bundle/docs/changelogs/index.md +592 -0
  21. package/bundle/docs/changelogs/latest.md +225 -0
  22. package/bundle/docs/changelogs/preview.md +129 -0
  23. package/bundle/docs/changelogs/releases.md +896 -0
  24. package/bundle/docs/cli/authentication.md +3 -0
  25. package/bundle/docs/cli/checkpointing.md +94 -0
  26. package/bundle/docs/cli/commands.md +354 -0
  27. package/bundle/docs/cli/configuration.md +792 -0
  28. package/bundle/docs/cli/context-memory.md +69 -0
  29. package/bundle/docs/cli/custom-commands.md +315 -0
  30. package/bundle/docs/cli/enterprise.md +565 -0
  31. package/bundle/docs/cli/gemini-ignore.md +71 -0
  32. package/bundle/docs/cli/gemini-md.md +108 -0
  33. package/bundle/docs/cli/generation-settings.md +210 -0
  34. package/bundle/docs/cli/headless.md +388 -0
  35. package/bundle/docs/cli/index.md +63 -0
  36. package/bundle/docs/cli/keyboard-shortcuts.md +143 -0
  37. package/bundle/docs/cli/model-routing.md +37 -0
  38. package/bundle/docs/cli/model.md +62 -0
  39. package/bundle/docs/cli/sandbox.md +171 -0
  40. package/bundle/docs/cli/session-management.md +158 -0
  41. package/bundle/docs/cli/settings.md +114 -0
  42. package/bundle/docs/cli/system-prompt.md +93 -0
  43. package/bundle/docs/cli/telemetry.md +791 -0
  44. package/bundle/docs/cli/themes.md +237 -0
  45. package/bundle/docs/cli/token-caching.md +20 -0
  46. package/bundle/docs/cli/trusted-folders.md +95 -0
  47. package/bundle/docs/cli/tutorials.md +83 -0
  48. package/bundle/docs/cli/uninstall.md +47 -0
  49. package/bundle/docs/core/index.md +101 -0
  50. package/bundle/docs/core/memport.md +244 -0
  51. package/bundle/docs/core/policy-engine.md +267 -0
  52. package/bundle/docs/core/tools-api.md +131 -0
  53. package/bundle/docs/examples/proxy-script.md +83 -0
  54. package/bundle/docs/extensions/extension-releasing.md +183 -0
  55. package/bundle/docs/extensions/getting-started-extensions.md +245 -0
  56. package/bundle/docs/extensions/index.md +293 -0
  57. package/bundle/docs/faq.md +154 -0
  58. package/bundle/docs/get-started/authentication.md +321 -0
  59. package/bundle/docs/get-started/configuration-v1.md +888 -0
  60. package/bundle/docs/get-started/configuration.md +1511 -0
  61. package/bundle/docs/get-started/deployment.md +143 -0
  62. package/bundle/docs/get-started/examples.md +219 -0
  63. package/bundle/docs/get-started/gemini-3.md +116 -0
  64. package/bundle/docs/get-started/index.md +71 -0
  65. package/bundle/docs/get-started/installation.md +141 -0
  66. package/bundle/docs/hooks/best-practices.md +806 -0
  67. package/bundle/docs/hooks/index.md +665 -0
  68. package/bundle/docs/hooks/reference.md +168 -0
  69. package/bundle/docs/hooks/writing-hooks.md +1026 -0
  70. package/bundle/docs/ide-integration/ide-companion-spec.md +267 -0
  71. package/bundle/docs/ide-integration/index.md +202 -0
  72. package/bundle/docs/index.md +147 -0
  73. package/bundle/docs/integration-tests.md +211 -0
  74. package/bundle/docs/issue-and-pr-automation.md +134 -0
  75. package/bundle/docs/local-development.md +128 -0
  76. package/bundle/docs/mermaid/context.mmd +103 -0
  77. package/bundle/docs/mermaid/render-path.mmd +64 -0
  78. package/bundle/docs/npm.md +62 -0
  79. package/bundle/docs/patches/CONTEXT_MEMORY_COMPARISON.md +306 -0
  80. package/bundle/docs/patches/MERGE_TO_0.24_ANALYSIS.md +321 -0
  81. package/bundle/docs/patches/README.md +62 -0
  82. package/bundle/docs/quota-and-pricing.md +158 -0
  83. package/bundle/docs/release-confidence.md +164 -0
  84. package/bundle/docs/releases.md +540 -0
  85. package/bundle/docs/sidebar.json +297 -0
  86. package/bundle/docs/termux-api/COMMANDS.md +592 -0
  87. package/bundle/docs/termux-api/DISCOVERY_SETUP.md +670 -0
  88. package/bundle/docs/termux-api/EXECUTION_PLAN.md +532 -0
  89. package/bundle/docs/termux-api/MERGE_STRATEGY.md +325 -0
  90. package/bundle/docs/termux-api/PATCHES.md +483 -0
  91. package/bundle/docs/termux-api/README.md +416 -0
  92. package/bundle/docs/tools/file-system.md +217 -0
  93. package/bundle/docs/tools/index.md +95 -0
  94. package/bundle/docs/tools/mcp-server.md +1044 -0
  95. package/bundle/docs/tools/memory.md +54 -0
  96. package/bundle/docs/tools/shell.md +260 -0
  97. package/bundle/docs/tools/todos.md +57 -0
  98. package/bundle/docs/tools/web-fetch.md +59 -0
  99. package/bundle/docs/tools/web-search.md +42 -0
  100. package/bundle/docs/tos-privacy.md +96 -0
  101. package/bundle/docs/troubleshooting.md +158 -0
  102. package/bundle/gemini.js +8901 -6534
  103. package/package.json +10 -8
@@ -0,0 +1,670 @@
1
+ # Tool Discovery Setup for Termux-API
2
+
3
+ **Project**: gemini-cli-termux **Author**: DioNanos **Date**: 2025-12-17
4
+
5
+ ---
6
+
7
+ ## Overview
8
+
9
+ This guide explains how to set up Tool Discovery to expose Termux-API commands
10
+ to Gemini CLI without modifying the core code.
11
+
12
+ ## Prerequisites
13
+
14
+ 1. Termux with termux-api package installed:
15
+
16
+ ```bash
17
+ pkg install termux-api
18
+ ```
19
+
20
+ 2. Termux:API App installed from F-Droid
21
+
22
+ 3. Working Gemini CLI:
23
+ ```bash
24
+ gemini --version
25
+ ```
26
+
27
+ ---
28
+
29
+ ## Quick Setup
30
+
31
+ ### 1. Create config directory
32
+
33
+ ```bash
34
+ mkdir -p ~/.config/gemini/termux-tools
35
+ ```
36
+
37
+ ### 2. Create discovery script
38
+
39
+ ```bash
40
+ cat > ~/.config/gemini/termux-tools/discovery.sh << 'SCRIPT'
41
+ #!/data/data/com.termux/files/usr/bin/bash
42
+ # Termux-API Tool Discovery for Gemini CLI
43
+ # Returns FunctionDeclarations for Termux commands
44
+
45
+ cat << 'EOF'
46
+ [
47
+ {
48
+ "name": "termux_battery_status",
49
+ "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).",
50
+ "parametersJsonSchema": {
51
+ "type": "object",
52
+ "properties": {}
53
+ }
54
+ },
55
+ {
56
+ "name": "termux_clipboard_get",
57
+ "description": "Read the current content of the Android clipboard. Returns the clipboard text content to stdout.",
58
+ "parametersJsonSchema": {
59
+ "type": "object",
60
+ "properties": {}
61
+ }
62
+ },
63
+ {
64
+ "name": "termux_clipboard_set",
65
+ "description": "Set the Android clipboard content. The text parameter will be copied to the system clipboard.",
66
+ "parametersJsonSchema": {
67
+ "type": "object",
68
+ "properties": {
69
+ "text": {
70
+ "type": "string",
71
+ "description": "Text to copy to clipboard"
72
+ }
73
+ },
74
+ "required": ["text"]
75
+ }
76
+ },
77
+ {
78
+ "name": "termux_toast",
79
+ "description": "Show a toast notification message on screen. Optional parameters control appearance and duration.",
80
+ "parametersJsonSchema": {
81
+ "type": "object",
82
+ "properties": {
83
+ "message": {
84
+ "type": "string",
85
+ "description": "Message to display in toast"
86
+ },
87
+ "short": {
88
+ "type": "boolean",
89
+ "description": "Use short duration (default: false for long)"
90
+ },
91
+ "gravity": {
92
+ "type": "string",
93
+ "enum": ["top", "middle", "bottom"],
94
+ "description": "Toast position on screen"
95
+ },
96
+ "background_color": {
97
+ "type": "string",
98
+ "description": "Background color (e.g., 'red', '#FF0000')"
99
+ },
100
+ "text_color": {
101
+ "type": "string",
102
+ "description": "Text color (e.g., 'white', '#FFFFFF')"
103
+ }
104
+ },
105
+ "required": ["message"]
106
+ }
107
+ },
108
+ {
109
+ "name": "termux_notification",
110
+ "description": "Create a persistent notification in the Android notification shade. Supports title, content, icons, actions, buttons, LED, sound, and vibration.",
111
+ "parametersJsonSchema": {
112
+ "type": "object",
113
+ "properties": {
114
+ "title": {
115
+ "type": "string",
116
+ "description": "Notification title"
117
+ },
118
+ "content": {
119
+ "type": "string",
120
+ "description": "Notification body text"
121
+ },
122
+ "id": {
123
+ "type": "string",
124
+ "description": "Unique ID to update/remove notification later"
125
+ },
126
+ "priority": {
127
+ "type": "string",
128
+ "enum": ["high", "low", "default"],
129
+ "description": "Notification priority"
130
+ },
131
+ "sound": {
132
+ "type": "boolean",
133
+ "description": "Play notification sound"
134
+ },
135
+ "vibrate": {
136
+ "type": "string",
137
+ "description": "Vibration pattern (e.g., '500,500,500')"
138
+ },
139
+ "ongoing": {
140
+ "type": "boolean",
141
+ "description": "Make notification persistent (cannot be swiped away)"
142
+ }
143
+ },
144
+ "required": ["title", "content"]
145
+ }
146
+ },
147
+ {
148
+ "name": "termux_notification_remove",
149
+ "description": "Remove a notification by its ID.",
150
+ "parametersJsonSchema": {
151
+ "type": "object",
152
+ "properties": {
153
+ "id": {
154
+ "type": "string",
155
+ "description": "Notification ID to remove"
156
+ }
157
+ },
158
+ "required": ["id"]
159
+ }
160
+ },
161
+ {
162
+ "name": "termux_tts_speak",
163
+ "description": "Speak text using Android Text-to-Speech engine. Supports language, pitch, and rate settings.",
164
+ "parametersJsonSchema": {
165
+ "type": "object",
166
+ "properties": {
167
+ "text": {
168
+ "type": "string",
169
+ "description": "Text to speak"
170
+ },
171
+ "language": {
172
+ "type": "string",
173
+ "description": "Language code (e.g., 'en', 'it', 'de')"
174
+ },
175
+ "pitch": {
176
+ "type": "number",
177
+ "description": "Pitch multiplier (default: 1.0)"
178
+ },
179
+ "rate": {
180
+ "type": "number",
181
+ "description": "Speech rate multiplier (default: 1.0)"
182
+ }
183
+ },
184
+ "required": ["text"]
185
+ }
186
+ },
187
+ {
188
+ "name": "termux_vibrate",
189
+ "description": "Vibrate the device for specified duration.",
190
+ "parametersJsonSchema": {
191
+ "type": "object",
192
+ "properties": {
193
+ "duration": {
194
+ "type": "integer",
195
+ "description": "Vibration duration in milliseconds (default: 1000)"
196
+ },
197
+ "force": {
198
+ "type": "boolean",
199
+ "description": "Vibrate even if device is in silent mode"
200
+ }
201
+ }
202
+ }
203
+ },
204
+ {
205
+ "name": "termux_torch",
206
+ "description": "Control the device flashlight/torch.",
207
+ "parametersJsonSchema": {
208
+ "type": "object",
209
+ "properties": {
210
+ "state": {
211
+ "type": "string",
212
+ "enum": ["on", "off"],
213
+ "description": "Turn torch on or off"
214
+ }
215
+ },
216
+ "required": ["state"]
217
+ }
218
+ },
219
+ {
220
+ "name": "termux_wifi_connectioninfo",
221
+ "description": "Get current WiFi connection information. Returns JSON with SSID, BSSID, IP address, link speed, RSSI signal strength, and more.",
222
+ "parametersJsonSchema": {
223
+ "type": "object",
224
+ "properties": {}
225
+ }
226
+ },
227
+ {
228
+ "name": "termux_location",
229
+ "description": "Get device GPS location. Returns JSON with latitude, longitude, altitude, accuracy, speed, bearing, and provider information.",
230
+ "parametersJsonSchema": {
231
+ "type": "object",
232
+ "properties": {
233
+ "provider": {
234
+ "type": "string",
235
+ "enum": ["gps", "network", "passive"],
236
+ "description": "Location provider (gps=high accuracy, network=fast, passive=lowest power)"
237
+ },
238
+ "request": {
239
+ "type": "string",
240
+ "enum": ["once", "last", "updates"],
241
+ "description": "Request type: once (single fix), last (cached), updates (continuous)"
242
+ }
243
+ }
244
+ }
245
+ },
246
+ {
247
+ "name": "termux_audio_info",
248
+ "description": "Get audio system information including speaker, bluetooth, and headset states.",
249
+ "parametersJsonSchema": {
250
+ "type": "object",
251
+ "properties": {}
252
+ }
253
+ },
254
+ {
255
+ "name": "termux_volume",
256
+ "description": "Get or set system volume levels. Without parameters returns all volume levels. With parameters sets specific stream volume.",
257
+ "parametersJsonSchema": {
258
+ "type": "object",
259
+ "properties": {
260
+ "stream": {
261
+ "type": "string",
262
+ "enum": ["alarm", "music", "notification", "ring", "system", "call"],
263
+ "description": "Audio stream to control"
264
+ },
265
+ "volume": {
266
+ "type": "integer",
267
+ "description": "Volume level to set (0-15 typically)"
268
+ }
269
+ }
270
+ }
271
+ },
272
+ {
273
+ "name": "termux_brightness",
274
+ "description": "Set screen brightness level.",
275
+ "parametersJsonSchema": {
276
+ "type": "object",
277
+ "properties": {
278
+ "brightness": {
279
+ "type": "string",
280
+ "description": "Brightness value 0-255 or 'auto'"
281
+ }
282
+ },
283
+ "required": ["brightness"]
284
+ }
285
+ },
286
+ {
287
+ "name": "termux_camera_info",
288
+ "description": "Get information about available cameras. Returns JSON array with camera IDs, facing direction, and supported resolutions.",
289
+ "parametersJsonSchema": {
290
+ "type": "object",
291
+ "properties": {}
292
+ }
293
+ },
294
+ {
295
+ "name": "termux_camera_photo",
296
+ "description": "Take a photo with the device camera.",
297
+ "parametersJsonSchema": {
298
+ "type": "object",
299
+ "properties": {
300
+ "camera_id": {
301
+ "type": "integer",
302
+ "description": "Camera ID (0=back, 1=front typically)"
303
+ },
304
+ "output_file": {
305
+ "type": "string",
306
+ "description": "Output file path for the photo"
307
+ }
308
+ },
309
+ "required": ["output_file"]
310
+ }
311
+ },
312
+ {
313
+ "name": "termux_dialog",
314
+ "description": "Show an interactive dialog to the user. Supports various input types.",
315
+ "parametersJsonSchema": {
316
+ "type": "object",
317
+ "properties": {
318
+ "title": {
319
+ "type": "string",
320
+ "description": "Dialog title"
321
+ },
322
+ "type": {
323
+ "type": "string",
324
+ "enum": ["confirm", "text", "spinner", "date", "time", "counter"],
325
+ "description": "Dialog type"
326
+ },
327
+ "values": {
328
+ "type": "string",
329
+ "description": "Comma-separated values for spinner/radio"
330
+ },
331
+ "hint": {
332
+ "type": "string",
333
+ "description": "Input hint for text dialogs"
334
+ }
335
+ }
336
+ }
337
+ },
338
+ {
339
+ "name": "termux_share",
340
+ "description": "Share content using Android share intent.",
341
+ "parametersJsonSchema": {
342
+ "type": "object",
343
+ "properties": {
344
+ "text": {
345
+ "type": "string",
346
+ "description": "Text to share"
347
+ },
348
+ "file": {
349
+ "type": "string",
350
+ "description": "File path to share"
351
+ },
352
+ "title": {
353
+ "type": "string",
354
+ "description": "Share dialog title"
355
+ },
356
+ "action": {
357
+ "type": "string",
358
+ "enum": ["send", "view", "edit"],
359
+ "description": "Share action type"
360
+ }
361
+ }
362
+ }
363
+ },
364
+ {
365
+ "name": "termux_open_url",
366
+ "description": "Open a URL in the default browser.",
367
+ "parametersJsonSchema": {
368
+ "type": "object",
369
+ "properties": {
370
+ "url": {
371
+ "type": "string",
372
+ "description": "URL to open"
373
+ }
374
+ },
375
+ "required": ["url"]
376
+ }
377
+ }
378
+ ]
379
+ EOF
380
+ SCRIPT
381
+ chmod +x ~/.config/gemini/termux-tools/discovery.sh
382
+ ```
383
+
384
+ ### 3. Create call script
385
+
386
+ ```bash
387
+ cat > ~/.config/gemini/termux-tools/call.sh << 'SCRIPT'
388
+ #!/data/data/com.termux/files/usr/bin/bash
389
+ # Termux-API Tool Call dispatcher for Gemini CLI
390
+ # Usage: call.sh <tool_name> < params.json
391
+
392
+ TOOL_NAME="$1"
393
+
394
+ # Read JSON params from stdin
395
+ PARAMS=$(cat)
396
+
397
+ case "$TOOL_NAME" in
398
+ termux_battery_status)
399
+ termux-battery-status
400
+ ;;
401
+
402
+ termux_clipboard_get)
403
+ termux-clipboard-get
404
+ ;;
405
+
406
+ termux_clipboard_set)
407
+ TEXT=$(echo "$PARAMS" | jq -r '.text // empty')
408
+ if [ -n "$TEXT" ]; then
409
+ echo "$TEXT" | termux-clipboard-set
410
+ echo '{"status": "ok"}'
411
+ else
412
+ echo '{"error": "text parameter required"}'
413
+ exit 1
414
+ fi
415
+ ;;
416
+
417
+ termux_toast)
418
+ MSG=$(echo "$PARAMS" | jq -r '.message // empty')
419
+ SHORT=$(echo "$PARAMS" | jq -r '.short // false')
420
+ GRAVITY=$(echo "$PARAMS" | jq -r '.gravity // empty')
421
+ BG=$(echo "$PARAMS" | jq -r '.background_color // empty')
422
+ TC=$(echo "$PARAMS" | jq -r '.text_color // empty')
423
+
424
+ ARGS=""
425
+ [ "$SHORT" = "true" ] && ARGS="$ARGS -s"
426
+ [ -n "$GRAVITY" ] && ARGS="$ARGS -g $GRAVITY"
427
+ [ -n "$BG" ] && ARGS="$ARGS -c $BG"
428
+ [ -n "$TC" ] && ARGS="$ARGS -C $TC"
429
+
430
+ echo "$MSG" | termux-toast $ARGS
431
+ echo '{"status": "ok"}'
432
+ ;;
433
+
434
+ termux_notification)
435
+ TITLE=$(echo "$PARAMS" | jq -r '.title // empty')
436
+ CONTENT=$(echo "$PARAMS" | jq -r '.content // empty')
437
+ ID=$(echo "$PARAMS" | jq -r '.id // empty')
438
+ PRIORITY=$(echo "$PARAMS" | jq -r '.priority // empty')
439
+ SOUND=$(echo "$PARAMS" | jq -r '.sound // false')
440
+ VIBRATE=$(echo "$PARAMS" | jq -r '.vibrate // empty')
441
+ ONGOING=$(echo "$PARAMS" | jq -r '.ongoing // false')
442
+
443
+ ARGS="-t \"$TITLE\" -c \"$CONTENT\""
444
+ [ -n "$ID" ] && ARGS="$ARGS --id $ID"
445
+ [ -n "$PRIORITY" ] && ARGS="$ARGS --priority $PRIORITY"
446
+ [ "$SOUND" = "true" ] && ARGS="$ARGS --sound"
447
+ [ -n "$VIBRATE" ] && ARGS="$ARGS --vibrate $VIBRATE"
448
+ [ "$ONGOING" = "true" ] && ARGS="$ARGS --ongoing"
449
+
450
+ eval "termux-notification $ARGS"
451
+ echo '{"status": "ok"}'
452
+ ;;
453
+
454
+ termux_notification_remove)
455
+ ID=$(echo "$PARAMS" | jq -r '.id // empty')
456
+ termux-notification-remove --id "$ID"
457
+ echo '{"status": "ok"}'
458
+ ;;
459
+
460
+ termux_tts_speak)
461
+ TEXT=$(echo "$PARAMS" | jq -r '.text // empty')
462
+ LANG=$(echo "$PARAMS" | jq -r '.language // empty')
463
+ PITCH=$(echo "$PARAMS" | jq -r '.pitch // empty')
464
+ RATE=$(echo "$PARAMS" | jq -r '.rate // empty')
465
+
466
+ ARGS=""
467
+ [ -n "$LANG" ] && ARGS="$ARGS -l $LANG"
468
+ [ -n "$PITCH" ] && ARGS="$ARGS -p $PITCH"
469
+ [ -n "$RATE" ] && ARGS="$ARGS -r $RATE"
470
+
471
+ echo "$TEXT" | termux-tts-speak $ARGS
472
+ echo '{"status": "ok"}'
473
+ ;;
474
+
475
+ termux_vibrate)
476
+ DUR=$(echo "$PARAMS" | jq -r '.duration // 1000')
477
+ FORCE=$(echo "$PARAMS" | jq -r '.force // false')
478
+
479
+ ARGS="-d $DUR"
480
+ [ "$FORCE" = "true" ] && ARGS="$ARGS -f"
481
+
482
+ termux-vibrate $ARGS
483
+ echo '{"status": "ok"}'
484
+ ;;
485
+
486
+ termux_torch)
487
+ STATE=$(echo "$PARAMS" | jq -r '.state // empty')
488
+ termux-torch "$STATE"
489
+ echo '{"status": "ok"}'
490
+ ;;
491
+
492
+ termux_wifi_connectioninfo)
493
+ termux-wifi-connectioninfo
494
+ ;;
495
+
496
+ termux_location)
497
+ PROVIDER=$(echo "$PARAMS" | jq -r '.provider // "gps"')
498
+ REQUEST=$(echo "$PARAMS" | jq -r '.request // "once"')
499
+ termux-location -p "$PROVIDER" -r "$REQUEST"
500
+ ;;
501
+
502
+ termux_audio_info)
503
+ termux-audio-info
504
+ ;;
505
+
506
+ termux_volume)
507
+ STREAM=$(echo "$PARAMS" | jq -r '.stream // empty')
508
+ VOL=$(echo "$PARAMS" | jq -r '.volume // empty')
509
+
510
+ if [ -n "$STREAM" ] && [ -n "$VOL" ]; then
511
+ termux-volume "$STREAM" "$VOL"
512
+ echo '{"status": "ok"}'
513
+ else
514
+ termux-volume
515
+ fi
516
+ ;;
517
+
518
+ termux_brightness)
519
+ BRIGHTNESS=$(echo "$PARAMS" | jq -r '.brightness // empty')
520
+ termux-brightness "$BRIGHTNESS"
521
+ echo '{"status": "ok"}'
522
+ ;;
523
+
524
+ termux_camera_info)
525
+ termux-camera-info
526
+ ;;
527
+
528
+ termux_camera_photo)
529
+ CAM_ID=$(echo "$PARAMS" | jq -r '.camera_id // 0')
530
+ OUTPUT=$(echo "$PARAMS" | jq -r '.output_file // empty')
531
+ termux-camera-photo -c "$CAM_ID" "$OUTPUT"
532
+ echo "{\"status\": \"ok\", \"file\": \"$OUTPUT\"}"
533
+ ;;
534
+
535
+ termux_dialog)
536
+ TITLE=$(echo "$PARAMS" | jq -r '.title // empty')
537
+ TYPE=$(echo "$PARAMS" | jq -r '.type // "confirm"')
538
+ VALUES=$(echo "$PARAMS" | jq -r '.values // empty')
539
+ HINT=$(echo "$PARAMS" | jq -r '.hint // empty')
540
+
541
+ ARGS=""
542
+ [ -n "$TITLE" ] && ARGS="$ARGS -t \"$TITLE\""
543
+
544
+ case "$TYPE" in
545
+ confirm) ARGS="$ARGS confirm" ;;
546
+ text) ARGS="$ARGS -i" ;;
547
+ spinner) ARGS="$ARGS spinner --values \"$VALUES\"" ;;
548
+ date) ARGS="$ARGS date" ;;
549
+ time) ARGS="$ARGS time" ;;
550
+ counter) ARGS="$ARGS counter" ;;
551
+ esac
552
+
553
+ [ -n "$HINT" ] && ARGS="$ARGS -i \"$HINT\""
554
+
555
+ eval "termux-dialog $ARGS"
556
+ ;;
557
+
558
+ termux_share)
559
+ TEXT=$(echo "$PARAMS" | jq -r '.text // empty')
560
+ FILE=$(echo "$PARAMS" | jq -r '.file // empty')
561
+ TITLE=$(echo "$PARAMS" | jq -r '.title // empty')
562
+ ACTION=$(echo "$PARAMS" | jq -r '.action // "send"')
563
+
564
+ ARGS="-a $ACTION"
565
+ [ -n "$TITLE" ] && ARGS="$ARGS -t \"$TITLE\""
566
+
567
+ if [ -n "$TEXT" ]; then
568
+ echo "$TEXT" | termux-share $ARGS
569
+ elif [ -n "$FILE" ]; then
570
+ termux-share $ARGS "$FILE"
571
+ fi
572
+ echo '{"status": "ok"}'
573
+ ;;
574
+
575
+ termux_open_url)
576
+ URL=$(echo "$PARAMS" | jq -r '.url // empty')
577
+ termux-open-url "$URL"
578
+ echo '{"status": "ok"}'
579
+ ;;
580
+
581
+ *)
582
+ echo "{\"error\": \"Unknown tool: $TOOL_NAME\"}"
583
+ exit 1
584
+ ;;
585
+ esac
586
+ SCRIPT
587
+ chmod +x ~/.config/gemini/termux-tools/call.sh
588
+ ```
589
+
590
+ ### 4. Configure Gemini CLI
591
+
592
+ Edit `~/.config/gemini/settings.json`:
593
+
594
+ ```json
595
+ {
596
+ "tool_discovery_command": "bash ~/.config/gemini/termux-tools/discovery.sh",
597
+ "tool_call_command": "bash ~/.config/gemini/termux-tools/call.sh"
598
+ }
599
+ ```
600
+
601
+ ### 5. Test
602
+
603
+ ```bash
604
+ # Verify discovery
605
+ ~/.config/gemini/termux-tools/discovery.sh | jq '.[] | .name'
606
+
607
+ # Verify call
608
+ echo '{}' | ~/.config/gemini/termux-tools/call.sh termux_battery_status
609
+
610
+ # Test with Gemini
611
+ gemini "What's my battery status?"
612
+ ```
613
+
614
+ ---
615
+
616
+ ## Installation Verification
617
+
618
+ ```bash
619
+ # Check Termux-API
620
+ pkg list-installed | grep termux-api
621
+
622
+ # Check jq (required for call.sh)
623
+ which jq || pkg install jq
624
+
625
+ # Check permissions
626
+ termux-setup-storage # Grant storage access
627
+ ```
628
+
629
+ ---
630
+
631
+ ## Troubleshooting
632
+
633
+ ### Tool not found
634
+
635
+ ```
636
+ Error: Unknown tool: termux_xxx
637
+ ```
638
+
639
+ **Solution**: Verify that the tool is defined in `discovery.sh` and `call.sh`
640
+
641
+ ### Permission denied
642
+
643
+ ```
644
+ Error: Permission denied for termux-xxx
645
+ ```
646
+
647
+ **Solution**: Open Termux:API app and grant necessary permissions
648
+
649
+ ### JSON parse error
650
+
651
+ ```
652
+ Error: jq: parse error
653
+ ```
654
+
655
+ **Solution**: Verify that parameters are valid JSON
656
+
657
+ ---
658
+
659
+ ## Extending
660
+
661
+ To add new commands:
662
+
663
+ 1. Add FunctionDeclaration in `discovery.sh`
664
+ 2. Add case handler in `call.sh`
665
+ 3. Test with direct call
666
+ 4. Verify with Gemini
667
+
668
+ ---
669
+
670
+ _Author: DioNanos_