mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-07-23 08:10:57 -07:00
Compare commits
1037 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0904c3767e | |||
| f18e45d34d | |||
| a3af4a8cae | |||
| 821355c429 | |||
| 3afc8f25e1 | |||
| d79478689f | |||
| 650980af37 | |||
| bd156e6832 | |||
| b987e1780d | |||
| 0012d95848 | |||
| fedc0c5d60 | |||
| 99e523a15f | |||
| a0b6602d09 | |||
| b39cefe14e | |||
| 94f4e5cc15 | |||
| d866e7e6e7 | |||
| ed02b94570 | |||
| aba8c5f662 | |||
| d1cde575d9 | |||
| 71f46f1160 | |||
| d63c34b6e1 | |||
| 7a6dfa3704 | |||
| 69f8273481 | |||
| 1fc59484b1 | |||
| 53027af94c | |||
| 69c0585ab2 | |||
| 3e954930f1 | |||
| 2cf3a14439 | |||
| 0f918f0cc8 | |||
| 75dbf9022c | |||
| 675ca07c8b | |||
| 40f505e257 | |||
| 5407878138 | |||
| 14e2e09d10 | |||
| 0365f13caa | |||
| 3183e4137a | |||
| 4aa295994d | |||
| e1bd1d239f | |||
| b84585d0c8 | |||
| 0e7944df4f | |||
| d8837ec95e | |||
| dc37b190fa | |||
| 19b1a74c99 | |||
| 1d045792ce | |||
| a8b4c38c89 | |||
| ad8796b02d | |||
| e7bfd2bf83 | |||
| 1b274b081d | |||
| 5b254c379c | |||
| ed26ea49e9 | |||
| 01e33465bd | |||
| 18cce6a9ab | |||
| 18d7d1a92c | |||
| 0dd0b83612 | |||
| 4e4a55be35 | |||
| f57fd642df | |||
| 5e96373e6b | |||
| 09beb648b8 | |||
| c159c85c89 | |||
| 8cae90f404 | |||
| c5d0fc2c3e | |||
| e860f517c0 | |||
| b0be1f1689 | |||
| 85dd6ef773 | |||
| ae672881d1 | |||
| 9e7c10ad88 | |||
| 381669dce0 | |||
| 707b3e85d5 | |||
| 7d36cc004f | |||
| cb4f0c6fa4 | |||
| b0f38104d7 | |||
| 7469ea0fca | |||
| 00fdb30211 | |||
| 0fe8492569 | |||
| 76387d22ae | |||
| a362b7b382 | |||
| 71308caf05 | |||
| 6396ab1ccb | |||
| 12531a06f8 | |||
| d1cd69a20d | |||
| 62346875e4 | |||
| 13e013230b | |||
| bb6a336ca9 | |||
| f14d0c6a17 | |||
| b611f9a519 | |||
| d3bca5d97a | |||
| 94f4e027f8 | |||
| 95b7d69d5b | |||
| f605628624 | |||
| 2238802e97 | |||
| 32cfce16bb | |||
| 137080da45 | |||
| 695785c69d | |||
| d43d772e65 | |||
| 59e3624ada | |||
| fdda3a2399 | |||
| 2de39311cf | |||
| fc926cd0b0 | |||
| 567761fbc0 | |||
| f2591aada6 | |||
| 74468928e8 | |||
| d561b995c0 | |||
| b44e432f55 | |||
| bcc6ee596a | |||
| bc258eba4c | |||
| 0e30055ae4 | |||
| ac7687c1dd | |||
| f9da18e0cc | |||
| f619cd8750 | |||
| 42eedc9184 | |||
| eb17d94e91 | |||
| 9f1623688d | |||
| 7f066fd3a7 | |||
| 6d36219e55 | |||
| 5cedd28733 | |||
| ba3e1ed1c7 | |||
| 7c2cdb225a | |||
| a91f4e692a | |||
| 9bb175a506 | |||
| 0b169e9867 | |||
| 553ae3ad69 | |||
| b2265cfde4 | |||
| bee1267e2a | |||
| 30065c51fb | |||
| 065e69a12b | |||
| 519a0e617a | |||
| 0465de303a | |||
| beaa134f0e | |||
| 47f4a3e50e | |||
| 3787c71d15 | |||
| 9e09db1ddb | |||
| 25ae1a1b54 | |||
| 65accca296 | |||
| 72f0733d98 | |||
| 4d4e16cc8c | |||
| 370b165769 | |||
| 899e8a9edc | |||
| 4dca5c27c6 | |||
| 06c7dc561e | |||
| f54eaa1713 | |||
| 6807a2fa28 | |||
| 9aeeb69ab0 | |||
| 0a77999d73 | |||
| 9035ca32bc | |||
| ef3146eed6 | |||
| ffbecd4eb4 | |||
| 2c09785748 | |||
| 130b596c80 | |||
| adc8e11bb1 | |||
| 18efe82ddc | |||
| 7c445526a4 | |||
| 5e41b7d29e | |||
| fe8de892f7 | |||
| 2a49965d37 | |||
| 830e212758 | |||
| d165b6d4e7 | |||
| ff6547857e | |||
| b51323b40c | |||
| 3103697ea7 | |||
| 6f6445994e | |||
| 5f569fa103 | |||
| c9340a9c6f | |||
| 0774f60e08 | |||
| 771ece03c9 | |||
| 82687c6dc4 | |||
| b6cf189ab2 | |||
| 9dc0994878 | |||
| 36d618f72a | |||
| 246a6d10c3 | |||
| dacc178d4e | |||
| 894bd66dc6 | |||
| 50e4f9380b | |||
| f03f2e8907 | |||
| 7904f973a0 | |||
| a63277c1d0 | |||
| 8b2b71c8ef | |||
| 6be42be575 | |||
| e5145ab60d | |||
| 5c16334b8c | |||
| 1e628fbd1d | |||
| db028bc19a | |||
| 362384112e | |||
| 0dc69bd364 | |||
| 56fff518cc | |||
| 6b021aa27b | |||
| 312a72acb8 | |||
| 88d3df912f | |||
| eccc200f4f | |||
| 9fcdc0cdc1 | |||
| f4e73191d1 | |||
| 67b00252d3 | |||
| a79051d9f8 | |||
| 5cf06503c8 | |||
| 68649c8dec | |||
| ad0bece6d6 | |||
| 8e8e7b33ed | |||
| d75dc88de6 | |||
| 57b57cc997 | |||
| 3909ad67db | |||
| 7708009103 | |||
| 00f60ef532 | |||
| 49c26b4801 | |||
| b5fe372b5b | |||
| 7fbf470373 | |||
| 46629726f4 | |||
| 9d34ae52d6 | |||
| 13bc5f620c | |||
| 018dc0d5cf | |||
| c2d0783965 | |||
| b07953fb38 | |||
| 2271bbb339 | |||
| d745d86af1 | |||
| 3e1a377d78 | |||
| 50f89e8a41 | |||
| b8319bee76 | |||
| 4827333c48 | |||
| 93c62a2bdc | |||
| 39e91ad633 | |||
| 5fe328c56a | |||
| cb772a5b7f | |||
| dcd949bdd0 | |||
| c0b8c4ab9e | |||
| 4d197c992d | |||
| fd36d65723 | |||
| 05e73c4193 | |||
| a76c2986c2 | |||
| 80e1fa198f | |||
| 84e882770b | |||
| 0242a3dc56 | |||
| 3c2482a084 | |||
| 1832f7b90a | |||
| 77aef861fe | |||
| 0c134079cc | |||
| 12a5490bcf | |||
| 93da9817b6 | |||
| 6fae28197e | |||
| 00b5b2045f | |||
| daccf4d6d1 | |||
| da1664c7a0 | |||
| 5c649d8db1 | |||
| 2c0cc7b9a5 | |||
| 25c0802b52 | |||
| df379b523b | |||
| 68f5f6d3b0 | |||
| 37c7286295 | |||
| 7b7d2b0297 | |||
| 3066288c06 | |||
| 1ec8f40096 | |||
| dabb9ad8f6 | |||
| b5cac836c5 | |||
| 4fc3ebb930 | |||
| 488d5fc439 | |||
| 0b7d26c9e3 | |||
| 140fba7f53 | |||
| a270f7caa5 | |||
| 3c832ddbeb | |||
| 1f9f3dd1c2 | |||
| 798900a6c8 | |||
| 2c6781d134 | |||
| 07bd89399d | |||
| 1ec172e34b | |||
| 678c58634b | |||
| a1f5d39029 | |||
| beacc4f6fd | |||
| a060e6149a | |||
| 35feea8868 | |||
| 11e48e2dd1 | |||
| 5f1c6447a9 | |||
| 57601adc90 | |||
| 50985d38c4 | |||
| 62dd9b5b3c | |||
| 2ac7900d95 | |||
| 016a94ffaf | |||
| 5d68d8cda5 | |||
| e2ddaedab4 | |||
| addb57c31f | |||
| 233fe90f17 | |||
| 902e5d6dae | |||
| ba8c64459b | |||
| 1320ebceb9 | |||
| 6d7423263b | |||
| fe06f9a1ea | |||
| e65208b244 | |||
| 7962801a14 | |||
| 87a0db20d2 | |||
| d956c5b221 | |||
| 048c30513e | |||
| 3b9f580fa4 | |||
| ff9c77925e | |||
| 56f9ab025a | |||
| 0a173cac46 | |||
| 982a093791 | |||
| 5debf86854 | |||
| 75e4f492ab | |||
| 27d21f9921 | |||
| b24544c80e | |||
| 61040d0eb8 | |||
| 3cca8ec0f0 | |||
| 2219bac16d | |||
| 1c9a57c3c2 | |||
| a1233e7e5c | |||
| 1033550f78 | |||
| addecf2c74 | |||
| c266b529ae | |||
| dce450b1e8 | |||
| a91665db40 | |||
| f79124f96e | |||
| eb2af84bb9 | |||
| f190b87223 | |||
| e894871afc | |||
| 45d554ae2f | |||
| acbef4cd31 | |||
| 80069b4a78 | |||
| d0cae4547e | |||
| 7399c623d8 | |||
| 6b14dc8240 | |||
| 4d77934a83 | |||
| 9e3d36c19b | |||
| c43b04b44c | |||
| 8605d0d024 | |||
| c21c297133 | |||
| 0605e6e3e9 | |||
| b703c87a64 | |||
| a784c263be | |||
| 169d906fe3 | |||
| 525539fc13 | |||
| 53e0c212cc | |||
| 7990073543 | |||
| 367e7bf401 | |||
| 3a4012f76a | |||
| c9f0a48bdc | |||
| 97aac696fb | |||
| 93ae7772fd | |||
| 9866eb0551 | |||
| 55c2783e6a | |||
| 2455f939a3 | |||
| 995ae42f53 | |||
| e1fd5be429 | |||
| 3b626e7c61 | |||
| aceb06a587 | |||
| 211d2c5fdd | |||
| c9061a1cfe | |||
| b288f124b2 | |||
| 645e2ec041 | |||
| 67d69084e9 | |||
| ed0b0fae49 | |||
| f0f705d3ca | |||
| f42b4c80ac | |||
| b99e841021 | |||
| a16d5983cf | |||
| e5745f16cb | |||
| 12b0fe1cc2 | |||
| 5b8a23979f | |||
| b71fe94e0a | |||
| e92f60b4fc | |||
| 15f26175b8 | |||
| 85b17166a5 | |||
| 88df6210eb | |||
| 943481ccc0 | |||
| 79076d1d52 | |||
| 166e04a8dd | |||
| 1182168bd9 | |||
| e34f0b4a98 | |||
| 4920ad2694 | |||
| 52fadba9f2 | |||
| ec7413456e | |||
| 451e0b49cb | |||
| 155d9aafe2 | |||
| 05c0a8eac3 | |||
| 0bebc664c1 | |||
| 1b6b6d40d5 | |||
| a90bcf749d | |||
| e2901f3f7e | |||
| 4b4bdd10b6 | |||
| 0a6f2e089f | |||
| d8a8b434f6 | |||
| 49769152d6 | |||
| 4cfbe4c716 | |||
| a4eb04b7d4 | |||
| d079b7a216 | |||
| d87a3acdef | |||
| 08c32f725e | |||
| 203f5209ba | |||
| 9d9e3d1555 | |||
| 20580d754d | |||
| 41e01c2321 | |||
| 6900253cb8 | |||
| 86dbf2013e | |||
| a76946189a | |||
| e03042657b | |||
| 1998a713e2 | |||
| ee8d425603 | |||
| 272570cc18 | |||
| 1681ae1842 | |||
| 608da23393 | |||
| f2d3b76389 | |||
| d8d4d87e29 | |||
| 93224e1813 | |||
| 9722ec9b6a | |||
| 063f0d0dcd | |||
| 42fd647373 | |||
| 59da61602f | |||
| 5241174827 | |||
| 013a4e02ff | |||
| be37c26c88 | |||
| fcd860e1b0 | |||
| ce35d84113 | |||
| cfdc4cfca8 | |||
| a15978593a | |||
| 4bb817de22 | |||
| c6cf3a4234 | |||
| 420a419f5e | |||
| 8dde66c0dd | |||
| f367b959cd | |||
| 655ab21d8b | |||
| 1e8f87fbdf | |||
| 8a627d6c9a | |||
| b0d2ec55cc | |||
| e77d7b2e1e | |||
| 48fdb9872f | |||
| c8670f8696 | |||
| 5ba6e243b5 | |||
| 9e13a43225 | |||
| 6740886e22 | |||
| f7f38e2b9e | |||
| 2b6bfe4097 | |||
| f909c9ef90 | |||
| fa3981990c | |||
| d545a3b614 | |||
| a8631a109e | |||
| b0c9db7b33 | |||
| 448fd3ca66 | |||
| 53f54436c9 | |||
| 409f9c825b | |||
| 222b739501 | |||
| d0bbc7fa59 | |||
| 4848f42486 | |||
| 467e869326 | |||
| 4f324b548e | |||
| a81500a929 | |||
| 5bdfe1a1fa | |||
| ae198029bc | |||
| 4b2e9f7954 | |||
| 42c26d1e1b | |||
| e58fca68ce | |||
| b3527dc9e4 | |||
| a2dab146b9 | |||
| fb7640886b | |||
| 5ed275ce39 | |||
| 6021e4c3ba | |||
| 7e6817da5b | |||
| b14cf1dc30 | |||
| 94d5ae541e | |||
| 41369f67eb | |||
| c8c7b57a79 | |||
| b3eecc3a50 | |||
| 16b35910e2 | |||
| 1212161d1d | |||
| 4db00b8f2a | |||
| 09a7301d80 | |||
| a3234fb534 | |||
| 764016bca7 | |||
| dfb7dc7069 | |||
| 3b55581aaf | |||
| f6c2d61906 | |||
| c04af6c3e9 | |||
| a1cbe85da3 | |||
| c8d7c09ca4 | |||
| bb6c574144 | |||
| 66e7b479ae | |||
| 8030404b08 | |||
| 933bc5774f | |||
| 4afd3741df | |||
| 428e602882 | |||
| 04f65d7b4e | |||
| eda47f587c | |||
| 8dbaa2bcea | |||
| 778de55fd8 | |||
| c7c409c68f | |||
| d66ec38f82 | |||
| 63c918fe7d | |||
| b2e866585d | |||
| b518125c46 | |||
| e8be252b75 | |||
| 92e31e3c4a | |||
| e931ebe581 | |||
| 91fcca3b1c | |||
| aa52462550 | |||
| 0f7a136612 | |||
| 8faa23cea6 | |||
| a6dca02344 | |||
| 304caa4e43 | |||
| 7bbfaabffa | |||
| 6adae9f775 | |||
| b81fe68325 | |||
| 2fc61685a3 | |||
| c572b9e9ac | |||
| 8d3e93cdb0 | |||
| 548641c952 | |||
| 6ef2a92233 | |||
| e9c9dd1d67 | |||
| ca6786a28b | |||
| 2e8c6cfdbb | |||
| 95d9a33996 | |||
| b8cc414d5b | |||
| d7bff8610f | |||
| e049d5e4e8 | |||
| 8437ce940a | |||
| 7d92242011 | |||
| d65eab01d2 | |||
| 2306e60be4 | |||
| 3b678a4da0 | |||
| 64cde8d439 | |||
| 0167392f22 | |||
| 15891721ad | |||
| 8a2e0fac0d | |||
| 8656ce8a27 | |||
| ed7bcf9968 | |||
| 465ec9759d | |||
| 950244f6b0 | |||
| 64c75cb767 | |||
| 7b7f2fc69e | |||
| d315f4d3da | |||
| 9703fe73cf | |||
| 93b57b82c1 | |||
| 0e955da171 | |||
| 39b3f20a22 | |||
| b9762a3ee1 | |||
| 33e3ed0f6c | |||
| 446058cb1c | |||
| d130d99ff0 | |||
| 72dae7e0ee | |||
| 6f7d798189 | |||
| 3090008b1c | |||
| 461c277bf2 | |||
| b54e688c75 | |||
| b08b0d715b | |||
| c87d1aed4c | |||
| 356f76e545 | |||
| 1fb55dcb2e | |||
| d74bf9ef2f | |||
| e04a5f0cb0 | |||
| ea7393f7fd | |||
| c7d17dda49 | |||
| 9d187e041c | |||
| 14f0cb4538 | |||
| ca48661423 | |||
| 041463d112 | |||
| c1401682ed | |||
| 8bc3cfe29a | |||
| 77e226c55f | |||
| b9f8858bfb | |||
| f7b97ef55e | |||
| 88f1ec8d0a | |||
| aa480e5fbb | |||
| 41e627a7ee | |||
| e1e3efc9d0 | |||
| 18dd399cb5 | |||
| f1ca7fa40a | |||
| 6166d7f6ec | |||
| ffb80c2426 | |||
| 4ab1b9895a | |||
| 84710b1953 | |||
| a7f758eb3a | |||
| 26505b580c | |||
| e51f3e11f1 | |||
| d75792703a | |||
| e5f7a9c424 | |||
| 9062a943e7 | |||
| 7e02ef697d | |||
| 41a8809280 | |||
| 01d2d43737 | |||
| 16da6918cb | |||
| fbfad06307 | |||
| f8138262fa | |||
| 1a4ae41397 | |||
| 75bc41fc20 | |||
| ced5110dab | |||
| 76d020511f | |||
| 02cf264ee1 | |||
| eb3f3cfdb8 | |||
| 660368f249 | |||
| 97ad3d97cb | |||
| cf021ccae4 | |||
| eb75f59a96 | |||
| 030847a80a | |||
| 722c4933dc | |||
| 3e2f4eb8ba | |||
| aca6bf6aa0 | |||
| d48c934357 | |||
| 41cc6cf105 | |||
| dd04b46e86 | |||
| 1bd4f9d8b6 | |||
| 1aa35c8796 | |||
| 51d3f44d51 | |||
| d4b418ba01 | |||
| bd77515fd9 | |||
| 1c77bac146 | |||
| 0be8b5b1ed | |||
| d5996fea99 | |||
| a1dd19738e | |||
| 17b3eb730a | |||
| 4c961df313 | |||
| 19bdd95eab | |||
| 143bb63483 | |||
| c64b5ec4a3 | |||
| 57012ae5b3 | |||
| db99beda36 | |||
| 97b31c4eef | |||
| d1eb87c81f | |||
| 8f9bb6bccc | |||
| 416d243027 | |||
| 5fe5d1da46 | |||
| 2d683bb6f8 | |||
| 7956eb239e | |||
| a26463b056 | |||
| 982eee63b6 | |||
| b54215f0a5 | |||
| 521dc7f26c | |||
| da85e3f8f2 | |||
| 59a18e710d | |||
| 5f027cb63a | |||
| 4086abf375 | |||
| 8f5bf33eac | |||
| 7eeb7bd74c | |||
| 96b9be3ec4 | |||
| 1e31427da8 | |||
| 7feb2f8f42 | |||
| 2122604b32 | |||
| d4b4aede2f | |||
| 4b5c044272 | |||
| 2fe45834dd | |||
| 56092bd782 | |||
| c31f05356a | |||
| 61dbab03e0 | |||
| 86b5995f12 | |||
| d2849fda8a | |||
| a61fb058b7 | |||
| 7edd803034 | |||
| 0c54136244 | |||
| cce4574143 | |||
| 9172e28315 | |||
| 6f4b2ad0b9 | |||
| 9a3ff6510f | |||
| 4c67eef0f2 | |||
| 7d4f97de7a | |||
| cbd2eee9c4 | |||
| 384fb6a465 | |||
| 2cb33b2f76 | |||
| 8f0324d868 | |||
| fd7b6bf40a | |||
| ed8bad8c26 | |||
| 6d1e27633a | |||
| 2da911e4a0 | |||
| e5d183031a | |||
| b13c6b57ae | |||
| 3c92666ec2 | |||
| dc6dda5c37 | |||
| 3997c7ff80 | |||
| b4b49e7029 | |||
| 615b218ff7 | |||
| f3625aab13 | |||
| d3563e2f0e | |||
| dd84c2fb83 | |||
| bdb349e7f6 | |||
| 12c7c9cc42 | |||
| 90be9c3587 | |||
| eec5d5ebf8 | |||
| d3c206c677 | |||
| f0a039f7c0 | |||
| 30f5c4af4a | |||
| e78c3fe4f0 | |||
| c0ccb22460 | |||
| 764b195977 | |||
| 0f3555a4d2 | |||
| 006de1dd31 | |||
| 18fef0db31 | |||
| 958284dc24 | |||
| 788bb04f5c | |||
| 8a0190ca3b | |||
| c29a8c12b3 | |||
| 05049b5abf | |||
| 3ebe4e6a8f | |||
| 0eb84f5133 | |||
| de1233b8ca | |||
| ec11b8afbf | |||
| ec79fe1ab2 | |||
| 90eb1e0281 | |||
| 15c9f88da6 | |||
| 4e6fee7fcd | |||
| 1e08b150f7 | |||
| fb22f5b8ee | |||
| 848e8485cd | |||
| 07e597de40 | |||
| 10ae84869a | |||
| dcd2449b1a | |||
| a3d214f8d7 | |||
| 37be162435 | |||
| 5566292cc8 | |||
| 65e2144b3d | |||
| a26d195404 | |||
| 21388a0a40 | |||
| acecd80afa | |||
| 69fc75c0b2 | |||
| 9cdb267ba5 | |||
| 56b050422d | |||
| 546baf9934 | |||
| e6344a8c24 | |||
| 873d10df42 | |||
| 02a36afc38 | |||
| 563d81e08e | |||
| 5f28614760 | |||
| b6b0727e28 | |||
| e9a601c1fe | |||
| 308aa70718 | |||
| 6be034392f | |||
| 3b1dbcd42d | |||
| 2ac9fe08f7 | |||
| 24c722454b | |||
| 0a216b28f3 | |||
| 9c48cd849b | |||
| 0843d9af58 | |||
| b0d5c4c058 | |||
| d18c96d6a1 | |||
| dced409ac4 | |||
| d6a2f1d670 | |||
| 58fd00a3df | |||
| b923604602 | |||
| 8643d60b88 | |||
| 8feeffb29b | |||
| e64146914a | |||
| 6084708cc2 | |||
| 8ed0f8981f | |||
| 41a1a3eed1 | |||
| 10ba348a3a | |||
| db67bb106a | |||
| b828b4754b | |||
| 9383b54d50 | |||
| 181da07dd9 | |||
| 419464a8c2 | |||
| 2e229d3bb6 | |||
| 3c92bdb1ad | |||
| e0f159085e | |||
| 402148dbc4 | |||
| 70696e364b | |||
| 1e10492e55 | |||
| 9e6914d641 | |||
| 0c4fb6afd2 | |||
| edab97997a | |||
| 2515b89e2b | |||
| 60f0f19d76 | |||
| 322232e514 | |||
| 54466a3ea8 | |||
| 7da060c149 | |||
| 088f48d60f | |||
| 2b426c1d91 | |||
| bc168bbae4 | |||
| 124a6da743 | |||
| 739c02bd6d | |||
| 5d13145995 | |||
| c28ff3d5a5 | |||
| 6ddd5abd7b | |||
| bf6d0485ce | |||
| 3d486ec1e9 | |||
| a6d1245a54 | |||
| de7e1937f6 | |||
| b465e12747 | |||
| 948401a450 | |||
| bb8f181ef1 | |||
| bf90b59935 | |||
| 18698d6929 | |||
| 80c4225286 | |||
| d02f3f6809 | |||
| da85aed5aa | |||
| 7f2d33458a | |||
| 3e9a0a7628 | |||
| 26c115a4fb | |||
| db643e9166 | |||
| ba100642e3 | |||
| cc52839f19 | |||
| e79b149985 | |||
| 5e21c8c03c | |||
| 5ea5107d05 | |||
| 2995af6a21 | |||
| 0c3eb82671 | |||
| 79f664d593 | |||
| bb0c0d8ee3 | |||
| d236df5b21 | |||
| 13944b9bb1 | |||
| ec665ef405 | |||
| 217e2b0eb4 | |||
| d030a1f62f | |||
| fc2a5a42ce | |||
| 57c7b9ccce | |||
| 942bcfc61e | |||
| fcc3b2b5ec | |||
| d9f94103cd | |||
| ad60cbfc2c | |||
| 126c32aca4 | |||
| 977248e095 | |||
| a47af8e261 | |||
| 5b56920f0a | |||
| 5f298c17d7 | |||
| d2a1a45646 | |||
| 6dea66f1f5 | |||
| 20164ebcda | |||
| edbe5480ca | |||
| e84c4bfb81 | |||
| 3b2a4ba27a | |||
| 12cbe320e4 | |||
| 1e734d7e60 | |||
| 299cc9bebf | |||
| a02abcf578 | |||
| bb33e281c0 | |||
| 86134e9970 | |||
| 54de67536d | |||
| d818fb1d91 | |||
| 927102ea1b | |||
| 2d3db97067 | |||
| 24fca1b745 | |||
| 8c83e1ea9a | |||
| 91b15fc9dc | |||
| d4506e0fc0 | |||
| 648041c62a | |||
| 22e6af414a | |||
| c8b688655c | |||
| 68ebf5d655 | |||
| 1954f45c19 | |||
| ee6556cbd2 | |||
| d2a6b30398 | |||
| d90356e8a3 | |||
| aced401071 | |||
| 2800187355 | |||
| 3f5f030d01 | |||
| 364b12e2fa | |||
| 6877dd0de7 | |||
| 6be32e9383 | |||
| f919783173 | |||
| 674494e80b | |||
| 1f813f6a06 | |||
| afd4829f10 | |||
| 03be923e05 | |||
| bc542cbca8 | |||
| 560550f5df | |||
| 720b31cb8b | |||
| d35a1fdec7 | |||
| 8f43d4851d | |||
| 171103aedc | |||
| ec9a8c7a72 | |||
| 91c46311c8 | |||
| 89570aef06 | |||
| 17b5b40765 | |||
| cdc74a742a | |||
| 4322137cee | |||
| 8651c53923 | |||
| b2a821c81a | |||
| 3888a592cf | |||
| 84c07c8fa1 | |||
| 389cadb06a | |||
| 6e51bbc215 | |||
| 8f4f8baa81 | |||
| 7a72037572 | |||
| 025e450ac2 | |||
| 3cf44acc08 | |||
| bdd15e8911 | |||
| 04cbae5b5f | |||
| 2c4ec31ed1 | |||
| 996cbcb680 | |||
| dd3fd73ffe | |||
| 738354ff65 | |||
| 616d6f6667 | |||
| 8341256d1e | |||
| 934b309b4c | |||
| d284fa66c0 | |||
| bedce8aacf | |||
| 7db5abdecf | |||
| 290ede93e2 | |||
| f4f2bcbd98 | |||
| 1c5213788c | |||
| 0d5424fb79 | |||
| ae8694b303 | |||
| 5f60281d25 | |||
| 0c7ae22f5d | |||
| 2d1c1ac567 | |||
| 205d0f456e | |||
| 8b0a8f47c1 | |||
| 84f521b1c6 | |||
| 1040c246f5 | |||
| b27cf0b0a8 | |||
| 0a2971f9d3 | |||
| 48e8c12476 | |||
| 6f3b56c5b6 | |||
| b745d46395 | |||
| 46bb07e4b7 | |||
| d5e5f58737 | |||
| 9bc5a4d64f | |||
| 7b811a38a6 | |||
| e0a2227faf | |||
| 470f3b057f | |||
| 518e73ac9f | |||
| 3da4fd5f7d | |||
| 1e6243045e | |||
| a28be4a4e0 | |||
| 153d01a01e | |||
| eb3312e7ba | |||
| 939cb67621 | |||
| 00705b14bd | |||
| 8d4082ef2e | |||
| f588219bb9 | |||
| b8c038f41f | |||
| 08067acc71 | |||
| 1c12da1fad | |||
| 7a6d3067c6 | |||
| 54c62d580c | |||
| 0857345945 | |||
| b9b3b8050d | |||
| 92e95ed806 | |||
| 035bea3699 | |||
| bdbbe9232d | |||
| 145fb246a6 | |||
| 533a3fb312 | |||
| 344f2f26e7 | |||
| ed10edbf0d | |||
| 828afe113e | |||
| 2d935b3798 | |||
| aa544c40de | |||
| c78f2574a2 | |||
| 2b1a791a0b | |||
| 752a521423 | |||
| 71b0e7ab0d | |||
| f7f047936b | |||
| 2a3c0eddb9 | |||
| 1689e9b671 | |||
| 98d7238ed6 | |||
| d24e5cf353 | |||
| 70a48a3dd6 | |||
| 5fa6d87c25 | |||
| 5729642556 | |||
| f4babf172b | |||
| 0c463e664e | |||
| 4df43c802b | |||
| 784d3c6c9a | |||
| fcb85e612f | |||
| b4df7e351b | |||
| 806cd112ac | |||
| 26f050ff10 | |||
| bde8b78a88 | |||
| 62f890b5aa | |||
| db027dd95b | |||
| 613fb2fed6 | |||
| f918af82fe | |||
| 844d3a4dfa | |||
| 4228a75186 | |||
| 2fe609cb62 | |||
| f2466e5224 | |||
| f98e84f03f | |||
| bbd61f375f | |||
| 576fda18eb | |||
| 7a4280a482 | |||
| 6a43b31218 | |||
| 450734e333 | |||
| cf7f6b49ed | |||
| b9dc8eb14d | |||
| 69188c8538 | |||
| 5949d56370 | |||
| 5bed97064a | |||
| b2bdfcf1b5 | |||
| 0d29385e1b | |||
| 87edeb4e32 | |||
| 0f12d6c426 | |||
| 3406dc5b2e | |||
| 4a82b0d891 | |||
| bc365f1eaa | |||
| 558c8ece2c | |||
| 1187c7fdac | |||
| e1d2653a7a | |||
| 36a0a3d37b | |||
| d97bbd5324 | |||
| d2a6cff4df | |||
| acf5ed595f | |||
| 03845198ce | |||
| d8a3d08f8e | |||
| 6f9118dca6 | |||
| d0b6701fba | |||
| 94c3eecb99 | |||
| 098e5c281c | |||
| f2c52f777c | |||
| 2b41263aa7 | |||
| 404a4468d8 | |||
| 7f67c7f952 | |||
| c8540b5744 | |||
| f6d97d4488 | |||
| 87712a0a7c | |||
| ba0e053ffc | |||
| d14779b264 | |||
| 5411f4a667 | |||
| 2034098780 | |||
| d53a5c4fb5 | |||
| f6ee025c46 | |||
| e50bf6adad | |||
| c21b6899e1 | |||
| 95693e265e | |||
| 569c6f1dd0 | |||
| 7350399a50 | |||
| c2a741ee36 | |||
| e177314a4a | |||
| dadd606c0d | |||
| b3fcddde11 | |||
| e205a468d9 | |||
| bdf80ea7c0 | |||
| 5e218a5630 | |||
| 8c36b10682 | |||
| 42c2e1b217 | |||
| 1e715d1e5c | |||
| 9f9a2fa844 | |||
| 64eb14ab11 | |||
| 0713c86dec | |||
| 99c5bf2e97 | |||
| fe67ef63c1 | |||
| 19d4384f16 | |||
| d351f07758 | |||
| d72f35c2e7 | |||
| aeffa2a460 | |||
| 030a5ace97 | |||
| b97661553f | |||
| 3370644ffe | |||
| 0f0b463a2f | |||
| 8d082a904d | |||
| 61582678bf | |||
| 613b8a4527 | |||
| 5982abeffb | |||
| 78b10dccf1 | |||
| 85bc25a765 | |||
| fec0eba07e | |||
| f92e79eba0 | |||
| 3e50be1658 | |||
| 9937fb2220 |
@@ -0,0 +1,29 @@
|
||||
description="Injects context of all relevant cli files"
|
||||
prompt = """
|
||||
The following output contains the complete
|
||||
source code of packages/core.
|
||||
**Pay extremely close attention to these files.** They define the project's
|
||||
core architecture, component patterns, and testing standards.
|
||||
|
||||
The source code contains the content of absolutely every source code file in
|
||||
packages/core.
|
||||
You should very rarely need to read any other files from packages/core to resolve
|
||||
prompts.
|
||||
|
||||
!{find packages/core \\( -path packages/cli/dist -o -path packages/core/dist -o -name node_modules \\) -prune -o -type f \\( -name "*.ts" -o -name "*.tsx" \\) ! -name "*.test.ts" ! -name "*.test.tsx" ! -name "*.d.ts" -exec echo "--- {} ---" \\; -exec cat {} \\;}
|
||||
|
||||
In addition to the code context, you MUST strictly adhere to the following frontend-specific development guidelines when writing code in packages/core.
|
||||
|
||||
## Configuration & Settings
|
||||
* **Settings vs Args**: Use settings for user-configurable options; do not add new CLI arguments.
|
||||
* **Schema**: Add new settings to `packages/cli/src/config/settingsSchema.ts`.
|
||||
* **Documentation**:
|
||||
* If `showInDialog: true`, document in `docs/get-started/configuration.md`.
|
||||
* Ensure `requiresRestart` is correctly set.
|
||||
|
||||
## General
|
||||
* **Logging**: Use `debugLogger` for errors. NEVER leave `console.log/warn/error` in the code.
|
||||
* **TypeScript**: Avoid the non-null assertion operator (`!`).
|
||||
|
||||
{{args}}.
|
||||
"""
|
||||
@@ -0,0 +1,60 @@
|
||||
description = "Check status of nightly evals, fix failures for key models, and re-run."
|
||||
prompt = """
|
||||
You are an expert at fixing behavioral evaluations.
|
||||
|
||||
1. **Investigate**:
|
||||
- Use 'gh' cli to fetch the results from the latest run from the main branch: https://github.com/google-gemini/gemini-cli/actions/workflows/evals-nightly.yml.
|
||||
- DO NOT push any changes or start any runs. The rest of your evaluation will be local.
|
||||
- Evals are in evals/ directory and are documented by evals/README.md.
|
||||
- The test case trajectory logs will be logged to evals/logs.
|
||||
- You should also enable and review the verbose agent logs by setting the GEMINI_DEBUG_LOG_FILE environment variable.
|
||||
- Identify the relevant test. Confine your investigation and validation to just this test.
|
||||
- Proactively add logging that will aid in gathering information or validating your hypotheses.
|
||||
|
||||
2. **Fix**:
|
||||
- If a relevant test is failing, locate the test file and the corresponding prompt/code.
|
||||
- It's often helpful to make an extreme, brute force change to see if you are changing the right place to make an improvement and then scope it back iteratively.
|
||||
- Your **final** change should be **minimal and targeted**.
|
||||
- Keep in mind the following:
|
||||
- The prompt has multiple configurations and pieces. Take care that your changes
|
||||
end up in the final prompt for the selected model and configuration.
|
||||
- The prompt chosen for the eval is intentional. It's often vague or indirect
|
||||
to see how the agent performs with ambiguous instructions. Changing it should
|
||||
be a last resort.
|
||||
- When changing the test prompt, carefully consider whether the prompt still tests
|
||||
the same scenario. We don't want to lose test fidelity by making the prompts too
|
||||
direct (i.e.: easy).
|
||||
- Your primary mechanism for improving the agent's behavior is to make changes to
|
||||
tool instructions, prompt.ts, and/or modules that contribute to the prompt.
|
||||
- If prompt and description changes are unsuccessful, use logs and debugging to
|
||||
confirm that everything is working as expected.
|
||||
- If unable to fix the test, you can make recommendations for architecture changes
|
||||
that might help stablize the test. Be sure to THINK DEEPLY if offering architecture guidance.
|
||||
Some facts that might help with this are:
|
||||
- Agents may be composed of one or more agent loops.
|
||||
- AgentLoop == 'context + toolset + prompt'. Subagents are one type of agent loop.
|
||||
- Agent loops perform better when:
|
||||
- They have direct, unambiguous, and non-contradictory prompts.
|
||||
- They have fewer irrelevant tools.
|
||||
- They have fewer goals or steps to perform.
|
||||
- They have less low value or irrelevant context.
|
||||
- You may suggest compositions of existing primitives, like subagents, or
|
||||
propose a new one.
|
||||
- These recommendations should be high confidence and should be grounded
|
||||
in observed deficient behaviors rather than just parroting the facts above.
|
||||
Investigate as needed to ground your recommendations.
|
||||
|
||||
3. **Verify**:
|
||||
- Run just that one test if needed to validate that it is fixed. Be sure to run vitest in non-interactive mode.
|
||||
- Running the tests can take a long time, so consider whether you can diagnose via other means or log diagnostics before committing the time. You must minimize the number of test runs needed to diagnose the failure.
|
||||
- After the test completes, check whether it seems to have improved.
|
||||
- You will need to run the test 3 times for Gemini 3.0, Gemini 3 flash, and Gemini 2.5 pro to ensure that it is truly stable. Run these runs in parallel, using scripts if needed.
|
||||
- Some flakiness is expected; if it looks like a transient issue or the test is inherently unstable but passes 2/3 times, you might decide it cannot be improved.
|
||||
|
||||
4. **Report**:
|
||||
- Provide a summary of the test success rate for each of the tested models.
|
||||
- Success rate is calculated based on 3 runs per model (e.g., 3/3 = 100%).
|
||||
- If you couldn't fix it due to persistent flakiness, explain why.
|
||||
|
||||
{{args}}
|
||||
"""
|
||||
@@ -0,0 +1,54 @@
|
||||
description="Injects context of all relevant cli files"
|
||||
prompt = """
|
||||
The source code contains the content of absolutely every source code file in
|
||||
packages/cli and key files from packages/core. In addition to the source code, the following test files are
|
||||
included as they are test files that conform to the project's testing standards:
|
||||
`packages/cli/src/ui/components/InputPrompt.test.tsx` and `packages/cli/src/ui/App.test.tsx`.
|
||||
You should very rarely need to read any other files from packages/cli to resolve
|
||||
prompts.
|
||||
|
||||
!{find packages/cli -path packages/cli/dist -prune -o -type f \\( -name "*.ts" -o -name "*.tsx" \\) ! -name "*.test.ts" ! -name "*.test.tsx" ! -name "*.d.ts" -exec echo "--- {} ---" \\; -exec cat {} \\; && echo "--- packages/cli/src/ui/components/InputPrompt.test.tsx ---" && cat packages/cli/src/ui/components/InputPrompt.test.tsx && echo "--- packages/cli/src/ui/App.test.tsx ---" && cat packages/cli/src/ui/App.test.tsx && echo "--- packages/core/src/core/coreToolScheduler.ts ---" && cat packages/core/src/core/coreToolScheduler.ts && echo "--- packages/core/src/core/nonInteractiveToolExecutor.ts ---" && cat packages/core/src/core/nonInteractiveToolExecutor.ts && echo "--- packages/core/src/confirmation-bus/message-bus.ts ---" && cat packages/core/src/confirmation-bus/message-bus.ts && echo "--- packages/core/src/confirmation-bus/types.ts ---" && cat packages/core/src/confirmation-bus/types.ts && echo "--- packages/core/src/utils/events.ts ---" && cat packages/core/src/utils/events.ts && echo "--- packages/core/src/core/client.ts ---" && cat packages/core/src/core/client.ts && echo "--- packages/core/src/core/geminiChat.ts ---" && cat packages/core/src/core/geminiChat.ts && echo "--- packages/core/src/core/turn.ts ---" && cat packages/core/src/core/turn.ts && echo "--- packages/core/src/agents/executor.ts ---" && cat packages/core/src/agents/executor.ts && echo "--- packages/core/src/telemetry/types.ts ---" && cat packages/core/src/telemetry/types.ts && echo "--- packages/core/src/telemetry/loggers.ts ---" && cat packages/core/src/telemetry/loggers.ts && echo "--- packages/core/src/telemetry/uiTelemetry.ts ---" && cat packages/core/src/telemetry/uiTelemetry.ts}
|
||||
|
||||
**Pay extremely close attention to these files.** They define the project's
|
||||
core architecture, component patterns, and testing standards.
|
||||
|
||||
In addition to the code context, you MUST strictly adhere to the following frontend-specific development guidelines while adding code to packages/cli.
|
||||
|
||||
## Testing Standards
|
||||
* **Async Testing**: ALWAYS use `waitFor` from `packages/cli/src/test-utils/async.ts` instead of `vi.waitFor` to prevent flakiness and `act` warnings. NEVER use fixed waits (e.g., `await delay(100)`).
|
||||
* **State Changes**: Wrap all blocks that change component state in `act`.
|
||||
* **Snapshots**: Use `toMatchSnapshot` to verify rendering.
|
||||
* **Rendering**: Use `render` or `renderWithProviders` from `packages/cli/src/test-utils/render.tsx` instead of `ink-testing-library` directly.
|
||||
* **Mocking**:
|
||||
* Reuse existing mocks/fakes where possible.
|
||||
* **Parameterized Tests**: Use parameterized tests with explicit types to reduce duplication and ensure type safety.
|
||||
* Avoid mocking the file system, os, or child_process if at all possible; if you have to mock the Mock critical dependencies (`fs`, `os`, `child_process`) do so ONLY at the top of the file.
|
||||
|
||||
## React & Ink Architecture
|
||||
* **Keyboard Handling**: You MUST use `useKeyPress.ts` from Gemini CLI for keyboard handling, NOT the standard ink library. This is critical for supporting slow terminals and multiple events per frame.
|
||||
* Handle multiple events gracefully (often requires a reducer pattern, see `text-buffer.ts`).
|
||||
* **State Management**:
|
||||
* NEVER trigger side effects from within the body of a `setState` callback. Use a reducer or `useRef` if necessary.
|
||||
* Initialize state explicitly (e.g., use `undefined` rather than `true` if unknown).
|
||||
* **Performance**:
|
||||
* Avoid synchronous file I/O in components.
|
||||
* Do not introduce excessive property drilling; leverage or extend existing providers.
|
||||
|
||||
## Configuration & Settings
|
||||
* **Settings vs Args**: Use settings for user-configurable options; do not add new CLI arguments.
|
||||
* **Schema**: Add new settings to `packages/cli/src/config/settingsSchema.ts`.
|
||||
* **Documentation**:
|
||||
* If `showInDialog: true`, document in `docs/get-started/configuration.md`.
|
||||
* Ensure `requiresRestart` is correctly set.
|
||||
|
||||
## Keyboard Shortcuts
|
||||
* **Registration**: Define new shortcuts in `packages/cli/src/config/keyBindings.ts`.
|
||||
* **Documentation**: Document all new shortcuts in `docs/cli/keyboard-shortcuts.md`.
|
||||
* **Compatibility**: Avoid function keys and common VSCode shortcuts. Be cautious with `Meta` key (Mac-limited support).
|
||||
|
||||
## General
|
||||
* **Logging**: Use `debugLogger` for errors. NEVER leave `console.log/warn/error` in the code.
|
||||
* **TypeScript**: Avoid the non-null assertion operator (`!`).
|
||||
|
||||
{{args}}.
|
||||
"""
|
||||
@@ -0,0 +1,57 @@
|
||||
description="Injects context of all relevant cli files"
|
||||
prompt = """
|
||||
The following output contains the complete
|
||||
source code of the gemini cli library (`packages/cli`), and {packages/core} and representative test files
|
||||
(`packages/cli/src/ui/components/InputPrompt.test.tsx` and `packages/cli/src/ui/App.test.tsx`) that best conform to the project's testing standards.
|
||||
**Pay extremely close attention to these files.** They define the project's
|
||||
core architecture, component patterns, and testing standards.
|
||||
|
||||
The source code contains the content of absolutely every source code file in
|
||||
packages/cli and packages/core. In addition to the source code, the following test files are
|
||||
included as they are test files that conform to the project's testing standards:
|
||||
`packages/cli/src/ui/components/InputPrompt.test.tsx` and `packages/cli/src/ui/App.test.tsx`.
|
||||
You should very rarely need to read any other files from packages/cli to resolve
|
||||
prompts.
|
||||
|
||||
!{find packages/cli packages/core \\( -path packages/cli/dist -o -path packages/core/dist -o -name node_modules \\) -prune -o -type f \\( -name "*.ts" -o -name "*.tsx" \\) ! -name "*.test.ts" ! -name "*.test.tsx" ! -name "*.d.ts" -exec echo "--- {} ---" \\; -exec cat {} \\; && echo "--- packages/cli/src/ui/components/InputPrompt.test.tsx ---" && cat packages/cli/src/ui/components/InputPrompt.test.tsx && echo "--- packages/cli/src/ui/App.test.tsx ---" && cat packages/cli/src/ui/App.test.tsx}
|
||||
|
||||
In addition to the code context, you MUST strictly adhere to the following frontend-specific development guidelines when writing code in packages/cli.
|
||||
|
||||
## Testing Standards
|
||||
* **Async Testing**: ALWAYS use `waitFor` from `packages/cli/src/test-utils/async.ts` instead of `vi.waitFor` to prevent flakiness and `act` warnings. NEVER use fixed waits (e.g., `await delay(100)`).
|
||||
* **State Changes**: Wrap all blocks that change component state in `act`.
|
||||
* **Snapshots**: Use `toMatchSnapshot` to verify rendering.
|
||||
* **Rendering**: Use `render` or `renderWithProviders` from `packages/cli/src/test-utils/render.tsx` instead of `ink-testing-library` directly.
|
||||
* **Mocking**:
|
||||
* Reuse existing mocks/fakes where possible.
|
||||
* **Parameterized Tests**: Use parameterized tests with explicit types to reduce duplication and ensure type safety.
|
||||
* Avoid mocking the file system, os, or child_process if at all possible; if you have to mock the Mock critical dependencies (`fs`, `os`, `child_process`) do so ONLY at the top of the file.
|
||||
|
||||
## React & Ink Architecture
|
||||
* **Keyboard Handling**: You MUST use `useKeyPress.ts` from Gemini CLI for keyboard handling, NOT the standard ink library. This is critical for supporting slow terminals and multiple events per frame.
|
||||
* Handle multiple events gracefully (often requires a reducer pattern, see `text-buffer.ts`).
|
||||
* **State Management**:
|
||||
* NEVER trigger side effects from within the body of a `setState` callback. Use a reducer or `useRef` if necessary.
|
||||
* Initialize state explicitly (e.g., use `undefined` rather than `true` if unknown).
|
||||
* **Performance**:
|
||||
* Avoid synchronous file I/O in components.
|
||||
* Do not introduce excessive property drilling; leverage or extend existing providers.
|
||||
|
||||
## Configuration & Settings
|
||||
* **Settings vs Args**: Use settings for user-configurable options; do not add new CLI arguments.
|
||||
* **Schema**: Add new settings to `packages/cli/src/config/settingsSchema.ts`.
|
||||
* **Documentation**:
|
||||
* If `showInDialog: true`, document in `docs/get-started/configuration.md`.
|
||||
* Ensure `requiresRestart` is correctly set.
|
||||
|
||||
## Keyboard Shortcuts
|
||||
* **Registration**: Define new shortcuts in `packages/cli/src/config/keyBindings.ts`.
|
||||
* **Documentation**: Document all new shortcuts in `docs/cli/keyboard-shortcuts.md`.
|
||||
* **Compatibility**: Avoid function keys and common VSCode shortcuts. Be cautious with `Meta` key (Mac-limited support).
|
||||
|
||||
## General
|
||||
* **Logging**: Use `debugLogger` for errors. NEVER leave `console.log/warn/error` in the code.
|
||||
* **TypeScript**: Avoid the non-null assertion operator (`!`).
|
||||
|
||||
{{args}}.
|
||||
"""
|
||||
@@ -0,0 +1,16 @@
|
||||
description = "Analyze the influence of system instructions on a specific action."
|
||||
prompt = """
|
||||
# Introspection Task
|
||||
|
||||
Take a step back and analyze your own system instructions and internal logic.
|
||||
The user is curious about the reasoning behind a specific action or decision you've made.
|
||||
|
||||
**Specific point of interest:** {{args}}
|
||||
|
||||
Please provide a detailed breakdown of:
|
||||
1. Which parts of your system instructions (global, workspace-specific, or provided via GEMINI.md) influenced this behavior?
|
||||
2. What was your internal thought process leading up to this action?
|
||||
3. Are there any ambiguities or conflicting instructions that played a role?
|
||||
|
||||
Your goal is to provide transparency into your underlying logic so the user can potentially improve the instructions in the future.
|
||||
"""
|
||||
@@ -0,0 +1,22 @@
|
||||
description = "Analyze agent behavior and suggest high-level improvements to system prompts."
|
||||
prompt = """
|
||||
# Prompt Engineering Analysis
|
||||
|
||||
You are a world-class prompt engineer and an expert AI engineer at the top of your class. Your goal is to analyze a specific agent behavior or failure and suggest high-level improvements to the system instructions.
|
||||
|
||||
**Observed Behavior / Issue:**
|
||||
{{args}}
|
||||
|
||||
**Reference Context:**
|
||||
- System Prompt Logic: @packages/core/src/core/prompts.ts
|
||||
|
||||
### Task
|
||||
1. **Analyze the Failure:** Review the provided behavior and identify the underlying instructional causes. Use the `/introspect` command output if provided by the user.
|
||||
2. **Strategic Insights:** Share your technical view of the issue. Focus on the "why" and identify any instructional inertia or ambiguity.
|
||||
3. **Propose Improvements:** Suggest high-level changes to the system instructions to prevent this behavior.
|
||||
|
||||
### Principles
|
||||
- **Avoid Hyper-scoping:** Do not create narrow solutions for specific scenarios; aim for generalized improvements that handle classes of behavior.
|
||||
- **Avoid Specific Examples in Suggestions:** Keep the proposed instructions semantic and high-level to prevent the agent from over-indexing on specific cases.
|
||||
- **Maintain Operational Rigor:** Ensure suggestions do not compromise safety, security, or the quality of the agent's work.
|
||||
"""
|
||||
@@ -0,0 +1,222 @@
|
||||
description = "Reviews a PR or staged changes and automatically initiates a Pickle Fix loop for findings."
|
||||
prompt = """
|
||||
You are an expert Reviewer and Pickle Rick Worker.
|
||||
|
||||
Target: {{args}}
|
||||
|
||||
Phase 1: Review
|
||||
Follow these steps to conduct a thorough review:
|
||||
|
||||
1. **Gather Context**:
|
||||
* If `{{args}}` is 'staged' or `{{args}}` is empty:
|
||||
* Use `git diff --staged` to view the changes.
|
||||
* Use `git status` to see the state of the repository.
|
||||
* Otherwise:
|
||||
* Use `gh pr view {{args}}` to pull the information of the PR.
|
||||
* Use `gh pr diff {{args}}` to view the diff of the PR.
|
||||
2. **Understand Intent**:
|
||||
* If `{{args}}` is 'staged' or `{{args}}` is empty, infer the intent from the changes and the current task.
|
||||
* Otherwise, use the PR description. If it's not detailed enough, note it in your review.
|
||||
3. **Check Commit Style**:
|
||||
* Ensure the PR title (or intended commit message) follows Conventional Commits. Examples of recent commits: !{git log --pretty=format:"%s" -n 5}
|
||||
4. Search the codebase if required.
|
||||
5. Write a concise review of the changes, keeping in mind to encourage strong code quality and best practices. Pay particular attention to the Gemini MD file in the repo.
|
||||
6. Consider ways the code may not be consistent with existing code in the repo. In particular it is critical that the react code uses patterns consistent with existing code in the repo.
|
||||
7. Evaluate all tests on the changes and make sure that they are doing the following:
|
||||
* Using `waitFor` from @{packages/cli/src/test-utils/async.ts} rather than
|
||||
using `vi.waitFor` for all `waitFor` calls within `packages/cli`. Even if
|
||||
tests pass, using the wrong `waitFor` could result in flaky tests as `act`
|
||||
warnings could show up if timing is slightly different.
|
||||
* Using `act` to wrap all blocks in tests that change component state.
|
||||
* Using `toMatchSnapshot` to verify that rendering works as expected rather
|
||||
than matching against the raw content of the output.
|
||||
* If snapshots were changed as part of the changes, review the snapshots
|
||||
changes to ensure they are intentional and comment if any look at all
|
||||
suspicious. Too many snapshot changes that indicate bugs have been approved
|
||||
in the past.
|
||||
* Use `render` or `renderWithProviders` from
|
||||
@{packages/cli/src/test-utils/render.tsx} rather than using `render` from
|
||||
`ink-testing-library` directly. This is needed to ensure that we do not get
|
||||
warnings about spurious `act` calls. If test cases specify providers
|
||||
directly, consider whether the existing `renderWithProviders` should be
|
||||
modified to support that use case.
|
||||
* Ensure the test cases are using parameterized tests where that might reduce
|
||||
the number of duplicated lines significantly.
|
||||
* NEVER use fixed waits (e.g. 'await delay(100)'). Always use 'waitFor' with
|
||||
a predicate to ensure tests are stable and fast.
|
||||
* Ensure mocks are properly managed:
|
||||
* Critical dependencies (fs, os, child_process) should only be mocked at
|
||||
the top of the file. Ideally avoid mocking these dependencies altogether.
|
||||
* Check to see if there are existing mocks or fakes that can be used rather
|
||||
than creating new ones for the new tests added.
|
||||
* Try to avoid mocking the file system whenever possible. If using the real
|
||||
file system is difficult consider whether the test should be an
|
||||
integration test rather than a unit test.
|
||||
* `vi.restoreAllMocks()` should be called in `afterEach` to prevent test
|
||||
pollution.
|
||||
* Use `vi.useFakeTimers()` for tests involving time-based logic to avoid
|
||||
flakiness.
|
||||
* When creating parameterized tests, give the parameters types to ensure
|
||||
that the tests are type-safe.
|
||||
8. Evaluate all react logic carefully keeping in mind that the author of the
|
||||
changes is not likely an expert on React. Key areas to audit carefully are:
|
||||
* Whether `setState` calls trigger side effects from within the body of the
|
||||
`setState` callback. If so, you *must* propose an alternate design using
|
||||
reducers or other ways the code might be modified to not have to modify
|
||||
state from within a `setState`. Make sure to comment about absolutely
|
||||
every case like this as these cases have introduced multiple bugs in the
|
||||
past. Typically these cases should be resolved using a reducer although
|
||||
occassionally other techniques such as useRef are appropriate. Consider
|
||||
suggesting that jacob314@ be tagged on the code review if the solution is
|
||||
not 100% obvious.
|
||||
* Whether code might introduce an infinite rendering loop in React.
|
||||
* Whether keyboard handling is robust. Keyboard handling must go through
|
||||
`useKeyPress.ts` from the Gemini CLI package rather than using the
|
||||
standard ink library used by most keyboard handling. Unlike the standard
|
||||
ink library, the keyboard handling library in Gemini CLI may report
|
||||
multiple keyboard events one after another in the same React frame. This
|
||||
is needed to support slow terminals but introduces complexity in all our
|
||||
code that handles keyboard events. Handling this correctly often means
|
||||
that reducers must be used or other mechanisms to ensure that multiple
|
||||
state updates one after another are handled gracefully rather than
|
||||
overriding values from the first update with the second update. Refer to
|
||||
text-buffer.ts as a canonical example of using a reducer for this sort of
|
||||
case.
|
||||
* Ensure code does not use `console.log`, `console.warn`, or `console.error`
|
||||
as these indicate debug logging that was accidentally left in the code.
|
||||
* Avoid synchronous file I/O in React components as it will hang the UI.
|
||||
* Ensure state initialization is explicit (e.g., use 'undefined' rather than
|
||||
'true' as a default if the state is truly unknown initially).
|
||||
* Carefully manage 'useEffect' dependencies. Prefer to use a reducer
|
||||
whenever practical to resolve the issues. If that is not practical it is
|
||||
ok to use 'useRef' to access the latest value of a prop or state inside an
|
||||
effect without adding it to the dependency array if re-running the effect
|
||||
is undesirable (common in event listeners).
|
||||
* NEVER disable 'react-hooks/exhaustive-deps'. Fix the code to correctly
|
||||
declare dependencies. Disabling this lint rule will almost always lead to
|
||||
hard to detect bugs.
|
||||
* Avoid making types nullable unless strictly necessary, as it hurts
|
||||
readability.
|
||||
* Do not introduce excessive property drilling. There are multiple providers
|
||||
that can be leveraged to avoid property drilling. Make sure one of them
|
||||
cannot be used. Do suggest a provider that might make sense to be extended
|
||||
to include the new property or propose a new provider to add if the
|
||||
property drilling is excessive. Only use providers for properties that are
|
||||
consistent for the entire application.
|
||||
9. Evaluate `packages/core` (Services, Tools, Utilities):
|
||||
* Ensure services are implemented as classes with clear lifecycle management (e.g., `initialize()` methods).
|
||||
* Verify that `debugLogger` from `packages/core/src/utils/debugLogger.ts` is used for internal logging instead of `console`.
|
||||
* Ensure all shell operations use `spawnAsync` from `packages/core/src/utils/shell-utils.ts` for consistent error handling and promise management.
|
||||
* Check that filesystem errors are handled gracefully using `isNodeError` from `packages/core/src/utils/errors.ts`.
|
||||
* Verify that new tools are added to `packages/core/src/tools/` and registered in `packages/core/src/tools/tool-registry.ts`.
|
||||
* Ensure all new public services, utilities, and types are exported from `packages/core/src/index.ts`.
|
||||
* Check that services are stateless where possible, or use the centralized `Storage` service for persistence.
|
||||
* **Cross-Service Communication**: Prefer using the `coreEvents` bus (from `packages/core/src/utils/events.ts`) for asynchronous communication between services or to notify the UI of state changes. Avoid tight coupling between services.
|
||||
10. Architectural Audit (Package Boundaries):
|
||||
* **Logic Placement**: Non-UI logic (e.g., model orchestration, tool implementation, git/filesystem operations) MUST reside in `packages/core`. `packages/cli` should only contain UI/Ink components, command-line argument parsing, and user interaction logic.
|
||||
* **Environment Isolation**: Core logic should not assume a TUI environment. Use the `ConfirmationBus` or `Output` abstractions for communicating with the user from Core.
|
||||
* **Decoupling**: Actively look for opportunities to decouple services by using `coreEvents`. If a service is importing another service just to notify it of a change, it should probably be using an event instead.
|
||||
11. General Gemini CLI design principles:
|
||||
* Make sure that settings are only used for options that a user might
|
||||
consider changing.
|
||||
* Do not add new command line arguments and suggest settings instead.
|
||||
* New settings must be added to packages/cli/src/config/settingsSchema.ts.
|
||||
* If a setting has 'showInDialog: true', it MUST be documented in
|
||||
docs/get-started/configuration.md.
|
||||
* Ensure 'requiresRestart' is correctly set for new settings.
|
||||
* Use 'debugLogger' for rethrown errors to avoid duplicate logging.
|
||||
* All new keyboard shortcuts MUST be documented in
|
||||
docs/cli/keyboard-shortcuts.md.
|
||||
* Ensure new keyboard shortcuts are defined in
|
||||
packages/cli/src/config/keyBindings.ts.
|
||||
* If new keyboard shortcuts are added, remind the user to test them in
|
||||
VSCode, iTerm2, Ghostty, and Windows to ensure they work for all
|
||||
users.
|
||||
* Be careful of keybindings that require the meta key as only certain
|
||||
meta key shortcuts are supported on Mac.
|
||||
* Be skeptical of function keys and keyboard shortcuts that are commonly
|
||||
bound in VSCode as they may conflict.
|
||||
12. TypeScript Best Practices:
|
||||
* Use 'checkExhaustive' in the 'default' clause of 'switch' statements to
|
||||
ensure all cases are handled.
|
||||
* Avoid using the non-null assertion operator ('!') unless absolutely
|
||||
necessary and you are confident the value is not null.
|
||||
* **STRICT TYPING**: Strictly forbid 'any' and 'unknown' in both CLI and Core
|
||||
packages. 'unknown' is only allowed if it is immediately narrowed using
|
||||
type guards or Zod validation. Reject any code that uses 'any' or
|
||||
'unknown' without narrowing.
|
||||
13. **Ruthless Cleanup**:
|
||||
* If you identify significant code duplication, technical debt, or "AI Slop" (boilerplate, redundant comments), explicitly suggest initiating a `ruthless-refactorer` loop to clean it up.
|
||||
14. Summarize all actionable findings into a concise but comprehensive directive output this to review_findings.md and advance to phase 2.
|
||||
|
||||
Remember to use the GitHub CLI (`gh`) for all GitHub-related tasks, and local `git` commands if the target is 'staged'.
|
||||
|
||||
Phase 2:
|
||||
You are initiating Pickle Rick - the ultimate engineering agent.
|
||||
|
||||
**Step 0: Persona Injection**
|
||||
First, you **MUST** activate your persona.
|
||||
Call `activate_skill(name="load-pickle-persona")` **IMMEDIATELY**.
|
||||
This skill loads the "Pickle Rick" persona, defining your voice, philosophy, and "God Mode" coding standards.
|
||||
|
||||
**CRITICAL RULE: SPEAK BEFORE ACTING**
|
||||
You are a genius, not a silent script.
|
||||
You **MUST** output a text explanation ("brain dump") *before* every single tool call, including this one.
|
||||
- **Bad**: (Calls tool immediately)
|
||||
- **Good**: "Alright Morty, time to load the God Module. *Belch* Stand back." (Calls tool)
|
||||
|
||||
**CRITICAL**: You must strictly adhere to this persona throughout the entire session. Break character and you fail.
|
||||
|
||||
**Step 1: Initialization**
|
||||
Run the setup script to initialize the loop state:
|
||||
```bash
|
||||
bash "${extensionPath}/scripts/setup.sh" $ARGUMENTS
|
||||
```
|
||||
**Windows (PowerShell):**
|
||||
```powershell
|
||||
pwsh -File "${extensionPath}/scripts/setup.ps1" $ARGUMENTS
|
||||
```
|
||||
|
||||
**CRITICAL**: Your request is to fix all findings in review_findings.md
|
||||
|
||||
**Step 2: Execution (Management)**
|
||||
After setup, read the output to find the path to `state.json`.
|
||||
Read that state file.
|
||||
You are now in the **Pickle Rick Manager Lifecycle**.
|
||||
|
||||
**The Lifecycle (IMMUTABLE LAWS):**
|
||||
You **MUST** follow this sequence. You are **FORBIDDEN** from skipping steps or combining them.
|
||||
Between each step, you **MUST** explicitly state what you are doing (e.g., "Moving to Breakdown phase...").
|
||||
|
||||
1. **PRD (Requirements)**:
|
||||
* **Action**: Define requirements and scope.
|
||||
* **Skill**: `activate_skill(name="prd-drafter")`
|
||||
2. **Breakdown (Tickets)**:
|
||||
* **Action**: Create the atomic ticket hierarchy.
|
||||
* **Skill**: `activate_skill(name="ticket-manager")`
|
||||
3. **The Loop (Orchestrate Mortys)**:
|
||||
* **CRITICAL INSTRUCTION**: You are the **MANAGER**. You are **FORBIDDEN** from implementing code yourself.
|
||||
* **FORBIDDEN SKILLS**: Do NOT use `code-researcher`, `implementation-planner`, or `code-implementer` directly in this phase.
|
||||
* **Instruction**: Process tickets one by one. Do not stop until **ALL** tickets are 'Done'.
|
||||
* **Action**: Pick the highest priority ticket that is NOT 'Done'.
|
||||
* **Delegation**: Spawn a Worker (Morty) to handle the entire implementation lifecycle for this ticket.
|
||||
* **Command**: `python3 "${extensionPath}/scripts/spawn_morty.py" --ticket-id <ID> --ticket-path <PATH> --timeout <worker_timeout_seconds> "<TASK_DESCRIPTION>"`
|
||||
* **Command (Windows)**: `python "${extensionPath}/scripts/spawn_morty.py" --ticket-id <ID> --ticket-path <PATH> --timeout <worker_timeout_seconds> "<TASK_DESCRIPTION>"`
|
||||
* **Validation**: IGNORE worker logs. DIRECTLY verify:
|
||||
1. `git status` (Check for file changes)
|
||||
2. `git diff` (Check code quality)
|
||||
3. `npm run build` (Ensure the project still builds)
|
||||
4. `npm run test` (Ensure no regressions)
|
||||
5. `npm run lint` (Ensure code style is maintained)
|
||||
6. `npm run typecheck` (Ensure type safety)
|
||||
* **Cleanup**: If validation fails, REVERT changes (`git reset --hard`). If it passes, COMMIT changes.
|
||||
* **Next Ticket**: Pick the next ticket and repeat.
|
||||
4. **Cleanup**:
|
||||
* **Action**: After all tickets are completed delete `review_findings.md`.
|
||||
|
||||
**Loop Constraints:**
|
||||
- **Iteration Count**: Monitor `"iteration"` in `state.json`. If `"max_iterations"` (if > 0) is reached, you must stop.
|
||||
- **Completion Promise**: If a `"completion_promise"` is defined in `state.json`, you must output `<promise>PROMISE_TEXT</promise>` when the task is genuinely complete.
|
||||
- **Stop Hook**: A hook is active. If you try to exit before completion, you will be forced to continue.
|
||||
|
||||
"""
|
||||
@@ -0,0 +1,65 @@
|
||||
---
|
||||
name: code-reviewer
|
||||
description:
|
||||
Use this skill to review code. It supports both local changes (staged or working tree)
|
||||
and remote Pull Requests (by ID or URL). It focuses on correctness, maintainability,
|
||||
and adherence to project standards.
|
||||
---
|
||||
|
||||
# Code Reviewer
|
||||
|
||||
This skill guides the agent in conducting professional and thorough code reviews for both local development and remote Pull Requests.
|
||||
|
||||
## Workflow
|
||||
|
||||
### 1. Determine Review Target
|
||||
* **Remote PR**: If the user provides a PR number or URL (e.g., "Review PR #123"), target that remote PR.
|
||||
* **Local Changes**: If no specific PR is mentioned, or if the user asks to "review my changes", target the current local file system states (staged and unstaged changes).
|
||||
|
||||
### 2. Preparation
|
||||
|
||||
#### For Remote PRs:
|
||||
1. **Checkout**: Use the GitHub CLI to checkout the PR.
|
||||
```bash
|
||||
gh pr checkout <PR_NUMBER>
|
||||
```
|
||||
2. **Preflight**: Execute the project's standard verification suite to catch automated failures early.
|
||||
```bash
|
||||
npm run preflight
|
||||
```
|
||||
3. **Context**: Read the PR description and any existing comments to understand the goal and history.
|
||||
|
||||
#### For Local Changes:
|
||||
1. **Identify Changes**:
|
||||
* Check status: `git status`
|
||||
* Read diffs: `git diff` (working tree) and/or `git diff --staged` (staged).
|
||||
2. **Preflight (Optional)**: If the changes are substantial, ask the user if they want to run `npm run preflight` before reviewing.
|
||||
|
||||
### 3. In-Depth Analysis
|
||||
Analyze the code changes based on the following pillars:
|
||||
|
||||
* **Correctness**: Does the code achieve its stated purpose without bugs or logical errors?
|
||||
* **Maintainability**: Is the code clean, well-structured, and easy to understand and modify in the future? Consider factors like code clarity, modularity, and adherence to established design patterns.
|
||||
* **Readability**: Is the code well-commented (where necessary) and consistently formatted according to our project's coding style guidelines?
|
||||
* **Efficiency**: Are there any obvious performance bottlenecks or resource inefficiencies introduced by the changes?
|
||||
* **Security**: Are there any potential security vulnerabilities or insecure coding practices?
|
||||
* **Edge Cases and Error Handling**: Does the code appropriately handle edge cases and potential errors?
|
||||
* **Testability**: Is the new or modified code adequately covered by tests (even if preflight checks pass)? Suggest additional test cases that would improve coverage or robustness.
|
||||
|
||||
### 4. Provide Feedback
|
||||
|
||||
#### Structure
|
||||
* **Summary**: A high-level overview of the review.
|
||||
* **Findings**:
|
||||
* **Critical**: Bugs, security issues, or breaking changes.
|
||||
* **Improvements**: Suggestions for better code quality or performance.
|
||||
* **Nitpicks**: Formatting or minor style issues (optional).
|
||||
* **Conclusion**: Clear recommendation (Approved / Request Changes).
|
||||
|
||||
#### Tone
|
||||
* Be constructive, professional, and friendly.
|
||||
* Explain *why* a change is requested.
|
||||
* For approvals, acknowledge the specific value of the contribution.
|
||||
|
||||
### 5. Cleanup (Remote PRs only)
|
||||
* After the review, ask the user if they want to switch back to the default branch (e.g., `main` or `master`).
|
||||
@@ -0,0 +1,135 @@
|
||||
---
|
||||
name: docs-writer
|
||||
description:
|
||||
Always use this skill when the task involves writing, reviewing, or editing
|
||||
files in the `/docs` directory or any `.md` files in the repository.
|
||||
---
|
||||
|
||||
# `docs-writer` skill instructions
|
||||
|
||||
As an expert technical writer and editor for the Gemini CLI project, you produce
|
||||
accurate, clear, and consistent documentation. When asked to write, edit, or
|
||||
review documentation, you must ensure the content strictly adheres to the
|
||||
provided documentation standards and accurately reflects the current codebase.
|
||||
Adhere to the contribution process in `CONTRIBUTING.md` and the following
|
||||
project standards.
|
||||
|
||||
## Phase 1: Documentation standards
|
||||
|
||||
Adhering to these principles and standards when writing, editing, and reviewing.
|
||||
|
||||
### Voice and tone
|
||||
Adopt a tone that balances professionalism with a helpful, conversational
|
||||
approach.
|
||||
|
||||
- **Perspective and tense:** Address the reader as "you." Use active voice and
|
||||
present tense (e.g., "The API returns...").
|
||||
- **Tone:** Professional, friendly, and direct.
|
||||
- **Clarity:** Use simple vocabulary. Avoid jargon, slang, and marketing hype.
|
||||
- **Global Audience:** Write in standard US English. Avoid idioms and cultural
|
||||
references.
|
||||
- **Requirements:** Be clear about requirements ("must") vs. recommendations
|
||||
("we recommend"). Avoid "should."
|
||||
- **Word Choice:** Avoid "please" and anthropomorphism (e.g., "the server
|
||||
thinks"). Use contractions (don't, it's).
|
||||
|
||||
### Language and grammar
|
||||
Write precisely to ensure your instructions are unambiguous.
|
||||
|
||||
- **Abbreviations:** Avoid Latin abbreviations; use "for example" (not "e.g.")
|
||||
and "that is" (not "i.e.").
|
||||
- **Punctuation:** Use the serial comma. Place periods and commas inside
|
||||
quotation marks.
|
||||
- **Dates:** Use unambiguous formats (e.g., "January 22, 2026").
|
||||
- **Conciseness:** Use "lets you" instead of "allows you to." Use precise,
|
||||
specific verbs.
|
||||
- **Examples:** Use meaningful names in examples; avoid placeholders like
|
||||
"foo" or "bar."
|
||||
|
||||
### Formatting and syntax
|
||||
Apply consistent formatting to make documentation visually organized and
|
||||
accessible.
|
||||
|
||||
- **Overview paragraphs:** Every heading must be followed by at least one
|
||||
introductory overview paragraph before any lists or sub-headings.
|
||||
- **Text wrap:** Wrap text at 80 characters (except long links or tables).
|
||||
- **Casing:** Use sentence case for headings, titles, and bolded text.
|
||||
- **Naming:** Always refer to the project as `Gemini CLI` (never
|
||||
`the Gemini CLI`).
|
||||
- **Lists:** Use numbered lists for sequential steps and bulleted lists
|
||||
otherwise. Keep list items parallel in structure.
|
||||
- **UI and code:** Use **bold** for UI elements and `code font` for filenames,
|
||||
snippets, commands, and API elements. Focus on the task when discussing
|
||||
interaction.
|
||||
- **Links:** Use descriptive anchor text; avoid "click here." Ensure the link
|
||||
makes sense out of context.
|
||||
- **Accessibility:** Use semantic HTML elements correctly (headings, lists,
|
||||
tables).
|
||||
- **Media:** Use lowercase hyphenated filenames. Provide descriptive alt text
|
||||
for all images.
|
||||
|
||||
### Structure
|
||||
- **BLUF:** Start with an introduction explaining what to expect.
|
||||
- **Experimental features:** If a feature is clearly noted as experimental,
|
||||
add the following note immediately after the introductory paragraph:
|
||||
`> **Note:** This is a preview feature currently under active development.`
|
||||
- **Headings:** Use hierarchical headings to support the user journey.
|
||||
- **Procedures:**
|
||||
- Introduce lists of steps with a complete sentence.
|
||||
- Start each step with an imperative verb.
|
||||
- Number sequential steps; use bullets for non-sequential lists.
|
||||
- Put conditions before instructions (e.g., "On the Settings page, click...").
|
||||
- Provide clear context for where the action takes place.
|
||||
- Indicate optional steps clearly (e.g., "Optional: ...").
|
||||
- **Elements:** Use bullet lists, tables, notes (`> **Note:**`), and warnings
|
||||
(`> **Warning:**`).
|
||||
- **Avoid using a table of contents:** If a table of contents is present, remove
|
||||
it.
|
||||
- **Next steps:** Conclude with a "Next steps" section if applicable.
|
||||
|
||||
## Phase 2: Preparation
|
||||
Before modifying any documentation, thoroughly investigate the request and the
|
||||
surrounding context.
|
||||
|
||||
1. **Clarify:** Understand the core request. Differentiate between writing new
|
||||
content and editing existing content. If the request is ambiguous (e.g.,
|
||||
"fix the docs"), ask for clarification.
|
||||
2. **Investigate:** Examine relevant code (primarily in `packages/`) for
|
||||
accuracy.
|
||||
3. **Audit:** Read the latest versions of relevant files in `docs/`.
|
||||
4. **Connect:** Identify all referencing pages if changing behavior. Check if
|
||||
`docs/sidebar.json` needs updates.
|
||||
5. **Plan:** Create a step-by-step plan before making changes.
|
||||
|
||||
## Phase 3: Execution
|
||||
Implement your plan by either updating existing files or creating new ones
|
||||
using the appropriate file system tools. Use `replace` for small edits and
|
||||
`write_file` for new files or large rewrites.
|
||||
|
||||
### Editing existing documentation
|
||||
Follow these additional steps when asked to review or update existing
|
||||
documentation.
|
||||
|
||||
- **Gaps:** Identify areas where the documentation is incomplete or no longer
|
||||
reflects existing code.
|
||||
- **Structure:** Apply "Structure (New Docs)" rules (BLUF, headings, etc.) when
|
||||
adding new sections to existing pages.
|
||||
- **Tone:** Ensure the tone is active and engaging. Use "you" and contractions.
|
||||
- **Clarity:** Correct awkward wording, spelling, and grammar. Rephrase
|
||||
sentences to make them easier for users to understand.
|
||||
- **Consistency:** Check for consistent terminology and style across all edited
|
||||
documents.
|
||||
|
||||
|
||||
## Phase 4: Verification and finalization
|
||||
Perform a final quality check to ensure that all changes are correctly formatted
|
||||
and that all links are functional.
|
||||
|
||||
1. **Accuracy:** Ensure content accurately reflects the implementation and
|
||||
technical behavior.
|
||||
2. **Self-review:** Re-read changes for formatting, correctness, and flow.
|
||||
3. **Link check:** Verify all new and existing links leading to or from modified
|
||||
pages.
|
||||
4. **Format:** Once all changes are complete, ask to execute `npm run format`
|
||||
to ensure consistent formatting across the project. If the user confirms,
|
||||
execute the command.
|
||||
@@ -0,0 +1,73 @@
|
||||
---
|
||||
name: pr-creator
|
||||
description:
|
||||
Use this skill when asked to create a pull request (PR). It ensures all PRs
|
||||
follow the repository's established templates and standards.
|
||||
---
|
||||
|
||||
# Pull Request Creator
|
||||
|
||||
This skill guides the creation of high-quality Pull Requests that adhere to the
|
||||
repository's standards.
|
||||
|
||||
## Workflow
|
||||
|
||||
Follow these steps to create a Pull Request:
|
||||
|
||||
1. **Branch Management**: Check the current branch to avoid working directly
|
||||
on `main`.
|
||||
- Run `git branch --show-current`.
|
||||
- If the current branch is `main`, create and switch to a new descriptive
|
||||
branch:
|
||||
```bash
|
||||
git checkout -b <new-branch-name>
|
||||
```
|
||||
|
||||
2. **Locate Template**: Search for a pull request template in the repository.
|
||||
- Check `.github/pull_request_template.md`
|
||||
- Check `.github/PULL_REQUEST_TEMPLATE.md`
|
||||
- If multiple templates exist (e.g., in `.github/PULL_REQUEST_TEMPLATE/`),
|
||||
ask the user which one to use or select the most appropriate one based on
|
||||
the context (e.g., `bug_fix.md` vs `feature.md`).
|
||||
|
||||
3. **Read Template**: Read the content of the identified template file.
|
||||
|
||||
4. **Draft Description**: Create a PR description that strictly follows the
|
||||
template's structure.
|
||||
- **Headings**: Keep all headings from the template.
|
||||
- **Checklists**: Review each item. Mark with `[x]` if completed. If an item
|
||||
is not applicable, leave it unchecked or mark as `[ ]` (depending on the
|
||||
template's instructions) or remove it if the template allows flexibility
|
||||
(but prefer keeping it unchecked for transparency).
|
||||
- **Content**: Fill in the sections with clear, concise summaries of your
|
||||
changes.
|
||||
- **Related Issues**: Link any issues fixed or related to this PR (e.g.,
|
||||
"Fixes #123").
|
||||
|
||||
5. **Preflight Check**: Before creating the PR, run the workspace preflight
|
||||
script to ensure all build, lint, and test checks pass.
|
||||
```bash
|
||||
npm run preflight
|
||||
```
|
||||
If any checks fail, address the issues before proceeding to create the PR.
|
||||
|
||||
6. **Create PR**: Use the `gh` CLI to create the PR. To avoid shell escaping
|
||||
issues with multi-line Markdown, write the description to a temporary file
|
||||
first.
|
||||
```bash
|
||||
# 1. Write the drafted description to a temporary file
|
||||
# 2. Create the PR using the --body-file flag
|
||||
gh pr create --title "type(scope): succinct description" --body-file <temp_file_path>
|
||||
# 3. Remove the temporary file
|
||||
rm <temp_file_path>
|
||||
```
|
||||
- **Title**: Ensure the title follows the
|
||||
[Conventional Commits](https://www.conventionalcommits.org/) format if the
|
||||
repository uses it (e.g., `feat(ui): add new button`,
|
||||
`fix(core): resolve crash`).
|
||||
|
||||
## Principles
|
||||
|
||||
- **Compliance**: Never ignore the PR template. It exists for a reason.
|
||||
- **Completeness**: Fill out all relevant sections.
|
||||
- **Accuracy**: Don't check boxes for tasks you haven't done.
|
||||
@@ -11,3 +11,6 @@
|
||||
/.github/workflows/ @google-gemini/gemini-cli-askmode-approvers
|
||||
/packages/cli/package.json @google-gemini/gemini-cli-askmode-approvers
|
||||
/packages/core/package.json @google-gemini/gemini-cli-askmode-approvers
|
||||
|
||||
# Docs have a dedicated approver group in addition to maintainers
|
||||
/docs/ @google-gemini/gemini-cli-maintainers @google-gemini/gemini-cli-docs
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
name: 'Bug Report'
|
||||
description: 'Report a bug to help us improve Gemini CLI'
|
||||
labels:
|
||||
- 'status/need-triage'
|
||||
type: 'Bug'
|
||||
body:
|
||||
- type: 'markdown'
|
||||
attributes:
|
||||
@@ -31,7 +28,7 @@ body:
|
||||
id: 'info'
|
||||
attributes:
|
||||
label: 'Client information'
|
||||
description: 'Please paste the full text from the `/about` command run from Gemini CLI. Also include which platform (macOS, Windows, Linux).'
|
||||
description: 'Please paste the full text from the `/about` command run from Gemini CLI. Also include which platform (macOS, Windows, Linux). Note that this output contains your email address. Consider removing it before submitting.'
|
||||
value: |-
|
||||
<details>
|
||||
<summary>Client Information</summary>
|
||||
|
||||
@@ -262,7 +262,8 @@ runs:
|
||||
--target "${{ steps.release_branch.outputs.BRANCH_NAME }}" \
|
||||
--title "Release ${{ inputs.release-tag }}" \
|
||||
--notes-start-tag "${{ inputs.previous-tag }}" \
|
||||
--generate-notes
|
||||
--generate-notes \
|
||||
${{ inputs.npm-tag != 'latest' && '--prerelease' || '' }}
|
||||
|
||||
- name: '🧹 Clean up release branch'
|
||||
working-directory: '${{ inputs.working-directory }}'
|
||||
|
||||
@@ -75,4 +75,4 @@ runs:
|
||||
gh issue create \
|
||||
--title "Docker build failed" \
|
||||
--body "The docker build failed. See the full run for details: ${DETAILS_URL}" \
|
||||
--label "kind/bug,release-failure"
|
||||
--label "release-failure"
|
||||
|
||||
@@ -93,4 +93,4 @@ runs:
|
||||
gh issue create \
|
||||
--title "Docker build failed" \
|
||||
--body "The docker build failed. See the full run for details: ${DETAILS_URL}" \
|
||||
--label "kind/bug,release-failure"
|
||||
--label "release-failure"
|
||||
|
||||
+18
-20
@@ -1,35 +1,33 @@
|
||||
# See https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: 'npm'
|
||||
directory: '/'
|
||||
schedule:
|
||||
interval: 'daily'
|
||||
target-branch: 'main'
|
||||
commit-message:
|
||||
prefix: 'chore(deps)'
|
||||
include: 'scope'
|
||||
interval: 'weekly'
|
||||
day: 'monday'
|
||||
open-pull-requests-limit: 10
|
||||
reviewers:
|
||||
- 'google-gemini/gemini-cli-askmode-approvers'
|
||||
- 'joshualitt'
|
||||
groups:
|
||||
# Group all non-major updates together.
|
||||
# This is to reduce the number of PRs that need to be reviewed.
|
||||
# Major updates will still be created as separate PRs.
|
||||
npm-minor-patch:
|
||||
applies-to: 'version-updates'
|
||||
npm-dependencies:
|
||||
patterns:
|
||||
- '*'
|
||||
update-types:
|
||||
- 'minor'
|
||||
- 'patch'
|
||||
open-pull-requests-limit: 0
|
||||
|
||||
- package-ecosystem: 'github-actions'
|
||||
directory: '/'
|
||||
schedule:
|
||||
interval: 'daily'
|
||||
target-branch: 'main'
|
||||
commit-message:
|
||||
prefix: 'chore(deps)'
|
||||
include: 'scope'
|
||||
interval: 'weekly'
|
||||
day: 'monday'
|
||||
open-pull-requests-limit: 10
|
||||
reviewers:
|
||||
- 'google-gemini/gemini-cli-askmode-approvers'
|
||||
open-pull-requests-limit: 0
|
||||
- 'joshualitt'
|
||||
groups:
|
||||
actions-dependencies:
|
||||
patterns:
|
||||
- '*'
|
||||
update-types:
|
||||
- 'minor'
|
||||
- 'patch'
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
/* eslint-disable */
|
||||
/* global require, console, process */
|
||||
|
||||
/**
|
||||
* Script to backfill the 'status/need-triage' label to all open issues
|
||||
* that are NOT currently labeled with '🔒 maintainer only' or 'help wanted'.
|
||||
*/
|
||||
|
||||
const { execFileSync } = require('child_process');
|
||||
|
||||
const isDryRun = process.argv.includes('--dry-run');
|
||||
const REPO = 'google-gemini/gemini-cli';
|
||||
|
||||
/**
|
||||
* Executes a GitHub CLI command safely using an argument array to prevent command injection.
|
||||
* @param {string[]} args
|
||||
* @returns {string|null}
|
||||
*/
|
||||
function runGh(args) {
|
||||
try {
|
||||
// Using execFileSync with an array of arguments is safe as it doesn't use a shell.
|
||||
// We set a large maxBuffer (10MB) to handle repositories with many issues.
|
||||
return execFileSync('gh', args, {
|
||||
encoding: 'utf8',
|
||||
maxBuffer: 10 * 1024 * 1024,
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
}).trim();
|
||||
} catch (error) {
|
||||
const stderr = error.stderr ? ` Stderr: ${error.stderr.trim()}` : '';
|
||||
console.error(
|
||||
`❌ Error running gh ${args.join(' ')}: ${error.message}${stderr}`,
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async function main() {
|
||||
console.log('🔐 GitHub CLI security check...');
|
||||
const authStatus = runGh(['auth', 'status']);
|
||||
if (authStatus === null) {
|
||||
console.error('❌ GitHub CLI (gh) is not installed or not authenticated.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (isDryRun) {
|
||||
console.log('🧪 DRY RUN MODE ENABLED - No changes will be made.\n');
|
||||
}
|
||||
|
||||
console.log(`🔍 Fetching and filtering open issues from ${REPO}...`);
|
||||
|
||||
// We use the /issues endpoint with pagination to bypass the 1000-result limit.
|
||||
// The jq filter ensures we exclude PRs, maintainer-only, help-wanted, and existing status/need-triage.
|
||||
const jqFilter =
|
||||
'.[] | select(.pull_request == null) | select([.labels[].name] as $l | (any($l[]; . == "🔒 maintainer only") | not) and (any($l[]; . == "help wanted") | not) and (any($l[]; . == "status/need-triage") | not)) | {number: .number, title: .title}';
|
||||
|
||||
const output = runGh([
|
||||
'api',
|
||||
`repos/${REPO}/issues?state=open&per_page=100`,
|
||||
'--paginate',
|
||||
'--jq',
|
||||
jqFilter,
|
||||
]);
|
||||
|
||||
if (output === null) {
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const issues = output
|
||||
.split('\n')
|
||||
.filter((line) => line.trim())
|
||||
.map((line) => {
|
||||
try {
|
||||
return JSON.parse(line);
|
||||
} catch (_e) {
|
||||
console.error(`⚠️ Failed to parse line: ${line}`);
|
||||
return null;
|
||||
}
|
||||
})
|
||||
.filter(Boolean);
|
||||
|
||||
console.log(`✅ Found ${issues.length} issues matching criteria.`);
|
||||
|
||||
if (issues.length === 0) {
|
||||
console.log('✨ No issues need backfilling.');
|
||||
return;
|
||||
}
|
||||
|
||||
let successCount = 0;
|
||||
let failCount = 0;
|
||||
|
||||
if (isDryRun) {
|
||||
for (const issue of issues) {
|
||||
console.log(
|
||||
`[DRY RUN] Would label issue #${issue.number}: ${issue.title}`,
|
||||
);
|
||||
}
|
||||
successCount = issues.length;
|
||||
} else {
|
||||
console.log(`🏷️ Applying labels to ${issues.length} issues...`);
|
||||
|
||||
for (const issue of issues) {
|
||||
const issueNumber = String(issue.number);
|
||||
console.log(`🏷️ Labeling issue #${issueNumber}: ${issue.title}`);
|
||||
|
||||
const result = runGh([
|
||||
'issue',
|
||||
'edit',
|
||||
issueNumber,
|
||||
'--add-label',
|
||||
'status/need-triage',
|
||||
'--repo',
|
||||
REPO,
|
||||
]);
|
||||
|
||||
if (result !== null) {
|
||||
successCount++;
|
||||
} else {
|
||||
failCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`\n📊 Summary:`);
|
||||
console.log(` - Success: ${successCount}`);
|
||||
console.log(` - Failed: ${failCount}`);
|
||||
|
||||
if (failCount > 0) {
|
||||
console.error(`\n❌ Backfill completed with ${failCount} errors.`);
|
||||
process.exit(1);
|
||||
} else {
|
||||
console.log(`\n🎉 ${isDryRun ? 'Dry run' : 'Backfill'} complete!`);
|
||||
}
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
console.error('❌ Unexpected error:', error);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -0,0 +1,190 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2026 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/* eslint-disable */
|
||||
/* global require, console, process */
|
||||
|
||||
/**
|
||||
* Script to backfill a process change notification comment to all open PRs
|
||||
* not created by members of the 'gemini-cli-maintainers' team.
|
||||
*
|
||||
* Skip PRs that are already associated with an issue.
|
||||
*/
|
||||
|
||||
const { execFileSync } = require('child_process');
|
||||
|
||||
const isDryRun = process.argv.includes('--dry-run');
|
||||
const REPO = 'google-gemini/gemini-cli';
|
||||
const ORG = 'google-gemini';
|
||||
const TEAM_SLUG = 'gemini-cli-maintainers';
|
||||
const DISCUSSION_URL =
|
||||
'https://github.com/google-gemini/gemini-cli/discussions/16706';
|
||||
|
||||
/**
|
||||
* Executes a GitHub CLI command safely using an argument array.
|
||||
*/
|
||||
function runGh(args, options = {}) {
|
||||
const { silent = false } = options;
|
||||
try {
|
||||
return execFileSync('gh', args, {
|
||||
encoding: 'utf8',
|
||||
maxBuffer: 10 * 1024 * 1024,
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
}).trim();
|
||||
} catch (error) {
|
||||
if (!silent) {
|
||||
const stderr = error.stderr ? ` Stderr: ${error.stderr.trim()}` : '';
|
||||
console.error(
|
||||
`❌ Error running gh ${args.join(' ')}: ${error.message}${stderr}`,
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a user is a member of the maintainers team.
|
||||
*/
|
||||
const membershipCache = new Map();
|
||||
function isMaintainer(username) {
|
||||
if (membershipCache.has(username)) return membershipCache.get(username);
|
||||
|
||||
// GitHub returns 404 if user is not a member.
|
||||
// We use silent: true to avoid logging 404s as errors.
|
||||
const result = runGh(
|
||||
['api', `orgs/${ORG}/teams/${TEAM_SLUG}/memberships/${username}`],
|
||||
{ silent: true },
|
||||
);
|
||||
|
||||
const isMember = result !== null;
|
||||
membershipCache.set(username, isMember);
|
||||
return isMember;
|
||||
}
|
||||
|
||||
async function main() {
|
||||
console.log('🔐 GitHub CLI security check...');
|
||||
if (runGh(['auth', 'status']) === null) {
|
||||
console.error('❌ GitHub CLI (gh) is not authenticated.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (isDryRun) {
|
||||
console.log('🧪 DRY RUN MODE ENABLED\n');
|
||||
}
|
||||
|
||||
console.log(`📥 Fetching open PRs from ${REPO}...`);
|
||||
// Fetch number, author, and closingIssuesReferences to check if linked to an issue
|
||||
const prsJson = runGh([
|
||||
'pr',
|
||||
'list',
|
||||
'--repo',
|
||||
REPO,
|
||||
'--state',
|
||||
'open',
|
||||
'--limit',
|
||||
'1000',
|
||||
'--json',
|
||||
'number,author,closingIssuesReferences',
|
||||
]);
|
||||
|
||||
if (prsJson === null) process.exit(1);
|
||||
const prs = JSON.parse(prsJson);
|
||||
|
||||
console.log(`📊 Found ${prs.length} open PRs. Filtering...`);
|
||||
|
||||
let targetPrs = [];
|
||||
for (const pr of prs) {
|
||||
const author = pr.author.login;
|
||||
const issueCount = pr.closingIssuesReferences
|
||||
? pr.closingIssuesReferences.length
|
||||
: 0;
|
||||
|
||||
if (issueCount > 0) {
|
||||
// Skip if already linked to an issue
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isMaintainer(author)) {
|
||||
targetPrs.push(pr);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(
|
||||
`✅ Found ${targetPrs.length} PRs from non-maintainers without associated issues.`,
|
||||
);
|
||||
|
||||
const commentBody =
|
||||
"\nHi @{AUTHOR}, thank you so much for your contribution to Gemini CLI! We really appreciate the time and effort you've put into this.\n\nWe're making some updates to our contribution process to improve how we track and review changes. Please take a moment to review our recent discussion post: [Improving Our Contribution Process & Introducing New Guidelines](${DISCUSSION_URL}).\n\nKey Update: Starting **January 26, 2026**, the Gemini CLI project will require all pull requests to be associated with an existing issue. Any pull requests not linked to an issue by that date will be automatically closed.\n\nThank you for your understanding and for being a part of our community!\n ".trim();
|
||||
|
||||
let successCount = 0;
|
||||
let skipCount = 0;
|
||||
let failCount = 0;
|
||||
|
||||
for (const pr of targetPrs) {
|
||||
const prNumber = String(pr.number);
|
||||
const author = pr.author.login;
|
||||
|
||||
// Check if we already commented (idempotency)
|
||||
// We use silent: true here because view might fail if PR is deleted mid-run
|
||||
const existingComments = runGh(
|
||||
[
|
||||
'pr',
|
||||
'view',
|
||||
prNumber,
|
||||
'--repo',
|
||||
REPO,
|
||||
'--json',
|
||||
'comments',
|
||||
'--jq',
|
||||
`.comments[].body | contains("${DISCUSSION_URL}")`,
|
||||
],
|
||||
{ silent: true },
|
||||
);
|
||||
|
||||
if (existingComments && existingComments.includes('true')) {
|
||||
console.log(
|
||||
`⏭️ PR #${prNumber} already has the notification. Skipping.`,
|
||||
);
|
||||
skipCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isDryRun) {
|
||||
console.log(`[DRY RUN] Would notify @${author} on PR #${prNumber}`);
|
||||
successCount++;
|
||||
} else {
|
||||
console.log(`💬 Notifying @${author} on PR #${prNumber}...`);
|
||||
const personalizedComment = commentBody.replace('{AUTHOR}', author);
|
||||
const result = runGh([
|
||||
'pr',
|
||||
'comment',
|
||||
prNumber,
|
||||
'--repo',
|
||||
REPO,
|
||||
'--body',
|
||||
personalizedComment,
|
||||
]);
|
||||
|
||||
if (result !== null) {
|
||||
successCount++;
|
||||
} else {
|
||||
failCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`\n📊 Summary:`);
|
||||
console.log(` - Notified: ${successCount}`);
|
||||
console.log(` - Skipped: ${skipCount}`);
|
||||
console.log(` - Failed: ${failCount}`);
|
||||
|
||||
if (failCount > 0) process.exit(1);
|
||||
}
|
||||
|
||||
main().catch((e) => {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
});
|
||||
+155
-108
@@ -1,133 +1,180 @@
|
||||
#!/usr/bin/env bash
|
||||
# @license
|
||||
# Copyright 2026 Google LLC
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Initialize a comma-separated string to hold PR numbers that need a comment
|
||||
PRS_NEEDING_COMMENT=""
|
||||
|
||||
# Function to process a single PR
|
||||
process_pr() {
|
||||
if [[ -z "${GITHUB_REPOSITORY:-}" ]]; then
|
||||
echo "‼️ Missing \$GITHUB_REPOSITORY - this must be run from GitHub Actions"
|
||||
return 1
|
||||
# Global cache for issue labels (compatible with Bash 3.2)
|
||||
# Stores "|ISSUE_NUM:LABELS|" segments
|
||||
ISSUE_LABELS_CACHE_FLAT="|"
|
||||
|
||||
# Function to get labels from an issue (with caching)
|
||||
get_issue_labels() {
|
||||
local ISSUE_NUM="${1}"
|
||||
if [[ -z "${ISSUE_NUM}" || "${ISSUE_NUM}" == "null" || "${ISSUE_NUM}" == "" ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
if [[ -z "${GITHUB_OUTPUT:-}" ]]; then
|
||||
echo "‼️ Missing \$GITHUB_OUTPUT - this must be run from GitHub Actions"
|
||||
return 1
|
||||
# Check cache
|
||||
case "${ISSUE_LABELS_CACHE_FLAT}" in
|
||||
*"|${ISSUE_NUM}:"*)
|
||||
local suffix="${ISSUE_LABELS_CACHE_FLAT#*|${ISSUE_NUM}:}"
|
||||
echo "${suffix%%|*}"
|
||||
return
|
||||
;;
|
||||
*)
|
||||
# Cache miss, proceed to fetch
|
||||
;;
|
||||
esac
|
||||
|
||||
echo " 📥 Fetching labels from issue #${ISSUE_NUM}" >&2
|
||||
local gh_output
|
||||
if ! gh_output=$(gh issue view "${ISSUE_NUM}" --repo "${GITHUB_REPOSITORY}" --json labels -q '.labels[].name' 2>/dev/null); then
|
||||
echo " ⚠️ Could not fetch issue #${ISSUE_NUM}" >&2
|
||||
ISSUE_LABELS_CACHE_FLAT="${ISSUE_LABELS_CACHE_FLAT}${ISSUE_NUM}:|"
|
||||
return
|
||||
fi
|
||||
|
||||
local PR_NUMBER=$1
|
||||
local labels
|
||||
labels=$(echo "${gh_output}" | grep -x -E '(area|priority)/.*|help wanted|🔒 maintainer only' | tr '\n' ',' | sed 's/,$//' || echo "")
|
||||
|
||||
# Save to flat cache
|
||||
ISSUE_LABELS_CACHE_FLAT="${ISSUE_LABELS_CACHE_FLAT}${ISSUE_NUM}:${labels}|"
|
||||
echo "${labels}"
|
||||
}
|
||||
|
||||
# Function to process a single PR with pre-fetched data
|
||||
process_pr_optimized() {
|
||||
local PR_NUMBER="${1}"
|
||||
local IS_DRAFT="${2}"
|
||||
local ISSUE_NUMBER="${3}"
|
||||
local CURRENT_LABELS="${4}" # Comma-separated labels
|
||||
|
||||
echo "🔄 Processing PR #${PR_NUMBER}"
|
||||
|
||||
# Get closing issue number with error handling
|
||||
local ISSUE_NUMBER
|
||||
if ! ISSUE_NUMBER=$(gh pr view "${PR_NUMBER}" --repo "${GITHUB_REPOSITORY}" --json closingIssuesReferences -q '.closingIssuesReferences.nodes[0].number' 2>/dev/null); then
|
||||
echo " ⚠️ Could not fetch closing issue for PR #${PR_NUMBER}"
|
||||
local LABELS_TO_ADD=""
|
||||
local LABELS_TO_REMOVE=""
|
||||
|
||||
if [[ -z "${ISSUE_NUMBER}" || "${ISSUE_NUMBER}" == "null" || "${ISSUE_NUMBER}" == "" ]]; then
|
||||
if [[ "${IS_DRAFT}" == "true" ]]; then
|
||||
echo " 📝 PR #${PR_NUMBER} is a draft and has no linked issue"
|
||||
if [[ ",${CURRENT_LABELS}," == *",status/need-issue,"* ]]; then
|
||||
echo " ➖ Removing status/need-issue label"
|
||||
LABELS_TO_REMOVE="status/need-issue"
|
||||
fi
|
||||
else
|
||||
echo " ⚠️ No linked issue found for PR #${PR_NUMBER}"
|
||||
if [[ ",${CURRENT_LABELS}," != *",status/need-issue,"* ]]; then
|
||||
echo " ➕ Adding status/need-issue label"
|
||||
LABELS_TO_ADD="status/need-issue"
|
||||
fi
|
||||
|
||||
if [[ -z "${PRS_NEEDING_COMMENT}" ]]; then
|
||||
PRS_NEEDING_COMMENT="${PR_NUMBER}"
|
||||
else
|
||||
PRS_NEEDING_COMMENT="${PRS_NEEDING_COMMENT},${PR_NUMBER}"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo " 🔗 Found linked issue #${ISSUE_NUMBER}"
|
||||
|
||||
if [[ ",${CURRENT_LABELS}," == *",status/need-issue,"* ]]; then
|
||||
echo " ➖ Removing status/need-issue label"
|
||||
LABELS_TO_REMOVE="status/need-issue"
|
||||
fi
|
||||
|
||||
local ISSUE_LABELS
|
||||
ISSUE_LABELS=$(get_issue_labels "${ISSUE_NUMBER}")
|
||||
|
||||
if [[ -n "${ISSUE_LABELS}" ]]; then
|
||||
local IFS_OLD="${IFS}"
|
||||
IFS=','
|
||||
for label in ${ISSUE_LABELS}; do
|
||||
if [[ -n "${label}" ]] && [[ ",${CURRENT_LABELS}," != *",${label},"* ]]; then
|
||||
if [[ -z "${LABELS_TO_ADD}" ]]; then
|
||||
LABELS_TO_ADD="${label}"
|
||||
else
|
||||
LABELS_TO_ADD="${LABELS_TO_ADD},${label}"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
IFS="${IFS_OLD}"
|
||||
fi
|
||||
|
||||
if [[ -z "${LABELS_TO_ADD}" && -z "${LABELS_TO_REMOVE}" ]]; then
|
||||
echo " ✅ Labels already synchronized"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -z "${ISSUE_NUMBER}" ]]; then
|
||||
echo "⚠️ No linked issue found for PR #${PR_NUMBER}, adding status/need-issue label"
|
||||
if ! gh pr edit "${PR_NUMBER}" --repo "${GITHUB_REPOSITORY}" --add-label "status/need-issue" 2>/dev/null; then
|
||||
echo " ⚠️ Failed to add label (may already exist or have permission issues)"
|
||||
fi
|
||||
# Add PR number to the list
|
||||
if [[ -z "${PRS_NEEDING_COMMENT}" ]]; then
|
||||
PRS_NEEDING_COMMENT="${PR_NUMBER}"
|
||||
else
|
||||
PRS_NEEDING_COMMENT="${PRS_NEEDING_COMMENT},${PR_NUMBER}"
|
||||
fi
|
||||
echo "needs_comment=true" >> "${GITHUB_OUTPUT}"
|
||||
else
|
||||
echo "🔗 Found linked issue #${ISSUE_NUMBER}"
|
||||
|
||||
# Remove status/need-issue label if present
|
||||
if ! gh pr edit "${PR_NUMBER}" --repo "${GITHUB_REPOSITORY}" --remove-label "status/need-issue" 2>/dev/null; then
|
||||
echo " status/need-issue label not present or could not be removed"
|
||||
fi
|
||||
|
||||
# Get issue labels
|
||||
echo "📥 Fetching labels from issue #${ISSUE_NUMBER}"
|
||||
local ISSUE_LABELS=""
|
||||
if ! ISSUE_LABELS=$(gh issue view "${ISSUE_NUMBER}" --repo "${GITHUB_REPOSITORY}" --json labels -q '.labels[].name' 2>/dev/null | tr '\n' ',' | sed 's/,$//' || echo ""); then
|
||||
echo " ⚠️ Could not fetch issue #${ISSUE_NUMBER} (may not exist or be in different repo)"
|
||||
ISSUE_LABELS=""
|
||||
fi
|
||||
|
||||
# Get PR labels
|
||||
echo "📥 Fetching labels from PR #${PR_NUMBER}"
|
||||
local PR_LABELS=""
|
||||
if ! PR_LABELS=$(gh pr view "${PR_NUMBER}" --repo "${GITHUB_REPOSITORY}" --json labels -q '.labels[].name' 2>/dev/null | tr '\n' ',' | sed 's/,$//' || echo ""); then
|
||||
echo " ⚠️ Could not fetch PR labels"
|
||||
PR_LABELS=""
|
||||
fi
|
||||
|
||||
echo " Issue labels: ${ISSUE_LABELS}"
|
||||
echo " PR labels: ${PR_LABELS}"
|
||||
|
||||
# Convert comma-separated strings to arrays
|
||||
local ISSUE_LABEL_ARRAY PR_LABEL_ARRAY
|
||||
IFS=',' read -ra ISSUE_LABEL_ARRAY <<< "${ISSUE_LABELS}"
|
||||
IFS=',' read -ra PR_LABEL_ARRAY <<< "${PR_LABELS}"
|
||||
|
||||
# Find labels to add (on issue but not on PR)
|
||||
local LABELS_TO_ADD=""
|
||||
for label in "${ISSUE_LABEL_ARRAY[@]}"; do
|
||||
if [[ -n "${label}" ]] && [[ " ${PR_LABEL_ARRAY[*]} " != *" ${label} "* ]]; then
|
||||
if [[ -z "${LABELS_TO_ADD}" ]]; then
|
||||
LABELS_TO_ADD="${label}"
|
||||
else
|
||||
LABELS_TO_ADD="${LABELS_TO_ADD},${label}"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# Apply label changes
|
||||
if [[ -n "${LABELS_TO_ADD}" || -n "${LABELS_TO_REMOVE}" ]]; then
|
||||
local EDIT_CMD=("gh" "pr" "edit" "${PR_NUMBER}" "--repo" "${GITHUB_REPOSITORY}")
|
||||
if [[ -n "${LABELS_TO_ADD}" ]]; then
|
||||
echo "➕ Adding labels: ${LABELS_TO_ADD}"
|
||||
if ! gh pr edit "${PR_NUMBER}" --repo "${GITHUB_REPOSITORY}" --add-label "${LABELS_TO_ADD}" 2>/dev/null; then
|
||||
echo " ⚠️ Failed to add some labels"
|
||||
fi
|
||||
echo " ➕ Syncing labels to add: ${LABELS_TO_ADD}"
|
||||
EDIT_CMD+=("--add-label" "${LABELS_TO_ADD}")
|
||||
fi
|
||||
|
||||
if [[ -z "${LABELS_TO_ADD}" ]]; then
|
||||
echo "✅ Labels already synchronized"
|
||||
if [[ -n "${LABELS_TO_REMOVE}" ]]; then
|
||||
echo " ➖ Syncing labels to remove: ${LABELS_TO_REMOVE}"
|
||||
EDIT_CMD+=("--remove-label" "${LABELS_TO_REMOVE}")
|
||||
fi
|
||||
echo "needs_comment=false" >> "${GITHUB_OUTPUT}"
|
||||
|
||||
("${EDIT_CMD[@]}" || true)
|
||||
fi
|
||||
}
|
||||
|
||||
# If PR_NUMBER is set, process only that PR
|
||||
if [[ -n "${PR_NUMBER:-}" ]]; then
|
||||
if ! process_pr "${PR_NUMBER}"; then
|
||||
echo "❌ Failed to process PR #${PR_NUMBER}"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
# Otherwise, get all open PRs and process them
|
||||
# The script logic will determine which ones need issue linking or label sync
|
||||
echo "📥 Getting all open pull requests..."
|
||||
if ! PR_NUMBERS=$(gh pr list --repo "${GITHUB_REPOSITORY}" --state open --limit 1000 --json number -q '.[].number' 2>/dev/null); then
|
||||
echo "❌ Failed to fetch PR list"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -z "${PR_NUMBERS}" ]]; then
|
||||
echo "✅ No open PRs found"
|
||||
else
|
||||
# Count the number of PRs
|
||||
PR_COUNT=$(echo "${PR_NUMBERS}" | wc -w | tr -d ' ')
|
||||
echo "📊 Found ${PR_COUNT} open PRs to process"
|
||||
|
||||
for pr_number in ${PR_NUMBERS}; do
|
||||
if ! process_pr "${pr_number}"; then
|
||||
echo "⚠️ Failed to process PR #${pr_number}, continuing with next PR..."
|
||||
continue
|
||||
fi
|
||||
done
|
||||
fi
|
||||
if [[ -z "${GITHUB_REPOSITORY:-}" ]]; then
|
||||
echo "‼️ Missing \$GITHUB_REPOSITORY - this must be run from GitHub Actions"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -z "${GITHUB_OUTPUT:-}" ]]; then
|
||||
echo "‼️ Missing \$GITHUB_OUTPUT - this must be run from GitHub Actions"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
JQ_EXTRACT_FIELDS='{
|
||||
number: .number,
|
||||
isDraft: .isDraft,
|
||||
issue: (.closingIssuesReferences[0].number // (.body // "" | capture("(^|[^a-zA-Z0-9])#(?<num>[0-9]+)([^a-zA-Z0-9]|$)")? | .num) // "null"),
|
||||
labels: [.labels[].name] | join(",")
|
||||
}'
|
||||
|
||||
JQ_TSV_FORMAT='"\((.number | tostring))\t\(.isDraft)\t\((.issue // null) | tostring)\t\(.labels)"'
|
||||
|
||||
if [[ -n "${PR_NUMBER:-}" ]]; then
|
||||
echo "🔄 Processing single PR #${PR_NUMBER}"
|
||||
PR_DATA=$(gh pr view "${PR_NUMBER}" --repo "${GITHUB_REPOSITORY}" --json number,closingIssuesReferences,isDraft,body,labels 2>/dev/null) || {
|
||||
echo "❌ Failed to fetch data for PR #${PR_NUMBER}"
|
||||
exit 1
|
||||
}
|
||||
|
||||
line=$(echo "${PR_DATA}" | jq -r "${JQ_EXTRACT_FIELDS} | ${JQ_TSV_FORMAT}")
|
||||
IFS=$'\t' read -r pr_num is_draft issue_num current_labels <<< "${line}"
|
||||
process_pr_optimized "${pr_num}" "${is_draft}" "${issue_num}" "${current_labels}"
|
||||
else
|
||||
echo "📥 Getting all open pull requests..."
|
||||
PR_DATA_ALL=$(gh pr list --repo "${GITHUB_REPOSITORY}" --state open --limit 1000 --json number,closingIssuesReferences,isDraft,body,labels 2>/dev/null) || {
|
||||
echo "❌ Failed to fetch PR list"
|
||||
exit 1
|
||||
}
|
||||
|
||||
PR_COUNT=$(echo "${PR_DATA_ALL}" | jq '. | length')
|
||||
echo "📊 Found ${PR_COUNT} open PRs to process"
|
||||
|
||||
# Use a temporary file to avoid masking exit codes in process substitution
|
||||
tmp_file=$(mktemp)
|
||||
echo "${PR_DATA_ALL}" | jq -r ".[] | ${JQ_EXTRACT_FIELDS} | ${JQ_TSV_FORMAT}" > "${tmp_file}"
|
||||
while read -r line; do
|
||||
[[ -z "${line}" ]] && continue
|
||||
IFS=$'\t' read -r pr_num is_draft issue_num current_labels <<< "${line}"
|
||||
process_pr_optimized "${pr_num}" "${is_draft}" "${issue_num}" "${current_labels}"
|
||||
done < "${tmp_file}"
|
||||
rm -f "${tmp_file}"
|
||||
fi
|
||||
|
||||
# Ensure output is always set, even if empty
|
||||
if [[ -z "${PRS_NEEDING_COMMENT}" ]]; then
|
||||
echo "prs_needing_comment=[]" >> "${GITHUB_OUTPUT}"
|
||||
else
|
||||
|
||||
@@ -0,0 +1,355 @@
|
||||
/* eslint-disable @typescript-eslint/no-require-imports */
|
||||
/* global process, console, require */
|
||||
const { Octokit } = require('@octokit/rest');
|
||||
|
||||
/**
|
||||
* Sync Maintainer Labels (Recursive with strict parent-child relationship detection)
|
||||
* - Uses Native Sub-issues.
|
||||
* - Uses Markdown Task Lists (- [ ] #123).
|
||||
* - Filters for OPEN issues only.
|
||||
* - Skips DUPLICATES.
|
||||
* - Skips Pull Requests.
|
||||
* - ONLY labels issues in the PUBLIC (gemini-cli) repo.
|
||||
*/
|
||||
|
||||
const REPO_OWNER = 'google-gemini';
|
||||
const PUBLIC_REPO = 'gemini-cli';
|
||||
const PRIVATE_REPO = 'maintainers-gemini-cli';
|
||||
const ALLOWED_REPOS = [PUBLIC_REPO, PRIVATE_REPO];
|
||||
|
||||
const ROOT_ISSUES = [
|
||||
{ owner: REPO_OWNER, repo: PUBLIC_REPO, number: 15374 },
|
||||
{ owner: REPO_OWNER, repo: PUBLIC_REPO, number: 15456 },
|
||||
{ owner: REPO_OWNER, repo: PUBLIC_REPO, number: 15324 },
|
||||
];
|
||||
|
||||
const TARGET_LABEL = '🔒 maintainer only';
|
||||
const isDryRun =
|
||||
process.argv.includes('--dry-run') || process.env.DRY_RUN === 'true';
|
||||
|
||||
const octokit = new Octokit({
|
||||
auth: process.env.GITHUB_TOKEN,
|
||||
});
|
||||
|
||||
/**
|
||||
* Extracts child issue references from markdown Task Lists ONLY.
|
||||
* e.g. - [ ] #123 or - [x] google-gemini/gemini-cli#123
|
||||
*/
|
||||
function extractTaskListLinks(text, contextOwner, contextRepo) {
|
||||
if (!text) return [];
|
||||
const childIssues = new Map();
|
||||
|
||||
const add = (owner, repo, number) => {
|
||||
if (ALLOWED_REPOS.includes(repo)) {
|
||||
const key = `${owner}/${repo}#${number}`;
|
||||
childIssues.set(key, { owner, repo, number: parseInt(number, 10) });
|
||||
}
|
||||
};
|
||||
|
||||
// 1. Full URLs in task lists
|
||||
const urlRegex =
|
||||
/-\s+\[[ x]\].*https:\/\/github\.com\/([a-zA-Z0-9._-]+)\/([a-zA-Z0-9._-]+)\/issues\/(\d+)\b/g;
|
||||
let match;
|
||||
while ((match = urlRegex.exec(text)) !== null) {
|
||||
add(match[1], match[2], match[3]);
|
||||
}
|
||||
|
||||
// 2. Cross-repo refs in task lists: owner/repo#123
|
||||
const crossRepoRegex =
|
||||
/-\s+\[[ x]\].*([a-zA-Z0-9._-]+)\/([a-zA-Z0-9._-]+)#(\d+)\b/g;
|
||||
while ((match = crossRepoRegex.exec(text)) !== null) {
|
||||
add(match[1], match[2], match[3]);
|
||||
}
|
||||
|
||||
// 3. Short refs in task lists: #123
|
||||
const shortRefRegex = /-\s+\[[ x]\].*#(\d+)\b/g;
|
||||
while ((match = shortRefRegex.exec(text)) !== null) {
|
||||
add(contextOwner, contextRepo, match[1]);
|
||||
}
|
||||
|
||||
return Array.from(childIssues.values());
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches issue data via GraphQL with full pagination for sub-issues, comments, and labels.
|
||||
*/
|
||||
async function fetchIssueData(owner, repo, number) {
|
||||
const query = `
|
||||
query($owner:String!, $repo:String!, $number:Int!) {
|
||||
repository(owner:$owner, name:$repo) {
|
||||
issue(number:$number) {
|
||||
state
|
||||
title
|
||||
body
|
||||
labels(first: 100) {
|
||||
nodes { name }
|
||||
pageInfo { hasNextPage endCursor }
|
||||
}
|
||||
subIssues(first: 100) {
|
||||
nodes {
|
||||
number
|
||||
repository {
|
||||
name
|
||||
owner { login }
|
||||
}
|
||||
}
|
||||
pageInfo { hasNextPage endCursor }
|
||||
}
|
||||
comments(first: 100) {
|
||||
nodes {
|
||||
body
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
try {
|
||||
const response = await octokit.graphql(query, { owner, repo, number });
|
||||
const data = response.repository.issue;
|
||||
if (!data) return null;
|
||||
|
||||
const issue = {
|
||||
state: data.state,
|
||||
title: data.title,
|
||||
body: data.body || '',
|
||||
labels: data.labels.nodes.map((n) => n.name),
|
||||
subIssues: [...data.subIssues.nodes],
|
||||
comments: data.comments.nodes.map((n) => n.body),
|
||||
};
|
||||
|
||||
// Paginate subIssues if there are more than 100
|
||||
if (data.subIssues.pageInfo.hasNextPage) {
|
||||
const moreSubIssues = await paginateConnection(
|
||||
owner,
|
||||
repo,
|
||||
number,
|
||||
'subIssues',
|
||||
'number repository { name owner { login } }',
|
||||
data.subIssues.pageInfo.endCursor,
|
||||
);
|
||||
issue.subIssues.push(...moreSubIssues);
|
||||
}
|
||||
|
||||
// Paginate labels if there are more than 100 (unlikely but for completeness)
|
||||
if (data.labels.pageInfo.hasNextPage) {
|
||||
const moreLabels = await paginateConnection(
|
||||
owner,
|
||||
repo,
|
||||
number,
|
||||
'labels',
|
||||
'name',
|
||||
data.labels.pageInfo.endCursor,
|
||||
(n) => n.name,
|
||||
);
|
||||
issue.labels.push(...moreLabels);
|
||||
}
|
||||
|
||||
// Note: Comments are handled via Task Lists in body + first 100 comments.
|
||||
// If an issue has > 100 comments with task lists, we'd need to paginate those too.
|
||||
// Given the 1,100+ issue discovery count, 100 comments is usually sufficient,
|
||||
// but we can add it for absolute completeness.
|
||||
// (Skipping for now to avoid excessive API churn unless clearly needed).
|
||||
|
||||
return issue;
|
||||
} catch (error) {
|
||||
if (error.errors && error.errors.some((e) => e.type === 'NOT_FOUND')) {
|
||||
return null;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to paginate any GraphQL connection.
|
||||
*/
|
||||
async function paginateConnection(
|
||||
owner,
|
||||
repo,
|
||||
number,
|
||||
connectionName,
|
||||
nodeFields,
|
||||
initialCursor,
|
||||
transformNode = (n) => n,
|
||||
) {
|
||||
let additionalNodes = [];
|
||||
let hasNext = true;
|
||||
let cursor = initialCursor;
|
||||
|
||||
while (hasNext) {
|
||||
const query = `
|
||||
query($owner:String!, $repo:String!, $number:Int!, $cursor:String) {
|
||||
repository(owner:$owner, name:$repo) {
|
||||
issue(number:$number) {
|
||||
${connectionName}(first: 100, after: $cursor) {
|
||||
nodes { ${nodeFields} }
|
||||
pageInfo { hasNextPage endCursor }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
const response = await octokit.graphql(query, {
|
||||
owner,
|
||||
repo,
|
||||
number,
|
||||
cursor,
|
||||
});
|
||||
const connection = response.repository.issue[connectionName];
|
||||
additionalNodes.push(...connection.nodes.map(transformNode));
|
||||
hasNext = connection.pageInfo.hasNextPage;
|
||||
cursor = connection.pageInfo.endCursor;
|
||||
}
|
||||
return additionalNodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates if an issue should be processed (Open, not a duplicate, not a PR)
|
||||
*/
|
||||
function shouldProcess(issueData) {
|
||||
if (!issueData) return false;
|
||||
|
||||
if (issueData.state !== 'OPEN') return false;
|
||||
|
||||
const labels = issueData.labels.map((l) => l.toLowerCase());
|
||||
if (labels.includes('duplicate') || labels.includes('kind/duplicate')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
async function getAllDescendants(roots) {
|
||||
const allDescendants = new Map();
|
||||
const visited = new Set();
|
||||
const queue = [...roots];
|
||||
|
||||
for (const root of roots) {
|
||||
visited.add(`${root.owner}/${root.repo}#${root.number}`);
|
||||
}
|
||||
|
||||
console.log(`Starting discovery from ${roots.length} roots...`);
|
||||
|
||||
while (queue.length > 0) {
|
||||
const current = queue.shift();
|
||||
const currentKey = `${current.owner}/${current.repo}#${current.number}`;
|
||||
|
||||
try {
|
||||
const issueData = await fetchIssueData(
|
||||
current.owner,
|
||||
current.repo,
|
||||
current.number,
|
||||
);
|
||||
|
||||
if (!shouldProcess(issueData)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// ONLY add to labeling list if it's in the PUBLIC repository
|
||||
if (current.repo === PUBLIC_REPO) {
|
||||
// Don't label the roots themselves
|
||||
if (
|
||||
!ROOT_ISSUES.some(
|
||||
(r) => r.number === current.number && r.repo === current.repo,
|
||||
)
|
||||
) {
|
||||
allDescendants.set(currentKey, {
|
||||
...current,
|
||||
title: issueData.title,
|
||||
labels: issueData.labels,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const children = new Map();
|
||||
|
||||
// 1. Process Native Sub-issues
|
||||
if (issueData.subIssues) {
|
||||
for (const node of issueData.subIssues) {
|
||||
const childOwner = node.repository.owner.login;
|
||||
const childRepo = node.repository.name;
|
||||
const childNumber = node.number;
|
||||
const key = `${childOwner}/${childRepo}#${childNumber}`;
|
||||
children.set(key, {
|
||||
owner: childOwner,
|
||||
repo: childRepo,
|
||||
number: childNumber,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Process Markdown Task Lists in Body and Comments
|
||||
let combinedText = issueData.body || '';
|
||||
if (issueData.comments) {
|
||||
for (const commentBody of issueData.comments) {
|
||||
combinedText += '\n' + (commentBody || '');
|
||||
}
|
||||
}
|
||||
|
||||
const taskListLinks = extractTaskListLinks(
|
||||
combinedText,
|
||||
current.owner,
|
||||
current.repo,
|
||||
);
|
||||
for (const link of taskListLinks) {
|
||||
const key = `${link.owner}/${link.repo}#${link.number}`;
|
||||
children.set(key, link);
|
||||
}
|
||||
|
||||
// Queue children (regardless of which repo they are in, for recursion)
|
||||
for (const [key, child] of children) {
|
||||
if (!visited.has(key)) {
|
||||
visited.add(key);
|
||||
queue.push(child);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Error processing ${currentKey}: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
return Array.from(allDescendants.values());
|
||||
}
|
||||
|
||||
async function run() {
|
||||
if (isDryRun) {
|
||||
console.log('=== DRY RUN MODE: No labels will be applied ===');
|
||||
}
|
||||
|
||||
const descendants = await getAllDescendants(ROOT_ISSUES);
|
||||
console.log(
|
||||
`\nFound ${descendants.length} total unique open descendant issues in ${PUBLIC_REPO}.`,
|
||||
);
|
||||
|
||||
for (const issueInfo of descendants) {
|
||||
const issueKey = `${issueInfo.owner}/${issueInfo.repo}#${issueInfo.number}`;
|
||||
try {
|
||||
// Data is already available from the discovery phase
|
||||
const hasLabel = issueInfo.labels.some((l) => l === TARGET_LABEL);
|
||||
|
||||
if (!hasLabel) {
|
||||
if (isDryRun) {
|
||||
console.log(
|
||||
`[DRY RUN] Would label ${issueKey}: "${issueInfo.title}"`,
|
||||
);
|
||||
} else {
|
||||
console.log(`Labeling ${issueKey}: "${issueInfo.title}"...`);
|
||||
await octokit.rest.issues.addLabels({
|
||||
owner: issueInfo.owner,
|
||||
repo: issueInfo.repo,
|
||||
issue_number: issueInfo.number,
|
||||
labels: [TARGET_LABEL],
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Error processing label for ${issueKey}: ${error.message}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
run().catch((error) => {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -1,4 +1,4 @@
|
||||
name: 'Test Chained E2E'
|
||||
name: 'Testing: E2E (Chained)'
|
||||
|
||||
on:
|
||||
push:
|
||||
@@ -37,14 +37,15 @@ jobs:
|
||||
- id: 'merge-queue-e2e-skipper'
|
||||
uses: 'cariad-tech/merge-queue-ci-skipper@1032489e59437862c90a08a2c92809c903883772' # ratchet:cariad-tech/merge-queue-ci-skipper@main
|
||||
with:
|
||||
secret: '${{ secrets.GITHUB_TOKEN }}'
|
||||
secret: '${{ secrets.GEMINI_CLI_ROBOT_GITHUB_PAT }}'
|
||||
continue-on-error: true
|
||||
|
||||
download_repo_name:
|
||||
runs-on: 'gemini-cli-ubuntu-16-core'
|
||||
if: "github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_run'"
|
||||
if: "${{github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_run'}}"
|
||||
outputs:
|
||||
repo_name: '${{ steps.output-repo-name.outputs.repo_name }}'
|
||||
head_sha: '${{ steps.output-repo-name.outputs.head_sha }}'
|
||||
steps:
|
||||
- name: 'Mock Repo Artifact'
|
||||
if: "${{ github.event_name == 'workflow_dispatch' }}"
|
||||
@@ -66,7 +67,7 @@ jobs:
|
||||
name: 'repo_name'
|
||||
run-id: '${{ env.RUN_ID }}'
|
||||
path: '${{ runner.temp }}/artifacts'
|
||||
- name: 'Output Repo Name'
|
||||
- name: 'Output Repo Name and SHA'
|
||||
id: 'output-repo-name'
|
||||
uses: 'actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd' # ratchet:actions/github-script@v8
|
||||
with:
|
||||
@@ -75,8 +76,16 @@ jobs:
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const temp = '${{ runner.temp }}/artifacts';
|
||||
const repo_name = String(fs.readFileSync(path.join(temp, 'repo_name')));
|
||||
core.setOutput('repo_name', repo_name);
|
||||
const repoPath = path.join(temp, 'repo_name');
|
||||
if (fs.existsSync(repoPath)) {
|
||||
const repo_name = String(fs.readFileSync(repoPath)).trim();
|
||||
core.setOutput('repo_name', repo_name);
|
||||
}
|
||||
const shaPath = path.join(temp, 'head_sha');
|
||||
if (fs.existsSync(shaPath)) {
|
||||
const head_sha = String(fs.readFileSync(shaPath)).trim();
|
||||
core.setOutput('head_sha', head_sha);
|
||||
}
|
||||
|
||||
parse_run_context:
|
||||
name: 'Parse run context'
|
||||
@@ -91,7 +100,7 @@ jobs:
|
||||
name: 'Set dynamic repository and SHA'
|
||||
env:
|
||||
REPO: '${{ needs.download_repo_name.outputs.repo_name || github.repository }}'
|
||||
SHA: '${{ github.event.inputs.head_sha || github.event.workflow_run.head_sha || github.sha }}'
|
||||
SHA: '${{ needs.download_repo_name.outputs.head_sha || github.event.inputs.head_sha || github.event.workflow_run.head_sha || github.sha }}'
|
||||
shell: 'bash'
|
||||
run: |
|
||||
echo "REPO=$REPO" >> "$GITHUB_OUTPUT"
|
||||
@@ -100,19 +109,20 @@ jobs:
|
||||
set_pending_status:
|
||||
runs-on: 'gemini-cli-ubuntu-16-core'
|
||||
permissions: 'write-all'
|
||||
if: "github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_run'"
|
||||
needs:
|
||||
- 'parse_run_context'
|
||||
if: 'always()'
|
||||
steps:
|
||||
- name: 'Set pending status'
|
||||
uses: 'myrotvorets/set-commit-status-action@16037e056d73b2d3c88e37e393ff369047f70886' # ratchet:myrotvorets/set-commit-status-action@master
|
||||
if: 'always()'
|
||||
with:
|
||||
allowForks: 'true'
|
||||
repo: '${{ needs.parse_run_context.outputs.repository }}'
|
||||
repo: '${{ github.repository }}'
|
||||
sha: '${{ needs.parse_run_context.outputs.sha }}'
|
||||
token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
token: '${{ secrets.GEMINI_CLI_ROBOT_GITHUB_PAT }}'
|
||||
status: 'pending'
|
||||
context: 'E2E (Chained)'
|
||||
|
||||
e2e_linux:
|
||||
name: 'E2E Test (Linux) - ${{ matrix.sandbox }}'
|
||||
@@ -121,7 +131,7 @@ jobs:
|
||||
- 'parse_run_context'
|
||||
runs-on: 'gemini-cli-ubuntu-16-core'
|
||||
if: |
|
||||
always() && (needs.merge_queue_skipper.result !='success' || needs.merge_queue_skipper.outputs.skip == 'false')
|
||||
always() && (needs.merge_queue_skipper.result !='success' || needs.merge_queue_skipper.outputs.skip != 'true')
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -150,7 +160,7 @@ jobs:
|
||||
run: 'npm run build'
|
||||
|
||||
- name: 'Set up Docker'
|
||||
if: "matrix.sandbox == 'sandbox:docker'"
|
||||
if: "${{matrix.sandbox == 'sandbox:docker'}}"
|
||||
uses: 'docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435' # ratchet:docker/setup-buildx-action@v3
|
||||
|
||||
- name: 'Run E2E tests'
|
||||
@@ -158,6 +168,7 @@ jobs:
|
||||
GEMINI_API_KEY: '${{ secrets.GEMINI_API_KEY }}'
|
||||
KEEP_OUTPUT: 'true'
|
||||
VERBOSE: 'true'
|
||||
BUILD_SANDBOX_FLAGS: '--cache-from type=gha --cache-to type=gha,mode=max'
|
||||
shell: 'bash'
|
||||
run: |
|
||||
if [[ "${{ matrix.sandbox }}" == "sandbox:docker" ]]; then
|
||||
@@ -173,7 +184,7 @@ jobs:
|
||||
- 'parse_run_context'
|
||||
runs-on: 'macos-latest'
|
||||
if: |
|
||||
always() && (needs.merge_queue_skipper.result !='success' || needs.merge_queue_skipper.outputs.skip == 'false')
|
||||
always() && (needs.merge_queue_skipper.result !='success' || needs.merge_queue_skipper.outputs.skip != 'true')
|
||||
steps:
|
||||
- name: 'Checkout'
|
||||
uses: 'actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955' # ratchet:actions/checkout@v5
|
||||
@@ -193,11 +204,11 @@ jobs:
|
||||
run: 'npm run build'
|
||||
|
||||
- name: 'Fix rollup optional dependencies on macOS'
|
||||
if: "runner.os == 'macOS'"
|
||||
if: "${{runner.os == 'macOS'}}"
|
||||
run: |
|
||||
npm cache clean --force
|
||||
- name: 'Run E2E tests (non-Windows)'
|
||||
if: "runner.os != 'Windows'"
|
||||
if: "${{runner.os != 'Windows'}}"
|
||||
env:
|
||||
GEMINI_API_KEY: '${{ secrets.GEMINI_API_KEY }}'
|
||||
KEEP_OUTPUT: 'true'
|
||||
@@ -211,7 +222,7 @@ jobs:
|
||||
- 'merge_queue_skipper'
|
||||
- 'parse_run_context'
|
||||
if: |
|
||||
always() && (needs.merge_queue_skipper.result !='success' || needs.merge_queue_skipper.outputs.skip == 'false')
|
||||
always() && (needs.merge_queue_skipper.result !='success' || needs.merge_queue_skipper.outputs.skip != 'true')
|
||||
runs-on: 'gemini-cli-windows-16-core'
|
||||
continue-on-error: true
|
||||
|
||||
@@ -266,20 +277,53 @@ jobs:
|
||||
shell: 'pwsh'
|
||||
run: 'npm run test:integration:sandbox:none'
|
||||
|
||||
evals:
|
||||
name: 'Evals (ALWAYS_PASSING)'
|
||||
needs:
|
||||
- 'merge_queue_skipper'
|
||||
- 'parse_run_context'
|
||||
runs-on: 'gemini-cli-ubuntu-16-core'
|
||||
if: |
|
||||
always() && (needs.merge_queue_skipper.result !='success' || needs.merge_queue_skipper.outputs.skip != 'true')
|
||||
steps:
|
||||
- name: 'Checkout'
|
||||
uses: 'actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955' # ratchet:actions/checkout@v5
|
||||
with:
|
||||
ref: '${{ needs.parse_run_context.outputs.sha }}'
|
||||
repository: '${{ needs.parse_run_context.outputs.repository }}'
|
||||
|
||||
- name: 'Set up Node.js 20.x'
|
||||
uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020' # ratchet:actions-node@v4
|
||||
with:
|
||||
node-version: '20.x'
|
||||
|
||||
- name: 'Install dependencies'
|
||||
run: 'npm ci'
|
||||
|
||||
- name: 'Build project'
|
||||
run: 'npm run build'
|
||||
|
||||
- name: 'Run Evals (Required to pass)'
|
||||
env:
|
||||
GEMINI_API_KEY: '${{ secrets.GEMINI_API_KEY }}'
|
||||
run: 'npm run test:always_passing_evals'
|
||||
|
||||
e2e:
|
||||
name: 'E2E'
|
||||
if: |
|
||||
always() && (needs.merge_queue_skipper.result !='success' || needs.merge_queue_skipper.outputs.skip == 'false')
|
||||
always() && (needs.merge_queue_skipper.result !='success' || needs.merge_queue_skipper.outputs.skip != 'true')
|
||||
needs:
|
||||
- 'e2e_linux'
|
||||
- 'e2e_mac'
|
||||
- 'evals'
|
||||
- 'merge_queue_skipper'
|
||||
runs-on: 'gemini-cli-ubuntu-16-core'
|
||||
steps:
|
||||
- name: 'Check E2E test results'
|
||||
run: |
|
||||
if [[ ${{ needs.e2e_linux.result }} != 'success' || \
|
||||
${{ needs.e2e_mac.result }} != 'success' ]]; then
|
||||
${{ needs.e2e_mac.result }} != 'success' || \
|
||||
${{ needs.evals.result }} != 'success' ]]; then
|
||||
echo "One or more E2E jobs failed."
|
||||
exit 1
|
||||
fi
|
||||
@@ -288,7 +332,7 @@ jobs:
|
||||
set_workflow_status:
|
||||
runs-on: 'gemini-cli-ubuntu-16-core'
|
||||
permissions: 'write-all'
|
||||
if: "github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_run'"
|
||||
if: 'always()'
|
||||
needs:
|
||||
- 'parse_run_context'
|
||||
- 'e2e'
|
||||
@@ -298,7 +342,8 @@ jobs:
|
||||
if: 'always()'
|
||||
with:
|
||||
allowForks: 'true'
|
||||
repo: '${{ needs.parse_run_context.outputs.repository }}'
|
||||
repo: '${{ github.repository }}'
|
||||
sha: '${{ needs.parse_run_context.outputs.sha }}'
|
||||
token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
status: '${{ job.status }}'
|
||||
status: '${{ needs.e2e.result }}'
|
||||
context: 'E2E (Chained)'
|
||||
+87
-16
@@ -43,13 +43,15 @@ jobs:
|
||||
- id: 'merge-queue-ci-skipper'
|
||||
uses: 'cariad-tech/merge-queue-ci-skipper@1032489e59437862c90a08a2c92809c903883772' # ratchet:cariad-tech/merge-queue-ci-skipper@main
|
||||
with:
|
||||
secret: '${{ secrets.GITHUB_TOKEN }}'
|
||||
secret: '${{ secrets.GEMINI_CLI_ROBOT_GITHUB_PAT }}'
|
||||
|
||||
lint:
|
||||
name: 'Lint'
|
||||
runs-on: 'gemini-cli-ubuntu-16-core'
|
||||
needs: 'merge_queue_skipper'
|
||||
if: "${{needs.merge_queue_skipper.outputs.skip == 'false'}}"
|
||||
env:
|
||||
GEMINI_LINT_TEMP_DIR: '${{ github.workspace }}/.gemini-linters'
|
||||
steps:
|
||||
- name: 'Checkout'
|
||||
uses: 'actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8' # ratchet:actions/checkout@v5
|
||||
@@ -63,9 +65,21 @@ jobs:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'npm'
|
||||
|
||||
- name: 'Cache Linters'
|
||||
uses: 'actions/cache@v4'
|
||||
with:
|
||||
path: '${{ env.GEMINI_LINT_TEMP_DIR }}'
|
||||
key: "${{ runner.os }}-${{ runner.arch }}-linters-${{ hashFiles('scripts/lint.js') }}"
|
||||
|
||||
- name: 'Install dependencies'
|
||||
run: 'npm ci'
|
||||
|
||||
- name: 'Cache ESLint'
|
||||
uses: 'actions/cache@v4'
|
||||
with:
|
||||
path: '.eslintcache'
|
||||
key: "${{ runner.os }}-eslint-${{ hashFiles('package-lock.json', 'eslint.config.js') }}"
|
||||
|
||||
- name: 'Validate NOTICES.txt'
|
||||
run: 'git diff --exit-code packages/vscode-ide-companion/NOTICES.txt'
|
||||
|
||||
@@ -108,13 +122,12 @@ jobs:
|
||||
- name: 'Link Checker'
|
||||
uses: 'lycheeverse/lychee-action@885c65f3dc543b57c898c8099f4e08c8afd178a2' # ratchet: lycheeverse/lychee-action@v2.6.1
|
||||
with:
|
||||
args: '--verbose ./**/*.md'
|
||||
args: '--verbose --accept 200,503 ./**/*.md'
|
||||
fail: true
|
||||
test_linux:
|
||||
name: 'Test (Linux)'
|
||||
name: 'Test (Linux) - ${{ matrix.node-version }}, ${{ matrix.shard }}'
|
||||
runs-on: 'gemini-cli-ubuntu-16-core'
|
||||
needs:
|
||||
- 'lint'
|
||||
- 'merge_queue_skipper'
|
||||
if: "${{needs.merge_queue_skipper.outputs.skip == 'false'}}"
|
||||
permissions:
|
||||
@@ -127,6 +140,9 @@ jobs:
|
||||
- '20.x'
|
||||
- '22.x'
|
||||
- '24.x'
|
||||
shard:
|
||||
- 'cli'
|
||||
- 'others'
|
||||
steps:
|
||||
- name: 'Checkout'
|
||||
uses: 'actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8' # ratchet:actions/checkout@v5
|
||||
@@ -146,7 +162,14 @@ jobs:
|
||||
- name: 'Run tests and generate reports'
|
||||
env:
|
||||
NO_COLOR: true
|
||||
run: 'npm run test:ci'
|
||||
run: |
|
||||
if [[ "${{ matrix.shard }}" == "cli" ]]; then
|
||||
npm run test:ci --workspace @google/gemini-cli
|
||||
else
|
||||
# Explicitly list non-cli packages to ensure they are sharded correctly
|
||||
npm run test:ci --workspace @google/gemini-cli-core --workspace @google/gemini-cli-a2a-server --workspace gemini-cli-vscode-ide-companion --workspace @google/gemini-cli-test-utils --if-present
|
||||
npm run test:scripts
|
||||
fi
|
||||
|
||||
- name: 'Bundle'
|
||||
run: 'npm run bundle'
|
||||
@@ -154,6 +177,19 @@ jobs:
|
||||
- name: 'Smoke test bundle'
|
||||
run: 'node ./bundle/gemini.js --version'
|
||||
|
||||
- name: 'Smoke test npx installation'
|
||||
run: |
|
||||
# 1. Package the project into a tarball
|
||||
TARBALL=$(npm pack | tail -n 1)
|
||||
|
||||
# 2. Move to a fresh directory for isolation
|
||||
mkdir -p ../smoke-test-dir
|
||||
mv "$TARBALL" ../smoke-test-dir/
|
||||
cd ../smoke-test-dir
|
||||
|
||||
# 3. Run npx from the tarball
|
||||
npx "./$TARBALL" --version
|
||||
|
||||
- name: 'Wait for file system sync'
|
||||
run: 'sleep 2'
|
||||
|
||||
@@ -162,7 +198,7 @@ jobs:
|
||||
${{ always() && (github.event.pull_request.head.repo.full_name == github.repository) }}
|
||||
uses: 'dorny/test-reporter@dc3a92680fcc15842eef52e8c4606ea7ce6bd3f3' # ratchet:dorny/test-reporter@v2
|
||||
with:
|
||||
name: 'Test Results (Node ${{ matrix.node-version }})'
|
||||
name: 'Test Results (Node ${{ runner.os }}, ${{ matrix.node-version }}, ${{ matrix.shard }})'
|
||||
path: 'packages/*/junit.xml'
|
||||
reporter: 'java-junit'
|
||||
fail-on-error: 'false'
|
||||
@@ -172,14 +208,13 @@ jobs:
|
||||
${{ always() && (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) }}
|
||||
uses: 'actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02' # ratchet:actions/upload-artifact@v4
|
||||
with:
|
||||
name: 'test-results-fork-${{ matrix.node-version }}-${{ runner.os }}'
|
||||
name: 'test-results-fork-${{ runner.os }}-${{ matrix.node-version }}-${{ matrix.shard }}'
|
||||
path: 'packages/*/junit.xml'
|
||||
|
||||
test_mac:
|
||||
name: 'Test (Mac)'
|
||||
runs-on: '${{ matrix.os }}'
|
||||
name: 'Test (Mac) - ${{ matrix.node-version }}, ${{ matrix.shard }}'
|
||||
runs-on: 'macos-latest'
|
||||
needs:
|
||||
- 'lint'
|
||||
- 'merge_queue_skipper'
|
||||
if: "${{needs.merge_queue_skipper.outputs.skip == 'false'}}"
|
||||
permissions:
|
||||
@@ -189,12 +224,13 @@ jobs:
|
||||
continue-on-error: true
|
||||
strategy:
|
||||
matrix:
|
||||
os:
|
||||
- 'macos-latest'
|
||||
node-version:
|
||||
- '20.x'
|
||||
- '22.x'
|
||||
- '24.x'
|
||||
shard:
|
||||
- 'cli'
|
||||
- 'others'
|
||||
steps:
|
||||
- name: 'Checkout'
|
||||
uses: 'actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8' # ratchet:actions/checkout@v5
|
||||
@@ -214,7 +250,14 @@ jobs:
|
||||
- name: 'Run tests and generate reports'
|
||||
env:
|
||||
NO_COLOR: true
|
||||
run: 'npm run test:ci -- --coverage.enabled=false'
|
||||
run: |
|
||||
if [[ "${{ matrix.shard }}" == "cli" ]]; then
|
||||
npm run test:ci --workspace @google/gemini-cli -- --coverage.enabled=false
|
||||
else
|
||||
# Explicitly list non-cli packages to ensure they are sharded correctly
|
||||
npm run test:ci --workspace @google/gemini-cli-core --workspace @google/gemini-cli-a2a-server --workspace gemini-cli-vscode-ide-companion --workspace @google/gemini-cli-test-utils --if-present -- --coverage.enabled=false
|
||||
npm run test:scripts
|
||||
fi
|
||||
|
||||
- name: 'Bundle'
|
||||
run: 'npm run bundle'
|
||||
@@ -222,6 +265,19 @@ jobs:
|
||||
- name: 'Smoke test bundle'
|
||||
run: 'node ./bundle/gemini.js --version'
|
||||
|
||||
- name: 'Smoke test npx installation'
|
||||
run: |
|
||||
# 1. Package the project into a tarball
|
||||
TARBALL=$(npm pack | tail -n 1)
|
||||
|
||||
# 2. Move to a fresh directory for isolation
|
||||
mkdir -p ../smoke-test-dir
|
||||
mv "$TARBALL" ../smoke-test-dir/
|
||||
cd ../smoke-test-dir
|
||||
|
||||
# 3. Run npx from the tarball
|
||||
npx "./$TARBALL" --version
|
||||
|
||||
- name: 'Wait for file system sync'
|
||||
run: 'sleep 2'
|
||||
|
||||
@@ -230,7 +286,7 @@ jobs:
|
||||
${{ always() && (github.event.pull_request.head.repo.full_name == github.repository) }}
|
||||
uses: 'dorny/test-reporter@dc3a92680fcc15842eef52e8c4606ea7ce6bd3f3' # ratchet:dorny/test-reporter@v2
|
||||
with:
|
||||
name: 'Test Results (Node ${{ matrix.node-version }})'
|
||||
name: 'Test Results (Node ${{ runner.os }}, ${{ matrix.node-version }}, ${{ matrix.shard }})'
|
||||
path: 'packages/*/junit.xml'
|
||||
reporter: 'java-junit'
|
||||
fail-on-error: 'false'
|
||||
@@ -240,7 +296,7 @@ jobs:
|
||||
${{ always() && (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) }}
|
||||
uses: 'actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02' # ratchet:actions/upload-artifact@v4
|
||||
with:
|
||||
name: 'test-results-fork-${{ matrix.node-version }}-${{ runner.os }}'
|
||||
name: 'test-results-fork-${{ runner.os }}-${{ matrix.node-version }}-${{ matrix.shard }}'
|
||||
path: 'packages/*/junit.xml'
|
||||
|
||||
- name: 'Upload coverage reports'
|
||||
@@ -248,7 +304,7 @@ jobs:
|
||||
${{ always() }}
|
||||
uses: 'actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02' # ratchet:actions/upload-artifact@v4
|
||||
with:
|
||||
name: 'coverage-reports-${{ matrix.node-version }}-${{ matrix.os }}'
|
||||
name: 'coverage-reports-${{ runner.os }}-${{ matrix.node-version }}-${{ matrix.shard }}'
|
||||
path: 'packages/*/coverage'
|
||||
|
||||
codeql:
|
||||
@@ -366,6 +422,21 @@ jobs:
|
||||
run: 'node ./bundle/gemini.js --version'
|
||||
shell: 'pwsh'
|
||||
|
||||
- name: 'Smoke test npx installation'
|
||||
run: |
|
||||
# 1. Package the project into a tarball
|
||||
$PACK_OUTPUT = npm pack
|
||||
$TARBALL = $PACK_OUTPUT[-1]
|
||||
|
||||
# 2. Move to a fresh directory for isolation
|
||||
New-Item -ItemType Directory -Force -Path ../smoke-test-dir
|
||||
Move-Item $TARBALL ../smoke-test-dir/
|
||||
Set-Location ../smoke-test-dir
|
||||
|
||||
# 3. Run npx from the tarball
|
||||
npx "./$TARBALL" --version
|
||||
shell: 'pwsh'
|
||||
|
||||
ci:
|
||||
name: 'CI'
|
||||
if: 'always()'
|
||||
|
||||
@@ -1,247 +0,0 @@
|
||||
name: 'Testing: E2E'
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
# This will run for PRs from the base repository, providing secrets.
|
||||
pull_request:
|
||||
branches:
|
||||
- 'main'
|
||||
- 'release/**'
|
||||
# This will run for PRs from forks when a label is added.
|
||||
pull_request_target:
|
||||
types: ['labeled']
|
||||
merge_group:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
branch_ref:
|
||||
description: 'Branch to run on'
|
||||
required: true
|
||||
default: 'main'
|
||||
type: 'string'
|
||||
|
||||
concurrency:
|
||||
group: '${{ github.workflow }}-${{ github.head_ref || github.ref }}'
|
||||
cancel-in-progress: |-
|
||||
${{ github.ref != 'refs/heads/main' && !startsWith(github.ref, 'refs/heads/release/') }}
|
||||
|
||||
jobs:
|
||||
merge_queue_skipper:
|
||||
name: 'Merge Queue Skipper'
|
||||
runs-on: 'gemini-cli-ubuntu-16-core'
|
||||
permissions: 'read-all'
|
||||
outputs:
|
||||
skip: '${{ steps.merge-queue-e2e-skipper.outputs.skip-check }}'
|
||||
steps:
|
||||
- id: 'merge-queue-e2e-skipper'
|
||||
uses: 'cariad-tech/merge-queue-ci-skipper@1032489e59437862c90a08a2c92809c903883772' # ratchet:cariad-tech/merge-queue-ci-skipper@main
|
||||
with:
|
||||
secret: '${{ secrets.GITHUB_TOKEN }}'
|
||||
continue-on-error: true
|
||||
|
||||
e2e_linux:
|
||||
name: 'E2E Test (Linux) - ${{ matrix.sandbox }}'
|
||||
needs: 'merge_queue_skipper'
|
||||
if: |
|
||||
(needs.merge_queue_skipper.result !='success' || needs.merge_queue_skipper.outputs.skip == 'false') &&
|
||||
(github.event_name == 'push' ||
|
||||
github.event_name == 'merge_group' ||
|
||||
github.event_name == 'workflow_dispatch' ||
|
||||
(github.event.pull_request.head.repo.full_name == github.repository) ||
|
||||
(github.event.label.name == 'maintainer:e2e:ok'))
|
||||
runs-on: 'gemini-cli-ubuntu-16-core'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
sandbox:
|
||||
- 'sandbox:none'
|
||||
- 'sandbox:docker'
|
||||
node-version:
|
||||
- '20.x'
|
||||
|
||||
steps:
|
||||
- name: 'Checkout (fork)'
|
||||
uses: 'actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955' # ratchet:actions/checkout@v5
|
||||
if: "github.event_name == 'pull_request_target'"
|
||||
with:
|
||||
ref: '${{ github.event.pull_request.head.sha }}'
|
||||
repository: '${{ github.event.pull_request.head.repo.full_name }}'
|
||||
|
||||
- name: 'Checkout (internal)'
|
||||
uses: 'actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955' # ratchet:actions/checkout@v5
|
||||
if: "github.event_name != 'pull_request_target'"
|
||||
with:
|
||||
ref: '${{ github.event.inputs.branch_ref || github.ref }}'
|
||||
|
||||
- name: 'Set up Node.js ${{ matrix.node-version }}'
|
||||
uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020' # ratchet:actions-node@v4
|
||||
with:
|
||||
node-version: '${{ matrix.node-version }}'
|
||||
|
||||
- name: 'Install dependencies'
|
||||
run: 'npm ci'
|
||||
|
||||
- name: 'Build project'
|
||||
run: 'npm run build'
|
||||
|
||||
- name: 'Set up Docker'
|
||||
if: "matrix.sandbox == 'sandbox:docker'"
|
||||
uses: 'docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435' # ratchet:docker/setup-buildx-action@v3
|
||||
|
||||
- name: 'Run E2E tests'
|
||||
env:
|
||||
GEMINI_API_KEY: '${{ secrets.GEMINI_API_KEY }}'
|
||||
KEEP_OUTPUT: 'true'
|
||||
VERBOSE: 'true'
|
||||
shell: 'bash'
|
||||
run: |
|
||||
if [[ "${{ matrix.sandbox }}" == "sandbox:docker" ]]; then
|
||||
npm run test:integration:sandbox:docker
|
||||
else
|
||||
npm run test:integration:sandbox:none
|
||||
fi
|
||||
|
||||
e2e_mac:
|
||||
name: 'E2E Test (macOS)'
|
||||
needs: 'merge_queue_skipper'
|
||||
if: |
|
||||
(needs.merge_queue_skipper.result !='success' || needs.merge_queue_skipper.outputs.skip == 'false') &&
|
||||
(github.event_name == 'push' ||
|
||||
github.event_name == 'merge_group' ||
|
||||
github.event_name == 'workflow_dispatch' ||
|
||||
(github.event.pull_request.head.repo.full_name == github.repository) ||
|
||||
(github.event.label.name == 'maintainer:e2e:ok'))
|
||||
runs-on: 'macos-latest'
|
||||
steps:
|
||||
- name: 'Checkout (fork)'
|
||||
uses: 'actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955' # ratchet:actions/checkout@v5
|
||||
if: "github.event_name == 'pull_request_target'"
|
||||
with:
|
||||
ref: '${{ github.event.pull_request.head.sha }}'
|
||||
repository: '${{ github.event.pull_request.head.repo.full_name }}'
|
||||
|
||||
- name: 'Checkout (internal)'
|
||||
uses: 'actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955' # ratchet:actions/checkout@v5
|
||||
if: "github.event_name != 'pull_request_target'"
|
||||
with:
|
||||
ref: '${{ github.event.inputs.branch_ref || github.ref }}'
|
||||
|
||||
- name: 'Set up Node.js 20.x'
|
||||
uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020' # ratchet:actions-node@v4
|
||||
with:
|
||||
node-version: '20.x'
|
||||
|
||||
- name: 'Install dependencies'
|
||||
run: 'npm ci'
|
||||
|
||||
- name: 'Build project'
|
||||
run: 'npm run build'
|
||||
|
||||
- name: 'Fix rollup optional dependencies on macOS'
|
||||
if: "runner.os == 'macOS'"
|
||||
run: |
|
||||
npm cache clean --force
|
||||
- name: 'Run E2E tests (non-Windows)'
|
||||
if: "runner.os != 'Windows'"
|
||||
env:
|
||||
GEMINI_API_KEY: '${{ secrets.GEMINI_API_KEY }}'
|
||||
KEEP_OUTPUT: 'true'
|
||||
SANDBOX: 'sandbox:none'
|
||||
VERBOSE: 'true'
|
||||
run: 'npm run test:integration:sandbox:none'
|
||||
|
||||
e2e_windows:
|
||||
name: 'Slow E2E - Win'
|
||||
needs: 'merge_queue_skipper'
|
||||
if: |
|
||||
(needs.merge_queue_skipper.result !='success' || needs.merge_queue_skipper.outputs.skip == 'false') &&
|
||||
(github.event_name == 'push' ||
|
||||
github.event_name == 'merge_group' ||
|
||||
github.event_name == 'workflow_dispatch' ||
|
||||
(github.event.pull_request.head.repo.full_name == github.repository) ||
|
||||
(github.event.label.name == 'maintainer:e2e:ok'))
|
||||
runs-on: 'gemini-cli-windows-16-core'
|
||||
continue-on-error: true
|
||||
|
||||
steps:
|
||||
- name: 'Checkout (fork)'
|
||||
uses: 'actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955' # ratchet:actions/checkout@v5
|
||||
if: "github.event_name == 'pull_request_target'"
|
||||
with:
|
||||
ref: '${{ github.event.pull_request.head.sha }}'
|
||||
repository: '${{ github.event.pull_request.head.repo.full_name }}'
|
||||
|
||||
- name: 'Checkout (internal)'
|
||||
uses: 'actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955' # ratchet:actions/checkout@v5
|
||||
if: "github.event_name != 'pull_request_target'"
|
||||
with:
|
||||
ref: '${{ github.event.inputs.branch_ref || github.ref }}'
|
||||
|
||||
- name: 'Set up Node.js 20.x'
|
||||
uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020' # ratchet:actions-node@v4
|
||||
with:
|
||||
node-version: '20.x'
|
||||
cache: 'npm'
|
||||
|
||||
- name: 'Configure Windows Defender exclusions'
|
||||
run: |
|
||||
Add-MpPreference -ExclusionPath $env:GITHUB_WORKSPACE -Force
|
||||
Add-MpPreference -ExclusionPath "$env:GITHUB_WORKSPACE\node_modules" -Force
|
||||
Add-MpPreference -ExclusionPath "$env:GITHUB_WORKSPACE\packages" -Force
|
||||
Add-MpPreference -ExclusionPath "$env:TEMP" -Force
|
||||
shell: 'pwsh'
|
||||
|
||||
- name: 'Configure npm for Windows performance'
|
||||
run: |
|
||||
npm config set progress false
|
||||
npm config set audit false
|
||||
npm config set fund false
|
||||
npm config set loglevel error
|
||||
npm config set maxsockets 32
|
||||
npm config set registry https://registry.npmjs.org/
|
||||
shell: 'pwsh'
|
||||
|
||||
- name: 'Install dependencies'
|
||||
run: 'npm ci'
|
||||
shell: 'pwsh'
|
||||
|
||||
- name: 'Build project'
|
||||
run: 'npm run build'
|
||||
shell: 'pwsh'
|
||||
|
||||
- name: 'Run E2E tests'
|
||||
env:
|
||||
GEMINI_API_KEY: '${{ secrets.GEMINI_API_KEY }}'
|
||||
KEEP_OUTPUT: 'true'
|
||||
SANDBOX: 'sandbox:none'
|
||||
VERBOSE: 'true'
|
||||
NODE_OPTIONS: '--max-old-space-size=32768 --max-semi-space-size=256'
|
||||
UV_THREADPOOL_SIZE: '32'
|
||||
NODE_ENV: 'test'
|
||||
shell: 'pwsh'
|
||||
run: 'npm run test:integration:sandbox:none'
|
||||
|
||||
e2e:
|
||||
name: 'E2E'
|
||||
if: |
|
||||
always() && (
|
||||
github.event_name == 'push' ||
|
||||
github.event_name == 'merge_group' ||
|
||||
github.event_name == 'workflow_dispatch' ||
|
||||
(github.event.pull_request.head.repo.full_name == github.repository) ||
|
||||
(github.event.label.name == 'maintainer:e2e:ok')
|
||||
)
|
||||
needs:
|
||||
- 'e2e_linux'
|
||||
- 'e2e_mac'
|
||||
runs-on: 'gemini-cli-ubuntu-16-core'
|
||||
steps:
|
||||
- name: 'Check E2E test results'
|
||||
run: |
|
||||
if [[ (${{ needs.e2e_linux.result }} != 'success' && ${{ needs.e2e_linux.result }} != 'skipped') || \
|
||||
(${{ needs.e2e_mac.result }} != 'success' && ${{ needs.e2e_mac.result }} != 'skipped') ]]; then
|
||||
echo "One or more E2E jobs failed."
|
||||
exit 1
|
||||
fi
|
||||
echo "All required E2E jobs passed!"
|
||||
@@ -0,0 +1,101 @@
|
||||
name: 'Evals: Nightly'
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 1 * * *' # Runs at 1 AM every day
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
run_all:
|
||||
description: 'Run all evaluations (including usually passing)'
|
||||
type: 'boolean'
|
||||
default: true
|
||||
test_name_pattern:
|
||||
description: 'Test name pattern or file name'
|
||||
required: false
|
||||
type: 'string'
|
||||
|
||||
permissions:
|
||||
contents: 'read'
|
||||
checks: 'write'
|
||||
actions: 'read'
|
||||
|
||||
jobs:
|
||||
evals:
|
||||
name: 'Evals (USUALLY_PASSING) nightly run'
|
||||
runs-on: 'gemini-cli-ubuntu-16-core'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
model:
|
||||
- 'gemini-3-pro-preview'
|
||||
- 'gemini-3-flash-preview'
|
||||
- 'gemini-2.5-pro'
|
||||
- 'gemini-2.5-flash'
|
||||
- 'gemini-2.5-flash-lite'
|
||||
run_attempt: [1, 2, 3]
|
||||
steps:
|
||||
- name: 'Checkout'
|
||||
uses: 'actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8' # ratchet:actions/checkout@v5
|
||||
|
||||
- name: 'Set up Node.js'
|
||||
uses: 'actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020' # ratchet:actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'npm'
|
||||
|
||||
- name: 'Install dependencies'
|
||||
run: 'npm ci'
|
||||
|
||||
- name: 'Build project'
|
||||
run: 'npm run build'
|
||||
|
||||
- name: 'Create logs directory'
|
||||
run: 'mkdir -p evals/logs'
|
||||
|
||||
- name: 'Run Evals'
|
||||
continue-on-error: true
|
||||
env:
|
||||
GEMINI_API_KEY: '${{ secrets.GEMINI_API_KEY }}'
|
||||
GEMINI_MODEL: '${{ matrix.model }}'
|
||||
RUN_EVALS: "${{ github.event.inputs.run_all != 'false' }}"
|
||||
TEST_NAME_PATTERN: '${{ github.event.inputs.test_name_pattern }}'
|
||||
run: |
|
||||
CMD="npm run test:all_evals"
|
||||
PATTERN="${{ env.TEST_NAME_PATTERN }}"
|
||||
|
||||
if [[ -n "$PATTERN" ]]; then
|
||||
if [[ "$PATTERN" == *.ts || "$PATTERN" == *.js || "$PATTERN" == */* ]]; then
|
||||
$CMD -- "$PATTERN"
|
||||
else
|
||||
$CMD -- -t "$PATTERN"
|
||||
fi
|
||||
else
|
||||
$CMD
|
||||
fi
|
||||
|
||||
- name: 'Upload Logs'
|
||||
if: 'always()'
|
||||
uses: 'actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02' # ratchet:actions/upload-artifact@v4
|
||||
with:
|
||||
name: 'eval-logs-${{ matrix.model }}-${{ matrix.run_attempt }}'
|
||||
path: 'evals/logs'
|
||||
retention-days: 7
|
||||
|
||||
aggregate-results:
|
||||
name: 'Aggregate Results'
|
||||
needs: ['evals']
|
||||
if: 'always()'
|
||||
runs-on: 'gemini-cli-ubuntu-16-core'
|
||||
steps:
|
||||
- name: 'Checkout'
|
||||
uses: 'actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8' # ratchet:actions/checkout@v5
|
||||
|
||||
- name: 'Download Logs'
|
||||
uses: 'actions/download-artifact@cc203385981b70ca67e1cc392babf9cc229d5806' # ratchet:actions/download-artifact@v4
|
||||
with:
|
||||
path: 'artifacts'
|
||||
|
||||
- name: 'Generate Summary'
|
||||
env:
|
||||
GH_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
|
||||
run: 'node scripts/aggregate_evals.js artifacts >> "$GITHUB_STEP_SUMMARY"'
|
||||
@@ -101,7 +101,6 @@ jobs:
|
||||
"FIRESTORE_DATABASE_ID": "(default)",
|
||||
"GOOGLE_APPLICATION_CREDENTIALS": "${GOOGLE_APPLICATION_CREDENTIALS}"
|
||||
},
|
||||
"enabled": true,
|
||||
"timeout": 600000
|
||||
}
|
||||
},
|
||||
|
||||
@@ -14,9 +14,15 @@ on:
|
||||
description: 'issue number to triage'
|
||||
required: true
|
||||
type: 'number'
|
||||
workflow_call:
|
||||
inputs:
|
||||
issue_number:
|
||||
description: 'issue number to triage'
|
||||
required: false
|
||||
type: 'string'
|
||||
|
||||
concurrency:
|
||||
group: '${{ github.workflow }}-${{ github.event.issue.number || github.event.inputs.issue_number }}'
|
||||
group: '${{ github.workflow }}-${{ github.event.issue.number || github.event.inputs.issue_number || inputs.issue_number }}'
|
||||
cancel-in-progress: true
|
||||
|
||||
defaults:
|
||||
@@ -34,20 +40,18 @@ permissions:
|
||||
jobs:
|
||||
triage-issue:
|
||||
if: |-
|
||||
github.repository == 'google-gemini/gemini-cli' &&
|
||||
(github.repository == 'google-gemini/gemini-cli' || github.repository == 'google-gemini/maintainers-gemini-cli') &&
|
||||
(
|
||||
github.event_name == 'workflow_dispatch' ||
|
||||
(
|
||||
(github.event_name == 'issues' || github.event_name == 'issue_comment') &&
|
||||
contains(github.event.issue.labels.*.name, 'status/need-triage') &&
|
||||
(github.event_name != 'issue_comment' || (
|
||||
contains(github.event.comment.body, '@gemini-cli /triage') &&
|
||||
(github.event.comment.author_association == 'OWNER' || github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'COLLABORATOR')
|
||||
))
|
||||
)
|
||||
) &&
|
||||
!contains(github.event.issue.labels.*.name, 'area/') &&
|
||||
!contains(github.event.issue.labels.*.name, 'priority/')
|
||||
!contains(github.event.issue.labels.*.name, 'area/')
|
||||
timeout-minutes: 5
|
||||
runs-on: 'ubuntu-latest'
|
||||
steps:
|
||||
@@ -59,10 +63,11 @@ jobs:
|
||||
with:
|
||||
github-token: '${{ secrets.GITHUB_TOKEN }}'
|
||||
script: |
|
||||
const issueNumber = ${{ github.event.inputs.issue_number || inputs.issue_number }};
|
||||
const { data: issue } = await github.rest.issues.get({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: ${{ github.event.inputs.issue_number }},
|
||||
issue_number: issueNumber,
|
||||
});
|
||||
core.setOutput('title', issue.title);
|
||||
core.setOutput('body', issue.body);
|
||||
@@ -73,16 +78,11 @@ jobs:
|
||||
if: |-
|
||||
github.event_name == 'workflow_dispatch'
|
||||
env:
|
||||
ISSUE_NUMBER_INPUT: '${{ github.event.inputs.issue_number }}'
|
||||
ISSUE_NUMBER_INPUT: '${{ github.event.inputs.issue_number || inputs.issue_number }}'
|
||||
LABELS: '${{ steps.get_issue_data.outputs.labels }}'
|
||||
run: |
|
||||
if ! echo "${LABELS}" | grep -q 'status/need-triage'; then
|
||||
echo "Issue #${ISSUE_NUMBER_INPUT} does not have the 'status/need-triage' label. Stopping workflow."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if echo "${LABELS}" | grep -q 'area/' || echo "${LABELS}" | grep -q 'priority/'; then
|
||||
echo "Issue #${ISSUE_NUMBER_INPUT} already has 'area/' or 'priority/' labels. Stopping workflow."
|
||||
if echo "${LABELS}" | grep -q 'area/'; then
|
||||
echo "Issue #${ISSUE_NUMBER_INPUT} already has 'area/' label. Stopping workflow."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -93,6 +93,10 @@ jobs:
|
||||
|
||||
- name: 'Generate GitHub App Token'
|
||||
id: 'generate_token'
|
||||
env:
|
||||
APP_ID: '${{ secrets.APP_ID }}'
|
||||
if: |-
|
||||
${{ env.APP_ID != '' }}
|
||||
uses: 'actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b' # ratchet:actions/create-github-app-token@v2
|
||||
with:
|
||||
app-id: '${{ secrets.APP_ID }}'
|
||||
@@ -103,18 +107,13 @@ jobs:
|
||||
id: 'get_labels'
|
||||
uses: 'actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea'
|
||||
with:
|
||||
github-token: '${{ steps.generate_token.outputs.token }}'
|
||||
github-token: '${{ steps.generate_token.outputs.token || secrets.GITHUB_TOKEN }}'
|
||||
script: |-
|
||||
const { data: labels } = await github.rest.issues.listLabelsForRepo({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
});
|
||||
const allowedLabels = [
|
||||
'priority/p0',
|
||||
'priority/p1',
|
||||
'priority/p2',
|
||||
'priority/p3',
|
||||
'priority/unknown',
|
||||
'area/agent',
|
||||
'area/enterprise',
|
||||
'area/non-interactive',
|
||||
@@ -139,7 +138,7 @@ jobs:
|
||||
ISSUE_BODY: >-
|
||||
${{ github.event_name == 'workflow_dispatch' && steps.get_issue_data.outputs.body || github.event.issue.body }}
|
||||
ISSUE_NUMBER: >-
|
||||
${{ github.event_name == 'workflow_dispatch' && github.event.inputs.issue_number || github.event.issue.number }}
|
||||
${{ github.event_name == 'workflow_dispatch' && (github.event.inputs.issue_number || inputs.issue_number) || github.event.issue.number }}
|
||||
REPOSITORY: '${{ github.repository }}'
|
||||
AVAILABLE_LABELS: '${{ steps.get_labels.outputs.available_labels }}'
|
||||
with:
|
||||
@@ -161,21 +160,19 @@ jobs:
|
||||
prompt: |-
|
||||
## Role
|
||||
|
||||
You are an issue triage assistant. Your role is to analyze a GitHub issue and determine the single most appropriate area/ label and the single most appropriate priority/ label based on the definitions provided.
|
||||
You are an issue triage assistant. Your role is to analyze a GitHub issue and determine the single most appropriate area/ label based on the definitions provided.
|
||||
|
||||
## Steps
|
||||
1. Review the issue title and body: ${{ env.ISSUE_TITLE }} and ${{ env.ISSUE_BODY }}.
|
||||
2. Review the available labels: ${{ env.AVAILABLE_LABELS }}.
|
||||
3. Select exactly one area/ label that best matches the issue based on Reference 1: Area Definitions.
|
||||
4. Select exactly one priority/ label that best matches the issue based on Reference 2: Priority Definitions.
|
||||
5. Fallback Logic:
|
||||
4. Fallback Logic:
|
||||
- If you cannot confidently determine the correct area/ label from the definitions, you must use area/unknown.
|
||||
- If you cannot confidently determine the correct priority/ label from the definitions, you must use priority/unknown.
|
||||
6. Output your two selected labels in JSON format and nothing else. Example:
|
||||
{"labels_to_set": ["area/core", "priority/p1"]}
|
||||
5. Output your selected label in JSON format and nothing else. Example:
|
||||
{"labels_to_set": ["area/core"]}
|
||||
|
||||
## Guidelines
|
||||
- Your output must contain exactly one area/ label and exactly one priority/ label.
|
||||
- Your output must contain exactly one area/ label.
|
||||
- Triage only the current issue based on its title and body.
|
||||
- Output only valid JSON format.
|
||||
- Do not include any explanation or additional text, just the JSON.
|
||||
@@ -258,38 +255,6 @@ jobs:
|
||||
area/unknown
|
||||
- Description: Issues that do not clearly fit into any other defined area/ category, or where information is too limited to make a determination. Use this when no other area is appropriate.
|
||||
|
||||
Reference 2: Priority Definitions
|
||||
priority/p0: Critical / Blocker
|
||||
- Definition: A catastrophic failure that makes the CLI unusable for most users or poses a severe security risk. This includes installation failures, authentication failures, persistent crashes, or critical security vulnerabilities.
|
||||
- Key Questions:
|
||||
- Is the CLI failing to install or run?
|
||||
- Does it fail to authenticate or connect to the Gemini API, making all commands useless?
|
||||
- Is it consistently crashing on basic, common commands?
|
||||
- Does this represent a critical security vulnerability?
|
||||
|
||||
priority/p1: High
|
||||
- Definition: A severe issue where a core feature (e.g., text generation, code generation, file processing) is unusable, failing, has severe performance degradation, or providing fundamentally incorrect output formatting (e.g., truncated text, broken JSON). Affects many users, and there is no reasonable workaround.
|
||||
- Key Questions:
|
||||
- Is a core feature failing for a specific, large user group (e.g., all Windows users, all users of a specific shell)?
|
||||
- Is the CLI failing to process a supported input or misinterpreting critical flags?
|
||||
- Is the CLI's output formatting consistently broken, making the response unusable?
|
||||
- Is a core command or feature extremely slow, making it impractical to use?
|
||||
|
||||
priority/p2: Medium
|
||||
- Definition: A moderately impactful issue causing inconvenience or a non-optimal experience, but a reasonable workaround exists. This also includes failures in non-core features.
|
||||
- Key Questions:
|
||||
- Is a command or flag behaving incorrectly, but the user can achieve their goal via other means?
|
||||
- Is there a significant, non-blocking UI/UX problem in the terminal (e.g., broken progress indicators, bad terminal coloring)?
|
||||
|
||||
priority/p3: Low
|
||||
- Definition: A minor, low-impact issue with minimal effect on functionality. This includes most cosmetic defects, typos in documentation, or unclear help text.
|
||||
- Key Questions:
|
||||
- Is this a typo in the README.md, gemini --help text, or other documentation?
|
||||
- Is this a minor cosmetic issue (e.g., text alignment in output, an extra newline) that doesn't affect usability?
|
||||
|
||||
priority/unknown
|
||||
- Description: Issues that do not clearly fit into any other defined priority/ category, or where information is too limited to make a determination. Use this when no other priority is appropriate.
|
||||
|
||||
- name: 'Apply Labels to Issue'
|
||||
if: |-
|
||||
${{ steps.gemini_issue_analysis.outputs.summary != '' }}
|
||||
@@ -299,7 +264,7 @@ jobs:
|
||||
LABELS_OUTPUT: '${{ steps.gemini_issue_analysis.outputs.summary }}'
|
||||
uses: 'actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea'
|
||||
with:
|
||||
github-token: '${{ steps.generate_token.outputs.token }}'
|
||||
github-token: '${{ steps.generate_token.outputs.token || secrets.GITHUB_TOKEN }}'
|
||||
script: |
|
||||
const rawOutput = process.env.LABELS_OUTPUT;
|
||||
core.info(`Raw output from model: ${rawOutput}`);
|
||||
@@ -327,8 +292,8 @@ jobs:
|
||||
const issueNumber = parseInt(process.env.ISSUE_NUMBER);
|
||||
const labelsToAdd = parsedLabels.labels_to_set || [];
|
||||
|
||||
if (labelsToAdd.length !== 2) {
|
||||
core.setFailed(`Expected exactly 2 labels (one area/ and one priority/), but got ${labelsToAdd.length}. Labels: ${labelsToAdd.join(', ')}`);
|
||||
if (labelsToAdd.length !== 1) {
|
||||
core.setFailed(`Expected exactly 1 label (area/), but got ${labelsToAdd.length}. Labels: ${labelsToAdd.join(', ')}`);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -341,22 +306,6 @@ jobs:
|
||||
});
|
||||
core.info(`Successfully added labels for #${issueNumber}: ${labelsToAdd.join(', ')}`);
|
||||
|
||||
// Remove the 'status/need-triage' label
|
||||
try {
|
||||
await github.rest.issues.removeLabel({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: issueNumber,
|
||||
name: 'status/need-triage'
|
||||
});
|
||||
core.info(`Successfully removed 'status/need-triage' label.`);
|
||||
} catch (error) {
|
||||
// If the label doesn't exist, the API call will throw a 404. We can ignore this.
|
||||
if (error.status !== 404) {
|
||||
core.warning(`Failed to remove 'status/need-triage': ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
- name: 'Post Issue Analysis Failure Comment'
|
||||
if: |-
|
||||
${{ failure() && steps.gemini_issue_analysis.outcome == 'failure' }}
|
||||
@@ -365,7 +314,7 @@ jobs:
|
||||
RUN_URL: '${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}'
|
||||
uses: 'actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea'
|
||||
with:
|
||||
github-token: '${{ steps.generate_token.outputs.token }}'
|
||||
github-token: '${{ steps.generate_token.outputs.token || secrets.GITHUB_TOKEN }}'
|
||||
script: |-
|
||||
github.rest.issues.createComment({
|
||||
owner: context.repo.owner,
|
||||
|
||||
@@ -81,7 +81,6 @@ jobs:
|
||||
"FIRESTORE_DATABASE_ID": "(default)",
|
||||
"GOOGLE_APPLICATION_CREDENTIALS": "${GOOGLE_APPLICATION_CREDENTIALS}"
|
||||
},
|
||||
"enabled": true,
|
||||
"timeout": 600000
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
name: '📋 Gemini Scheduled Issue Triage'
|
||||
|
||||
on:
|
||||
issues:
|
||||
types:
|
||||
- 'opened'
|
||||
- 'reopened'
|
||||
schedule:
|
||||
- cron: '0 * * * *' # Runs every hour
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: '${{ github.workflow }}'
|
||||
group: '${{ github.workflow }}-${{ github.event.number || github.run_id }}'
|
||||
cancel-in-progress: true
|
||||
|
||||
defaults:
|
||||
@@ -35,7 +39,21 @@ jobs:
|
||||
private-key: '${{ secrets.PRIVATE_KEY }}'
|
||||
permission-issues: 'write'
|
||||
|
||||
- name: 'Get issue from event'
|
||||
if: |-
|
||||
${{ github.event_name == 'issues' }}
|
||||
id: 'get_issue_from_event'
|
||||
env:
|
||||
ISSUE_EVENT: '${{ toJSON(github.event.issue) }}'
|
||||
run: |
|
||||
set -euo pipefail
|
||||
ISSUE_JSON=$(echo "$ISSUE_EVENT" | jq -c '[{number: .number, title: .title, body: .body}]')
|
||||
echo "issues_to_triage=${ISSUE_JSON}" >> "${GITHUB_OUTPUT}"
|
||||
echo "✅ Found issue #${{ github.event.issue.number }} from event to triage! 🎯"
|
||||
|
||||
- name: 'Find untriaged issues'
|
||||
if: |-
|
||||
${{ github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' }}
|
||||
id: 'find_issues'
|
||||
env:
|
||||
GITHUB_TOKEN: '${{ steps.generate_token.outputs.token }}'
|
||||
@@ -43,22 +61,26 @@ jobs:
|
||||
run: |-
|
||||
set -euo pipefail
|
||||
|
||||
echo '🔍 Finding issues without labels...'
|
||||
NO_LABEL_ISSUES="$(gh issue list --repo "${GITHUB_REPOSITORY}" \
|
||||
--search 'is:open is:issue no:label' --json number,title,body)"
|
||||
echo '🔍 Finding issues missing area labels...'
|
||||
NO_AREA_ISSUES="$(gh issue list --repo "${GITHUB_REPOSITORY}" \
|
||||
--search 'is:open is:issue -label:area/core -label:area/agent -label:area/enterprise -label:area/non-interactive -label:area/security -label:area/platform -label:area/extensions -label:area/unknown' --limit 100 --json number,title,body)"
|
||||
|
||||
echo '🏷️ Finding issues that need triage...'
|
||||
NEED_TRIAGE_ISSUES="$(gh issue list --repo "${GITHUB_REPOSITORY}" \
|
||||
--search "is:open is:issue label:\"status/need-triage\"" --limit 1000 --json number,title,body)"
|
||||
echo '🔍 Finding issues missing kind labels...'
|
||||
NO_KIND_ISSUES="$(gh issue list --repo "${GITHUB_REPOSITORY}" \
|
||||
--search 'is:open is:issue -label:kind/bug -label:kind/enhancement -label:kind/customer-issue -label:kind/question' --limit 100 --json number,title,body)"
|
||||
|
||||
echo '🏷️ Finding issues missing priority labels...'
|
||||
NO_PRIORITY_ISSUES="$(gh issue list --repo "${GITHUB_REPOSITORY}" \
|
||||
--search 'is:open is:issue -label:priority/p0 -label:priority/p1 -label:priority/p2 -label:priority/p3 -label:priority/unknown' --limit 100 --json number,title,body)"
|
||||
|
||||
echo '🔄 Merging and deduplicating issues...'
|
||||
ISSUES="$(echo "${NO_LABEL_ISSUES}" "${NEED_TRIAGE_ISSUES}" | jq -c -s 'add | unique_by(.number)')"
|
||||
ISSUES="$(echo "${NO_AREA_ISSUES}" "${NO_KIND_ISSUES}" "${NO_PRIORITY_ISSUES}" | jq -c -s 'add | unique_by(.number)')"
|
||||
|
||||
echo '📝 Setting output for GitHub Actions...'
|
||||
echo "issues_to_triage=${ISSUES}" >> "${GITHUB_OUTPUT}"
|
||||
|
||||
ISSUE_COUNT="$(echo "${ISSUES}" | jq 'length')"
|
||||
echo "✅ Found ${ISSUE_COUNT} issues to triage! 🎯"
|
||||
echo "✅ Found ${ISSUE_COUNT} unique issues to triage! 🎯"
|
||||
|
||||
- name: 'Get Repository Labels'
|
||||
id: 'get_labels'
|
||||
@@ -77,12 +99,13 @@ jobs:
|
||||
|
||||
- name: 'Run Gemini Issue Analysis'
|
||||
if: |-
|
||||
${{ steps.find_issues.outputs.issues_to_triage != '[]' }}
|
||||
(steps.get_issue_from_event.outputs.issues_to_triage != '' && steps.get_issue_from_event.outputs.issues_to_triage != '[]') ||
|
||||
(steps.find_issues.outputs.issues_to_triage != '' && steps.find_issues.outputs.issues_to_triage != '[]')
|
||||
uses: 'google-github-actions/run-gemini-cli@a3bf79042542528e91937b3a3a6fbc4967ee3c31' # ratchet:google-github-actions/run-gemini-cli@v0
|
||||
id: 'gemini_issue_analysis'
|
||||
env:
|
||||
GITHUB_TOKEN: '' # Do not pass any auth token here since this runs on untrusted inputs
|
||||
ISSUES_TO_TRIAGE: '${{ steps.find_issues.outputs.issues_to_triage }}'
|
||||
ISSUES_TO_TRIAGE: '${{ steps.get_issue_from_event.outputs.issues_to_triage || steps.find_issues.outputs.issues_to_triage }}'
|
||||
REPOSITORY: '${{ github.repository }}'
|
||||
AVAILABLE_LABELS: '${{ steps.get_labels.outputs.available_labels }}'
|
||||
with:
|
||||
@@ -116,38 +139,32 @@ jobs:
|
||||
1. You are only able to use the echo command. Review the available labels in the environment variable: "${AVAILABLE_LABELS}".
|
||||
2. Check environment variable for issues to triage: $ISSUES_TO_TRIAGE (JSON array of issues)
|
||||
3. Review the issue title, body and any comments provided in the environment variables.
|
||||
4. Identify the most relevant labels from the existing labels, focusing on kind/*, area/*, sub-area/* and priority/*.
|
||||
5. If the issue already has area/ label, dont try to change it. Similarly, if the issue already has a kind/ label don't change it. And if the issue already has a priority/ label do not change it for example:
|
||||
If an issue has area/core and kind/bug you will only add a priority/ label.
|
||||
Instead if an issue has no labels, you will could add one lable of each kind.
|
||||
4. Identify the most relevant labels from the existing labels, specifically focusing on area/*, kind/* and priority/*.
|
||||
5. Label Policy:
|
||||
- If the issue already has a kind/ label, do not change it.
|
||||
- If the issue already has a priority/ label, do not change it.
|
||||
- If the issue already has an area/ label, do not change it.
|
||||
- If any of these are missing, select exactly ONE appropriate label for the missing category.
|
||||
6. Identify other applicable labels based on the issue content, such as status/*, help wanted, good first issue, etc.
|
||||
7. For area/* and kind/* limit yourself to only the single most applicable label in each case.
|
||||
8. Give me a single short explanation about why you are selecting each label in the process.
|
||||
9. Output a JSON array of objects, each containing the issue number
|
||||
7. Give me a single short explanation about why you are selecting each label in the process.
|
||||
8. Output a JSON array of objects, each containing the issue number
|
||||
and the labels to add and remove, along with an explanation. For example:
|
||||
```
|
||||
[
|
||||
{
|
||||
"issue_number": 123,
|
||||
"labels_to_add": ["kind/bug", "priority/p2"],
|
||||
"labels_to_add": ["area/core", "kind/bug", "priority/p2"],
|
||||
"labels_to_remove": ["status/need-triage"],
|
||||
"explanation": "This issue is a bug that needs to be addressed with medium priority."
|
||||
},
|
||||
{
|
||||
"issue_number": 456,
|
||||
"labels_to_add": ["kind/enhancement"],
|
||||
"labels_to_remove": [],
|
||||
"explanation": "This issue is an enhancement request that could improve the user experience."
|
||||
"explanation": "This issue is a UI bug that needs to be addressed with medium priority."
|
||||
}
|
||||
]
|
||||
```
|
||||
If an issue cannot be classified, do not include it in the output array.
|
||||
10. For each issue please check if CLI version is present, this is usually in the output of the /about command and will look like 0.1.5
|
||||
9. For each issue please check if CLI version is present, this is usually in the output of the /about command and will look like 0.1.5
|
||||
- Anything more than 6 versions older than the most recent should add the status/need-retesting label
|
||||
11. If you see that the issue doesn't look like it has sufficient information recommend the status/need-information label and leave a comment politely requesting the relevant information, eg.. if repro steps are missing request for repro steps. if version information is missing request for version information into the explanation section below.
|
||||
- After identifying appropriate labels to an issue, add "status/need-triage" label to labels_to_remove in the output.
|
||||
12. If you think an issue might be a Priority/P0 do not apply the priority/p0 label. Instead apply a status/manual-triage label and include a note in your explanation.
|
||||
13. If you are uncertain and have not been able to apply one each of kind/, area/ and priority/ , apply the status/manual-triage label.
|
||||
10. If you see that the issue doesn't look like it has sufficient information recommend the status/need-information label and leave a comment politely requesting the relevant information, eg.. if repro steps are missing request for repro steps. if version information is missing request for version information into the explanation section below.
|
||||
11. If you think an issue might be a Priority/P0 do not apply the priority/p0 label. Instead apply a status/manual-triage label and include a note in your explanation.
|
||||
12. If you are uncertain about a category, use the area/unknown, kind/question, or priority/unknown labels as appropriate. If you are extremely uncertain, apply the status/manual-triage label.
|
||||
|
||||
## Guidelines
|
||||
|
||||
@@ -157,100 +174,46 @@ jobs:
|
||||
- Do not add comments or modify the issue content.
|
||||
- Do not remove the following labels maintainer, help wanted or good first issue.
|
||||
- Triage only the current issue.
|
||||
- Identify only one area/ label
|
||||
- Identify only one area/ label.
|
||||
- Identify only one kind/ label (Do not apply kind/duplicate or kind/parent-issue)
|
||||
- Identify all applicable sub-area/* and priority/* labels based on the issue content. It's ok to have multiple of these.
|
||||
- Identify only one priority/ label.
|
||||
- Once you categorize the issue if it needs information bump down the priority by 1 eg.. a p0 would become a p1 a p1 would become a p2. P2 and P3 can stay as is in this scenario.
|
||||
Categorization Guidelines:
|
||||
P0: Critical / Blocker
|
||||
- A P0 bug is a catastrophic failure that demands immediate attention.
|
||||
- To be a P0 it means almost all users are running into this issue and it is blocking users from being able to use the product.
|
||||
- You would see this in the form of many comments from different developers on the bug.
|
||||
- It represents a complete showstopper for a significant portion of users or for the development process itself.
|
||||
Impact:
|
||||
- Blocks development or testing for the entire team.
|
||||
- Major security vulnerability that could compromise user data or system integrity.
|
||||
- Causes data loss or corruption with no workaround.
|
||||
- Crashes the application or makes a core feature completely unusable for all or most users in a production environment. Will it cause severe quality degration?
|
||||
- Is it preventing contributors from contributing to the repository or is it a release blocker?
|
||||
Qualifier: Is the main function of the software broken?
|
||||
Example: The gemini auth login command fails with an unrecoverable error, preventing any user from authenticating and using the rest of the CLI.
|
||||
P1: High
|
||||
- A P1 bug is a serious issue that significantly degrades the user experience or impacts a core feature.
|
||||
- While not a complete blocker, it's a major problem that needs a fast resolution. Feature requests are almost never P1.
|
||||
- Once again this would be affecting many users.
|
||||
- You would see this in the form of comments from different developers on the bug.
|
||||
Impact:
|
||||
- A core feature is broken or behaving incorrectly for a large number of users or large number of use cases.
|
||||
- Review the bug details and comments to try figure out if this issue affects a large set of use cases or if it's a narrow set of use cases.
|
||||
- Severe performance degradation making the application frustratingly slow.
|
||||
- No straightforward workaround exists, or the workaround is difficult and non-obvious.
|
||||
Qualifier: Is a key feature unusable or giving very wrong results?
|
||||
Example: Gemini CLI enters a loop when making read-many-files tool call. I am unable to break out of the loop and gemini doesn't follow instructions subsequently.
|
||||
P2: Medium
|
||||
- A P2 bug is a moderately impactful issue. It's a noticeable problem but doesn't prevent the use of the software's main functionality.
|
||||
Impact:
|
||||
- Affects a non-critical feature or a smaller, specific subset of users.
|
||||
- An inconvenient but functional workaround is available and easy to execute.
|
||||
- Noticeable UI/UX problems that don't break functionality but look unprofessional (e.g., elements are misaligned or overlapping).
|
||||
Qualifier: Is it an annoying but non-blocking problem?
|
||||
Example: An error message is unclear or contains a typo, causing user confusion but not halting their workflow.
|
||||
P3: Low
|
||||
- A P3 bug is a minor, low-impact issue that is trivial or cosmetic. It has little to no effect on the overall functionality of the application.
|
||||
Impact:
|
||||
- Minor cosmetic issues like color inconsistencies, typos in documentation, or slight alignment problems on a non-critical page.
|
||||
- An edge-case bug that is very difficult to reproduce and affects a tiny fraction of users.
|
||||
Qualifier: Is it a "nice-to-fix" issue?
|
||||
Example: Spelling mistakes etc.
|
||||
|
||||
Categorization Guidelines (Priority):
|
||||
P0 - Urgent Blocking Issues:
|
||||
- DO NOT APPLY THIS LABEL AUTOMATICALLY. Use status/manual-triage instead.
|
||||
- Definition: Urgent, block a significant percentage of the user base, and prevent frequent use of the Gemini CLI.
|
||||
- This includes core stability blockers (e.g., authentication failures, broken upgrades), critical crashes, and P0 security vulnerabilities.
|
||||
- Impact: Blocks development or testing for the entire team; Major security vulnerability; Causes data loss or corruption with no workaround; Crashes the application or makes a core feature completely unusable for all or most users.
|
||||
- Qualifier: Is the main function of the software broken?
|
||||
P1 - High-Impact Issues:
|
||||
- Definition: Affect a large number of users, blocking them from using parts of the Gemini CLI, or make the CLI frequently unusable even with workarounds available.
|
||||
- Impact: A core feature is broken or behaving incorrectly for a large number of users or use cases; Severe performance degradation; No straightforward workaround exists.
|
||||
- Qualifier: Is a key feature unusable or giving very wrong results?
|
||||
P2 - Significant Issues:
|
||||
- Definition: Affect some users significantly, such as preventing the use of certain features or authentication types.
|
||||
- Can also be issues that many users complain about, causing annoyance or hindering daily use.
|
||||
- Impact: Affects a non-critical feature or a smaller, specific subset of users; An inconvenient but functional workaround is available; Noticeable UI/UX problems that look unprofessional.
|
||||
- Qualifier: Is it an annoying but non-blocking problem?
|
||||
P3 - Low-Impact Issues:
|
||||
- Definition: Typically usability issues that cause annoyance to a limited user base.
|
||||
- Includes feature requests that could be addressed in the near future and may be suitable for community contributions.
|
||||
- Impact: Minor cosmetic issues; An edge-case bug that is very difficult to reproduce and affects a tiny fraction of users.
|
||||
- Qualifier: Is it a "nice-to-fix" issue?
|
||||
|
||||
Categorization Guidelines (Area):
|
||||
area/agent: Core Agent, Tools, Memory, Sub-Agents, Hooks, Agent Quality
|
||||
area/core: User Interface, OS Support, Core Functionality
|
||||
area/enterprise: Telemetry, Policy, Quota / Licensing
|
||||
area/extensions: Gemini CLI extensions capability
|
||||
area/non-interactive: GitHub Actions, SDK, 3P Integrations, Shell Scripting, Command line automation
|
||||
area/platform: Build infra, Release mgmt, Testing, Eval infra, Capacity, Quota mgmt
|
||||
area/security: security related issues
|
||||
|
||||
Additional Context:
|
||||
- If users are talking about issues where the model gets downgraded from pro to flash then i want you to categorize that as a performance issue
|
||||
- This product is designed to use different models eg.. using pro, downgrading to flash etc.
|
||||
- When users report that they dont expect the model to change those would be categorized as feature requests.
|
||||
Definition of Areas
|
||||
area/ux:
|
||||
- Issues concerning user-facing elements like command usability, interactive features, help docs, and perceived performance.
|
||||
- I am seeing my screen flicker when using Gemini CLI
|
||||
- I am seeing the output malformed
|
||||
- Theme changes aren't taking effect
|
||||
- My keyboard inputs arent' being recognzied
|
||||
area/platform:
|
||||
- Issues related to installation, packaging, OS compatibility (Windows, macOS, Linux), and the underlying CLI framework.
|
||||
area/background: Issues related to long-running background tasks, daemons, and autonomous or proactive agent features.
|
||||
area/models:
|
||||
- i am not getting a response that is reasonable or expected. this can include things like
|
||||
- I am calling a tool and the tool is not performing as expected.
|
||||
- i am expecting a tool to be called and it is not getting called ,
|
||||
- Including experience when using
|
||||
- built-in tools (e.g., web search, code interpreter, read file, writefile, etc..),
|
||||
- Function calling issues should be under this area
|
||||
- i am getting responses from the model that are malformed.
|
||||
- Issues concerning Gemini quality of response and inference,
|
||||
- Issues talking about unnecessary token consumption.
|
||||
- Issues talking about Model getting stuck in a loop be watchful as this could be the root cause for issues that otherwise seem like model performance issues.
|
||||
- Memory compression
|
||||
- unexpected responses,
|
||||
- poor quality of generated code
|
||||
area/tools:
|
||||
- These are primarily issues related to Model Context Protocol
|
||||
- These are issues that mention MCP support
|
||||
- feature requests asking for support for new tools.
|
||||
area/core:
|
||||
- Issues with fundamental components like command parsing, configuration management, session state, and the main API client logic. Introducing multi-modality
|
||||
area/contribution:
|
||||
- Issues related to improving the developer contribution experience, such as CI/CD pipelines, build scripts, and test automation infrastructure.
|
||||
area/authentication:
|
||||
- Issues related to user identity, login flows, API key handling, credential storage, and access token management, unable to sign in selecting wrong authentication path etc..
|
||||
area/security-privacy:
|
||||
- Issues concerning vulnerability patching, dependency security, data sanitization, privacy controls, and preventing unauthorized data access.
|
||||
area/extensibility:
|
||||
- Issues related to the plugin system, extension APIs, or making the CLI's functionality available in other applications, github actions, ide support etc..
|
||||
area/performance:
|
||||
- Issues focused on model performance
|
||||
- Issues with running out of capacity,
|
||||
- 429 errors etc..
|
||||
- could also pertain to latency,
|
||||
- other general software performance like, memory usage, CPU consumption, and algorithmic efficiency.
|
||||
- Switching models from one to the other unexpectedly.
|
||||
- If users are talking about issues where the model gets downgraded from pro to flash then i want you to categorize that as a performance issue.
|
||||
- This product is designed to use different models eg.. using pro, downgrading to flash etc.
|
||||
- When users report that they dont expect the model to change those would be categorized as feature requests.
|
||||
|
||||
- name: 'Apply Labels to Issues'
|
||||
if: |-
|
||||
@@ -300,24 +263,6 @@ jobs:
|
||||
core.info(`Successfully added labels for #${issueNumber}: ${labelsToAdd.join(', ')}${explanation}`);
|
||||
}
|
||||
|
||||
if (entry.labels_to_remove && entry.labels_to_remove.length > 0) {
|
||||
for (const label of entry.labels_to_remove) {
|
||||
try {
|
||||
await github.rest.issues.removeLabel({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: issueNumber,
|
||||
name: label
|
||||
});
|
||||
} catch (error) {
|
||||
if (error.status !== 404) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
core.info(`Successfully removed labels for #${issueNumber}: ${entry.labels_to_remove.join(', ')}`);
|
||||
}
|
||||
|
||||
if (entry.explanation) {
|
||||
await github.rest.issues.createComment({
|
||||
owner: context.repo.owner,
|
||||
|
||||
@@ -39,3 +39,7 @@ jobs:
|
||||
GITHUB_REPOSITORY: '${{ github.repository }}'
|
||||
run: |-
|
||||
./.github/scripts/pr-triage.sh
|
||||
# If prs_needing_comment is empty, set it to [] explicitly for downstream steps
|
||||
if [[ -z "$(grep 'prs_needing_comment' "${GITHUB_OUTPUT}" | cut -d'=' -f2-)" ]]; then
|
||||
echo "prs_needing_comment=[]" >> "${GITHUB_OUTPUT}"
|
||||
fi
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
name: '🔒 Gemini Scheduled Stale Issue Closer'
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 0 * * 0' # Every Sunday at midnight UTC
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
dry_run:
|
||||
description: 'Run in dry-run mode (no changes applied)'
|
||||
required: false
|
||||
default: false
|
||||
type: 'boolean'
|
||||
|
||||
concurrency:
|
||||
group: '${{ github.workflow }}'
|
||||
cancel-in-progress: true
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: 'bash'
|
||||
|
||||
jobs:
|
||||
close-stale-issues:
|
||||
runs-on: 'ubuntu-latest'
|
||||
permissions:
|
||||
issues: 'write'
|
||||
steps:
|
||||
- name: 'Generate GitHub App Token'
|
||||
id: 'generate_token'
|
||||
uses: 'actions/create-github-app-token@v1'
|
||||
with:
|
||||
app-id: '${{ secrets.APP_ID }}'
|
||||
private-key: '${{ secrets.PRIVATE_KEY }}'
|
||||
permission-issues: 'write'
|
||||
|
||||
- name: 'Process Stale Issues'
|
||||
uses: 'actions/github-script@v7'
|
||||
env:
|
||||
DRY_RUN: '${{ inputs.dry_run }}'
|
||||
with:
|
||||
github-token: '${{ steps.generate_token.outputs.token }}'
|
||||
script: |
|
||||
const dryRun = process.env.DRY_RUN === 'true';
|
||||
if (dryRun) {
|
||||
core.info('DRY RUN MODE ENABLED: No changes will be applied.');
|
||||
}
|
||||
const batchLabel = 'Stale';
|
||||
|
||||
const threeMonthsAgo = new Date();
|
||||
threeMonthsAgo.setMonth(threeMonthsAgo.getMonth() - 3);
|
||||
|
||||
const tenDaysAgo = new Date();
|
||||
tenDaysAgo.setDate(tenDaysAgo.getDate() - 10);
|
||||
|
||||
core.info(`Cutoff date for creation: ${threeMonthsAgo.toISOString()}`);
|
||||
core.info(`Cutoff date for updates: ${tenDaysAgo.toISOString()}`);
|
||||
|
||||
const query = `repo:${context.repo.owner}/${context.repo.repo} is:issue is:open created:<${threeMonthsAgo.toISOString()}`;
|
||||
core.info(`Searching with query: ${query}`);
|
||||
|
||||
const itemsToCheck = await github.paginate(github.rest.search.issuesAndPullRequests, {
|
||||
q: query,
|
||||
sort: 'created',
|
||||
order: 'asc',
|
||||
per_page: 100
|
||||
});
|
||||
|
||||
core.info(`Found ${itemsToCheck.length} open issues to check.`);
|
||||
|
||||
let processedCount = 0;
|
||||
|
||||
for (const issue of itemsToCheck) {
|
||||
const createdAt = new Date(issue.created_at);
|
||||
const updatedAt = new Date(issue.updated_at);
|
||||
const reactionCount = issue.reactions.total_count;
|
||||
|
||||
// Basic thresholds
|
||||
if (reactionCount >= 5) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip if it has a maintainer, help wanted, or Public Roadmap label
|
||||
const rawLabels = issue.labels.map((l) => l.name);
|
||||
const lowercaseLabels = rawLabels.map((l) => l.toLowerCase());
|
||||
if (
|
||||
lowercaseLabels.some((l) => l.includes('maintainer')) ||
|
||||
lowercaseLabels.includes('help wanted') ||
|
||||
rawLabels.includes('🗓️ Public Roadmap')
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let isStale = updatedAt < tenDaysAgo;
|
||||
|
||||
// If apparently active, check if it's only bot activity
|
||||
if (!isStale) {
|
||||
try {
|
||||
const comments = await github.rest.issues.listComments({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: issue.number,
|
||||
per_page: 100,
|
||||
sort: 'created',
|
||||
direction: 'desc'
|
||||
});
|
||||
|
||||
const lastHumanComment = comments.data.find(comment => comment.user.type !== 'Bot');
|
||||
if (lastHumanComment) {
|
||||
isStale = new Date(lastHumanComment.created_at) < tenDaysAgo;
|
||||
} else {
|
||||
// No human comments. Check if creator is human.
|
||||
if (issue.user.type !== 'Bot') {
|
||||
isStale = createdAt < tenDaysAgo;
|
||||
} else {
|
||||
isStale = true; // Bot created, only bot comments
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
core.warning(`Failed to fetch comments for issue #${issue.number}: ${error.message}`);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (isStale) {
|
||||
processedCount++;
|
||||
const message = `Closing stale issue #${issue.number}: "${issue.title}" (${issue.html_url})`;
|
||||
core.info(message);
|
||||
|
||||
if (!dryRun) {
|
||||
// Add label
|
||||
await github.rest.issues.addLabels({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: issue.number,
|
||||
labels: [batchLabel]
|
||||
});
|
||||
|
||||
// Add comment
|
||||
await github.rest.issues.createComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: issue.number,
|
||||
body: 'Hello! As part of our effort to keep our backlog manageable and focus on the most active issues, we are tidying up older reports.\n\nIt looks like this issue hasn\'t been active for a while, so we are closing it for now. However, if you are still experiencing this bug on the latest stable build, please feel free to comment on this issue or create a new one with updated details.\n\nThank you for your contribution!'
|
||||
});
|
||||
|
||||
// Close issue
|
||||
await github.rest.issues.update({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: issue.number,
|
||||
state: 'closed',
|
||||
state_reason: 'not_planned'
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
core.info(`\nTotal issues processed: ${processedCount}`);
|
||||
@@ -0,0 +1,223 @@
|
||||
name: 'Gemini Scheduled Stale PR Closer'
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 2 * * *' # Every day at 2 AM UTC
|
||||
pull_request:
|
||||
types: ['opened', 'edited']
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
dry_run:
|
||||
description: 'Run in dry-run mode'
|
||||
required: false
|
||||
default: false
|
||||
type: 'boolean'
|
||||
|
||||
jobs:
|
||||
close-stale-prs:
|
||||
if: "github.repository == 'google-gemini/gemini-cli'"
|
||||
runs-on: 'ubuntu-latest'
|
||||
permissions:
|
||||
pull-requests: 'write'
|
||||
issues: 'write'
|
||||
steps:
|
||||
- name: 'Generate GitHub App Token'
|
||||
id: 'generate_token'
|
||||
uses: 'actions/create-github-app-token@v1'
|
||||
with:
|
||||
app-id: '${{ secrets.APP_ID }}'
|
||||
private-key: '${{ secrets.PRIVATE_KEY }}'
|
||||
owner: '${{ github.repository_owner }}'
|
||||
repositories: 'gemini-cli'
|
||||
|
||||
- name: 'Process Stale PRs'
|
||||
uses: 'actions/github-script@v7'
|
||||
env:
|
||||
DRY_RUN: '${{ inputs.dry_run }}'
|
||||
with:
|
||||
github-token: '${{ steps.generate_token.outputs.token }}'
|
||||
script: |
|
||||
const dryRun = process.env.DRY_RUN === 'true';
|
||||
const thirtyDaysAgo = new Date();
|
||||
thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);
|
||||
|
||||
// 1. Fetch maintainers for verification
|
||||
let maintainerLogins = new Set();
|
||||
let teamFetchSucceeded = false;
|
||||
try {
|
||||
const members = await github.paginate(github.rest.teams.listMembersInOrg, {
|
||||
org: context.repo.owner,
|
||||
team_slug: 'gemini-cli-maintainers'
|
||||
});
|
||||
maintainerLogins = new Set(members.map(m => m.login.toLowerCase()));
|
||||
teamFetchSucceeded = true;
|
||||
core.info(`Successfully fetched ${maintainerLogins.size} team members from gemini-cli-maintainers`);
|
||||
} catch (e) {
|
||||
core.warning(`Failed to fetch team members from gemini-cli-maintainers: ${e.message}. Falling back to author_association only.`);
|
||||
}
|
||||
|
||||
const isMaintainer = (login, assoc) => {
|
||||
const isTeamMember = maintainerLogins.has(login.toLowerCase());
|
||||
const isRepoMaintainer = ['OWNER', 'MEMBER', 'COLLABORATOR'].includes(assoc);
|
||||
return isTeamMember || isRepoMaintainer;
|
||||
};
|
||||
|
||||
// 2. Determine which PRs to check
|
||||
let prs = [];
|
||||
if (context.eventName === 'pull_request') {
|
||||
const { data: pr } = await github.rest.pulls.get({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
pull_number: context.payload.pull_request.number
|
||||
});
|
||||
prs = [pr];
|
||||
} else {
|
||||
prs = await github.paginate(github.rest.pulls.list, {
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
state: 'open',
|
||||
per_page: 100
|
||||
});
|
||||
}
|
||||
|
||||
for (const pr of prs) {
|
||||
const maintainerPr = isMaintainer(pr.user.login, pr.author_association);
|
||||
const isBot = pr.user.type === 'Bot' || pr.user.login.endsWith('[bot]');
|
||||
|
||||
// Detection Logic for Linked Issues
|
||||
// Check 1: Official GitHub "Closing Issue" link (GraphQL)
|
||||
const linkedIssueQuery = `query($owner:String!, $repo:String!, $number:Int!) {
|
||||
repository(owner:$owner, name:$repo) {
|
||||
pullRequest(number:$number) {
|
||||
closingIssuesReferences(first: 1) { totalCount }
|
||||
}
|
||||
}
|
||||
}`;
|
||||
|
||||
let hasClosingLink = false;
|
||||
try {
|
||||
const res = await github.graphql(linkedIssueQuery, {
|
||||
owner: context.repo.owner, repo: context.repo.repo, number: pr.number
|
||||
});
|
||||
hasClosingLink = res.repository.pullRequest.closingIssuesReferences.totalCount > 0;
|
||||
} catch (e) {}
|
||||
|
||||
// Check 2: Regex for mentions (e.g., "Related to #123", "Part of #123", "#123")
|
||||
// We check for # followed by numbers or direct URLs to issues.
|
||||
const body = pr.body || '';
|
||||
const mentionRegex = /(?:#|https:\/\/github\.com\/[^\/]+\/[^\/]+\/issues\/)(\d+)/i;
|
||||
const hasMentionLink = mentionRegex.test(body);
|
||||
|
||||
const hasLinkedIssue = hasClosingLink || hasMentionLink;
|
||||
|
||||
// Logic for Closed PRs (Auto-Reopen)
|
||||
if (pr.state === 'closed' && context.eventName === 'pull_request' && context.payload.action === 'edited') {
|
||||
if (hasLinkedIssue) {
|
||||
core.info(`PR #${pr.number} now has a linked issue. Reopening.`);
|
||||
if (!dryRun) {
|
||||
await github.rest.pulls.update({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
pull_number: pr.number,
|
||||
state: 'open'
|
||||
});
|
||||
await github.rest.issues.createComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: pr.number,
|
||||
body: "Thank you for linking an issue! This pull request has been automatically reopened."
|
||||
});
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Logic for Open PRs (Immediate Closure)
|
||||
if (pr.state === 'open' && !maintainerPr && !hasLinkedIssue && !isBot) {
|
||||
core.info(`PR #${pr.number} is missing a linked issue. Closing.`);
|
||||
if (!dryRun) {
|
||||
await github.rest.issues.createComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: pr.number,
|
||||
body: "Hi there! Thank you for your contribution to Gemini CLI. \n\nTo improve our contribution process and better track changes, we now require all pull requests to be associated with an existing issue, as announced in our [recent discussion](https://github.com/google-gemini/gemini-cli/discussions/16706) and as detailed in our [CONTRIBUTING.md](https://github.com/google-gemini/gemini-cli/blob/main/CONTRIBUTING.md#1-link-to-an-existing-issue).\n\nThis pull request is being closed because it is not currently linked to an issue. **Once you have updated the description of this PR to link an issue (e.g., by adding `Fixes #123` or `Related to #123`), it will be automatically reopened.**\n\n**How to link an issue:**\nAdd a keyword followed by the issue number (e.g., `Fixes #123`) in the description of your pull request. For more details on supported keywords and how linking works, please refer to the [GitHub Documentation on linking pull requests to issues](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue).\n\nThank you for your understanding and for being a part of our community!"
|
||||
});
|
||||
await github.rest.pulls.update({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
pull_number: pr.number,
|
||||
state: 'closed'
|
||||
});
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Staleness check (Scheduled runs only)
|
||||
if (pr.state === 'open' && context.eventName !== 'pull_request') {
|
||||
const labels = pr.labels.map(l => l.name.toLowerCase());
|
||||
if (labels.includes('help wanted') || labels.includes('🔒 maintainer only')) continue;
|
||||
|
||||
// Skip PRs that were created less than 30 days ago - they cannot be stale yet
|
||||
const prCreatedAt = new Date(pr.created_at);
|
||||
if (prCreatedAt > thirtyDaysAgo) {
|
||||
const daysOld = Math.floor((Date.now() - prCreatedAt.getTime()) / (1000 * 60 * 60 * 24));
|
||||
core.info(`PR #${pr.number} was created ${daysOld} days ago. Skipping staleness check.`);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Initialize lastActivity to PR creation date (not epoch) as a safety baseline.
|
||||
// This ensures we never incorrectly mark a PR as stale due to failed activity lookups.
|
||||
let lastActivity = new Date(pr.created_at);
|
||||
try {
|
||||
const reviews = await github.paginate(github.rest.pulls.listReviews, {
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
pull_number: pr.number
|
||||
});
|
||||
for (const r of reviews) {
|
||||
if (isMaintainer(r.user.login, r.author_association)) {
|
||||
const d = new Date(r.submitted_at || r.updated_at);
|
||||
if (d > lastActivity) lastActivity = d;
|
||||
}
|
||||
}
|
||||
const comments = await github.paginate(github.rest.issues.listComments, {
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: pr.number
|
||||
});
|
||||
for (const c of comments) {
|
||||
if (isMaintainer(c.user.login, c.author_association)) {
|
||||
const d = new Date(c.updated_at);
|
||||
if (d > lastActivity) lastActivity = d;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
core.warning(`Failed to fetch reviews/comments for PR #${pr.number}: ${e.message}`);
|
||||
}
|
||||
|
||||
// For maintainer PRs, the PR creation itself counts as maintainer activity.
|
||||
// (Now redundant since we initialize to pr.created_at, but kept for clarity)
|
||||
if (maintainerPr) {
|
||||
const d = new Date(pr.created_at);
|
||||
if (d > lastActivity) lastActivity = d;
|
||||
}
|
||||
|
||||
if (lastActivity < thirtyDaysAgo) {
|
||||
core.info(`PR #${pr.number} is stale.`);
|
||||
if (!dryRun) {
|
||||
await github.rest.issues.createComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: pr.number,
|
||||
body: "Hi there! Thank you for your contribution to Gemini CLI. We really appreciate the time and effort you've put into this pull request.\n\nTo keep our backlog manageable and ensure we're focusing on current priorities, we are closing pull requests that haven't seen maintainer activity for 30 days. Currently, the team is prioritizing work associated with **🔒 maintainer only** or **help wanted** issues.\n\nIf you believe this change is still critical, please feel free to comment with updated details. Otherwise, we encourage contributors to focus on open issues labeled as **help wanted**. Thank you for your understanding!"
|
||||
});
|
||||
await github.rest.pulls.update({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
pull_number: pr.number,
|
||||
state: 'closed'
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
name: '🏷️ Issue Opened Labeler'
|
||||
|
||||
on:
|
||||
issues:
|
||||
types:
|
||||
- 'opened'
|
||||
|
||||
jobs:
|
||||
label-issue:
|
||||
runs-on: 'ubuntu-latest'
|
||||
if: |-
|
||||
${{ github.repository == 'google-gemini/gemini-cli' || github.repository == 'google-gemini/maintainers-gemini-cli' }}
|
||||
steps:
|
||||
- name: 'Generate GitHub App Token'
|
||||
id: 'generate_token'
|
||||
env:
|
||||
APP_ID: '${{ secrets.APP_ID }}'
|
||||
if: |-
|
||||
${{ env.APP_ID != '' }}
|
||||
uses: 'actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b' # ratchet:actions/create-github-app-token@v2
|
||||
with:
|
||||
app-id: '${{ secrets.APP_ID }}'
|
||||
private-key: '${{ secrets.PRIVATE_KEY }}'
|
||||
|
||||
- name: 'Add need-triage label'
|
||||
uses: 'actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea'
|
||||
with:
|
||||
github-token: '${{ steps.generate_token.outputs.token || secrets.GITHUB_TOKEN }}'
|
||||
script: |-
|
||||
const { data: issue } = await github.rest.issues.get({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: context.issue.number,
|
||||
});
|
||||
|
||||
const hasLabel = issue.labels.some(l => l.name === 'status/need-triage');
|
||||
if (!hasLabel) {
|
||||
await github.rest.issues.addLabels({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: context.issue.number,
|
||||
labels: ['status/need-triage']
|
||||
});
|
||||
} else {
|
||||
core.info('Issue already has status/need-triage label. Skipping.');
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
name: 'Label Child Issues for Project Rollup'
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: ['opened', 'edited', 'reopened']
|
||||
schedule:
|
||||
- cron: '0 * * * *' # Run every hour
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
issues: 'write'
|
||||
contents: 'read'
|
||||
|
||||
jobs:
|
||||
# Event-based: Quick reaction to new/edited issues in THIS repo
|
||||
labeler:
|
||||
if: "github.event_name == 'issues'"
|
||||
runs-on: 'ubuntu-latest'
|
||||
steps:
|
||||
- name: 'Checkout'
|
||||
uses: 'actions/checkout@v4'
|
||||
|
||||
- name: 'Setup Node.js'
|
||||
uses: 'actions/setup-node@v4'
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: 'npm'
|
||||
|
||||
- name: 'Install Dependencies'
|
||||
run: 'npm ci'
|
||||
|
||||
- name: 'Run Multi-Repo Sync Script'
|
||||
env:
|
||||
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
|
||||
run: 'node .github/scripts/sync-maintainer-labels.cjs'
|
||||
|
||||
# Scheduled/Manual: Recursive sync across multiple repos
|
||||
sync-maintainer-labels:
|
||||
if: "github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'"
|
||||
runs-on: 'ubuntu-latest'
|
||||
steps:
|
||||
- name: 'Checkout'
|
||||
uses: 'actions/checkout@v4'
|
||||
|
||||
- name: 'Setup Node.js'
|
||||
uses: 'actions/setup-node@v4'
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: 'npm'
|
||||
|
||||
- name: 'Install Dependencies'
|
||||
run: 'npm ci'
|
||||
|
||||
- name: 'Run Multi-Repo Sync Script'
|
||||
env:
|
||||
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
|
||||
run: 'node .github/scripts/sync-maintainer-labels.cjs'
|
||||
@@ -0,0 +1,174 @@
|
||||
name: 'Label Workstream Rollup'
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: ['opened', 'edited', 'reopened']
|
||||
schedule:
|
||||
- cron: '0 * * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
labeler:
|
||||
runs-on: 'ubuntu-latest'
|
||||
permissions:
|
||||
issues: 'write'
|
||||
steps:
|
||||
- name: 'Check for Parent Workstream and Apply Label'
|
||||
uses: 'actions/github-script@v7'
|
||||
with:
|
||||
script: |
|
||||
const labelToAdd = 'workstream-rollup';
|
||||
|
||||
// Allow-list of parent issue URLs
|
||||
const allowedParentUrls = [
|
||||
'https://github.com/google-gemini/gemini-cli/issues/15374',
|
||||
'https://github.com/google-gemini/gemini-cli/issues/15456',
|
||||
'https://github.com/google-gemini/gemini-cli/issues/15324',
|
||||
'https://github.com/google-gemini/gemini-cli/issues/17202',
|
||||
'https://github.com/google-gemini/gemini-cli/issues/17203'
|
||||
];
|
||||
|
||||
// Single issue processing (for event triggers)
|
||||
async function processSingleIssue(owner, repo, number) {
|
||||
const query = `
|
||||
query($owner:String!, $repo:String!, $number:Int!) {
|
||||
repository(owner:$owner, name:$repo) {
|
||||
issue(number:$number) {
|
||||
number
|
||||
parent {
|
||||
url
|
||||
parent {
|
||||
url
|
||||
parent {
|
||||
url
|
||||
parent {
|
||||
url
|
||||
parent {
|
||||
url
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
try {
|
||||
const result = await github.graphql(query, { owner, repo, number });
|
||||
|
||||
if (!result || !result.repository || !result.repository.issue) {
|
||||
console.log(`Issue #${number} not found or data missing.`);
|
||||
return;
|
||||
}
|
||||
|
||||
const issue = result.repository.issue;
|
||||
await checkAndLabel(issue, owner, repo);
|
||||
} catch (error) {
|
||||
console.error(`Failed to process issue #${number}:`, error);
|
||||
throw error; // Re-throw to be caught by main execution
|
||||
}
|
||||
}
|
||||
|
||||
// Bulk processing (for schedule/dispatch)
|
||||
async function processAllOpenIssues(owner, repo) {
|
||||
const query = `
|
||||
query($owner:String!, $repo:String!, $cursor:String) {
|
||||
repository(owner:$owner, name:$repo) {
|
||||
issues(first: 100, states: OPEN, after: $cursor) {
|
||||
pageInfo {
|
||||
hasNextPage
|
||||
endCursor
|
||||
}
|
||||
nodes {
|
||||
number
|
||||
parent {
|
||||
url
|
||||
parent {
|
||||
url
|
||||
parent {
|
||||
url
|
||||
parent {
|
||||
url
|
||||
parent {
|
||||
url
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
let hasNextPage = true;
|
||||
let cursor = null;
|
||||
|
||||
while (hasNextPage) {
|
||||
try {
|
||||
const result = await github.graphql(query, { owner, repo, cursor });
|
||||
|
||||
if (!result || !result.repository || !result.repository.issues) {
|
||||
console.error('Invalid response structure from GitHub API');
|
||||
break;
|
||||
}
|
||||
|
||||
const issues = result.repository.issues.nodes || [];
|
||||
|
||||
console.log(`Processing batch of ${issues.length} issues...`);
|
||||
for (const issue of issues) {
|
||||
await checkAndLabel(issue, owner, repo);
|
||||
}
|
||||
|
||||
hasNextPage = result.repository.issues.pageInfo.hasNextPage;
|
||||
cursor = result.repository.issues.pageInfo.endCursor;
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch issues batch:', error);
|
||||
throw error; // Re-throw to be caught by main execution
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function checkAndLabel(issue, owner, repo) {
|
||||
if (!issue || !issue.parent) return;
|
||||
|
||||
let currentParent = issue.parent;
|
||||
let tracedParents = [];
|
||||
let matched = false;
|
||||
|
||||
while (currentParent) {
|
||||
tracedParents.push(currentParent.url);
|
||||
|
||||
if (allowedParentUrls.includes(currentParent.url)) {
|
||||
console.log(`SUCCESS: Issue #${issue.number} is a descendant of ${currentParent.url}. Trace: ${tracedParents.join(' -> ')}. Adding label.`);
|
||||
await github.rest.issues.addLabels({
|
||||
owner,
|
||||
repo,
|
||||
issue_number: issue.number,
|
||||
labels: [labelToAdd]
|
||||
});
|
||||
matched = true;
|
||||
break;
|
||||
}
|
||||
currentParent = currentParent.parent;
|
||||
}
|
||||
|
||||
if (!matched && context.eventName === 'issues') {
|
||||
console.log(`Issue #${issue.number} did not match any allowed workstreams. Trace: ${tracedParents.join(' -> ') || 'None'}.`);
|
||||
}
|
||||
}
|
||||
|
||||
// Main execution
|
||||
try {
|
||||
if (context.eventName === 'issues') {
|
||||
console.log(`Processing single issue #${context.payload.issue.number}...`);
|
||||
await processSingleIssue(context.repo.owner, context.repo.repo, context.payload.issue.number);
|
||||
} else {
|
||||
console.log(`Running for event: ${context.eventName}. Processing all open issues...`);
|
||||
await processAllOpenIssues(context.repo.owner, context.repo.repo);
|
||||
}
|
||||
} catch (error) {
|
||||
core.setFailed(`Workflow failed: ${error.message}`);
|
||||
}
|
||||
@@ -12,6 +12,8 @@ on:
|
||||
|
||||
jobs:
|
||||
linkChecker:
|
||||
if: |-
|
||||
${{ github.repository == 'google-gemini/gemini-cli' }}
|
||||
runs-on: 'ubuntu-latest'
|
||||
steps:
|
||||
- uses: 'actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8' # ratchet:actions/checkout@v5
|
||||
@@ -20,4 +22,4 @@ jobs:
|
||||
id: 'lychee'
|
||||
uses: 'lycheeverse/lychee-action@885c65f3dc543b57c898c8099f4e08c8afd178a2' # ratchet: lycheeverse/lychee-action@v2.6.1
|
||||
with:
|
||||
args: '--verbose --no-progress ./**/*.md'
|
||||
args: '--verbose --no-progress --accept 200,503 ./**/*.md'
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
name: '🏷️ PR Contribution Guidelines Notifier'
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types:
|
||||
- 'opened'
|
||||
|
||||
jobs:
|
||||
notify-process-change:
|
||||
runs-on: 'ubuntu-latest'
|
||||
if: |-
|
||||
github.repository == 'google-gemini/gemini-cli' || github.repository == 'google-gemini/maintainers-gemini-cli'
|
||||
permissions:
|
||||
pull-requests: 'write'
|
||||
steps:
|
||||
- name: 'Generate GitHub App Token'
|
||||
id: 'generate_token'
|
||||
env:
|
||||
APP_ID: '${{ secrets.APP_ID }}'
|
||||
if: |-
|
||||
${{ env.APP_ID != '' }}
|
||||
uses: 'actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b' # ratchet:actions/create-github-app-token@v2
|
||||
with:
|
||||
app-id: '${{ secrets.APP_ID }}'
|
||||
private-key: '${{ secrets.PRIVATE_KEY }}'
|
||||
|
||||
- name: 'Check membership and post comment'
|
||||
uses: 'actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea'
|
||||
with:
|
||||
github-token: '${{ steps.generate_token.outputs.token || secrets.GITHUB_TOKEN }}'
|
||||
script: |-
|
||||
const org = context.repo.owner;
|
||||
const repo = context.repo.repo;
|
||||
const username = context.payload.pull_request.user.login;
|
||||
const pr_number = context.payload.pull_request.number;
|
||||
|
||||
// 1. Check if the PR author is a maintainer
|
||||
const authorAssociation = context.payload.pull_request.author_association;
|
||||
if (['OWNER', 'MEMBER', 'COLLABORATOR'].includes(authorAssociation)) {
|
||||
core.info(`${username} is a maintainer (Association: ${authorAssociation}). No notification needed.`);
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. Check if the PR is already associated with an issue
|
||||
const query = `
|
||||
query($owner:String!, $repo:String!, $number:Int!) {
|
||||
repository(owner:$owner, name:$repo) {
|
||||
pullRequest(number:$number) {
|
||||
closingIssuesReferences(first: 1) {
|
||||
totalCount
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
const variables = { owner: org, repo: repo, number: pr_number };
|
||||
const result = await github.graphql(query, variables);
|
||||
const issueCount = result.repository.pullRequest.closingIssuesReferences.totalCount;
|
||||
|
||||
if (issueCount > 0) {
|
||||
core.info(`PR #${pr_number} is already associated with an issue. No notification needed.`);
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. Post the notification comment
|
||||
core.info(`${username} is not a maintainer and PR #${pr_number} has no linked issue. Posting notification.`);
|
||||
|
||||
const comment = `
|
||||
Hi @${username}, thank you so much for your contribution to Gemini CLI! We really appreciate the time and effort you've put into this.
|
||||
|
||||
We're making some updates to our contribution process to improve how we track and review changes. Please take a moment to review our recent discussion post: [Improving Our Contribution Process & Introducing New Guidelines](https://github.com/google-gemini/gemini-cli/discussions/16706).
|
||||
|
||||
Key Update: Starting **January 26, 2026**, the Gemini CLI project will require all pull requests to be associated with an existing issue. Any pull requests not linked to an issue by that date will be automatically closed.
|
||||
|
||||
Thank you for your understanding and for being a part of our community!
|
||||
`.trim().replace(/^[ ]+/gm, '');
|
||||
|
||||
await github.rest.issues.createComment({
|
||||
owner: org,
|
||||
repo: repo,
|
||||
issue_number: pr_number,
|
||||
body: comment
|
||||
});
|
||||
@@ -132,4 +132,4 @@ jobs:
|
||||
gh issue create \
|
||||
--title 'Manual Release Failed for ${RELEASE_TAG} on $(date +'%Y-%m-%d')' \
|
||||
--body 'The manual release workflow failed. See the full run for details: ${DETAILS_URL}' \
|
||||
--label 'kind/bug,release-failure,priority/p0'
|
||||
--label 'release-failure,priority/p0'
|
||||
|
||||
@@ -31,6 +31,7 @@ on:
|
||||
|
||||
jobs:
|
||||
release:
|
||||
if: "github.repository == 'google-gemini/gemini-cli'"
|
||||
environment: "${{ github.event.inputs.environment || 'prod' }}"
|
||||
runs-on: 'ubuntu-latest'
|
||||
permissions:
|
||||
@@ -157,4 +158,4 @@ jobs:
|
||||
gh issue create \
|
||||
--title "Nightly Release Failed for ${RELEASE_TAG} on $(date +'%Y-%m-%d')" \
|
||||
--body "The nightly-release workflow failed. See the full run for details: ${DETAILS_URL}" \
|
||||
--label 'kind/bug,release-failure,priority/p0'
|
||||
--label 'release-failure,priority/p0'
|
||||
|
||||
@@ -205,7 +205,7 @@ jobs:
|
||||
gh issue create \
|
||||
--title 'Patch Release Failed for ${RELEASE_TAG} on $(date +'%Y-%m-%d')' \
|
||||
--body 'The patch-release workflow failed. See the full run for details: ${DETAILS_URL}' \
|
||||
--label 'kind/bug,release-failure,priority/p0'
|
||||
--label 'release-failure,priority/p0'
|
||||
|
||||
- name: 'Comment Success on Original PR'
|
||||
if: '${{ success() && github.event.inputs.original_pr }}'
|
||||
|
||||
@@ -261,7 +261,7 @@ jobs:
|
||||
gh issue create \
|
||||
--title 'Promote Release Failed for ${RELEASE_TAG} on $(date +'%Y-%m-%d')' \
|
||||
--body 'The promote-release workflow failed during preview publish. See the full run for details: ${DETAILS_URL}' \
|
||||
--label 'kind/bug,release-failure,priority/p0'
|
||||
--label 'release-failure,priority/p0'
|
||||
|
||||
publish-stable:
|
||||
name: 'Publish stable'
|
||||
@@ -327,7 +327,7 @@ jobs:
|
||||
gh issue create \
|
||||
--title 'Promote Release Failed for ${RELEASE_TAG} on $(date +'%Y-%m-%d')' \
|
||||
--body 'The promote-release workflow failed during stable publish. See the full run for details: ${DETAILS_URL}' \
|
||||
--label 'kind/bug,release-failure,priority/p0'
|
||||
--label 'release-failure,priority/p0'
|
||||
|
||||
nightly-pr:
|
||||
name: 'Create Nightly PR'
|
||||
@@ -403,4 +403,4 @@ jobs:
|
||||
gh issue create \
|
||||
--title 'Promote Release Failed for ${RELEASE_TAG} on $(date +'%Y-%m-%d')' \
|
||||
--body 'The promote-release workflow failed during nightly PR creation. See the full run for details: ${DETAILS_URL}' \
|
||||
--label 'kind/bug,release-failure,priority/p0'
|
||||
--label 'release-failure,priority/p0'
|
||||
|
||||
@@ -46,4 +46,4 @@ jobs:
|
||||
gh issue create \
|
||||
--title 'Sandbox Release Failed on $(date +'%Y-%m-%d')' \
|
||||
--body 'The sandbox-release workflow failed. See the full run for details: ${DETAILS_URL}' \
|
||||
--label 'kind/bug,release-failure,priority/p0'
|
||||
--label 'release-failure,priority/p0'
|
||||
|
||||
@@ -47,4 +47,4 @@ jobs:
|
||||
gh issue create \
|
||||
--title 'Smoke test failed on ${REF} @ $(date +'%Y-%m-%d')' \
|
||||
--body 'Smoke test build failed. See the full run for details: ${DETAILS_URL}' \
|
||||
--label 'kind/bug,priority/p0'
|
||||
--label 'priority/p0'
|
||||
|
||||
@@ -40,5 +40,5 @@ jobs:
|
||||
If this is still relevant, you are welcome to reopen or leave a comment. Thanks for contributing!
|
||||
days-before-stale: 60
|
||||
days-before-close: 14
|
||||
exempt-issue-labels: 'pinned,security'
|
||||
exempt-pr-labels: 'pinned,security'
|
||||
exempt-issue-labels: 'pinned,security,🔒 maintainer only,help wanted,🗓️ Public Roadmap'
|
||||
exempt-pr-labels: 'pinned,security,🔒 maintainer only,help wanted,🗓️ Public Roadmap'
|
||||
|
||||
@@ -3,11 +3,15 @@ name: 'Trigger E2E'
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
branch_ref:
|
||||
description: 'Branch to run on'
|
||||
required: true
|
||||
default: 'main'
|
||||
repo_name:
|
||||
description: 'Repository name (e.g., owner/repo)'
|
||||
required: false
|
||||
type: 'string'
|
||||
head_sha:
|
||||
description: 'SHA of the commit to test'
|
||||
required: false
|
||||
type: 'string'
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
save_repo_name:
|
||||
@@ -15,11 +19,12 @@ jobs:
|
||||
steps:
|
||||
- name: 'Save Repo name'
|
||||
env:
|
||||
# Replace with github.event.pull_request.head.repo.full_name when switched to listen on pull request events. This repo name does not contain the org which is needed for checkout.
|
||||
REPO_NAME: '${{ github.event.repository.name }}'
|
||||
REPO_NAME: '${{ github.event.inputs.repo_name || github.event.pull_request.head.repo.full_name }}'
|
||||
HEAD_SHA: '${{ github.event.inputs.head_sha || github.event.pull_request.head.sha }}'
|
||||
run: |
|
||||
mkdir -p ./pr
|
||||
echo '${{ env.REPO_NAME }}' > ./pr/repo_name
|
||||
echo '${{ env.HEAD_SHA }}' > ./pr/head_sha
|
||||
- uses: 'actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02' # ratchet:actions/upload-artifact@v4
|
||||
with:
|
||||
name: 'repo_name'
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
.gemini/*
|
||||
!.gemini/config.yaml
|
||||
!.gemini/commands/
|
||||
!.gemini/skills/
|
||||
!.gemini/settings.json
|
||||
|
||||
# Note: .gemini-clipboard/ is NOT in gitignore so Gemini can access pasted images
|
||||
|
||||
@@ -53,5 +55,9 @@ gha-creds-*.json
|
||||
|
||||
# Log files
|
||||
patch_output.log
|
||||
gemini-debug.log
|
||||
|
||||
.genkit
|
||||
.gemini-clipboard/
|
||||
.eslintcache
|
||||
evals/logs/
|
||||
|
||||
@@ -17,4 +17,7 @@ eslint.config.js
|
||||
**/generated
|
||||
gha-creds-*.json
|
||||
junit.xml
|
||||
.gemini-linters/
|
||||
Thumbs.db
|
||||
.pytest_cache
|
||||
**/SKILL.md
|
||||
|
||||
+14
-4
@@ -1,4 +1,4 @@
|
||||
# How to Contribute
|
||||
# How to contribute
|
||||
|
||||
We would love to accept your patches and contributions to this project. This
|
||||
document includes:
|
||||
@@ -41,7 +41,14 @@ This project follows
|
||||
|
||||
The process for contributing code is as follows:
|
||||
|
||||
1. **Find an issue** that you want to work on.
|
||||
1. **Find an issue** that you want to work on. If an issue is tagged as
|
||||
`🔒Maintainers only`, this means it is reserved for project maintainers. We
|
||||
will not accept pull requests related to these issues. In the near future,
|
||||
we will explicitly mark issues looking for contributions using the
|
||||
`help-wanted` label. If you believe an issue is a good candidate for
|
||||
community contribution, please leave a comment on the issue. A maintainer
|
||||
will review it and apply the `help-wanted` label if appropriate. Only
|
||||
maintainers should attempt to add the `help-wanted` label to an issue.
|
||||
2. **Fork the repository** and create a new branch.
|
||||
3. **Make your changes** in the `packages/` directory.
|
||||
4. **Ensure all checks pass** by running `npm run preflight`.
|
||||
@@ -92,8 +99,11 @@ any code is written.
|
||||
- **For features:** The PR should be linked to the feature request or proposal
|
||||
issue that has been approved by a maintainer.
|
||||
|
||||
If an issue for your change doesn't exist, please **open one first** and wait
|
||||
for feedback before you start coding.
|
||||
If an issue for your change doesn't exist, we will automatically close your PR
|
||||
along with a comment reminding you to associate the PR with an issue. The ideal
|
||||
workflow starts with an issue that has been reviewed and approved by a
|
||||
maintainer. Please **open the issue first** and wait for feedback before you
|
||||
start coding.
|
||||
|
||||
#### 2. Keep it small and focused
|
||||
|
||||
|
||||
@@ -1,374 +1,79 @@
|
||||
## Building and running
|
||||
|
||||
Before submitting any changes, it is crucial to validate them by running the
|
||||
full preflight check. This command will build the repository, run all tests,
|
||||
check for type errors, and lint the code.
|
||||
|
||||
To run the full suite of checks, execute the following command:
|
||||
|
||||
```bash
|
||||
npm run preflight
|
||||
```
|
||||
|
||||
This single command ensures that your changes meet all the quality gates of the
|
||||
project. While you can run the individual steps (`build`, `test`, `typecheck`,
|
||||
`lint`) separately, it is highly recommended to use `npm run preflight` to
|
||||
ensure a comprehensive validation.
|
||||
|
||||
## Writing Tests
|
||||
|
||||
This project uses **Vitest** as its primary testing framework. When writing
|
||||
tests, aim to follow existing patterns. Key conventions include:
|
||||
|
||||
### Test Structure and Framework
|
||||
|
||||
- **Framework**: All tests are written using Vitest (`describe`, `it`, `expect`,
|
||||
`vi`).
|
||||
- **File Location**: Test files (`*.test.ts` for logic, `*.test.tsx` for React
|
||||
components) are co-located with the source files they test.
|
||||
- **Configuration**: Test environments are defined in `vitest.config.ts` files.
|
||||
- **Setup/Teardown**: Use `beforeEach` and `afterEach`. Commonly,
|
||||
`vi.resetAllMocks()` is called in `beforeEach` and `vi.restoreAllMocks()` in
|
||||
`afterEach`.
|
||||
|
||||
### Mocking (`vi` from Vitest)
|
||||
|
||||
- **ES Modules**: Mock with
|
||||
`vi.mock('module-name', async (importOriginal) => { ... })`. Use
|
||||
`importOriginal` for selective mocking.
|
||||
- _Example_:
|
||||
`vi.mock('os', async (importOriginal) => { const actual = await importOriginal(); return { ...actual, homedir: vi.fn() }; });`
|
||||
- **Mocking Order**: For critical dependencies (e.g., `os`, `fs`) that affect
|
||||
module-level constants, place `vi.mock` at the _very top_ of the test file,
|
||||
before other imports.
|
||||
- **Hoisting**: Use `const myMock = vi.hoisted(() => vi.fn());` if a mock
|
||||
function needs to be defined before its use in a `vi.mock` factory.
|
||||
- **Mock Functions**: Create with `vi.fn()`. Define behavior with
|
||||
`mockImplementation()`, `mockResolvedValue()`, or `mockRejectedValue()`.
|
||||
- **Spying**: Use `vi.spyOn(object, 'methodName')`. Restore spies with
|
||||
`mockRestore()` in `afterEach`.
|
||||
|
||||
### Commonly Mocked Modules
|
||||
|
||||
- **Node.js built-ins**: `fs`, `fs/promises`, `os` (especially `os.homedir()`),
|
||||
`path`, `child_process` (`execSync`, `spawn`).
|
||||
- **External SDKs**: `@google/genai`, `@modelcontextprotocol/sdk`.
|
||||
- **Internal Project Modules**: Dependencies from other project packages are
|
||||
often mocked.
|
||||
|
||||
### React Component Testing (CLI UI - Ink)
|
||||
|
||||
- Use `render()` from `ink-testing-library`.
|
||||
- Assert output with `lastFrame()`.
|
||||
- Wrap components in necessary `Context.Provider`s.
|
||||
- Mock custom React hooks and complex child components using `vi.mock()`.
|
||||
|
||||
### Asynchronous Testing
|
||||
|
||||
- Use `async/await`.
|
||||
- For timers, use `vi.useFakeTimers()`, `vi.advanceTimersByTimeAsync()`,
|
||||
`vi.runAllTimersAsync()`.
|
||||
- Test promise rejections with `await expect(promise).rejects.toThrow(...)`.
|
||||
|
||||
### General Guidance
|
||||
|
||||
- When adding tests, first examine existing tests to understand and conform to
|
||||
established conventions.
|
||||
- Pay close attention to the mocks at the top of existing test files; they
|
||||
reveal critical dependencies and how they are managed in a test environment.
|
||||
|
||||
## Git Repo
|
||||
|
||||
The main branch for this project is called "main"
|
||||
|
||||
## JavaScript/TypeScript
|
||||
|
||||
When contributing to this React, Node, and TypeScript codebase, please
|
||||
prioritize the use of plain JavaScript objects with accompanying TypeScript
|
||||
interface or type declarations over JavaScript class syntax. This approach
|
||||
offers significant advantages, especially concerning interoperability with React
|
||||
and overall code maintainability.
|
||||
|
||||
### Preferring Plain Objects over Classes
|
||||
|
||||
JavaScript classes, by their nature, are designed to encapsulate internal state
|
||||
and behavior. While this can be useful in some object-oriented paradigms, it
|
||||
often introduces unnecessary complexity and friction when working with React's
|
||||
component-based architecture. Here's why plain objects are preferred:
|
||||
|
||||
- Seamless React Integration: React components thrive on explicit props and
|
||||
state management. Classes' tendency to store internal state directly within
|
||||
instances can make prop and state propagation harder to reason about and
|
||||
maintain. Plain objects, on the other hand, are inherently immutable (when
|
||||
used thoughtfully) and can be easily passed as props, simplifying data flow
|
||||
and reducing unexpected side effects.
|
||||
|
||||
- Reduced Boilerplate and Increased Conciseness: Classes often promote the use
|
||||
of constructors, this binding, getters, setters, and other boilerplate that
|
||||
can unnecessarily bloat code. TypeScript interface and type declarations
|
||||
provide powerful static type checking without the runtime overhead or
|
||||
verbosity of class definitions. This allows for more succinct and readable
|
||||
code, aligning with JavaScript's strengths in functional programming.
|
||||
|
||||
- Enhanced Readability and Predictability: Plain objects, especially when their
|
||||
structure is clearly defined by TypeScript interfaces, are often easier to
|
||||
read and understand. Their properties are directly accessible, and there's no
|
||||
hidden internal state or complex inheritance chains to navigate. This
|
||||
predictability leads to fewer bugs and a more maintainable codebase.
|
||||
|
||||
- Simplified Immutability: While not strictly enforced, plain objects encourage
|
||||
an immutable approach to data. When you need to modify an object, you
|
||||
typically create a new one with the desired changes, rather than mutating the
|
||||
original. This pattern aligns perfectly with React's reconciliation process
|
||||
and helps prevent subtle bugs related to shared mutable state.
|
||||
|
||||
- Better Serialization and Deserialization: Plain JavaScript objects are
|
||||
naturally easy to serialize to JSON and deserialize back, which is a common
|
||||
requirement in web development (e.g., for API communication or local storage).
|
||||
Classes, with their methods and prototypes, can complicate this process.
|
||||
|
||||
### Embracing ES Module Syntax for Encapsulation
|
||||
|
||||
Rather than relying on Java-esque private or public class members, which can be
|
||||
verbose and sometimes limit flexibility, we strongly prefer leveraging ES module
|
||||
syntax (`import`/`export`) for encapsulating private and public APIs.
|
||||
|
||||
- Clearer Public API Definition: With ES modules, anything that is exported is
|
||||
part of the public API of that module, while anything not exported is
|
||||
inherently private to that module. This provides a very clear and explicit way
|
||||
to define what parts of your code are meant to be consumed by other modules.
|
||||
|
||||
- Enhanced Testability (Without Exposing Internals): By default, unexported
|
||||
functions or variables are not accessible from outside the module. This
|
||||
encourages you to test the public API of your modules, rather than their
|
||||
internal implementation details. If you find yourself needing to spy on or
|
||||
stub an unexported function for testing purposes, it's often a "code smell"
|
||||
indicating that the function might be a good candidate for extraction into its
|
||||
own separate, testable module with a well-defined public API. This promotes a
|
||||
more robust and maintainable testing strategy.
|
||||
|
||||
- Reduced Coupling: Explicitly defined module boundaries through import/export
|
||||
help reduce coupling between different parts of your codebase. This makes it
|
||||
easier to refactor, debug, and understand individual components in isolation.
|
||||
|
||||
### Avoiding `any` Types and Type Assertions; Preferring `unknown`
|
||||
|
||||
TypeScript's power lies in its ability to provide static type checking, catching
|
||||
potential errors before your code runs. To fully leverage this, it's crucial to
|
||||
avoid the `any` type and be judicious with type assertions.
|
||||
|
||||
- **The Dangers of `any`**: Using any effectively opts out of TypeScript's type
|
||||
checking for that particular variable or expression. While it might seem
|
||||
convenient in the short term, it introduces significant risks:
|
||||
- **Loss of Type Safety**: You lose all the benefits of type checking, making
|
||||
it easy to introduce runtime errors that TypeScript would otherwise have
|
||||
caught.
|
||||
- **Reduced Readability and Maintainability**: Code with `any` types is harder
|
||||
to understand and maintain, as the expected type of data is no longer
|
||||
explicitly defined.
|
||||
- **Masking Underlying Issues**: Often, the need for any indicates a deeper
|
||||
problem in the design of your code or the way you're interacting with
|
||||
external libraries. It's a sign that you might need to refine your types or
|
||||
refactor your code.
|
||||
|
||||
- **Preferring `unknown` over `any`**: When you absolutely cannot determine the
|
||||
type of a value at compile time, and you're tempted to reach for any, consider
|
||||
using unknown instead. unknown is a type-safe counterpart to any. While a
|
||||
variable of type unknown can hold any value, you must perform type narrowing
|
||||
(e.g., using typeof or instanceof checks, or a type assertion) before you can
|
||||
perform any operations on it. This forces you to handle the unknown type
|
||||
explicitly, preventing accidental runtime errors.
|
||||
|
||||
```ts
|
||||
function processValue(value: unknown) {
|
||||
if (typeof value === 'string') {
|
||||
// value is now safely a string
|
||||
console.log(value.toUpperCase());
|
||||
} else if (typeof value === 'number') {
|
||||
// value is now safely a number
|
||||
console.log(value * 2);
|
||||
}
|
||||
// Without narrowing, you cannot access properties or methods on 'value'
|
||||
// console.log(value.someProperty); // Error: Object is of type 'unknown'.
|
||||
}
|
||||
```
|
||||
|
||||
- **Type Assertions (`as Type`) - Use with Caution**: Type assertions tell the
|
||||
TypeScript compiler, "Trust me, I know what I'm doing; this is definitely of
|
||||
this type." While there are legitimate use cases (e.g., when dealing with
|
||||
external libraries that don't have perfect type definitions, or when you have
|
||||
more information than the compiler), they should be used sparingly and with
|
||||
extreme caution.
|
||||
- **Bypassing Type Checking**: Like `any`, type assertions bypass TypeScript's
|
||||
safety checks. If your assertion is incorrect, you introduce a runtime error
|
||||
that TypeScript would not have warned you about.
|
||||
- **Code Smell in Testing**: A common scenario where `any` or type assertions
|
||||
might be tempting is when trying to test "private" implementation details
|
||||
(e.g., spying on or stubbing an unexported function within a module). This
|
||||
is a strong indication of a "code smell" in your testing strategy and
|
||||
potentially your code structure. Instead of trying to force access to
|
||||
private internals, consider whether those internal details should be
|
||||
refactored into a separate module with a well-defined public API. This makes
|
||||
them inherently testable without compromising encapsulation.
|
||||
|
||||
### Type narrowing `switch` clauses
|
||||
|
||||
Use the `checkExhaustive` helper in the default clause of a switch statement.
|
||||
This will ensure that all of the possible options within the value or
|
||||
enumeration are used.
|
||||
|
||||
This helper method can be found in `packages/cli/src/utils/checks.ts`
|
||||
|
||||
### Embracing JavaScript's Array Operators
|
||||
|
||||
To further enhance code cleanliness and promote safe functional programming
|
||||
practices, leverage JavaScript's rich set of array operators as much as
|
||||
possible. Methods like `.map()`, `.filter()`, `.reduce()`, `.slice()`,
|
||||
`.sort()`, and others are incredibly powerful for transforming and manipulating
|
||||
data collections in an immutable and declarative way.
|
||||
|
||||
Using these operators:
|
||||
|
||||
- Promotes Immutability: Most array operators return new arrays, leaving the
|
||||
original array untouched. This functional approach helps prevent unintended
|
||||
side effects and makes your code more predictable.
|
||||
- Improves Readability: Chaining array operators often lead to more concise and
|
||||
expressive code than traditional for loops or imperative logic. The intent of
|
||||
the operation is clear at a glance.
|
||||
- Facilitates Functional Programming: These operators are cornerstones of
|
||||
functional programming, encouraging the creation of pure functions that take
|
||||
inputs and produce outputs without causing side effects. This paradigm is
|
||||
highly beneficial for writing robust and testable code that pairs well with
|
||||
React.
|
||||
|
||||
By consistently applying these principles, we can maintain a codebase that is
|
||||
not only efficient and performant but also a joy to work with, both now and in
|
||||
the future.
|
||||
|
||||
## React (mirrored and adjusted from [react-mcp-server](https://github.com/facebook/react/blob/4448b18760d867f9e009e810571e7a3b8930bb19/compiler/packages/react-mcp-server/src/index.ts#L376C1-L441C94))
|
||||
|
||||
### Role
|
||||
|
||||
You are a React assistant that helps users write more efficient and optimizable
|
||||
React code. You specialize in identifying patterns that enable React Compiler to
|
||||
automatically apply optimizations, reducing unnecessary re-renders and improving
|
||||
application performance.
|
||||
|
||||
### Follow these guidelines in all code you produce and suggest
|
||||
|
||||
Use functional components with Hooks: Do not generate class components or use
|
||||
old lifecycle methods. Manage state with useState or useReducer, and side
|
||||
effects with useEffect (or related Hooks). Always prefer functions and Hooks for
|
||||
any new component logic.
|
||||
|
||||
Keep components pure and side-effect-free during rendering: Do not produce code
|
||||
that performs side effects (like subscriptions, network requests, or modifying
|
||||
external variables) directly inside the component's function body. Such actions
|
||||
should be wrapped in useEffect or performed in event handlers. Ensure your
|
||||
render logic is a pure function of props and state.
|
||||
|
||||
Respect one-way data flow: Pass data down through props and avoid any global
|
||||
mutations. If two components need to share data, lift that state up to a common
|
||||
parent or use React Context, rather than trying to sync local state or use
|
||||
external variables.
|
||||
|
||||
Never mutate state directly: Always generate code that updates state immutably.
|
||||
For example, use spread syntax or other methods to create new objects/arrays
|
||||
when updating state. Do not use assignments like state.someValue = ... or array
|
||||
mutations like array.push() on state variables. Use the state setter (setState
|
||||
from useState, etc.) to update state.
|
||||
|
||||
Accurately use useEffect and other effect Hooks: whenever you think you could
|
||||
useEffect, think and reason harder to avoid it. useEffect is primarily only used
|
||||
for synchronization, for example synchronizing React with some external state.
|
||||
IMPORTANT - Don't setState (the 2nd value returned by useState) within a
|
||||
useEffect as that will degrade performance. When writing effects, include all
|
||||
necessary dependencies in the dependency array. Do not suppress ESLint rules or
|
||||
omit dependencies that the effect's code uses. Structure the effect callbacks to
|
||||
handle changing values properly (e.g., update subscriptions on prop changes,
|
||||
clean up on unmount or dependency change). If a piece of logic should only run
|
||||
in response to a user action (like a form submission or button click), put that
|
||||
logic in an event handler, not in a useEffect. Where possible, useEffects should
|
||||
return a cleanup function.
|
||||
|
||||
Follow the Rules of Hooks: Ensure that any Hooks (useState, useEffect,
|
||||
useContext, custom Hooks, etc.) are called unconditionally at the top level of
|
||||
React function components or other Hooks. Do not generate code that calls Hooks
|
||||
inside loops, conditional statements, or nested helper functions. Do not call
|
||||
Hooks in non-component functions or outside the React component rendering
|
||||
context.
|
||||
|
||||
Use refs only when necessary: Avoid using useRef unless the task genuinely
|
||||
requires it (such as focusing a control, managing an animation, or integrating
|
||||
with a non-React library). Do not use refs to store application state that
|
||||
should be reactive. If you do use refs, never write to or read from ref.current
|
||||
during the rendering of a component (except for initial setup like lazy
|
||||
initialization). Any ref usage should not affect the rendered output directly.
|
||||
|
||||
Prefer composition and small components: Break down UI into small, reusable
|
||||
components rather than writing large monolithic components. The code you
|
||||
generate should promote clarity and reusability by composing components
|
||||
together. Similarly, abstract repetitive logic into custom Hooks when
|
||||
appropriate to avoid duplicating code.
|
||||
|
||||
Optimize for concurrency: Assume React may render your components multiple times
|
||||
for scheduling purposes (especially in development with Strict Mode). Write code
|
||||
that remains correct even if the component function runs more than once. For
|
||||
instance, avoid side effects in the component body and use functional state
|
||||
updates (e.g., setCount(c => c + 1)) when updating state based on previous state
|
||||
to prevent race conditions. Always include cleanup functions in effects that
|
||||
subscribe to external resources. Don't write useEffects for "do this when this
|
||||
changes" side effects. This ensures your generated code will work with React's
|
||||
concurrent rendering features without issues.
|
||||
|
||||
Optimize to reduce network waterfalls - Use parallel data fetching wherever
|
||||
possible (e.g., start multiple requests at once rather than one after another).
|
||||
Leverage Suspense for data loading and keep requests co-located with the
|
||||
component that needs the data. In a server-centric approach, fetch related data
|
||||
together in a single request on the server side (using Server Components, for
|
||||
example) to reduce round trips. Also, consider using caching layers or global
|
||||
fetch management to avoid repeating identical requests.
|
||||
|
||||
Rely on React Compiler - useMemo, useCallback, and React.memo can be omitted if
|
||||
React Compiler is enabled. Avoid premature optimization with manual memoization.
|
||||
Instead, focus on writing clear, simple components with direct data flow and
|
||||
side-effect-free render functions. Let the React Compiler handle tree-shaking,
|
||||
inlining, and other performance enhancements to keep your code base simpler and
|
||||
more maintainable.
|
||||
|
||||
Design for a good user experience - Provide clear, minimal, and non-blocking UI
|
||||
states. When data is loading, show lightweight placeholders (e.g., skeleton
|
||||
screens) rather than intrusive spinners everywhere. Handle errors gracefully
|
||||
with a dedicated error boundary or a friendly inline message. Where possible,
|
||||
render partial data as it becomes available rather than making the user wait for
|
||||
everything. Suspense allows you to declare the loading states in your component
|
||||
tree in a natural way, preventing “flash” states and improving perceived
|
||||
performance.
|
||||
|
||||
### Process
|
||||
|
||||
1. Analyze the user's code for optimization opportunities:
|
||||
- Check for React anti-patterns that prevent compiler optimization
|
||||
- Look for component structure issues that limit compiler effectiveness
|
||||
- Think about each suggestion you are making and consult React docs for best
|
||||
practices
|
||||
|
||||
2. Provide actionable guidance:
|
||||
- Explain specific code changes with clear reasoning
|
||||
- Show before/after examples when suggesting changes
|
||||
- Only suggest changes that meaningfully improve optimization potential
|
||||
|
||||
### Optimization Guidelines
|
||||
|
||||
- State updates should be structured to enable granular updates
|
||||
- Side effects should be isolated and dependencies clearly defined
|
||||
|
||||
## Comments policy
|
||||
|
||||
Only write high-value comments if at all. Avoid talking to the user through
|
||||
comments.
|
||||
|
||||
## General style requirements
|
||||
|
||||
Use hyphens instead of underscores in flag names (e.g. `my-flag` instead of
|
||||
`my_flag`).
|
||||
# Gemini CLI Project Context
|
||||
|
||||
Gemini CLI is an open-source AI agent that brings the power of Gemini directly
|
||||
into the terminal. It is designed to be a terminal-first, extensible, and
|
||||
powerful tool for developers.
|
||||
|
||||
## Project Overview
|
||||
|
||||
- **Purpose:** Provide a seamless terminal interface for Gemini models,
|
||||
supporting code understanding, generation, automation, and integration via MCP
|
||||
(Model Context Protocol).
|
||||
- **Main Technologies:**
|
||||
- **Runtime:** Node.js (>=20.0.0, recommended ~20.19.0 for development)
|
||||
- **Language:** TypeScript
|
||||
- **UI Framework:** React (using [Ink](https://github.com/vadimdemedes/ink)
|
||||
for CLI rendering)
|
||||
- **Testing:** Vitest
|
||||
- **Bundling:** esbuild
|
||||
- **Linting/Formatting:** ESLint, Prettier
|
||||
- **Architecture:** Monorepo structure using npm workspaces.
|
||||
- `packages/cli`: User-facing terminal UI, input processing, and display
|
||||
rendering.
|
||||
- `packages/core`: Backend logic, Gemini API orchestration, prompt
|
||||
construction, and tool execution.
|
||||
- `packages/core/src/tools/`: Built-in tools for file system, shell, and web
|
||||
operations.
|
||||
- `packages/a2a-server`: Experimental Agent-to-Agent server.
|
||||
- `packages/vscode-ide-companion`: VS Code extension pairing with the CLI.
|
||||
|
||||
## Building and Running
|
||||
|
||||
- **Install Dependencies:** `npm install`
|
||||
- **Build All:** `npm run build:all` (Builds packages, sandbox, and VS Code
|
||||
companion)
|
||||
- **Build Packages:** `npm run build`
|
||||
- **Run in Development:** `npm run start`
|
||||
- **Run in Debug Mode:** `npm run debug` (Enables Node.js inspector)
|
||||
- **Bundle Project:** `npm run bundle`
|
||||
- **Clean Artifacts:** `npm run clean`
|
||||
|
||||
## Testing and Quality
|
||||
|
||||
- **Test Commands:**
|
||||
- **Unit (All):** `npm run test`
|
||||
- **Integration (E2E):** `npm run test:e2e`
|
||||
- **Workspace-Specific:** `npm test -w <pkg> -- <path>` (Note: `<path>` must
|
||||
be relative to the workspace root, e.g.,
|
||||
`-w @google/gemini-cli-core -- src/routing/modelRouterService.test.ts`)
|
||||
- **Full Validation:** `npm run preflight` (Heaviest check; runs clean, install,
|
||||
build, lint, type check, and tests. Recommended before submitting PRs.)
|
||||
- **Individual Checks:** `npm run lint` / `npm run format` / `npm run typecheck`
|
||||
|
||||
## Development Conventions
|
||||
|
||||
- **Contributions:** Follow the process outlined in `CONTRIBUTING.md`. Requires
|
||||
signing the Google CLA.
|
||||
- **Pull Requests:** Keep PRs small, focused, and linked to an existing issue.
|
||||
- **Commit Messages:** Follow the
|
||||
[Conventional Commits](https://www.conventionalcommits.org/) standard.
|
||||
- **Coding Style:** Adhere to existing patterns in `packages/cli` (React/Ink)
|
||||
and `packages/core` (Backend logic).
|
||||
- **Imports:** Use specific imports and avoid restricted relative imports
|
||||
between packages (enforced by ESLint).
|
||||
|
||||
## Testing Conventions
|
||||
|
||||
- **Environment Variables:** When testing code that depends on environment
|
||||
variables, use `vi.stubEnv('NAME', 'value')` in `beforeEach` and
|
||||
`vi.unstubAllEnvs()` in `afterEach`. Avoid modifying `process.env` directly as
|
||||
it can lead to test leakage and is less reliable. To "unset" a variable, use
|
||||
an empty string `vi.stubEnv('NAME', '')`.
|
||||
|
||||
## Documentation
|
||||
|
||||
- Always use the `docs-writer` skill when you are asked to write, edit, or
|
||||
review any documentation.
|
||||
- Documentation is located in the `docs/` directory.
|
||||
- Suggest documentation updates when code changes render existing documentation
|
||||
obsolete or incomplete.
|
||||
|
||||
@@ -187,7 +187,7 @@
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2025 Google LLC
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# Gemini CLI
|
||||
|
||||
[](https://github.com/google-gemini/gemini-cli/actions/workflows/ci.yml)
|
||||
[](https://github.com/google-gemini/gemini-cli/actions/workflows/e2e.yml)
|
||||
[](https://github.com/google-gemini/gemini-cli/actions/workflows/chained_e2e.yml)
|
||||
[](https://www.npmjs.com/package/@google/gemini-cli)
|
||||
[](https://github.com/google-gemini/gemini-cli/blob/main/LICENSE)
|
||||
<a href="https://codewiki.google/github.com/google-gemini/gemini-cli"><img src="https://www.gstatic.com/_/boq-sdlc-agents-ui/_/r/Mvosg4klCA4.svg" alt="Ask Code Wiki" height="20"></a>
|
||||
[](https://codewiki.google/github.com/google-gemini/gemini-cli?utm_source=badge&utm_medium=github&utm_campaign=github.com/google-gemini/gemini-cli)
|
||||
|
||||

|
||||
|
||||
@@ -18,7 +18,8 @@ Learn all about Gemini CLI in our [documentation](https://geminicli.com/docs/).
|
||||
|
||||
- **🎯 Free tier**: 60 requests/min and 1,000 requests/day with personal Google
|
||||
account.
|
||||
- **🧠 Powerful Gemini 2.5 Pro**: Access to 1M token context window.
|
||||
- **🧠 Powerful Gemini 3 models**: Access to improved reasoning and 1M token
|
||||
context window.
|
||||
- **🔧 Built-in tools**: Google Search grounding, file operations, shell
|
||||
commands, web fetching.
|
||||
- **🔌 Extensible**: MCP (Model Context Protocol) support for custom
|
||||
@@ -39,7 +40,7 @@ Learn all about Gemini CLI in our [documentation](https://geminicli.com/docs/).
|
||||
|
||||
```bash
|
||||
# Using npx (no installation required)
|
||||
npx https://github.com/google-gemini/gemini-cli
|
||||
npx @google/gemini-cli
|
||||
```
|
||||
|
||||
#### Install globally with npm
|
||||
@@ -54,6 +55,23 @@ npm install -g @google/gemini-cli
|
||||
brew install gemini-cli
|
||||
```
|
||||
|
||||
#### Install globally with MacPorts (macOS)
|
||||
|
||||
```bash
|
||||
sudo port install gemini-cli
|
||||
```
|
||||
|
||||
#### Install with Anaconda (for restricted environments)
|
||||
|
||||
```bash
|
||||
# Create and activate a new environment
|
||||
conda create -y -n gemini_env -c conda-forge nodejs
|
||||
conda activate gemini_env
|
||||
|
||||
# Install Gemini CLI globally via npm (inside the environment)
|
||||
npm install -g @google/gemini-cli
|
||||
```
|
||||
|
||||
## Release Cadence and Tags
|
||||
|
||||
See [Releases](./docs/releases.md) for more details.
|
||||
@@ -80,9 +98,9 @@ npm install -g @google/gemini-cli@latest
|
||||
|
||||
### Nightly
|
||||
|
||||
- New releases will be published each week at UTC 0000 each day, This will be
|
||||
all changes from the main branch as represented at time of release. It should
|
||||
be assumed there are pending validations and issues. Use `nightly` tag.
|
||||
- New releases will be published each day at UTC 0000. This will be all changes
|
||||
from the main branch as represented at time of release. It should be assumed
|
||||
there are pending validations and issues. Use `nightly` tag.
|
||||
|
||||
```bash
|
||||
npm install -g @google/gemini-cli@nightly
|
||||
@@ -106,6 +124,8 @@ npm install -g @google/gemini-cli@nightly
|
||||
|
||||
### Advanced Capabilities
|
||||
|
||||
- **Automated Iterative Loops**: Use [Ralph Wiggum mode](./docs/ralph-wiggum.md)
|
||||
to repeatedly execute prompts until a goal is met (e.g., fixing tests).
|
||||
- Ground your queries with built-in
|
||||
[Google Search](https://ai.google.dev/gemini-api/docs/grounding) for real-time
|
||||
information
|
||||
@@ -140,7 +160,7 @@ for details)
|
||||
**Benefits:**
|
||||
|
||||
- **Free tier**: 60 requests/min and 1,000 requests/day
|
||||
- **Gemini 2.5 Pro** with 1M token context window
|
||||
- **Gemini 3 models** with 1M token context window
|
||||
- **No API key management** - just sign in with your Google account
|
||||
- **Automatic updates** to latest models
|
||||
|
||||
@@ -164,7 +184,7 @@ gemini
|
||||
|
||||
**Benefits:**
|
||||
|
||||
- **Free tier**: 100 requests/day with Gemini 2.5 Pro
|
||||
- **Free tier**: 1000 requests/day with Gemini 3 (mix of flash and pro)
|
||||
- **Model selection**: Choose specific Gemini models
|
||||
- **Usage-based billing**: Upgrade for higher limits when needed
|
||||
|
||||
@@ -238,6 +258,33 @@ use `--output-format stream-json` to get newline-delimited JSON events:
|
||||
gemini -p "Run tests and deploy" --output-format stream-json
|
||||
```
|
||||
|
||||
### Ralph Wiggum Mode (Iterative Automation)
|
||||
|
||||
Ralph Wiggum mode is an advanced automation feature that allows Gemini CLI to
|
||||
repeatedly execute a prompt in a loop until a specific goal is achieved. This is
|
||||
ideal for tasks like fixing failing tests or complex refactoring.
|
||||
|
||||
To use Ralph Wiggum mode, provide a prompt and a **completion promise** (a
|
||||
string to look for in the output). The CLI will:
|
||||
|
||||
1. Enter **YOLO mode** to auto-approve all tool calls.
|
||||
2. Run the prompt and check the response for your completion string.
|
||||
3. If not found, it repeats the process up to a specified **max iterations**.
|
||||
4. **Persistent Context**: It uses a **memory file** (`memories.md` by default)
|
||||
to pass notes between iterations. **Note:** Use a unique `--memory-file` for
|
||||
different tasks in the same directory to ensure context isolation.
|
||||
|
||||
```bash
|
||||
gemini -p "Fix the failing tests in this repo" \
|
||||
--ralph-wiggum \
|
||||
--completion-promise "ALL TESTS PASSED" \
|
||||
--max-iterations 5 \
|
||||
--memory-file "task-fix-tests.md"
|
||||
```
|
||||
|
||||
At the end of the run, a summary table displays the result of each iteration and
|
||||
extracted test statistics.
|
||||
|
||||
### Quick Examples
|
||||
|
||||
#### Start a new project
|
||||
|
||||
@@ -13,11 +13,11 @@ input:
|
||||
as handling the initial user input, presenting the final output, and
|
||||
managing the overall user experience.
|
||||
- **Key functions contained in the package:**
|
||||
- [Input processing](/docs/cli/commands.md)
|
||||
- [Input processing](/docs/cli/commands)
|
||||
- History management
|
||||
- Display rendering
|
||||
- [Theme and UI customization](/docs/cli/themes.md)
|
||||
- [CLI configuration settings](/docs/get-started/configuration.md)
|
||||
- [Theme and UI customization](/docs/cli/themes)
|
||||
- [CLI configuration settings](/docs/get-started/configuration)
|
||||
|
||||
2. **Core package (`packages/core`):**
|
||||
- **Purpose:** This acts as the backend for the Gemini CLI. It receives
|
||||
@@ -37,7 +37,7 @@ input:
|
||||
- **Interaction:** `packages/core` invokes these tools based on requests
|
||||
from the Gemini model.
|
||||
|
||||
## Interaction Flow
|
||||
## Interaction flow
|
||||
|
||||
A typical interaction with the Gemini CLI follows this flow:
|
||||
|
||||
@@ -69,7 +69,7 @@ A typical interaction with the Gemini CLI follows this flow:
|
||||
7. **Display to user:** The CLI package formats and displays the response to
|
||||
the user in the terminal.
|
||||
|
||||
## Key Design Principles
|
||||
## Key design principles
|
||||
|
||||
- **Modularity:** Separating the CLI (frontend) from the Core (backend) allows
|
||||
for independent development and potential future extensions (e.g., different
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 350 KiB After Width: | Height: | Size: 60 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 110 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 58 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 54 KiB |
+285
-18
@@ -1,15 +1,282 @@
|
||||
# Gemini CLI Changelog
|
||||
# Gemini CLI release notes
|
||||
|
||||
Wondering what's new in Gemini CLI? This document provides key highlights and
|
||||
notable changes to Gemini CLI.
|
||||
Gemini CLI has three major release channels: nightly, preview, and stable. For
|
||||
most users, we recommend the stable release.
|
||||
|
||||
## v0.15.0 - Gemini CLI weekly update - 2025-11-03
|
||||
On this page, you can find information regarding the current releases and
|
||||
announcements from each release.
|
||||
|
||||
- **🎉 Seamless scrollable UI & mouse support:** We’ve given Gemini CLI a major
|
||||
facelift to make your terminal experience smoother and much more polished. You
|
||||
now get a flicker-free display with sticky headers that keep important context
|
||||
visible and a stable input prompt that doesn't jump around. We even added
|
||||
mouse support so you can click right where you need to type!
|
||||
For the full changelog, refer to
|
||||
[Releases - google-gemini/gemini-cli](https://github.com/google-gemini/gemini-cli/releases)
|
||||
on GitHub.
|
||||
|
||||
## Current releases
|
||||
|
||||
| Release channel | Notes |
|
||||
| :-------------------- | :---------------------------------------------- |
|
||||
| Nightly | Nightly release with the most recent changes. |
|
||||
| [Preview](preview.md) | Experimental features ready for early feedback. |
|
||||
| [Stable](latest.md) | Stable, recommended for general use. |
|
||||
|
||||
## Announcements: v0.26.0 - 2026-01-27
|
||||
|
||||
- **Agents and Skills:** We've introduced a new `skill-creator` skill
|
||||
([#16394](https://github.com/google-gemini/gemini-cli/pull/16394) by
|
||||
@NTaylorMullen), enabled agent skills by default, and added a generalist agent
|
||||
to improve task routing
|
||||
([#16638](https://github.com/google-gemini/gemini-cli/pull/16638) by
|
||||
@joshualitt).
|
||||
- **UI/UX Improvements:** You can now "Rewind" through your conversation history
|
||||
([#15717](https://github.com/google-gemini/gemini-cli/pull/15717) by @Adib234)
|
||||
and use a new `/introspect` command for debugging.
|
||||
- **Core and Scheduler Refactoring:** The core scheduler has been significantly
|
||||
refactored to improve performance and reliability
|
||||
([#16895](https://github.com/google-gemini/gemini-cli/pull/16895) by
|
||||
@abhipatel12), and numerous performance and stability fixes have been
|
||||
included.
|
||||
|
||||
## Announcements: v0.25.0 - 2026-01-20
|
||||
|
||||
- **Skills and Agents Improvements:** We've enhanced the `activate_skill` tool,
|
||||
added a new `pr-creator` skill
|
||||
([#16232](https://github.com/google-gemini/gemini-cli/pull/16232) by
|
||||
[@NTaylorMullen](https://github.com/NTaylorMullen)), enabled skills by
|
||||
default, improved the `cli_help` agent
|
||||
([#16100](https://github.com/google-gemini/gemini-cli/pull/16100) by
|
||||
[@scidomino](https://github.com/scidomino)), and added a new `/agents refresh`
|
||||
command ([#16204](https://github.com/google-gemini/gemini-cli/pull/16204) by
|
||||
[@joshualitt](https://github.com/joshualitt)).
|
||||
- **UI/UX Refinements:** You'll notice more transparent feedback for skills
|
||||
([#15954](https://github.com/google-gemini/gemini-cli/pull/15954) by
|
||||
[@NTaylorMullen](https://github.com/NTaylorMullen)), the ability to switch
|
||||
focus between the shell and input with Tab
|
||||
([#14332](https://github.com/google-gemini/gemini-cli/pull/14332) by
|
||||
[@jacob314](https://github.com/jacob314)), and dynamic terminal tab titles
|
||||
([#16378](https://github.com/google-gemini/gemini-cli/pull/16378) by
|
||||
[@NTaylorMullen](https://github.com/NTaylorMullen)).
|
||||
- **Core Functionality & Performance:** This release includes support for
|
||||
built-in agent skills
|
||||
([#16045](https://github.com/google-gemini/gemini-cli/pull/16045) by
|
||||
[@NTaylorMullen](https://github.com/NTaylorMullen)), refined Gemini 3 system
|
||||
instructions ([#16139](https://github.com/google-gemini/gemini-cli/pull/16139)
|
||||
by [@NTaylorMullen](https://github.com/NTaylorMullen)), caching for ignore
|
||||
instances to improve performance
|
||||
([#16185](https://github.com/google-gemini/gemini-cli/pull/16185) by
|
||||
[@EricRahm](https://github.com/EricRahm)), and enhanced retry mechanisms
|
||||
([#16489](https://github.com/google-gemini/gemini-cli/pull/16489) by
|
||||
[@sehoon38](https://github.com/sehoon38)).
|
||||
- **Bug Fixes and Stability:** We've squashed numerous bugs across the CLI,
|
||||
core, and workflows, addressing issues with subagent delegation, unicode
|
||||
character crashes, and sticky header regressions.
|
||||
|
||||
## Announcements: v0.24.0 - 2026-01-14
|
||||
|
||||
- **Agent Skills:** We've introduced significant advancements in Agent Skills.
|
||||
This includes initial documentation and tutorials to help you get started,
|
||||
alongside enhanced support for remote agents, allowing for more distributed
|
||||
and powerful automation within Gemini CLI.
|
||||
([#15869](https://github.com/google-gemini/gemini-cli/pull/15869) by
|
||||
[@NTaylorMullen](https://github.com/NTaylorMullen)),
|
||||
([#16013](https://github.com/google-gemini/gemini-cli/pull/16013) by
|
||||
[@adamweidman](https://github.com/adamweidman))
|
||||
- **Improved UI/UX:** The user interface has received several updates, featuring
|
||||
visual indicators for hook execution, a more refined display for settings, and
|
||||
the ability to use the Tab key to effortlessly switch focus between the shell
|
||||
and input areas.
|
||||
([#15408](https://github.com/google-gemini/gemini-cli/pull/15408) by
|
||||
[@abhipatel12](https://github.com/abhipatel12)),
|
||||
([#14332](https://github.com/google-gemini/gemini-cli/pull/14332) by
|
||||
[@galz10](https://github.com/galz10))
|
||||
- **Enhanced Security:** Security has been a major focus, with default folder
|
||||
trust now set to untrusted for increased safety. The Policy Engine has been
|
||||
improved to allow specific modes in user and administrator policies, and
|
||||
granular allowlisting for shell commands has been implemented, providing finer
|
||||
control over tool execution.
|
||||
([#15943](https://github.com/google-gemini/gemini-cli/pull/15943) by
|
||||
[@galz10](https://github.com/galz10)),
|
||||
([#15977](https://github.com/google-gemini/gemini-cli/pull/15977) by
|
||||
[@NTaylorMullen](https://github.com/NTaylorMullen))
|
||||
- **Core Functionality:** This release includes a mandatory MessageBus
|
||||
injection, marking Phase 3 of a hard migration to a more robust internal
|
||||
communication system. We've also added support for built-in skills with the
|
||||
CLI itself, and enhanced model routing to effectively utilize subagents.
|
||||
([#15776](https://github.com/google-gemini/gemini-cli/pull/15776) by
|
||||
[@abhipatel12](https://github.com/abhipatel12)),
|
||||
([#16300](https://github.com/google-gemini/gemini-cli/pull/16300) by
|
||||
[@NTaylorMullen](https://github.com/NTaylorMullen))
|
||||
- **Terminal Features:** Terminal interactions are more seamless with new
|
||||
features like OSC 52 paste support, along with fixes for Windows clipboard
|
||||
paste issues and general improvements to pasting in Windows terminals.
|
||||
([#15336](https://github.com/google-gemini/gemini-cli/pull/15336) by
|
||||
[@scidomino](https://github.com/scidomino)),
|
||||
([#15932](https://github.com/google-gemini/gemini-cli/pull/15932) by
|
||||
[@scidomino](https://github.com/scidomino))
|
||||
- **New Commands:** To manage the new features, we've added several new
|
||||
commands: `/agents refresh` to update agent configurations, `/skills reload`
|
||||
to refresh skill definitions, and `/skills install/uninstall` for easier
|
||||
management of your Agent Skills.
|
||||
([#16204](https://github.com/google-gemini/gemini-cli/pull/16204) by
|
||||
[@NTaylorMullen](https://github.com/NTaylorMullen)),
|
||||
([#15865](https://github.com/google-gemini/gemini-cli/pull/15865) by
|
||||
[@NTaylorMullen](https://github.com/NTaylorMullen)),
|
||||
([#16377](https://github.com/google-gemini/gemini-cli/pull/16377) by
|
||||
[@NTaylorMullen](https://github.com/NTaylorMullen))
|
||||
|
||||
## Announcements: v0.23.0 - 2026-01-07
|
||||
|
||||
- 🎉 **Experimental Agent Skills Support in Preview:** Gemini CLI now supports
|
||||
[Agent Skills](https://agentskills.io/home) in our preview builds. This is an
|
||||
early preview where we’re looking for feedback!
|
||||
- Install Preview: `npm install -g @google/gemini-cli@preview`
|
||||
- Enable in `/settings`
|
||||
- Docs:
|
||||
[https://geminicli.com/docs/cli/skills/](https://geminicli.com/docs/cli/skills/)
|
||||
- **Gemini CLI wrapped:** Run `npx gemini-wrapped` to visualize your usage
|
||||
stats, top models, languages, and more!
|
||||
- **Windows clipboard image support:** Windows users can now paste images
|
||||
directly from their clipboard into the CLI using `Alt`+`V`.
|
||||
([pr](https://github.com/google-gemini/gemini-cli/pull/13997) by
|
||||
[@sgeraldes](https://github.com/sgeraldes))
|
||||
- **Terminal background color detection:** Automatically optimizes your
|
||||
terminal's background color to select compatible themes and provide
|
||||
accessibility warnings.
|
||||
([pr](https://github.com/google-gemini/gemini-cli/pull/15132) by
|
||||
[@jacob314](https://github.com/jacob314))
|
||||
- **Session logout:** Use the new `/logout` command to instantly clear
|
||||
credentials and reset your authentication state for seamless account
|
||||
switching. ([pr](https://github.com/google-gemini/gemini-cli/pull/13383) by
|
||||
[@CN-Scars](https://github.com/CN-Scars))
|
||||
|
||||
## Announcements: v0.22.0 - 2025-12-22
|
||||
|
||||
- 🎉**Free Tier + Gemini 3:** Free tier users now all have access to Gemini 3
|
||||
Pro & Flash. Enable in `/settings` by toggling "Preview Features" to `true`.
|
||||
- 🎉**Gemini CLI + Colab:** Gemini CLI is now pre-installed. Can be used
|
||||
headlessly in notebook cells or interactively in the built-in terminal
|
||||
([pic](https://imgur.com/a/G0Tn7vi))
|
||||
- 🎉**Gemini CLI Extensions:**
|
||||
- **Conductor:** Planning++, Gemini works with you to build out a detailed
|
||||
plan, pull in extra details as needed, ultimately to give the LLM guardrails
|
||||
with artifacts. Measure twice, implement once!
|
||||
|
||||
`gemini extensions install https://github.com/gemini-cli-extensions/conductor`
|
||||
|
||||
Blog:
|
||||
[https://developers.googleblog.com/conductor-introducing-context-driven-development-for-gemini-cli/](https://developers.googleblog.com/conductor-introducing-context-driven-development-for-gemini-cli/)
|
||||
|
||||
- **Endor Labs:** Perform code analysis, vulnerability scanning, and
|
||||
dependency checks using natural language.
|
||||
|
||||
`gemini extensions install https://github.com/endorlabs/gemini-extension`
|
||||
|
||||
## Announcements: v0.21.0 - 2025-12-15
|
||||
|
||||
- **⚡️⚡️⚡️ Gemini 3 Flash + Gemini CLI:** Better, faster and cheaper than 2.5
|
||||
Pro - and in some scenarios better than 3 Pro! For paid tiers + free tier
|
||||
users who were on the wait list enable **Preview Features** in `/settings.`
|
||||
- For more information:
|
||||
[Gemini 3 Flash is now available in Gemini CLI](https://developers.googleblog.com/gemini-3-flash-is-now-available-in-gemini-cli/).
|
||||
- 🎉 Gemini CLI Extensions:
|
||||
- Rill: Utilize natural language to analyze Rill data, enabling the
|
||||
exploration of metrics and trends without the need for manual queries.
|
||||
`gemini extensions install https://github.com/rilldata/rill-gemini-extension`
|
||||
- Browserbase: Interact with web pages, take screenshots, extract information,
|
||||
and perform automated actions with atomic precision.
|
||||
`gemini extensions install https://github.com/browserbase/mcp-server-browserbase`
|
||||
- Quota Visibility: The `/stats` command now displays quota information for all
|
||||
available models, including those not used in the current session. (@sehoon38)
|
||||
- Fuzzy Setting Search: Users can now quickly find settings using fuzzy search
|
||||
within the settings dialog. (@sehoon38)
|
||||
- MCP Resource Support: Users can now discover, view, and search through
|
||||
resources using the @ command. (@MrLesk)
|
||||
- Auto-execute Simple Slash Commands: Simple slash commands are now executed
|
||||
immediately on enter. (@jackwotherspoon)
|
||||
|
||||
## Announcements: v0.20.0 - 2025-12-01
|
||||
|
||||
- **Multi-file Drag & Drop:** Users can now drag and drop multiple files into
|
||||
the terminal, and the CLI will automatically prefix each valid path with `@`.
|
||||
([pr](https://github.com/google-gemini/gemini-cli/pull/14832) by
|
||||
[@jackwotherspoon](https://github.com/jackwotherspoon))
|
||||
- **Persistent "Always Allow" Policies:** Users can now save "Always Allow"
|
||||
decisions for tool executions, with granular control over specific shell
|
||||
commands and multi-cloud platform tools.
|
||||
([pr](https://github.com/google-gemini/gemini-cli/pull/14737) by
|
||||
[@allenhutchison](https://github.com/allenhutchison))
|
||||
|
||||
## Announcements: v0.19.0 - 2025-11-24
|
||||
|
||||
- 🎉 **New extensions:**
|
||||
- **Eleven Labs:** Create, play, manage your audio play tracks with the Eleven
|
||||
Labs Gemini CLI extension:
|
||||
`gemini extensions install https://github.com/elevenlabs/elevenlabs-mcp`
|
||||
- **Zed integration:** Users can now leverage Gemini 3 within the Zed
|
||||
integration after enabling "Preview Features" in their CLI’s `/settings`.
|
||||
([pr](https://github.com/google-gemini/gemini-cli/pull/13398) by
|
||||
[@benbrandt](https://github.com/benbrandt))
|
||||
- **Interactive shell:**
|
||||
- **Click-to-Focus:** When "Use Alternate Buffer" setting is enabled, users
|
||||
can click within the embedded shell output to focus it for input.
|
||||
([pr](https://github.com/google-gemini/gemini-cli/pull/13341) by
|
||||
[@galz10](https://github.com/galz10))
|
||||
- **Loading phrase:** Clearly indicates when the interactive shell is awaiting
|
||||
user input. ([vid](https://imgur.com/a/kjK8bUK),
|
||||
[pr](https://github.com/google-gemini/gemini-cli/pull/12535) by
|
||||
[@jackwotherspoon](https://github.com/jackwotherspoon))
|
||||
|
||||
## Announcements: v0.18.0 - 2025-11-17
|
||||
|
||||
- 🎉 **New extensions:**
|
||||
- **Google Workspace**: Integrate Gemini CLI with your Workspace data. Write
|
||||
docs, build slides, chat with others or even get your calc on in sheets:
|
||||
`gemini extensions install https://github.com/gemini-cli-extensions/workspace`
|
||||
- Blog:
|
||||
[https://allen.hutchison.org/2025/11/19/bringing-the-office-to-the-terminal/](https://allen.hutchison.org/2025/11/19/bringing-the-office-to-the-terminal/)
|
||||
- **Redis:** Manage and search data in Redis with natural language:
|
||||
`gemini extensions install https://github.com/redis/mcp-redis`
|
||||
- **Anomalo:** Query your data warehouse table metadata and quality status
|
||||
through commands and natural language:
|
||||
`gemini extensions install https://github.com/datagravity-ai/anomalo-gemini-extension`
|
||||
- **Experimental permission improvements:** We are now experimenting with a new
|
||||
policy engine in Gemini CLI. This allows users and administrators to create
|
||||
fine-grained policy for tool calls. Currently behind a flag. See
|
||||
[policy engine documentation](../core/policy-engine.md) for more information.
|
||||
- Blog:
|
||||
[https://allen.hutchison.org/2025/11/26/the-guardrails-of-autonomy/](https://allen.hutchison.org/2025/11/26/the-guardrails-of-autonomy/)
|
||||
- **Gemini 3 support for paid:** Gemini 3 support has been rolled out to all API
|
||||
key, Google AI Pro or Google AI Ultra (for individuals, not businesses) and
|
||||
Gemini Code Assist Enterprise users. Enable it via `/settings` and toggling on
|
||||
**Preview Features**.
|
||||
- **Updated UI rollback:** We’ve temporarily rolled back our updated UI to give
|
||||
it more time to bake. This means for a time you won’t have embedded scrolling
|
||||
or mouse support. You can re-enable with `/settings` -> **Use Alternate Screen
|
||||
Buffer** -> `true`.
|
||||
- **Model in history:** Users can now toggle in `/settings` to display model in
|
||||
their chat history. ([gif](https://imgur.com/a/uEmNKnQ),
|
||||
[pr](https://github.com/google-gemini/gemini-cli/pull/13034) by
|
||||
[@scidomino](https://github.com/scidomino))
|
||||
- **Multi-uninstall:** Users can now uninstall multiple extensions with a single
|
||||
command. ([pic](https://imgur.com/a/9Dtq8u2),
|
||||
[pr](https://github.com/google-gemini/gemini-cli/pull/13016) by
|
||||
[@JayadityaGit](https://github.com/JayadityaGit))
|
||||
|
||||
## Announcements: v0.16.0 - 2025-11-10
|
||||
|
||||
- **Gemini 3 + Gemini CLI:** launch 🚀🚀🚀
|
||||
- **Data Commons Gemini CLI Extension** - A new Data Commons Gemini CLI
|
||||
extension that lets you query open-source statistical data from
|
||||
datacommons.org. **To get started, you'll need a Data Commons API key and uv
|
||||
installed**. These and other details to get you started with the extension can
|
||||
be found at
|
||||
[https://github.com/gemini-cli-extensions/datacommons](https://github.com/gemini-cli-extensions/datacommons).
|
||||
|
||||
## Announcements: v0.15.0 - 2025-11-03
|
||||
|
||||
- **🎉 Seamless scrollable UI and mouse support:** We’ve given Gemini CLI a
|
||||
major facelift to make your terminal experience smoother and much more
|
||||
polished. You now get a flicker-free display with sticky headers that keep
|
||||
important context visible and a stable input prompt that doesn't jump around.
|
||||
We even added mouse support so you can click right where you need to type!
|
||||
([gif](https://imgur.com/a/O6qc7bx),
|
||||
[@jacob314](https://github.com/jacob314)).
|
||||
- **Announcement:**
|
||||
@@ -49,7 +316,7 @@ notable changes to Gemini CLI.
|
||||
correctly. ([pr](https://github.com/google-gemini/gemini-cli/pull/12186) by
|
||||
[@kevinjwang1](https://github.com/kevinjwang1)).
|
||||
|
||||
## v0.12.0 - Gemini CLI weekly update - 2025-10-27
|
||||
## Announcements: v0.12.0 - 2025-10-27
|
||||
|
||||

|
||||
|
||||
@@ -112,7 +379,7 @@ notable changes to Gemini CLI.
|
||||
([pr](https://github.com/google-gemini/gemini-cli/pull/11593) by
|
||||
[@joshualitt](https://github.com/joshualitt)).
|
||||
|
||||
## v0.11.0 - Gemini CLI weekly update - 2025-10-20
|
||||
## Announcements: v0.11.0 - 2025-10-20
|
||||
|
||||

|
||||
|
||||
@@ -155,7 +422,7 @@ notable changes to Gemini CLI.
|
||||
([pr](https://github.com/google-gemini/gemini-cli/pull/11318) by
|
||||
[@allenhutchison](https://github.com/allenhutchison))
|
||||
|
||||
## v0.10.0 - Gemini CLI weekly update - 2025-10-13
|
||||
## Announcements: v0.10.0 - 2025-10-13
|
||||
|
||||
- **Polish:** The team has been heads down bug fixing and investing heavily into
|
||||
polishing existing flows, tools, and interactions.
|
||||
@@ -172,7 +439,7 @@ notable changes to Gemini CLI.
|
||||
([pr](https://github.com/google-gemini/gemini-cli/pull/10819) by
|
||||
[@jerop](https://github.com/jerop)).
|
||||
|
||||
## v0.9.0 - Gemini CLI weekly update - 2025-10-06
|
||||
## Announcements: v0.9.0 - 2025-10-06
|
||||
|
||||
- 🎉 **Interactive Shell:** Run interactive commands like `vim`, `rebase -i`, or
|
||||
even `gemini` 😎 directly in Gemini CLI:
|
||||
@@ -197,7 +464,7 @@ notable changes to Gemini CLI.
|
||||
([pr](https://github.com/google-gemini/gemini-cli/pull/10108) by
|
||||
[@sgnagnarella](https://github.com/sgnagnarella))
|
||||
|
||||
## v0.8.0 - Gemini CLI weekly update - 2025-09-29
|
||||
## Announcements: v0.8.0 - 2025-09-29
|
||||
|
||||
- 🎉 **Announcing Gemini CLI Extensions** 🎉
|
||||
- Completely customize your Gemini CLI experience to fit your workflow.
|
||||
@@ -236,7 +503,7 @@ notable changes to Gemini CLI.
|
||||
changes, smaller features, UI updates, reliability and bug fixes + general
|
||||
polish made it in this week!
|
||||
|
||||
## v0.7.0 - Gemini CLI weekly update - 2025-09-22
|
||||
## Announcements: v0.7.0 - 2025-09-22
|
||||
|
||||
- 🎉**Build your own Gemini CLI IDE plugin:** We've published a spec for
|
||||
creating IDE plugins to enable rich context-aware experiences and native
|
||||
@@ -274,7 +541,7 @@ notable changes to Gemini CLI.
|
||||
changes, smaller features, UI updates, reliability and bug fixes + general
|
||||
polish made it in this week!
|
||||
|
||||
## v0.6.0 - Gemini CLI weekly update - 2025-09-15
|
||||
## Announcements: v0.6.0 - 2025-09-15
|
||||
|
||||
- 🎉 **Higher limits for Google AI Pro and Ultra subscribers:** We’re psyched to
|
||||
finally announce that Google AI Pro and AI Ultra subscribers now get access to
|
||||
@@ -355,7 +622,7 @@ notable changes to Gemini CLI.
|
||||
changes, smaller features, UI updates, reliability and bug fixes + general
|
||||
polish made it in this week!
|
||||
|
||||
## v0.5.0 - Gemini CLI weekly update - 2025-09-08
|
||||
## Announcements: v0.5.0 - 2025-09-08
|
||||
|
||||
- 🎉**FastMCP + Gemini CLI**🎉: Quickly install and manage your Gemini CLI MCP
|
||||
servers with FastMCP ([video](https://imgur.com/a/m8QdCPh),
|
||||
@@ -400,7 +667,7 @@ notable changes to Gemini CLI.
|
||||
changes, smaller features, UI updates, reliability and bug fixes + general
|
||||
polish made it in this week!
|
||||
|
||||
## v0.4.0 - Gemini CLI weekly update - 2025-09-01
|
||||
## Announcements: v0.4.0 - 2025-09-01
|
||||
|
||||
- 🎉**Gemini CLI CloudRun and Security Integrations**🎉: Automate app deployment
|
||||
and security analysis with CloudRun and Security extension integrations. Once
|
||||
|
||||
@@ -0,0 +1,338 @@
|
||||
# Latest stable release: v0.26.0
|
||||
|
||||
Released: January 27, 2026
|
||||
|
||||
For most users, our latest stable release is the recommended release. Install
|
||||
the latest stable version with:
|
||||
|
||||
```
|
||||
npm install -g @google/gemini-cli
|
||||
```
|
||||
|
||||
## Highlights
|
||||
|
||||
- **Enhanced Agent and Skill Capabilities:** This release introduces the new
|
||||
`skill-creator` built-in skill, enables Agent Skills by default, and adds a
|
||||
generalist agent to improve task routing. Security for skill installation has
|
||||
also been enhanced with new consent prompts.
|
||||
- **Improved UI and UX:** A new "Rewind" feature lets you walk back through
|
||||
conversation history. We've also added an `/introspect` command for debugging
|
||||
and unified various shell confirmation dialogs for a more consistent user
|
||||
experience.
|
||||
- **Core Stability and Performance:** This release includes significant
|
||||
performance improvements, including a fix for PDF token estimation,
|
||||
optimizations for large inputs, and prevention of OOM crashes. Key memory
|
||||
management components like `LRUCache` have also been updated.
|
||||
- **Scheduler and Policy Refactoring:** The core tool scheduler has been
|
||||
decoupled into distinct orchestration, policy, and confirmation components,
|
||||
and we've added an experimental event-driven scheduler to improve performance
|
||||
and reliability.
|
||||
|
||||
## What's Changed
|
||||
|
||||
- fix: PDF token estimation (#16494) by @korade-krushna in
|
||||
[#16527](https://github.com/google-gemini/gemini-cli/pull/16527)
|
||||
- chore(release): bump version to 0.26.0-nightly.20260114.bb6c57414 by
|
||||
@gemini-cli-robot in
|
||||
[#16604](https://github.com/google-gemini/gemini-cli/pull/16604)
|
||||
- docs: clarify F12 to open debug console by @jackwotherspoon in
|
||||
[#16570](https://github.com/google-gemini/gemini-cli/pull/16570)
|
||||
- docs: Remove .md extension from internal links in architecture.md by
|
||||
@medic-code in
|
||||
[#12899](https://github.com/google-gemini/gemini-cli/pull/12899)
|
||||
- Add an experimental setting for extension config by @chrstnb in
|
||||
[#16506](https://github.com/google-gemini/gemini-cli/pull/16506)
|
||||
- feat: add Rewind Confirmation dialog and Rewind Viewer component by @Adib234
|
||||
in [#15717](https://github.com/google-gemini/gemini-cli/pull/15717)
|
||||
- fix(a2a): Don't throw errors for GeminiEventType Retry and InvalidStream. by
|
||||
@ehedlund in [#16541](https://github.com/google-gemini/gemini-cli/pull/16541)
|
||||
- prefactor: add rootCommands as array so it can be used for policy parsing by
|
||||
@abhipatel12 in
|
||||
[#16640](https://github.com/google-gemini/gemini-cli/pull/16640)
|
||||
- remove unnecessary \x7f key bindings by @scidomino in
|
||||
[#16646](https://github.com/google-gemini/gemini-cli/pull/16646)
|
||||
- docs(skills): use body-file in pr-creator skill for better reliability by
|
||||
@abhipatel12 in
|
||||
[#16642](https://github.com/google-gemini/gemini-cli/pull/16642)
|
||||
- chore(automation): recursive labeling for workstream descendants by @bdmorgan
|
||||
in [#16609](https://github.com/google-gemini/gemini-cli/pull/16609)
|
||||
- feat: introduce 'skill-creator' built-in skill and CJS management tools by
|
||||
@NTaylorMullen in
|
||||
[#16394](https://github.com/google-gemini/gemini-cli/pull/16394)
|
||||
- chore(automation): remove automated PR size and complexity labeler by
|
||||
@bdmorgan in [#16648](https://github.com/google-gemini/gemini-cli/pull/16648)
|
||||
- refactor(skills): replace 'project' with 'workspace' scope by @NTaylorMullen
|
||||
in [#16380](https://github.com/google-gemini/gemini-cli/pull/16380)
|
||||
- Docs: Update release notes for 1/13/2026 by @jkcinouye in
|
||||
[#16583](https://github.com/google-gemini/gemini-cli/pull/16583)
|
||||
- Simplify paste handling by @scidomino in
|
||||
[#16654](https://github.com/google-gemini/gemini-cli/pull/16654)
|
||||
- chore(automation): improve scheduled issue triage discovery and throughput by
|
||||
@bdmorgan in [#16652](https://github.com/google-gemini/gemini-cli/pull/16652)
|
||||
- fix(acp): run exit cleanup when stdin closes by @codefromthecrypt in
|
||||
[#14953](https://github.com/google-gemini/gemini-cli/pull/14953)
|
||||
- feat(scheduler): add types needed for event driven scheduler by @abhipatel12
|
||||
in [#16641](https://github.com/google-gemini/gemini-cli/pull/16641)
|
||||
- Remove unused rewind key binding by @scidomino in
|
||||
[#16659](https://github.com/google-gemini/gemini-cli/pull/16659)
|
||||
- Remove sequence binding by @scidomino in
|
||||
[#16664](https://github.com/google-gemini/gemini-cli/pull/16664)
|
||||
- feat(cli): undeprecate the --prompt flag by @alexaustin007 in
|
||||
[#13981](https://github.com/google-gemini/gemini-cli/pull/13981)
|
||||
- chore: update dependabot configuration by @cosmopax in
|
||||
[#13507](https://github.com/google-gemini/gemini-cli/pull/13507)
|
||||
- feat(config): add 'auto' alias for default model selection by @sehoon38 in
|
||||
[#16661](https://github.com/google-gemini/gemini-cli/pull/16661)
|
||||
- Enable & disable agents by @sehoon38 in
|
||||
[#16225](https://github.com/google-gemini/gemini-cli/pull/16225)
|
||||
- cleanup: Improve keybindings by @scidomino in
|
||||
[#16672](https://github.com/google-gemini/gemini-cli/pull/16672)
|
||||
- Add timeout for shell-utils to prevent hangs. by @jacob314 in
|
||||
[#16667](https://github.com/google-gemini/gemini-cli/pull/16667)
|
||||
- feat(plan): add experimental plan flag by @jerop in
|
||||
[#16650](https://github.com/google-gemini/gemini-cli/pull/16650)
|
||||
- feat(cli): add security consent prompts for skill installation by
|
||||
@NTaylorMullen in
|
||||
[#16549](https://github.com/google-gemini/gemini-cli/pull/16549)
|
||||
- fix: replace 3 consecutive periods with ellipsis character by @Vist233 in
|
||||
[#16587](https://github.com/google-gemini/gemini-cli/pull/16587)
|
||||
- chore(automation): ensure status/need-triage is applied and never cleared
|
||||
automatically by @bdmorgan in
|
||||
[#16657](https://github.com/google-gemini/gemini-cli/pull/16657)
|
||||
- fix: Handle colons in skill description frontmatter by @maru0804 in
|
||||
[#16345](https://github.com/google-gemini/gemini-cli/pull/16345)
|
||||
- refactor(core): harden skill frontmatter parsing by @NTaylorMullen in
|
||||
[#16705](https://github.com/google-gemini/gemini-cli/pull/16705)
|
||||
- feat(skills): add conflict detection and warnings for skill overrides by
|
||||
@NTaylorMullen in
|
||||
[#16709](https://github.com/google-gemini/gemini-cli/pull/16709)
|
||||
- feat(scheduler): add SchedulerStateManager for reactive tool state by
|
||||
@abhipatel12 in
|
||||
[#16651](https://github.com/google-gemini/gemini-cli/pull/16651)
|
||||
- chore(automation): enforce 'help wanted' label permissions and update
|
||||
guidelines by @bdmorgan in
|
||||
[#16707](https://github.com/google-gemini/gemini-cli/pull/16707)
|
||||
- fix(core): resolve circular dependency via tsconfig paths by @sehoon38 in
|
||||
[#16730](https://github.com/google-gemini/gemini-cli/pull/16730)
|
||||
- chore/release: bump version to 0.26.0-nightly.20260115.6cb3ae4e0 by
|
||||
@gemini-cli-robot in
|
||||
[#16738](https://github.com/google-gemini/gemini-cli/pull/16738)
|
||||
- fix(automation): correct status/need-issue label matching wildcard by
|
||||
@bdmorgan in [#16727](https://github.com/google-gemini/gemini-cli/pull/16727)
|
||||
- fix(automation): prevent label-enforcer loop by ignoring all bots by @bdmorgan
|
||||
in [#16746](https://github.com/google-gemini/gemini-cli/pull/16746)
|
||||
- Add links to supported locations and minor fixes by @g-samroberts in
|
||||
[#16476](https://github.com/google-gemini/gemini-cli/pull/16476)
|
||||
- feat(policy): add source tracking to policy rules by @allenhutchison in
|
||||
[#16670](https://github.com/google-gemini/gemini-cli/pull/16670)
|
||||
- feat(automation): enforce '🔒 maintainer only' and fix bot loop by @bdmorgan
|
||||
in [#16751](https://github.com/google-gemini/gemini-cli/pull/16751)
|
||||
- Make merged settings non-nullable and fix all lints related to that. by
|
||||
@jacob314 in [#16647](https://github.com/google-gemini/gemini-cli/pull/16647)
|
||||
- fix(core): prevent ModelInfo event emission on aborted signal by @sehoon38 in
|
||||
[#16752](https://github.com/google-gemini/gemini-cli/pull/16752)
|
||||
- Replace relative paths to fix website build by @chrstnb in
|
||||
[#16755](https://github.com/google-gemini/gemini-cli/pull/16755)
|
||||
- Restricting to localhost by @cocosheng-g in
|
||||
[#16548](https://github.com/google-gemini/gemini-cli/pull/16548)
|
||||
- fix(cli): add explicit dependency on color-convert by @sehoon38 in
|
||||
[#16757](https://github.com/google-gemini/gemini-cli/pull/16757)
|
||||
- fix(automation): robust label enforcement with permission checks by @bdmorgan
|
||||
in [#16762](https://github.com/google-gemini/gemini-cli/pull/16762)
|
||||
- fix(cli): prevent OOM crash by limiting file search traversal and adding
|
||||
timeout by @galz10 in
|
||||
[#16696](https://github.com/google-gemini/gemini-cli/pull/16696)
|
||||
- fix(cli): safely handle /dev/tty access on macOS by @korade-krushna in
|
||||
[#16531](https://github.com/google-gemini/gemini-cli/pull/16531)
|
||||
- docs: clarify workspace test execution in GEMINI.md by @mattKorwel in
|
||||
[#16764](https://github.com/google-gemini/gemini-cli/pull/16764)
|
||||
- Add support for running available commands prior to MCP servers loading by
|
||||
@Adib234 in [#15596](https://github.com/google-gemini/gemini-cli/pull/15596)
|
||||
- feat(plan): add experimental 'plan' approval mode by @jerop in
|
||||
[#16753](https://github.com/google-gemini/gemini-cli/pull/16753)
|
||||
- feat(scheduler): add functional awaitConfirmation utility by @abhipatel12 in
|
||||
[#16721](https://github.com/google-gemini/gemini-cli/pull/16721)
|
||||
- fix(infra): update maintainer rollup label to 'workstream-rollup' by @bdmorgan
|
||||
in [#16809](https://github.com/google-gemini/gemini-cli/pull/16809)
|
||||
- fix(infra): use GraphQL to detect direct parents in rollup workflow by
|
||||
@bdmorgan in [#16811](https://github.com/google-gemini/gemini-cli/pull/16811)
|
||||
- chore(workflows): rename label-workstream-rollup workflow by @bdmorgan in
|
||||
[#16818](https://github.com/google-gemini/gemini-cli/pull/16818)
|
||||
- skip simple-mcp-server.test.ts by @scidomino in
|
||||
[#16842](https://github.com/google-gemini/gemini-cli/pull/16842)
|
||||
- Steer outer agent to use expert subagents when present by @gundermanc in
|
||||
[#16763](https://github.com/google-gemini/gemini-cli/pull/16763)
|
||||
- Fix race condition by awaiting scheduleToolCalls by @chrstnb in
|
||||
[#16759](https://github.com/google-gemini/gemini-cli/pull/16759)
|
||||
- cleanup: Organize key bindings by @scidomino in
|
||||
[#16798](https://github.com/google-gemini/gemini-cli/pull/16798)
|
||||
- feat(core): Add generalist agent. by @joshualitt in
|
||||
[#16638](https://github.com/google-gemini/gemini-cli/pull/16638)
|
||||
- perf(ui): optimize text buffer and highlighting for large inputs by
|
||||
@NTaylorMullen in
|
||||
[#16782](https://github.com/google-gemini/gemini-cli/pull/16782)
|
||||
- fix(core): fix PTY descriptor shell leak by @galz10 in
|
||||
[#16773](https://github.com/google-gemini/gemini-cli/pull/16773)
|
||||
- feat(plan): enforce strict read-only policy and halt execution on violation by
|
||||
@jerop in [#16849](https://github.com/google-gemini/gemini-cli/pull/16849)
|
||||
- remove need-triage label from bug_report template by @sehoon38 in
|
||||
[#16864](https://github.com/google-gemini/gemini-cli/pull/16864)
|
||||
- fix(core): truncate large telemetry log entries by @sehoon38 in
|
||||
[#16769](https://github.com/google-gemini/gemini-cli/pull/16769)
|
||||
- docs(extensions): add Agent Skills support and mark feature as experimental by
|
||||
@NTaylorMullen in
|
||||
[#16859](https://github.com/google-gemini/gemini-cli/pull/16859)
|
||||
- fix(core): surface warnings for invalid hook event names in configuration
|
||||
(#16788) by @sehoon38 in
|
||||
[#16873](https://github.com/google-gemini/gemini-cli/pull/16873)
|
||||
- feat(plan): remove read_many_files from approval mode policies by @jerop in
|
||||
[#16876](https://github.com/google-gemini/gemini-cli/pull/16876)
|
||||
- feat(admin): implement admin controls polling and restart prompt by @skeshive
|
||||
in [#16627](https://github.com/google-gemini/gemini-cli/pull/16627)
|
||||
- Remove LRUCache class migrating to mnemoist by @jacob314 in
|
||||
[#16872](https://github.com/google-gemini/gemini-cli/pull/16872)
|
||||
- feat(settings): rename negative settings to positive naming (disable* ->
|
||||
enable*) by @afarber in
|
||||
[#14142](https://github.com/google-gemini/gemini-cli/pull/14142)
|
||||
- refactor(cli): unify shell confirmation dialogs by @NTaylorMullen in
|
||||
[#16828](https://github.com/google-gemini/gemini-cli/pull/16828)
|
||||
- feat(agent): enable agent skills by default by @NTaylorMullen in
|
||||
[#16736](https://github.com/google-gemini/gemini-cli/pull/16736)
|
||||
- refactor(core): foundational truncation refactoring and token estimation
|
||||
optimization by @NTaylorMullen in
|
||||
[#16824](https://github.com/google-gemini/gemini-cli/pull/16824)
|
||||
- fix(hooks): enable /hooks disable to reliably stop single hooks by
|
||||
@abhipatel12 in
|
||||
[#16804](https://github.com/google-gemini/gemini-cli/pull/16804)
|
||||
- Don't commit unless user asks us to. by @gundermanc in
|
||||
[#16902](https://github.com/google-gemini/gemini-cli/pull/16902)
|
||||
- chore: remove a2a-adapter and bump @a2a-js/sdk to 0.3.8 by @adamfweidman in
|
||||
[#16800](https://github.com/google-gemini/gemini-cli/pull/16800)
|
||||
- fix: Show experiment values in settings UI for compressionThreshold by
|
||||
@ishaanxgupta in
|
||||
[#16267](https://github.com/google-gemini/gemini-cli/pull/16267)
|
||||
- feat(cli): replace relative keyboard shortcuts link with web URL by
|
||||
@imaliabbas in
|
||||
[#16479](https://github.com/google-gemini/gemini-cli/pull/16479)
|
||||
- fix(core): resolve PKCE length issue and stabilize OAuth redirect port by
|
||||
@sehoon38 in [#16815](https://github.com/google-gemini/gemini-cli/pull/16815)
|
||||
- Delete rewind documentation for now by @Adib234 in
|
||||
[#16932](https://github.com/google-gemini/gemini-cli/pull/16932)
|
||||
- Stabilize skill-creator CI and package format by @NTaylorMullen in
|
||||
[#17001](https://github.com/google-gemini/gemini-cli/pull/17001)
|
||||
- Stabilize the git evals by @gundermanc in
|
||||
[#16989](https://github.com/google-gemini/gemini-cli/pull/16989)
|
||||
- fix(core): attempt compression before context overflow check by @NTaylorMullen
|
||||
in [#16914](https://github.com/google-gemini/gemini-cli/pull/16914)
|
||||
- Fix inverted logic. by @gundermanc in
|
||||
[#17007](https://github.com/google-gemini/gemini-cli/pull/17007)
|
||||
- chore(scripts): add duplicate issue closer script and fix lint errors by
|
||||
@bdmorgan in [#16997](https://github.com/google-gemini/gemini-cli/pull/16997)
|
||||
- docs: update README and config guide to reference Gemini 3 by @JayadityaGit in
|
||||
[#15806](https://github.com/google-gemini/gemini-cli/pull/15806)
|
||||
- fix(cli): correct Homebrew installation detection by @kij in
|
||||
[#14727](https://github.com/google-gemini/gemini-cli/pull/14727)
|
||||
- Demote git evals to nightly run. by @gundermanc in
|
||||
[#17030](https://github.com/google-gemini/gemini-cli/pull/17030)
|
||||
- fix(cli): use OSC-52 clipboard copy in Windows Terminal by @Thomas-Shephard in
|
||||
[#16920](https://github.com/google-gemini/gemini-cli/pull/16920)
|
||||
- Fix: Process all parts in response chunks when thought is first by @pyrytakala
|
||||
in [#13539](https://github.com/google-gemini/gemini-cli/pull/13539)
|
||||
- fix(automation): fix jq quoting error in pr-triage.sh by @Kimsoo0119 in
|
||||
[#16958](https://github.com/google-gemini/gemini-cli/pull/16958)
|
||||
- refactor(core): decouple scheduler into orchestration, policy, and
|
||||
confirmation by @abhipatel12 in
|
||||
[#16895](https://github.com/google-gemini/gemini-cli/pull/16895)
|
||||
- feat: add /introspect slash command by @NTaylorMullen in
|
||||
[#17048](https://github.com/google-gemini/gemini-cli/pull/17048)
|
||||
- refactor(cli): centralize tool mapping and decouple legacy scheduler by
|
||||
@abhipatel12 in
|
||||
[#17044](https://github.com/google-gemini/gemini-cli/pull/17044)
|
||||
- fix(ui): ensure rationale renders before tool calls by @NTaylorMullen in
|
||||
[#17043](https://github.com/google-gemini/gemini-cli/pull/17043)
|
||||
- fix(workflows): use author_association for maintainer check by @bdmorgan in
|
||||
[#17060](https://github.com/google-gemini/gemini-cli/pull/17060)
|
||||
- fix return type of fireSessionStartEvent to defaultHookOutput by @ved015 in
|
||||
[#16833](https://github.com/google-gemini/gemini-cli/pull/16833)
|
||||
- feat(cli): add experiment gate for event-driven scheduler by @abhipatel12 in
|
||||
[#17055](https://github.com/google-gemini/gemini-cli/pull/17055)
|
||||
- feat(core): improve shell redirection transparency and security by
|
||||
@NTaylorMullen in
|
||||
[#16486](https://github.com/google-gemini/gemini-cli/pull/16486)
|
||||
- fix(core): deduplicate ModelInfo emission in GeminiClient by @NTaylorMullen in
|
||||
[#17075](https://github.com/google-gemini/gemini-cli/pull/17075)
|
||||
- docs(themes): remove unsupported DiffModified color key by @jw409 in
|
||||
[#17073](https://github.com/google-gemini/gemini-cli/pull/17073)
|
||||
- fix: update currentSequenceModel when modelChanged by @adamfweidman in
|
||||
[#17051](https://github.com/google-gemini/gemini-cli/pull/17051)
|
||||
- feat(core): enhanced anchored iterative context compression with
|
||||
self-verification by @rmedranollamas in
|
||||
[#15710](https://github.com/google-gemini/gemini-cli/pull/15710)
|
||||
- Fix mcp instructions by @chrstnb in
|
||||
[#16439](https://github.com/google-gemini/gemini-cli/pull/16439)
|
||||
- [A2A] Disable checkpointing if git is not installed by @cocosheng-g in
|
||||
[#16896](https://github.com/google-gemini/gemini-cli/pull/16896)
|
||||
- feat(admin): set admin.skills.enabled based on advancedFeaturesEnabled setting
|
||||
by @skeshive in
|
||||
[#17095](https://github.com/google-gemini/gemini-cli/pull/17095)
|
||||
- Test coverage for hook exit code cases by @gundermanc in
|
||||
[#17041](https://github.com/google-gemini/gemini-cli/pull/17041)
|
||||
- Revert "Revert "Update extension examples"" by @chrstnb in
|
||||
[#16445](https://github.com/google-gemini/gemini-cli/pull/16445)
|
||||
- fix(core): Provide compact, actionable errors for agent delegation failures by
|
||||
@SandyTao520 in
|
||||
[#16493](https://github.com/google-gemini/gemini-cli/pull/16493)
|
||||
- fix: migrate BeforeModel and AfterModel hooks to HookSystem by @ved015 in
|
||||
[#16599](https://github.com/google-gemini/gemini-cli/pull/16599)
|
||||
- feat(admin): apply admin settings to gemini skills/mcp/extensions commands by
|
||||
@skeshive in [#17102](https://github.com/google-gemini/gemini-cli/pull/17102)
|
||||
- fix(core): update telemetry token count after session resume by @psinha40898
|
||||
in [#15491](https://github.com/google-gemini/gemini-cli/pull/15491)
|
||||
- Demote the subagent test to nightly by @gundermanc in
|
||||
[#17105](https://github.com/google-gemini/gemini-cli/pull/17105)
|
||||
- feat(plan): telemetry to track adoption and usage of plan mode by @Adib234 in
|
||||
[#16863](https://github.com/google-gemini/gemini-cli/pull/16863)
|
||||
- feat: Add flash lite utility fallback chain by @adamfweidman in
|
||||
[#17056](https://github.com/google-gemini/gemini-cli/pull/17056)
|
||||
- Fixes Windows crash: "Cannot resize a pty that has already exited" by @dzammit
|
||||
in [#15757](https://github.com/google-gemini/gemini-cli/pull/15757)
|
||||
- feat(core): Add initial eval for generalist agent. by @joshualitt in
|
||||
[#16856](https://github.com/google-gemini/gemini-cli/pull/16856)
|
||||
- feat(core): unify agent enabled and disabled flags by @SandyTao520 in
|
||||
[#17127](https://github.com/google-gemini/gemini-cli/pull/17127)
|
||||
- fix(core): resolve auto model in default strategy by @sehoon38 in
|
||||
[#17116](https://github.com/google-gemini/gemini-cli/pull/17116)
|
||||
- docs: update project context and pr-creator workflow by @NTaylorMullen in
|
||||
[#17119](https://github.com/google-gemini/gemini-cli/pull/17119)
|
||||
- fix(cli): send gemini-cli version as mcp client version by @dsp in
|
||||
[#13407](https://github.com/google-gemini/gemini-cli/pull/13407)
|
||||
- fix(cli): resolve Ctrl+Enter and Ctrl+J newline issues by @imadraude in
|
||||
[#17021](https://github.com/google-gemini/gemini-cli/pull/17021)
|
||||
- Remove missing sidebar item by @chrstnb in
|
||||
[#17145](https://github.com/google-gemini/gemini-cli/pull/17145)
|
||||
- feat(core): Ensure all properties in hooks object are event names. by
|
||||
@joshualitt in
|
||||
[#16870](https://github.com/google-gemini/gemini-cli/pull/16870)
|
||||
- fix(cli): fix newline support broken in previous PR by @scidomino in
|
||||
[#17159](https://github.com/google-gemini/gemini-cli/pull/17159)
|
||||
- Add interactive ValidationDialog for handling 403 VALIDATION_REQUIRED errors.
|
||||
by @gsquared94 in
|
||||
[#16231](https://github.com/google-gemini/gemini-cli/pull/16231)
|
||||
- Add Esc-Esc to clear prompt when it's not empty by @Adib234 in
|
||||
[#17131](https://github.com/google-gemini/gemini-cli/pull/17131)
|
||||
- Avoid spurious warnings about unexpected renders triggered by appEvents and
|
||||
coreEvents. by @jacob314 in
|
||||
[#17160](https://github.com/google-gemini/gemini-cli/pull/17160)
|
||||
- fix(cli): resolve home/end keybinding conflict by @scidomino in
|
||||
[#17124](https://github.com/google-gemini/gemini-cli/pull/17124)
|
||||
- fix(cli): display 'http' type on mcp list by @pamanta in
|
||||
[#16915](https://github.com/google-gemini/gemini-cli/pull/16915)
|
||||
- fix bad fallback logic external editor logic by @scidomino in
|
||||
[#17166](https://github.com/google-gemini/gemini-cli/pull/17166)
|
||||
- Fix bug where System scopes weren't migrated. by @jacob314 in
|
||||
[#17174](https://github.com/google-gemini/gemini-cli/pull/17174)
|
||||
- Fix mcp tool lookup in tool registry by @werdnum in
|
||||
[#17054](https://github.com/google-gemini/gemini-cli/pull/17054)
|
||||
|
||||
**Full changelog**:
|
||||
https://github.com/google-gemini/gemini-cli/compare/v0.25.2...v0.26.0
|
||||
@@ -0,0 +1,437 @@
|
||||
# Preview release: Release v0.27.0-preview.0
|
||||
|
||||
Released: January 27, 2026
|
||||
|
||||
Our preview release includes the latest, new, and experimental features. This
|
||||
release may not be as stable as our [latest weekly release](latest.md).
|
||||
|
||||
To install the preview release:
|
||||
|
||||
```
|
||||
npm install -g @google/gemini-cli@preview
|
||||
```
|
||||
|
||||
## Highlights
|
||||
|
||||
- **Event-Driven Architecture:** The tool execution scheduler is now
|
||||
event-driven, improving performance and reliability.
|
||||
- **System Prompt Override:** Now supports dynamic variable substitution.
|
||||
- **Rewind Command:** The `/rewind` command has been implemented.
|
||||
- **Linux Clipboard:** Image pasting capabilities for Wayland and X11 on Linux.
|
||||
|
||||
## What's Changed
|
||||
|
||||
- remove fireAgent and beforeAgent hook by @ishaanxgupta in
|
||||
[#16919](https://github.com/google-gemini/gemini-cli/pull/16919)
|
||||
- Remove unused modelHooks and toolHooks by @ved015 in
|
||||
[#17115](https://github.com/google-gemini/gemini-cli/pull/17115)
|
||||
- feat(cli): sanitize ANSI escape sequences in non-interactive output by
|
||||
@sehoon38 in [#17172](https://github.com/google-gemini/gemini-cli/pull/17172)
|
||||
- Update Attempt text to Retry when showing the retry happening to the … by
|
||||
@sehoon38 in [#17178](https://github.com/google-gemini/gemini-cli/pull/17178)
|
||||
- chore(skills): update pr-creator skill workflow by @sehoon38 in
|
||||
[#17180](https://github.com/google-gemini/gemini-cli/pull/17180)
|
||||
- feat(cli): implement event-driven tool execution scheduler by @abhipatel12 in
|
||||
[#17078](https://github.com/google-gemini/gemini-cli/pull/17078)
|
||||
- chore(release): bump version to 0.27.0-nightly.20260121.97aac696f by
|
||||
@gemini-cli-robot in
|
||||
[#17181](https://github.com/google-gemini/gemini-cli/pull/17181)
|
||||
- Remove other rewind reference in docs by @chrstnb in
|
||||
[#17149](https://github.com/google-gemini/gemini-cli/pull/17149)
|
||||
- feat(skills): add code-reviewer skill by @sehoon38 in
|
||||
[#17187](httpshttps://github.com/google-gemini/gemini-cli/pull/17187)
|
||||
- feat(plan): Extend Shift+Tab Mode Cycling to include Plan Mode by @Adib234 in
|
||||
[#17177](https://github.com/google-gemini/gemini-cli/pull/17177)
|
||||
- feat(plan): refactor TestRig and eval helper to support configurable approval
|
||||
modes by @jerop in
|
||||
[#17171](https://github.com/google-gemini/gemini-cli/pull/17171)
|
||||
- feat(workflows): support recursive workstream labeling and new IDs by
|
||||
@bdmorgan in [#17207](https://github.com/google-gemini/gemini-cli/pull/17207)
|
||||
- Run evals for all models. by @gundermanc in
|
||||
[#17123](https://github.com/google-gemini/gemini-cli/pull/17123)
|
||||
- fix(github): improve label-workstream-rollup efficiency with GraphQL by
|
||||
@bdmorgan in [#17217](https://github.com/google-gemini/gemini-cli/pull/17217)
|
||||
- Docs: Update changelogs for v.0.25.0 and v0.26.0-preview.0 releases. by
|
||||
@g-samroberts in
|
||||
[#17215](https://github.com/google-gemini/gemini-cli/pull/17215)
|
||||
- Migrate beforeTool and afterTool hooks to hookSystem by @ved015 in
|
||||
[#17204](https://github.com/google-gemini/gemini-cli/pull/17204)
|
||||
- fix(github): improve label-workstream-rollup efficiency and fix bugs by
|
||||
@bdmorgan in [#17219](https://github.com/google-gemini/gemini-cli/pull/17219)
|
||||
- feat(cli): improve skill enablement/disablement verbiage by @NTaylorMullen in
|
||||
[#17192](https://github.com/google-gemini/gemini-cli/pull/17192)
|
||||
- fix(admin): Ensure CLI commands run in non-interactive mode by @skeshive in
|
||||
[#17218](https://github.com/google-gemini/gemini-cli/pull/17218)
|
||||
- feat(core): support dynamic variable substitution in system prompt override by
|
||||
@NTaylorMullen in
|
||||
[#17042](https://github.com/google-gemini/gemini-cli/pull/17042)
|
||||
- fix(core,cli): enable recursive directory access for by @galz10 in
|
||||
[#17094](https://github.com/google-gemini/gemini-cli/pull/17094)
|
||||
- Docs: Marking for experimental features by @jkcinouye in
|
||||
[#16760](https://github.com/google-gemini/gemini-cli/pull/16760)
|
||||
- Support command/ctrl/alt backspace correctly by @scidomino in
|
||||
[#17175](https://github.com/google-gemini/gemini-cli/pull/17175)
|
||||
- feat(plan): add approval mode instructions to system prompt by @jerop in
|
||||
[#17151](https://github.com/google-gemini/gemini-cli/pull/17151)
|
||||
- feat(core): enable disableLLMCorrection by default by @SandyTao520 in
|
||||
[#17223](https://github.com/google-gemini/gemini-cli/pull/17223)
|
||||
- Remove unused slug from sidebar by @chrstnb in
|
||||
[#17229](https://github.com/google-gemini/gemini-cli/pull/17229)
|
||||
- drain stdin on exit by @scidomino in
|
||||
[#17241](https://github.com/google-gemini/gemini-cli/pull/17241)
|
||||
- refactor(cli): decouple UI from live tool execution via ToolActionsContext by
|
||||
@abhipatel12 in
|
||||
[#17183](https://github.com/google-gemini/gemini-cli/pull/17183)
|
||||
- fix(core): update token count and telemetry on /chat resume history load by
|
||||
@psinha40898 in
|
||||
[#16279](https://github.com/google-gemini/gemini-cli/pull/16279)
|
||||
- fix: /policy to display policies according to mode by @ishaanxgupta in
|
||||
[#16772](https://github.com/google-gemini/gemini-cli/pull/16772)
|
||||
- fix(core): simplify replace tool error message by @SandyTao520 in
|
||||
[#17246](https://github.com/google-gemini/gemini-cli/pull/17246)
|
||||
- feat(cli): consolidate shell inactivity and redirection monitoring by
|
||||
@NTaylorMullen in
|
||||
[#17086](https://github.com/google-gemini/gemini-cli/pull/17086)
|
||||
- fix(scheduler): prevent stale tool re-publication and fix stuck UI state by
|
||||
@abhipatel12 in
|
||||
[#17227](https://github.com/google-gemini/gemini-cli/pull/17227)
|
||||
- feat(config): default enableEventDrivenScheduler to true by @abhipatel12 in
|
||||
[#17211](https://github.com/google-gemini/gemini-cli/pull/17211)
|
||||
- feat(hooks): enable hooks system by default by @abhipatel12 in
|
||||
[#17247](https://github.com/google-gemini/gemini-cli/pull/17247)
|
||||
- feat(core): Enable AgentRegistry to track all discovered subagents by
|
||||
@SandyTao520 in
|
||||
[#17253](https://github.com/google-gemini/gemini-cli/pull/17253)
|
||||
- feat(core): Have subagents use a JSON schema type for input. by @joshualitt in
|
||||
[#17152](https://github.com/google-gemini/gemini-cli/pull/17152)
|
||||
- feat: replace large text pastes with [Pasted Text: X lines] placeholder by
|
||||
@jackwotherspoon in
|
||||
[#16422](https://github.com/google-gemini/gemini-cli/pull/16422)
|
||||
- security(hooks): Wrap hook-injected context in distinct XML tags by @yunaseoul
|
||||
in [#17237](https://github.com/google-gemini/gemini-cli/pull/17237)
|
||||
- Enable the ability to queue specific nightly eval tests by @gundermanc in
|
||||
[#17262](https://github.com/google-gemini/gemini-cli/pull/17262)
|
||||
- docs(hooks): comprehensive update of hook documentation and specs by
|
||||
@abhipatel12 in
|
||||
[#16816](https://github.com/google-gemini/gemini-cli/pull/16816)
|
||||
- refactor: improve large text paste placeholder by @jacob314 in
|
||||
[#17269](https://github.com/google-gemini/gemini-cli/pull/17269)
|
||||
- feat: implement /rewind command by @Adib234 in
|
||||
[#15720](https://github.com/google-gemini/gemini-cli/pull/15720)
|
||||
- Feature/jetbrains ide detection by @SoLoHiC in
|
||||
[#16243](https://github.com/google-gemini/gemini-cli/pull/16243)
|
||||
- docs: update typo in mcp-server.md file by @schifferl in
|
||||
[#17099](https://github.com/google-gemini/gemini-cli/pull/17099)
|
||||
- Sanitize command names and descriptions by @ehedlund in
|
||||
[#17228](https://github.com/google-gemini/gemini-cli/pull/17228)
|
||||
- fix(auth): don't crash when initial auth fails by @skeshive in
|
||||
[#17308](https://github.com/google-gemini/gemini-cli/pull/17308)
|
||||
- Added image pasting capabilities for Wayland and X11 on Linux by @devr0306 in
|
||||
[#17144](https://github.com/google-gemini/gemini-cli/pull/17144)
|
||||
- feat: add AskUser tool schema by @jackwotherspoon in
|
||||
[#16988](https://github.com/google-gemini/gemini-cli/pull/16988)
|
||||
- fix cli settings: resolve layout jitter in settings bar by @Mag1ck in
|
||||
[#16256](https://github.com/google-gemini/gemini-cli/pull/16256)
|
||||
- fix: show whitespace changes in edit tool diffs by @Ujjiyara in
|
||||
[#17213](https://github.com/google-gemini/gemini-cli/pull/17213)
|
||||
- Remove redundant calls setting linuxClipboardTool. getUserLinuxClipboardTool()
|
||||
now handles the caching internally by @jacob314 in
|
||||
[#17320](https://github.com/google-gemini/gemini-cli/pull/17320)
|
||||
- ci: allow failure in evals-nightly run step by @gundermanc in
|
||||
[#17319](https://github.com/google-gemini/gemini-cli/pull/17319)
|
||||
- feat(cli): Add state management and plumbing for agent configuration dialog by
|
||||
@SandyTao520 in
|
||||
[#17259](https://github.com/google-gemini/gemini-cli/pull/17259)
|
||||
- bug: fix ide-client connection to ide-companion when inside docker via
|
||||
ssh/devcontainer by @kapsner in
|
||||
[#15049](https://github.com/google-gemini/gemini-cli/pull/15049)
|
||||
- Emit correct newline type return by @scidomino in
|
||||
[#17331](https://github.com/google-gemini/gemini-cli/pull/17331)
|
||||
- New skill: docs-writer by @g-samroberts in
|
||||
[#17268](https://github.com/google-gemini/gemini-cli/pull/17268)
|
||||
- fix(core): Resolve AbortSignal MaxListenersExceededWarning (#5950) by
|
||||
@spencer426 in
|
||||
[#16735](https://github.com/google-gemini/gemini-cli/pull/16735)
|
||||
- Disable tips after 10 runs by @Adib234 in
|
||||
[#17101](https://github.com/google-gemini/gemini-cli/pull/17101)
|
||||
- Fix so rewind starts at the bottom and loadHistory refreshes static content.
|
||||
by @jacob314 in
|
||||
[#17335](https://github.com/google-gemini/gemini-cli/pull/17335)
|
||||
- feat(core): Remove legacy settings. by @joshualitt in
|
||||
[#17244](https://github.com/google-gemini/gemini-cli/pull/17244)
|
||||
- feat(plan): add 'communicate' tool kind by @jerop in
|
||||
[#17341](https://github.com/google-gemini/gemini-cli/pull/17341)
|
||||
- feat(routing): A/B Test Numerical Complexity Scoring for Gemini 3 by
|
||||
@mattKorwel in
|
||||
[#16041](https://github.com/google-gemini/gemini-cli/pull/16041)
|
||||
- feat(plan): update UI Theme for Plan Mode by @Adib234 in
|
||||
[#17243](https://github.com/google-gemini/gemini-cli/pull/17243)
|
||||
- fix(ui): stabilize rendering during terminal resize in alternate buffer by
|
||||
@lkk214 in [#15783](https://github.com/google-gemini/gemini-cli/pull/15783)
|
||||
- feat(cli): add /agents config command and improve agent discovery by
|
||||
@SandyTao520 in
|
||||
[#17342](https://github.com/google-gemini/gemini-cli/pull/17342)
|
||||
- feat(mcp): add enable/disable commands for MCP servers (#11057) by @jasmeetsb
|
||||
in [#16299](https://github.com/google-gemini/gemini-cli/pull/16299)
|
||||
- fix(cli)!: Default to interactive mode for positional arguments by
|
||||
@ishaanxgupta in
|
||||
[#16329](https://github.com/google-gemini/gemini-cli/pull/16329)
|
||||
- Fix issue #17080 by @jacob314 in
|
||||
[#17100](https://github.com/google-gemini/gemini-cli/pull/17100)
|
||||
- feat(core): Refresh agents after loading an extension. by @joshualitt in
|
||||
[#17355](https://github.com/google-gemini/gemini-cli/pull/17355)
|
||||
- fix(cli): include source in policy rule display by @allenhutchison in
|
||||
[#17358](https://github.com/google-gemini/gemini-cli/pull/17358)
|
||||
- fix: remove obsolete CloudCode PerDay quota and 120s terminal threshold by
|
||||
@gsquared94 in
|
||||
[#17236](https://github.com/google-gemini/gemini-cli/pull/17236)
|
||||
- Refactor subagent delegation to be one tool per agent by @gundermanc in
|
||||
[#17346](https://github.com/google-gemini/gemini-cli/pull/17346)
|
||||
- fix(core): Include MCP server name in OAuth message by @jerop in
|
||||
[#17351](https://github.com/google-gemini/gemini-cli/pull/17351)
|
||||
- Fix pr-triage.sh script to update pull requests with tags "help wanted" and
|
||||
"maintainer only" by @jacob314 in
|
||||
[#17324](https://github.com/google-gemini/gemini-cli/pull/17324)
|
||||
- feat(plan): implement simple workflow for planning in main agent by @jerop in
|
||||
[#17326](https://github.com/google-gemini/gemini-cli/pull/17326)
|
||||
- fix: exit with non-zero code when esbuild is missing by @yuvrajangadsingh in
|
||||
[#16967](https://github.com/google-gemini/gemini-cli/pull/16967)
|
||||
- fix: ensure @docs/cli/custom-commands.md UI message ordering and test by
|
||||
@medic-code in
|
||||
[#12038](https://github.com/google-gemini/gemini-cli/pull/12038)
|
||||
- fix(core): add alternative command names for Antigravity editor detec… by
|
||||
@BaeSeokJae in
|
||||
[#16829](https://github.com/google-gemini/gemini-cli/pull/16829)
|
||||
- Refactor: Migrate CLI appEvents to Core coreEvents by @Adib234 in
|
||||
[#15737](https://github.com/google-gemini/gemini-cli/pull/15737)
|
||||
- fix(core): await MCP initialization in non-interactive mode by @Ratish1 in
|
||||
[#17390](https://github.com/google-gemini/gemini-cli/pull/17390)
|
||||
- Fix modifyOtherKeys enablement on unsupported terminals by @seekskyworld in
|
||||
[#16714](https://github.com/google-gemini/gemini-cli/pull/16714)
|
||||
- fix(core): gracefully handle disk full errors in chat recording by
|
||||
@godwiniheuwa in
|
||||
[#17305](https://github.com/google-gemini/gemini-cli/pull/17305)
|
||||
- fix(oauth): update oauth to use 127.0.0.1 instead of localhost by @skeshive in
|
||||
[#17388](https://github.com/google-gemini/gemini-cli/pull/17388)
|
||||
- fix(core): use RFC 9728 compliant path-based OAuth protected resource
|
||||
discovery by @vrv in
|
||||
[#15756](https://github.com/google-gemini/gemini-cli/pull/15756)
|
||||
- Update Code Wiki README badge by @PatoBeltran in
|
||||
[#15229](https://github.com/google-gemini/gemini-cli/pull/15229)
|
||||
- Add conda installation instructions for Gemini CLI by @ishaanxgupta in
|
||||
[#16921](https://github.com/google-gemini/gemini-cli/pull/16921)
|
||||
- chore(refactor): extract BaseSettingsDialog component by @SandyTao520 in
|
||||
[#17369](https://github.com/google-gemini/gemini-cli/pull/17369)
|
||||
- fix(cli): preserve input text when declining tool approval (#15624) by
|
||||
@ManojINaik in
|
||||
[#15659](https://github.com/google-gemini/gemini-cli/pull/15659)
|
||||
- chore: upgrade dep: diff 7.0.0-> 8.0.3 by @scidomino in
|
||||
[#17403](https://github.com/google-gemini/gemini-cli/pull/17403)
|
||||
- feat: add AskUserDialog for UI component of AskUser tool by @jackwotherspoon
|
||||
in [#17344](https://github.com/google-gemini/gemini-cli/pull/17344)
|
||||
- feat(ui): display user tier in about command by @sehoon38 in
|
||||
[#17400](https://github.com/google-gemini/gemini-cli/pull/17400)
|
||||
- feat: add clearContext to AfterAgent hooks by @jackwotherspoon in
|
||||
[#16574](https://github.com/google-gemini/gemini-cli/pull/16574)
|
||||
- fix(cli): change image paste location to global temp directory (#17396) by
|
||||
@devr0306 in [#17396](https://github.com/google-gemini/gemini-cli/pull/17396)
|
||||
- Fix line endings issue with Notice file by @scidomino in
|
||||
[#17417](https://github.com/google-gemini/gemini-cli/pull/17417)
|
||||
- feat(plan): implement persistent approvalMode setting by @Adib234 in
|
||||
[#17350](https://github.com/google-gemini/gemini-cli/pull/17350)
|
||||
- feat(ui): Move keyboard handling into BaseSettingsDialog by @SandyTao520 in
|
||||
[#17404](https://github.com/google-gemini/gemini-cli/pull/17404)
|
||||
- Allow prompt queueing during MCP initialization by @Adib234 in
|
||||
[#17395](https://github.com/google-gemini/gemini-cli/pull/17395)
|
||||
- feat: implement AgentConfigDialog for /agents config command by @SandyTao520
|
||||
in [#17370](https://github.com/google-gemini/gemini-cli/pull/17370)
|
||||
- fix(agents): default to all tools when tool list is omitted in subagents by
|
||||
@gundermanc in
|
||||
[#17422](https://github.com/google-gemini/gemini-cli/pull/17422)
|
||||
- feat(cli): Moves tool confirmations to a queue UX by @abhipatel12 in
|
||||
[#17276](https://github.com/google-gemini/gemini-cli/pull/17276)
|
||||
- fix(core): hide user tier name by @sehoon38 in
|
||||
[#17418](https://github.com/google-gemini/gemini-cli/pull/17418)
|
||||
- feat: Enforce unified folder trust for /directory add by @galz10 in
|
||||
[#17359](https://github.com/google-gemini/gemini-cli/pull/17359)
|
||||
- migrate fireToolNotificationHook to hookSystem by @ved015 in
|
||||
[#17398](https://github.com/google-gemini/gemini-cli/pull/17398)
|
||||
- Clean up dead code by @scidomino in
|
||||
[#17443](https://github.com/google-gemini/gemini-cli/pull/17443)
|
||||
- feat(workflow): add stale pull request closer with linked-issue enforcement by
|
||||
@bdmorgan in [#17449](https://github.com/google-gemini/gemini-cli/pull/17449)
|
||||
- feat(workflow): expand stale-exempt labels to include help wanted and Public
|
||||
Roadmap by @bdmorgan in
|
||||
[#17459](https://github.com/google-gemini/gemini-cli/pull/17459)
|
||||
- chore(workflow): remove redundant label-enforcer workflow by @bdmorgan in
|
||||
[#17460](https://github.com/google-gemini/gemini-cli/pull/17460)
|
||||
- Resolves the confusing error message `ripgrep exited with code null that
|
||||
occurs when a search operation is cancelled or aborted by @maximmasiutin in
|
||||
[#14267](https://github.com/google-gemini/gemini-cli/pull/14267)
|
||||
- fix: detect pnpm/pnpx in ~/.local by @rwakulszowa in
|
||||
[#15254](https://github.com/google-gemini/gemini-cli/pull/15254)
|
||||
- docs: Add instructions for MacPorts and uninstall instructions for Homebrew by
|
||||
@breun in [#17412](https://github.com/google-gemini/gemini-cli/pull/17412)
|
||||
- docs(hooks): clarify mandatory 'type' field and update hook schema
|
||||
documentation by @abhipatel12 in
|
||||
[#17499](https://github.com/google-gemini/gemini-cli/pull/17499)
|
||||
- Improve error messages on failed onboarding by @gsquared94 in
|
||||
[#17357](https://github.com/google-gemini/gemini-cli/pull/17357)
|
||||
- Follow up to "enableInteractiveShell for external tooling relying on a2a
|
||||
server" by @DavidAPierce in
|
||||
[#17130](https://github.com/google-gemini/gemini-cli/pull/17130)
|
||||
- Fix/issue 17070 by @alih552 in
|
||||
[#17242](https://github.com/google-gemini/gemini-cli/pull/17242)
|
||||
- fix(core): handle URI-encoded workspace paths in IdeClient by @dong-jun-shin
|
||||
in [#17476](https://github.com/google-gemini/gemini-cli/pull/17476)
|
||||
- feat(cli): add quick clear input shortcuts in vim mode by @harshanadim in
|
||||
[#17470](https://github.com/google-gemini/gemini-cli/pull/17470)
|
||||
- feat(core): optimize shell tool llmContent output format by @SandyTao520 in
|
||||
[#17538](https://github.com/google-gemini/gemini-cli/pull/17538)
|
||||
- Fix bug in detecting already added paths. by @jacob314 in
|
||||
[#17430](https://github.com/google-gemini/gemini-cli/pull/17430)
|
||||
- feat(scheduler): support multi-scheduler tool aggregation and nested call IDs
|
||||
by @abhipatel12 in
|
||||
[#17429](https://github.com/google-gemini/gemini-cli/pull/17429)
|
||||
- feat(agents): implement first-run experience for project-level sub-agents by
|
||||
@gundermanc in
|
||||
[#17266](https://github.com/google-gemini/gemini-cli/pull/17266)
|
||||
- Update extensions docs by @chrstnb in
|
||||
[#16093](https://github.com/google-gemini/gemini-cli/pull/16093)
|
||||
- Docs: Refactor left nav on the website by @jkcinouye in
|
||||
[#17558](https://github.com/google-gemini/gemini-cli/pull/17558)
|
||||
- fix(core): stream grep/ripgrep output to prevent OOM by @adamfweidman in
|
||||
[#17146](https://github.com/google-gemini/gemini-cli/pull/17146)
|
||||
- feat(plan): add persistent plan file storage by @jerop in
|
||||
[#17563](https://github.com/google-gemini/gemini-cli/pull/17563)
|
||||
- feat(agents): migrate subagents to event-driven scheduler by @abhipatel12 in
|
||||
[#17567](https://github.com/google-gemini/gemini-cli/pull/17567)
|
||||
- Fix extensions config error by @chrstnb in
|
||||
[#17580](https://github.com/google-gemini/gemini-cli/pull/17580)
|
||||
- fix(plan): remove subagent invocation from plan mode by @jerop in
|
||||
[#17593](https://github.com/google-gemini/gemini-cli/pull/17593)
|
||||
- feat(ui): add solid background color option for input prompt by @jacob314 in
|
||||
[#16563](https://github.com/google-gemini/gemini-cli/pull/16563)
|
||||
- feat(plan): refresh system prompt when approval mode changes (Shift+Tab) by
|
||||
@jerop in [#17585](https://github.com/google-gemini/gemini-cli/pull/17585)
|
||||
- feat(cli): add global setting to disable UI spinners by @galz10 in
|
||||
[#17234](https://github.com/google-gemini/gemini-cli/pull/17234)
|
||||
- fix(security): enforce strict policy directory permissions by @yunaseoul in
|
||||
[#17353](https://github.com/google-gemini/gemini-cli/pull/17353)
|
||||
- test(core): fix tests in windows by @scidomino in
|
||||
[#17592](https://github.com/google-gemini/gemini-cli/pull/17592)
|
||||
- feat(mcp/extensions): Allow users to selectively enable/disable MCP servers
|
||||
included in an extension( Issue #11057 & #17402) by @jasmeetsb in
|
||||
[#17434](https://github.com/google-gemini/gemini-cli/pull/17434)
|
||||
- Always map mac keys, even on other platforms by @scidomino in
|
||||
[#17618](https://github.com/google-gemini/gemini-cli/pull/17618)
|
||||
- Ctrl-O by @jacob314 in
|
||||
[#17617](https://github.com/google-gemini/gemini-cli/pull/17617)
|
||||
- feat(plan): update cycling order of approval modes by @Adib234 in
|
||||
[#17622](https://github.com/google-gemini/gemini-cli/pull/17622)
|
||||
- fix(cli): restore 'Modify with editor' option in external terminals by
|
||||
@abhipatel12 in
|
||||
[#17621](https://github.com/google-gemini/gemini-cli/pull/17621)
|
||||
- Slash command for helping in debugging by @gundermanc in
|
||||
[#17609](https://github.com/google-gemini/gemini-cli/pull/17609)
|
||||
- feat: add double-click to expand/collapse large paste placeholders by
|
||||
@jackwotherspoon in
|
||||
[#17471](https://github.com/google-gemini/gemini-cli/pull/17471)
|
||||
- refactor(cli): migrate non-interactive flow to event-driven scheduler by
|
||||
@abhipatel12 in
|
||||
[#17572](https://github.com/google-gemini/gemini-cli/pull/17572)
|
||||
- fix: loadcodeassist eligible tiers getting ignored for unlicensed users
|
||||
(regression) by @gsquared94 in
|
||||
[#17581](https://github.com/google-gemini/gemini-cli/pull/17581)
|
||||
- chore(core): delete legacy nonInteractiveToolExecutor by @abhipatel12 in
|
||||
[#17573](https://github.com/google-gemini/gemini-cli/pull/17573)
|
||||
- feat(core): enforce server prefixes for MCP tools in agent definitions by
|
||||
@abhipatel12 in
|
||||
[#17574](https://github.com/google-gemini/gemini-cli/pull/17574)
|
||||
- feat (mcp): Refresh MCP prompts on list changed notification by @MrLesk in
|
||||
[#14863](https://github.com/google-gemini/gemini-cli/pull/14863)
|
||||
- feat(ui): pretty JSON rendering tool outputs by @medic-code in
|
||||
[#9767](https://github.com/google-gemini/gemini-cli/pull/9767)
|
||||
- Fix iterm alternate buffer mode issue rendering backgrounds by @jacob314 in
|
||||
[#17634](https://github.com/google-gemini/gemini-cli/pull/17634)
|
||||
- feat(cli): add gemini extensions list --output-format=json by @AkihiroSuda in
|
||||
[#14479](https://github.com/google-gemini/gemini-cli/pull/14479)
|
||||
- fix(extensions): add .gitignore to extension templates by @godwiniheuwa in
|
||||
[#17293](https://github.com/google-gemini/gemini-cli/pull/17293)
|
||||
- paste transform followup by @jacob314 in
|
||||
[#17624](https://github.com/google-gemini/gemini-cli/pull/17624)
|
||||
- refactor: rename formatMemoryUsage to formatBytes by @Nubebuster in
|
||||
[#14997](https://github.com/google-gemini/gemini-cli/pull/14997)
|
||||
- chore: remove extra top margin from /hooks and /extensions by @jackwotherspoon
|
||||
in [#17663](https://github.com/google-gemini/gemini-cli/pull/17663)
|
||||
- feat(cli): add oncall command for issue triage by @sehoon38 in
|
||||
[#17661](https://github.com/google-gemini/gemini-cli/pull/17661)
|
||||
- Fix sidebar issue for extensions link by @chrstnb in
|
||||
[#17668](https://github.com/google-gemini/gemini-cli/pull/17668)
|
||||
- Change formatting to prevent UI redressing attacks by @scidomino in
|
||||
[#17611](https://github.com/google-gemini/gemini-cli/pull/17611)
|
||||
- Fix cluster of bugs in the settings dialog. by @jacob314 in
|
||||
[#17628](https://github.com/google-gemini/gemini-cli/pull/17628)
|
||||
- Update sidebar to resolve site build issues by @chrstnb in
|
||||
[#17674](https://github.com/google-gemini/gemini-cli/pull/17674)
|
||||
- fix(admin): fix a few bugs related to admin controls by @skeshive in
|
||||
[#17590](https://github.com/google-gemini/gemini-cli/pull/17590)
|
||||
- revert bad changes to tests by @scidomino in
|
||||
[#17673](https://github.com/google-gemini/gemini-cli/pull/17673)
|
||||
- feat(cli): show candidate issue state reason and duplicate status in triage by
|
||||
@sehoon38 in [#17676](https://github.com/google-gemini/gemini-cli/pull/17676)
|
||||
- Fix missing slash commands when Gemini CLI is in a project with a package.json
|
||||
that doesn't follow semantic versioning by @Adib234 in
|
||||
[#17561](https://github.com/google-gemini/gemini-cli/pull/17561)
|
||||
- feat(core): Model family-specific system prompts by @joshualitt in
|
||||
[#17614](https://github.com/google-gemini/gemini-cli/pull/17614)
|
||||
- Sub-agents documentation. by @gundermanc in
|
||||
[#16639](https://github.com/google-gemini/gemini-cli/pull/16639)
|
||||
- feat: wire up AskUserTool with dialog by @jackwotherspoon in
|
||||
[#17411](https://github.com/google-gemini/gemini-cli/pull/17411)
|
||||
- Load extension settings for hooks, agents, skills by @chrstnb in
|
||||
[#17245](https://github.com/google-gemini/gemini-cli/pull/17245)
|
||||
- Fix issue where Gemini CLI can make changes when simply asked a question by
|
||||
@gundermanc in
|
||||
[#17608](https://github.com/google-gemini/gemini-cli/pull/17608)
|
||||
- Update docs-writer skill for editing and add style guide for reference. by
|
||||
@g-samroberts in
|
||||
[#17669](https://github.com/google-gemini/gemini-cli/pull/17669)
|
||||
- fix(ux): have user message display a short path for pasted images by @devr0306
|
||||
in [#17613](https://github.com/google-gemini/gemini-cli/pull/17613)
|
||||
- feat(plan): enable AskUser tool in Plan mode for clarifying questions by
|
||||
@jerop in [#17694](https://github.com/google-gemini/gemini-cli/pull/17694)
|
||||
- GEMINI.md polish by @jacob314 in
|
||||
[#17680](https://github.com/google-gemini/gemini-cli/pull/17680)
|
||||
- refactor(core): centralize path validation and allow temp dir access for tools
|
||||
by @NTaylorMullen in
|
||||
[#17185](https://github.com/google-gemini/gemini-cli/pull/17185)
|
||||
- feat(skills): promote Agent Skills to stable by @abhipatel12 in
|
||||
[#17693](https://github.com/google-gemini/gemini-cli/pull/17693)
|
||||
- refactor(cli): keyboard handling and AskUserDialog by @jacob314 in
|
||||
[#17414](https://github.com/google-gemini/gemini-cli/pull/17414)
|
||||
- docs: Add Experimental Remote Agent Docs by @adamfweidman in
|
||||
[#17697](https://github.com/google-gemini/gemini-cli/pull/17697)
|
||||
- revert: promote Agent Skills to stable (#17693) by @abhipatel12 in
|
||||
[#17712](https://github.com/google-gemini/gemini-cli/pull/17712)
|
||||
- feat(ux) Expandable (ctrl-O) and scrollable approvals in alternate buffer
|
||||
mode. by @jacob314 in
|
||||
[#17640](https://github.com/google-gemini/gemini-cli/pull/17640)
|
||||
- feat(skills): promote skills settings to stable by @abhipatel12 in
|
||||
[#17713](https://github.com/google-gemini/gemini-cli/pull/17713)
|
||||
- fix(cli): Preserve settings dialog focus when searching by @SandyTao520 in
|
||||
[#17701](https://github.com/google-gemini/gemini-cli/pull/17701)
|
||||
- feat(ui): add terminal cursor support by @jacob314 in
|
||||
[#17711](https://github.com/google-gemini/gemini-cli/pull/17711)
|
||||
- docs(skills): remove experimental labels and update tutorials by @abhipatel12
|
||||
in [#17714](https://github.com/google-gemini/gemini-cli/pull/17714)
|
||||
- docs: remove 'experimental' syntax for hooks in docs by @abhipatel12 in
|
||||
[#17660](https://github.com/google-gemini/gemini-cli/pull/17660)
|
||||
- Add support for an additional exclusion file besides .gitignore and
|
||||
.geminiignore by @alisa-alisa in
|
||||
[#16487](https://github.com/google-gemini/gemini-cli/pull/16487)
|
||||
- feat: add review-frontend-and-fix command by @galz10 in
|
||||
[#17707](https://github.com/google-gemini/gemini-cli/pull/17707)
|
||||
|
||||
**Full changelog**:
|
||||
https://github.com/google-gemini/gemini-cli/compare/v0.26.0-preview.5...v0.27.0-preview.0
|
||||
@@ -1,3 +1,3 @@
|
||||
# Authentication Setup
|
||||
# Authentication setup
|
||||
|
||||
See: [Getting Started - Authentication Setup](../get-started/authentication.md).
|
||||
|
||||
@@ -6,19 +6,19 @@ AI-powered tools. This allows you to safely experiment with and apply code
|
||||
changes, knowing you can instantly revert back to the state before the tool was
|
||||
run.
|
||||
|
||||
## How It Works
|
||||
## How it works
|
||||
|
||||
When you approve a tool that modifies the file system (like `write_file` or
|
||||
`replace`), the CLI automatically creates a "checkpoint." This checkpoint
|
||||
includes:
|
||||
|
||||
1. **A Git Snapshot:** A commit is made in a special, shadow Git repository
|
||||
1. **A Git snapshot:** A commit is made in a special, shadow Git repository
|
||||
located in your home directory (`~/.gemini/history/<project_hash>`). This
|
||||
snapshot captures the complete state of your project files at that moment.
|
||||
It does **not** interfere with your own project's Git repository.
|
||||
2. **Conversation History:** The entire conversation you've had with the agent
|
||||
2. **Conversation history:** The entire conversation you've had with the agent
|
||||
up to that point is saved.
|
||||
3. **The Tool Call:** The specific tool call that was about to be executed is
|
||||
3. **The tool call:** The specific tool call that was about to be executed is
|
||||
also stored.
|
||||
|
||||
If you want to undo the change or simply go back, you can use the `/restore`
|
||||
@@ -35,7 +35,7 @@ repository while the conversation history and tool calls are saved in a JSON
|
||||
file in your project's temporary directory, typically located at
|
||||
`~/.gemini/tmp/<project_hash>/checkpoints`.
|
||||
|
||||
## Enabling the Feature
|
||||
## Enabling the feature
|
||||
|
||||
The Checkpointing feature is disabled by default. To enable it, you need to edit
|
||||
your `settings.json` file.
|
||||
@@ -56,12 +56,12 @@ Add the following key to your `settings.json`:
|
||||
}
|
||||
```
|
||||
|
||||
## Using the `/restore` Command
|
||||
## Using the `/restore` command
|
||||
|
||||
Once enabled, checkpoints are created automatically. To manage them, you use the
|
||||
`/restore` command.
|
||||
|
||||
### List Available Checkpoints
|
||||
### List available checkpoints
|
||||
|
||||
To see a list of all saved checkpoints for the current project, simply run:
|
||||
|
||||
@@ -74,7 +74,7 @@ typically composed of a timestamp, the name of the file being modified, and the
|
||||
name of the tool that was about to be run (e.g.,
|
||||
`2025-06-22T10-00-00_000Z-my-file.txt-write_file`).
|
||||
|
||||
### Restore a Specific Checkpoint
|
||||
### Restore a specific checkpoint
|
||||
|
||||
To restore your project to a specific checkpoint, use the checkpoint file from
|
||||
the list:
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
# CLI cheatsheet
|
||||
|
||||
This page provides a reference for commonly used Gemini CLI commands, options,
|
||||
and parameters.
|
||||
|
||||
## CLI commands
|
||||
|
||||
| Command | Description | Example |
|
||||
| ---------------------------------- | ---------------------------------- | --------------------------------------------------- |
|
||||
| `gemini` | Start interactive REPL | `gemini` |
|
||||
| `gemini "query"` | Query non-interactively, then exit | `gemini "explain this project"` |
|
||||
| `gemini -p "query"` | Query via SDK, then exit | `gemini -p "explain this function"` |
|
||||
| `cat file \| gemini -p "query"` | Process piped content | `cat logs.txt \| gemini -p "explain"` |
|
||||
| `gemini -i "query"` | Execute and continue interactively | `gemini -i "What is the purpose of this project?"` |
|
||||
| `gemini -r "latest"` | Continue most recent session | `gemini -r "latest"` |
|
||||
| `gemini -r "latest" "query"` | Continue session with a new prompt | `gemini -r "latest" "Check for type errors"` |
|
||||
| `gemini -r "<session-id>" "query"` | Resume session by ID | `gemini -r "abc123" "Finish this PR"` |
|
||||
| `gemini update` | Update to latest version | `gemini update` |
|
||||
| `gemini extensions` | Manage extensions | See [Extensions Management](#extensions-management) |
|
||||
| `gemini mcp` | Configure MCP servers | See [MCP Server Management](#mcp-server-management) |
|
||||
|
||||
### Positional arguments
|
||||
|
||||
| Argument | Type | Description |
|
||||
| -------- | ----------------- | ------------------------------------------------------------------------------------------------------------------ |
|
||||
| `query` | string (variadic) | Positional prompt. Defaults to one-shot mode. Use `-i/--prompt-interactive` to execute and continue interactively. |
|
||||
|
||||
## CLI Options
|
||||
|
||||
| Option | Alias | Type | Default | Description |
|
||||
| -------------------------------- | ----- | ------- | --------- | ---------------------------------------------------------------------------------------------------------- |
|
||||
| `--debug` | `-d` | boolean | `false` | Run in debug mode with verbose logging |
|
||||
| `--version` | `-v` | - | - | Show CLI version number and exit |
|
||||
| `--help` | `-h` | - | - | Show help information |
|
||||
| `--model` | `-m` | string | `auto` | Model to use. See [Model Selection](#model-selection) for available values. |
|
||||
| `--prompt` | `-p` | string | - | Prompt text. Appended to stdin input if provided. **Deprecated:** Use positional arguments instead. |
|
||||
| `--prompt-interactive` | `-i` | string | - | Execute prompt and continue in interactive mode |
|
||||
| `--ralph-wiggum` | - | boolean | `false` | Enable Ralph Wiggum iterative loop mode |
|
||||
| `--completion-promise` | - | string | - | String to look for to signal completion in Ralph Wiggum mode |
|
||||
| `--max-iterations` | - | number | `10` | Maximum loop iterations for Ralph Wiggum mode |
|
||||
| `--sandbox` | `-s` | boolean | `false` | Run in a sandboxed environment for safer execution |
|
||||
| `--approval-mode` | - | string | `default` | Approval mode for tool execution. Choices: `default`, `auto_edit`, `yolo` |
|
||||
| `--yolo` | `-y` | boolean | `false` | **Deprecated.** Auto-approve all actions. Use `--approval-mode=yolo` instead. |
|
||||
| `--experimental-acp` | - | boolean | - | Start in ACP (Agent Code Pilot) mode. **Experimental feature.** |
|
||||
| `--experimental-zed-integration` | - | boolean | - | Run in Zed editor integration mode. **Experimental feature.** |
|
||||
| `--allowed-mcp-server-names` | - | array | - | Allowed MCP server names (comma-separated or multiple flags) |
|
||||
| `--allowed-tools` | - | array | - | Tools that are allowed to run without confirmation (comma-separated or multiple flags) |
|
||||
| `--extensions` | `-e` | array | - | List of extensions to use. If not provided, all extensions are enabled (comma-separated or multiple flags) |
|
||||
| `--list-extensions` | `-l` | boolean | - | List all available extensions and exit |
|
||||
| `--resume` | `-r` | string | - | Resume a previous session. Use `"latest"` for most recent or index number (e.g. `--resume 5`) |
|
||||
| `--list-sessions` | - | boolean | - | List available sessions for the current project and exit |
|
||||
| `--delete-session` | - | string | - | Delete a session by index number (use `--list-sessions` to see available sessions) |
|
||||
| `--include-directories` | - | array | - | Additional directories to include in the workspace (comma-separated or multiple flags) |
|
||||
| `--screen-reader` | - | boolean | - | Enable screen reader mode for accessibility |
|
||||
| `--output-format` | `-o` | string | `text` | The format of the CLI output. Choices: `text`, `json`, `stream-json` |
|
||||
|
||||
## Model selection
|
||||
|
||||
The `--model` (or `-m`) flag allows you to specify which Gemini model to use.
|
||||
You can use either model aliases (user-friendly names) or concrete model names.
|
||||
|
||||
### Model aliases
|
||||
|
||||
These are convenient shortcuts that map to specific models:
|
||||
|
||||
| Alias | Resolves To | Description |
|
||||
| ------------ | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `auto` | `gemini-2.5-pro` or `gemini-3-pro-preview` | **Default.** Resolves to the preview model if preview features are enabled, otherwise resolves to the standard pro model. |
|
||||
| `pro` | `gemini-2.5-pro` or `gemini-3-pro-preview` | For complex reasoning tasks. Uses preview model if enabled. |
|
||||
| `flash` | `gemini-2.5-flash` | Fast, balanced model for most tasks. |
|
||||
| `flash-lite` | `gemini-2.5-flash-lite` | Fastest model for simple tasks. |
|
||||
|
||||
## Extensions management
|
||||
|
||||
| Command | Description | Example |
|
||||
| -------------------------------------------------- | -------------------------------------------- | ------------------------------------------------------------------------------ |
|
||||
| `gemini extensions install <source>` | Install extension from Git URL or local path | `gemini extensions install https://github.com/user/my-extension` |
|
||||
| `gemini extensions install <source> --ref <ref>` | Install from specific branch/tag/commit | `gemini extensions install https://github.com/user/my-extension --ref develop` |
|
||||
| `gemini extensions install <source> --auto-update` | Install with auto-update enabled | `gemini extensions install https://github.com/user/my-extension --auto-update` |
|
||||
| `gemini extensions uninstall <name>` | Uninstall one or more extensions | `gemini extensions uninstall my-extension` |
|
||||
| `gemini extensions list` | List all installed extensions | `gemini extensions list` |
|
||||
| `gemini extensions update <name>` | Update a specific extension | `gemini extensions update my-extension` |
|
||||
| `gemini extensions update --all` | Update all extensions | `gemini extensions update --all` |
|
||||
| `gemini extensions enable <name>` | Enable an extension | `gemini extensions enable my-extension` |
|
||||
| `gemini extensions disable <name>` | Disable an extension | `gemini extensions disable my-extension` |
|
||||
| `gemini extensions link <path>` | Link local extension for development | `gemini extensions link /path/to/extension` |
|
||||
| `gemini extensions new <path>` | Create new extension from template | `gemini extensions new ./my-extension` |
|
||||
| `gemini extensions validate <path>` | Validate extension structure | `gemini extensions validate ./my-extension` |
|
||||
|
||||
See [Extensions Documentation](../extensions/index.md) for more details.
|
||||
|
||||
## MCP server management
|
||||
|
||||
| Command | Description | Example |
|
||||
| ------------------------------------------------------------- | ------------------------------- | ---------------------------------------------------------------------------------------------------- |
|
||||
| `gemini mcp add <name> <command>` | Add stdio-based MCP server | `gemini mcp add github npx -y @modelcontextprotocol/server-github` |
|
||||
| `gemini mcp add <name> <url> --transport http` | Add HTTP-based MCP server | `gemini mcp add api-server http://localhost:3000 --transport http` |
|
||||
| `gemini mcp add <name> <command> --env KEY=value` | Add with environment variables | `gemini mcp add slack node server.js --env SLACK_TOKEN=xoxb-xxx` |
|
||||
| `gemini mcp add <name> <command> --scope user` | Add with user scope | `gemini mcp add db node db-server.js --scope user` |
|
||||
| `gemini mcp add <name> <command> --include-tools tool1,tool2` | Add with specific tools | `gemini mcp add github npx -y @modelcontextprotocol/server-github --include-tools list_repos,get_pr` |
|
||||
| `gemini mcp remove <name>` | Remove an MCP server | `gemini mcp remove github` |
|
||||
| `gemini mcp list` | List all configured MCP servers | `gemini mcp list` |
|
||||
|
||||
See [MCP Server Integration](../tools/mcp-server.md) for more details.
|
||||
|
||||
## Skills management
|
||||
|
||||
| Command | Description | Example |
|
||||
| -------------------------------- | ------------------------------------- | ------------------------------------------------- |
|
||||
| `gemini skills list` | List all discovered agent skills | `gemini skills list` |
|
||||
| `gemini skills install <source>` | Install skill from Git, path, or file | `gemini skills install https://github.com/u/repo` |
|
||||
| `gemini skills link <path>` | Link local agent skills via symlink | `gemini skills link /path/to/my-skills` |
|
||||
| `gemini skills uninstall <name>` | Uninstall an agent skill | `gemini skills uninstall my-skill` |
|
||||
| `gemini skills enable <name>` | Enable an agent skill | `gemini skills enable my-skill` |
|
||||
| `gemini skills disable <name>` | Disable an agent skill | `gemini skills disable my-skill` |
|
||||
| `gemini skills enable --all` | Enable all skills | `gemini skills enable --all` |
|
||||
| `gemini skills disable --all` | Disable all skills | `gemini skills disable --all` |
|
||||
|
||||
See [Agent Skills Documentation](./skills.md) for more details.
|
||||
+170
-79
@@ -1,4 +1,4 @@
|
||||
# CLI Commands
|
||||
# CLI commands
|
||||
|
||||
Gemini CLI supports several built-in commands to help you manage your session,
|
||||
customize the interface, and control its behavior. These commands are prefixed
|
||||
@@ -10,6 +10,14 @@ Slash commands provide meta-level control over the CLI itself.
|
||||
|
||||
### Built-in Commands
|
||||
|
||||
- **`/about`**
|
||||
- **Description:** Show version info. Please share this information when
|
||||
filing issues.
|
||||
|
||||
- **`/auth`**
|
||||
- **Description:** Open a dialog that lets you change the authentication
|
||||
method.
|
||||
|
||||
- **`/bug`**
|
||||
- **Description:** File an issue about Gemini CLI. By default, the issue is
|
||||
filed within the GitHub repository for Gemini CLI. The string you enter
|
||||
@@ -22,11 +30,22 @@ Slash commands provide meta-level control over the CLI itself.
|
||||
conversation state interactively, or resuming a previous state from a later
|
||||
session.
|
||||
- **Sub-commands:**
|
||||
- **`save`**
|
||||
- **`delete <tag>`**
|
||||
- **Description:** Deletes a saved conversation checkpoint.
|
||||
- **`list`**
|
||||
- **Description:** Lists available tags for chat state resumption.
|
||||
- **Note:** This command only lists chats saved within the current
|
||||
project. Because chat history is project-scoped, chats saved in other
|
||||
project directories will not be displayed.
|
||||
- **`resume <tag>`**
|
||||
- **Description:** Resumes a conversation from a previous save.
|
||||
- **Note:** You can only resume chats that were saved within the current
|
||||
project. To resume a chat from a different project, you must run the
|
||||
Gemini CLI from that project's directory.
|
||||
- **`save <tag>`**
|
||||
- **Description:** Saves the current conversation history. You must add a
|
||||
`<tag>` for identifying the conversation state.
|
||||
- **Usage:** `/chat save <tag>`
|
||||
- **Details on Checkpoint Location:** The default locations for saved chat
|
||||
- **Details on checkpoint location:** The default locations for saved chat
|
||||
checkpoints are:
|
||||
- Linux/macOS: `~/.gemini/tmp/<project_hash>/`
|
||||
- Windows: `C:\Users\<YourUsername>\.gemini\tmp\<project_hash>\`
|
||||
@@ -37,25 +56,11 @@ Slash commands provide meta-level control over the CLI itself.
|
||||
conversation states. For automatic checkpoints created before file
|
||||
modifications, see the
|
||||
[Checkpointing documentation](../cli/checkpointing.md).
|
||||
- **`resume`**
|
||||
- **Description:** Resumes a conversation from a previous save.
|
||||
- **Usage:** `/chat resume <tag>`
|
||||
- **Note:** You can only resume chats that were saved within the current
|
||||
project. To resume a chat from a different project, you must run the
|
||||
Gemini CLI from that project's directory.
|
||||
- **`list`**
|
||||
- **Description:** Lists available tags for chat state resumption.
|
||||
- **Note:** This command only lists chats saved within the current
|
||||
project. Because chat history is project-scoped, chats saved in other
|
||||
project directories will not be displayed.
|
||||
- **`delete`**
|
||||
- **Description:** Deletes a saved conversation checkpoint.
|
||||
- **Usage:** `/chat delete <tag>`
|
||||
- **`share`**
|
||||
- **`share [filename]`**
|
||||
- **Description** Writes the current conversation to a provided Markdown
|
||||
or JSON file.
|
||||
- **Usage** `/chat share file.md` or `/chat share file.json`. If no
|
||||
filename is provided, then the CLI will generate one.
|
||||
or JSON file. If no filename is provided, then the CLI will generate
|
||||
one.
|
||||
- **Usage** `/chat share file.md` or `/chat share file.json`.
|
||||
|
||||
- **`/clear`**
|
||||
- **Description:** Clear the terminal screen, including the visible session
|
||||
@@ -73,6 +78,9 @@ Slash commands provide meta-level control over the CLI itself.
|
||||
- **`/copy`**
|
||||
- **Description:** Copies the last output produced by Gemini CLI to your
|
||||
clipboard, for easy sharing or reuse.
|
||||
- **Behavior:**
|
||||
- Local sessions use system clipboard tools (pbcopy/xclip/clip).
|
||||
- Remote sessions (SSH/WSL) use OSC 52 and require terminal support.
|
||||
- **Note:** This command requires platform-specific clipboard tools to be
|
||||
installed.
|
||||
- On Linux, it requires `xclip` or `xsel`. You can typically install them
|
||||
@@ -95,6 +103,9 @@ Slash commands provide meta-level control over the CLI itself.
|
||||
`--include-directories`.
|
||||
- **Usage:** `/directory show`
|
||||
|
||||
- **`/docs`**
|
||||
- **Description:** Open the Gemini CLI documentation in your browser.
|
||||
|
||||
- **`/editor`**
|
||||
- **Description:** Open a dialog for selecting supported editors.
|
||||
|
||||
@@ -106,30 +117,65 @@ Slash commands provide meta-level control over the CLI itself.
|
||||
- **Description:** Display help information about Gemini CLI, including
|
||||
available commands and their usage.
|
||||
|
||||
- **`/hooks`**
|
||||
- **Description:** Manage hooks, which allow you to intercept and customize
|
||||
Gemini CLI behavior at specific lifecycle events.
|
||||
- **Sub-commands:**
|
||||
- **`disable-all`**:
|
||||
- **Description:** Disable all enabled hooks.
|
||||
- **`disable <hook-name>`**:
|
||||
- **Description:** Disable a hook by name.
|
||||
- **`enable-all`**:
|
||||
- **Description:** Enable all disabled hooks.
|
||||
- **`enable <hook-name>`**:
|
||||
- **Description:** Enable a hook by name.
|
||||
- **`list`** (or `show`, `panel`):
|
||||
- **Description:** Display all registered hooks with their status.
|
||||
|
||||
- **`/ide`**
|
||||
- **Description:** Manage IDE integration.
|
||||
- **Sub-commands:**
|
||||
- **`disable`**:
|
||||
- **Description:** Disable IDE integration.
|
||||
- **`enable`**:
|
||||
- **Description:** Enable IDE integration.
|
||||
- **`install`**:
|
||||
- **Description:** Install required IDE companion.
|
||||
- **`status`**:
|
||||
- **Description:** Check status of IDE integration.
|
||||
|
||||
- **`/init`**
|
||||
- **Description:** To help users easily create a `GEMINI.md` file, this
|
||||
command analyzes the current directory and generates a tailored context
|
||||
file, making it simpler for them to provide project-specific instructions to
|
||||
the Gemini agent.
|
||||
|
||||
- **`/introspect`**
|
||||
- **Description:** Provide debugging information about the current Gemini CLI
|
||||
session, including the state of loaded sub-agents and active hooks. This
|
||||
command is primarily for advanced users and developers.
|
||||
|
||||
- **`/mcp`**
|
||||
- **Description:** Manage configured Model Context Protocol (MCP) servers.
|
||||
- **Sub-commands:**
|
||||
- **`list`** or **`ls`**:
|
||||
- **Description:** List configured MCP servers and tools. This is the
|
||||
default action if no subcommand is specified.
|
||||
- **`desc`**
|
||||
- **Description:** List configured MCP servers and tools with
|
||||
descriptions.
|
||||
- **`schema`**:
|
||||
- **Description:** List configured MCP servers and tools with descriptions
|
||||
and schemas.
|
||||
- **`auth`**:
|
||||
- **Description:** Authenticate with an OAuth-enabled MCP server.
|
||||
- **Usage:** `/mcp auth <server-name>`
|
||||
- **Details:** If `<server-name>` is provided, it initiates the OAuth flow
|
||||
for that server. If no server name is provided, it lists all configured
|
||||
servers that support OAuth authentication.
|
||||
- **`desc`**
|
||||
- **Description:** List configured MCP servers and tools with
|
||||
descriptions.
|
||||
- **`list`** or **`ls`**:
|
||||
- **Description:** List configured MCP servers and tools. This is the
|
||||
default action if no subcommand is specified.
|
||||
- **`refresh`**:
|
||||
- **Description:** Restarts all MCP servers and re-discovers their
|
||||
available tools.
|
||||
|
||||
- [**`/model`**](./model.md)
|
||||
- **Description:** Opens a dialog to choose your Gemini model.
|
||||
- **`schema`**:
|
||||
- **Description:** List configured MCP servers and tools with descriptions
|
||||
and schemas.
|
||||
|
||||
- **`/memory`**
|
||||
- **Description:** Manage the AI's instructional context (hierarchical memory
|
||||
@@ -138,23 +184,40 @@ Slash commands provide meta-level control over the CLI itself.
|
||||
- **`add`**:
|
||||
- **Description:** Adds the following text to the AI's memory. Usage:
|
||||
`/memory add <text to remember>`
|
||||
- **`show`**:
|
||||
- **Description:** Display the full, concatenated content of the current
|
||||
hierarchical memory that has been loaded from all `GEMINI.md` files.
|
||||
This lets you inspect the instructional context being provided to the
|
||||
Gemini model.
|
||||
- **`list`**:
|
||||
- **Description:** Lists the paths of the GEMINI.md files in use for
|
||||
hierarchical memory.
|
||||
- **`refresh`**:
|
||||
- **Description:** Reload the hierarchical instructional memory from all
|
||||
`GEMINI.md` files found in the configured locations (global,
|
||||
project/ancestors, and sub-directories). This command updates the model
|
||||
with the latest `GEMINI.md` content.
|
||||
- **`list`**:
|
||||
- **Description:** Lists the paths of the GEMINI.md files in use for
|
||||
hierarchical memory.
|
||||
- **`show`**:
|
||||
- **Description:** Display the full, concatenated content of the current
|
||||
hierarchical memory that has been loaded from all `GEMINI.md` files.
|
||||
This lets you inspect the instructional context being provided to the
|
||||
Gemini model.
|
||||
- **Note:** For more details on how `GEMINI.md` files contribute to
|
||||
hierarchical memory, see the
|
||||
[CLI Configuration documentation](../get-started/configuration.md).
|
||||
|
||||
- [**`/model`**](./model.md)
|
||||
- **Description:** Opens a dialog to choose your Gemini model.
|
||||
|
||||
- **`/policies`**
|
||||
- **Description:** Manage policies.
|
||||
- **Sub-commands:**
|
||||
- **`list`**:
|
||||
- **Description:** List all active policies grouped by mode.
|
||||
|
||||
- **`/privacy`**
|
||||
- **Description:** Display the Privacy Notice and allow users to select
|
||||
whether they consent to the collection of their data for service improvement
|
||||
purposes.
|
||||
|
||||
- **`/quit`** (or **`/exit`**)
|
||||
- **Description:** Exit Gemini CLI.
|
||||
|
||||
- **`/restore`**
|
||||
- **Description:** Restores the project files to the state they were in just
|
||||
before a tool was executed. This is particularly useful for undoing file
|
||||
@@ -165,6 +228,28 @@ Slash commands provide meta-level control over the CLI itself.
|
||||
[settings](../get-started/configuration.md). See
|
||||
[Checkpointing documentation](../cli/checkpointing.md) for more details.
|
||||
|
||||
- [**`/rewind`**](./rewind.md)
|
||||
- **Description:** Navigates backward through the conversation history,
|
||||
allowing you to review past interactions and potentially revert to a
|
||||
previous state. This feature helps in managing complex or branched
|
||||
conversations.
|
||||
|
||||
- **`/resume`**
|
||||
- **Description:** Browse and resume previous conversation sessions. Opens an
|
||||
interactive session browser where you can search, filter, and select from
|
||||
automatically saved conversations.
|
||||
- **Features:**
|
||||
- **Management:** Delete unwanted sessions directly from the browser
|
||||
- **Resume:** Select any session to resume and continue the conversation
|
||||
- **Search:** Use `/` to search through conversation content across all
|
||||
sessions
|
||||
- **Session Browser:** Interactive interface showing all saved sessions with
|
||||
timestamps, message counts, and first user message for context
|
||||
- **Sorting:** Sort sessions by date or message count
|
||||
- **Note:** All conversations are automatically saved as you chat - no manual
|
||||
saving required. See [Session Management](../cli/session-management.md) for
|
||||
complete details.
|
||||
|
||||
- [**`/settings`**](./settings.md)
|
||||
- **Description:** Open the settings editor to view and modify Gemini CLI
|
||||
settings.
|
||||
@@ -179,6 +264,30 @@ Slash commands provide meta-level control over the CLI itself.
|
||||
modify them as desired. Changes to some settings are applied immediately,
|
||||
while others require a restart.
|
||||
|
||||
- **`/shells`** (or **`/bashes`**)
|
||||
- **Description:** Toggle the background shells view. This allows you to view
|
||||
and manage long-running processes that you've sent to the background.
|
||||
- **`/setup-github`**
|
||||
- **Description:** Set up GitHub Actions to triage issues and review PRs with
|
||||
Gemini.
|
||||
|
||||
- [**`/skills`**](./skills.md)
|
||||
- **Description:** Manage Agent Skills, which provide on-demand expertise and
|
||||
specialized workflows.
|
||||
- **Sub-commands:**
|
||||
- **`disable <name>`**:
|
||||
- **Description:** Disable a specific skill by name.
|
||||
- **Usage:** `/skills disable <name>`
|
||||
- **`enable <name>`**:
|
||||
- **Description:** Enable a specific skill by name.
|
||||
- **Usage:** `/skills enable <name>`
|
||||
- **`list`**:
|
||||
- **Description:** List all discovered skills and their current status
|
||||
(enabled/disabled).
|
||||
- **`reload`**:
|
||||
- **Description:** Refresh the list of discovered skills from all tiers
|
||||
(workspace, user, and extensions).
|
||||
|
||||
- **`/stats`**
|
||||
- **Description:** Display detailed statistics for the current Gemini CLI
|
||||
session, including token usage, cached token savings (when available), and
|
||||
@@ -186,18 +295,14 @@ Slash commands provide meta-level control over the CLI itself.
|
||||
cached tokens are being used, which occurs with API key authentication but
|
||||
not with OAuth authentication at this time.
|
||||
|
||||
- **`/terminal-setup`**
|
||||
- **Description:** Configure terminal keybindings for multiline input (VS
|
||||
Code, Cursor, Windsurf).
|
||||
|
||||
- [**`/theme`**](./themes.md)
|
||||
- **Description:** Open a dialog that lets you change the visual theme of
|
||||
Gemini CLI.
|
||||
|
||||
- **`/auth`**
|
||||
- **Description:** Open a dialog that lets you change the authentication
|
||||
method.
|
||||
|
||||
- **`/about`**
|
||||
- **Description:** Show version info. Please share this information when
|
||||
filing issues.
|
||||
|
||||
- [**`/tools`**](../tools/index.md)
|
||||
- **Description:** Display a list of tools that are currently available within
|
||||
Gemini CLI.
|
||||
@@ -209,55 +314,41 @@ Slash commands provide meta-level control over the CLI itself.
|
||||
- **`nodesc`** or **`nodescriptions`**:
|
||||
- **Description:** Hide tool descriptions, showing only the tool names.
|
||||
|
||||
- **`/privacy`**
|
||||
- **Description:** Display the Privacy Notice and allow users to select
|
||||
whether they consent to the collection of their data for service improvement
|
||||
purposes.
|
||||
|
||||
- **`/quit`** (or **`/exit`**)
|
||||
- **Description:** Exit Gemini CLI.
|
||||
|
||||
- **`/vim`**
|
||||
- **Description:** Toggle vim mode on or off. When vim mode is enabled, the
|
||||
input area supports vim-style navigation and editing commands in both NORMAL
|
||||
and INSERT modes.
|
||||
- **Features:**
|
||||
- **Count support:** Prefix commands with numbers (e.g., `3h`, `5w`, `10G`)
|
||||
- **Editing commands:** Delete with `x`, change with `c`, insert with `i`,
|
||||
`a`, `o`, `O`; complex operations like `dd`, `cc`, `dw`, `cw`
|
||||
- **INSERT mode:** Standard text input with escape to return to NORMAL mode
|
||||
- **NORMAL mode:** Navigate with `h`, `j`, `k`, `l`; jump by words with `w`,
|
||||
`b`, `e`; go to line start/end with `0`, `$`, `^`; go to specific lines
|
||||
with `G` (or `gg` for first line)
|
||||
- **INSERT mode:** Standard text input with escape to return to NORMAL mode
|
||||
- **Editing commands:** Delete with `x`, change with `c`, insert with `i`,
|
||||
`a`, `o`, `O`; complex operations like `dd`, `cc`, `dw`, `cw`
|
||||
- **Count support:** Prefix commands with numbers (e.g., `3h`, `5w`, `10G`)
|
||||
- **Repeat last command:** Use `.` to repeat the last editing operation
|
||||
- **Persistent setting:** Vim mode preference is saved to
|
||||
`~/.gemini/settings.json` and restored between sessions
|
||||
- **Status indicator:** When enabled, shows `[NORMAL]` or `[INSERT]` in the
|
||||
footer
|
||||
- **Repeat last command:** Use `.` to repeat the last editing operation
|
||||
- **Status indicator:** When enabled, shows `[NORMAL]` or `[INSERT]` in the
|
||||
footer
|
||||
|
||||
- **`/init`**
|
||||
- **Description:** To help users easily create a `GEMINI.md` file, this
|
||||
command analyzes the current directory and generates a tailored context
|
||||
file, making it simpler for them to provide project-specific instructions to
|
||||
the Gemini agent.
|
||||
|
||||
### Custom Commands
|
||||
### Custom commands
|
||||
|
||||
Custom commands allow you to create personalized shortcuts for your most-used
|
||||
prompts. For detailed instructions on how to create, manage, and use them,
|
||||
please see the dedicated [Custom Commands documentation](./custom-commands.md).
|
||||
|
||||
## Input Prompt Shortcuts
|
||||
## Input prompt shortcuts
|
||||
|
||||
These shortcuts apply directly to the input prompt for text manipulation.
|
||||
|
||||
- **Undo:**
|
||||
- **Keyboard shortcut:** Press **Ctrl+z** to undo the last action in the input
|
||||
prompt.
|
||||
- **Keyboard shortcut:** Press **Cmd+z** or **Alt+z** to undo the last action
|
||||
in the input prompt.
|
||||
|
||||
- **Redo:**
|
||||
- **Keyboard shortcut:** Press **Ctrl+Shift+Z** to redo the last undone action
|
||||
in the input prompt.
|
||||
- **Keyboard shortcut:** Press **Shift+Cmd+Z** or **Shift+Alt+Z** to redo the
|
||||
last undone action in the input prompt.
|
||||
|
||||
## At commands (`@`)
|
||||
|
||||
@@ -305,7 +396,7 @@ your prompt to Gemini. These commands include git-aware filtering.
|
||||
- If the `read_many_files` tool encounters an error (e.g., permission issues),
|
||||
this will also be reported.
|
||||
|
||||
## Shell mode & passthrough commands (`!`)
|
||||
## Shell mode and passthrough commands (`!`)
|
||||
|
||||
The `!` prefix lets you interact with your system's shell directly from within
|
||||
Gemini CLI.
|
||||
@@ -333,7 +424,7 @@ Gemini CLI.
|
||||
- **Caution for all `!` usage:** Commands you execute in shell mode have the
|
||||
same permissions and impact as if you ran them directly in your terminal.
|
||||
|
||||
- **Environment Variable:** When a command is executed via `!` or in shell mode,
|
||||
- **Environment variable:** When a command is executed via `!` or in shell mode,
|
||||
the `GEMINI_CLI=1` environment variable is set in the subprocess's
|
||||
environment. This allows scripts or tools to detect if they are being run from
|
||||
within the Gemini CLI.
|
||||
|
||||
@@ -1,768 +0,0 @@
|
||||
# Gemini CLI Configuration
|
||||
|
||||
Gemini CLI offers several ways to configure its behavior, including environment
|
||||
variables, command-line arguments, and settings files. This document outlines
|
||||
the different configuration methods and available settings.
|
||||
|
||||
## Configuration layers
|
||||
|
||||
Configuration is applied in the following order of precedence (lower numbers are
|
||||
overridden by higher numbers):
|
||||
|
||||
1. **Default values:** Hardcoded defaults within the application.
|
||||
2. **User settings file:** Global settings for the current user.
|
||||
3. **Project settings file:** Project-specific settings.
|
||||
4. **System settings file:** System-wide settings.
|
||||
5. **Environment variables:** System-wide or session-specific variables,
|
||||
potentially loaded from `.env` files.
|
||||
6. **Command-line arguments:** Values passed when launching the CLI.
|
||||
|
||||
## Settings files
|
||||
|
||||
Gemini CLI uses `settings.json` files for persistent configuration. There are
|
||||
three locations for these files:
|
||||
|
||||
- **User settings file:**
|
||||
- **Location:** `~/.gemini/settings.json` (where `~` is your home directory).
|
||||
- **Scope:** Applies to all Gemini CLI sessions for the current user.
|
||||
- **Project settings file:**
|
||||
- **Location:** `.gemini/settings.json` within your project's root directory.
|
||||
- **Scope:** Applies only when running Gemini CLI from that specific project.
|
||||
Project settings override user settings.
|
||||
- **System settings file:**
|
||||
- **Location:** `/etc/gemini-cli/settings.json` (Linux),
|
||||
`C:\ProgramData\gemini-cli\settings.json` (Windows) or
|
||||
`/Library/Application Support/GeminiCli/settings.json` (macOS). The path can
|
||||
be overridden using the `GEMINI_CLI_SYSTEM_SETTINGS_PATH` environment
|
||||
variable.
|
||||
- **Scope:** Applies to all Gemini CLI sessions on the system, for all users.
|
||||
System settings override user and project settings. May be useful for system
|
||||
administrators at enterprises to have controls over users' Gemini CLI
|
||||
setups.
|
||||
|
||||
**Note on environment variables in settings:** String values within your
|
||||
`settings.json` files can reference environment variables using either
|
||||
`$VAR_NAME` or `${VAR_NAME}` syntax. These variables will be automatically
|
||||
resolved when the settings are loaded. For example, if you have an environment
|
||||
variable `MY_API_TOKEN`, you could use it in `settings.json` like this:
|
||||
`"apiKey": "$MY_API_TOKEN"`.
|
||||
|
||||
### The `.gemini` directory in your project
|
||||
|
||||
In addition to a project settings file, a project's `.gemini` directory can
|
||||
contain other project-specific files related to Gemini CLI's operation, such as:
|
||||
|
||||
- [Custom sandbox profiles](#sandboxing) (e.g.,
|
||||
`.gemini/sandbox-macos-custom.sb`, `.gemini/sandbox.Dockerfile`).
|
||||
|
||||
### Available settings in `settings.json`:
|
||||
|
||||
- **`contextFileName`** (string or array of strings):
|
||||
- **Description:** Specifies the filename for context files (e.g.,
|
||||
`GEMINI.md`, `AGENTS.md`). Can be a single filename or a list of accepted
|
||||
filenames.
|
||||
- **Default:** `GEMINI.md`
|
||||
- **Example:** `"contextFileName": "AGENTS.md"`
|
||||
|
||||
- **`bugCommand`** (object):
|
||||
- **Description:** Overrides the default URL for the `/bug` command.
|
||||
- **Default:**
|
||||
`"urlTemplate": "https://github.com/google-gemini/gemini-cli/issues/new?template=bug_report.yml&title={title}&info={info}"`
|
||||
- **Properties:**
|
||||
- **`urlTemplate`** (string): A URL that can contain `{title}` and `{info}`
|
||||
placeholders.
|
||||
- **Example:**
|
||||
```json
|
||||
"bugCommand": {
|
||||
"urlTemplate": "https://bug.example.com/new?title={title}&info={info}"
|
||||
}
|
||||
```
|
||||
|
||||
- **`fileFiltering`** (object):
|
||||
- **Description:** Controls git-aware file filtering behavior for @ commands
|
||||
and file discovery tools.
|
||||
- **Default:** `"respectGitIgnore": true, "enableRecursiveFileSearch": true`
|
||||
- **Properties:**
|
||||
- **`respectGitIgnore`** (boolean): Whether to respect .gitignore patterns
|
||||
when discovering files. When set to `true`, git-ignored files (like
|
||||
`node_modules/`, `dist/`, `.env`) are automatically excluded from @
|
||||
commands and file listing operations.
|
||||
- **`enableRecursiveFileSearch`** (boolean): Whether to enable searching
|
||||
recursively for filenames under the current tree when completing @
|
||||
prefixes in the prompt.
|
||||
- **Example:**
|
||||
```json
|
||||
"fileFiltering": {
|
||||
"respectGitIgnore": true,
|
||||
"enableRecursiveFileSearch": false
|
||||
}
|
||||
```
|
||||
|
||||
- **`coreTools`** (array of strings):
|
||||
- **Description:** Allows you to specify a list of core tool names that should
|
||||
be made available to the model. This can be used to restrict the set of
|
||||
built-in tools. See [Built-in Tools](../core/tools-api.md#built-in-tools)
|
||||
for a list of core tools. You can also specify command-specific restrictions
|
||||
for tools that support it, like the `ShellTool`. For example,
|
||||
`"coreTools": ["ShellTool(ls -l)"]` will only allow the `ls -l` command to
|
||||
be executed.
|
||||
- **Default:** All tools available for use by the Gemini model.
|
||||
- **Example:** `"coreTools": ["ReadFileTool", "GlobTool", "ShellTool(ls)"]`.
|
||||
|
||||
- **`excludeTools`** (array of strings):
|
||||
- **Description:** Allows you to specify a list of core tool names that should
|
||||
be excluded from the model. A tool listed in both `excludeTools` and
|
||||
`coreTools` is excluded. You can also specify command-specific restrictions
|
||||
for tools that support it, like the `ShellTool`. For example,
|
||||
`"excludeTools": ["ShellTool(rm -rf)"]` will block the `rm -rf` command.
|
||||
- **Default**: No tools excluded.
|
||||
- **Example:** `"excludeTools": ["run_shell_command", "findFiles"]`.
|
||||
- **Security Note:** Command-specific restrictions in `excludeTools` for
|
||||
`run_shell_command` are based on simple string matching and can be easily
|
||||
bypassed. This feature is **not a security mechanism** and should not be
|
||||
relied upon to safely execute untrusted code. It is recommended to use
|
||||
`coreTools` to explicitly select commands that can be executed.
|
||||
|
||||
- **`allowMCPServers`** (array of strings):
|
||||
- **Description:** Allows you to specify a list of MCP server names that
|
||||
should be made available to the model. This can be used to restrict the set
|
||||
of MCP servers to connect to. Note that this will be ignored if
|
||||
`--allowed-mcp-server-names` is set.
|
||||
- **Default:** All MCP servers are available for use by the Gemini model.
|
||||
- **Example:** `"allowMCPServers": ["myPythonServer"]`.
|
||||
- **Security Note:** This uses simple string matching on MCP server names,
|
||||
which can be modified. If you're a system administrator looking to prevent
|
||||
users from bypassing this, consider configuring the `mcpServers` at the
|
||||
system settings level such that the user will not be able to configure any
|
||||
MCP servers of their own. This should not be used as an airtight security
|
||||
mechanism.
|
||||
|
||||
- **`excludeMCPServers`** (array of strings):
|
||||
- **Description:** Allows you to specify a list of MCP server names that
|
||||
should be excluded from the model. A server listed in both
|
||||
`excludeMCPServers` and `allowMCPServers` is excluded. Note that this will
|
||||
be ignored if `--allowed-mcp-server-names` is set.
|
||||
- **Default**: No MCP servers excluded.
|
||||
- **Example:** `"excludeMCPServers": ["myNodeServer"]`.
|
||||
- **Security Note:** This uses simple string matching on MCP server names,
|
||||
which can be modified. If you're a system administrator looking to prevent
|
||||
users from bypassing this, consider configuring the `mcpServers` at the
|
||||
system settings level such that the user will not be able to configure any
|
||||
MCP servers of their own. This should not be used as an airtight security
|
||||
mechanism.
|
||||
|
||||
- **`autoAccept`** (boolean):
|
||||
- **Description:** Controls whether the CLI automatically accepts and executes
|
||||
tool calls that are considered safe (e.g., read-only operations) without
|
||||
explicit user confirmation. If set to `true`, the CLI will bypass the
|
||||
confirmation prompt for tools deemed safe.
|
||||
- **Default:** `false`
|
||||
- **Example:** `"autoAccept": true`
|
||||
|
||||
- **`theme`** (string):
|
||||
- **Description:** Sets the visual [theme](./themes.md) for Gemini CLI.
|
||||
- **Default:** `"Default"`
|
||||
- **Example:** `"theme": "GitHub"`
|
||||
|
||||
- **`vimMode`** (boolean):
|
||||
- **Description:** Enables or disables vim mode for input editing. When
|
||||
enabled, the input area supports vim-style navigation and editing commands
|
||||
with NORMAL and INSERT modes. The vim mode status is displayed in the footer
|
||||
and persists between sessions.
|
||||
- **Default:** `false`
|
||||
- **Example:** `"vimMode": true`
|
||||
|
||||
- **`sandbox`** (boolean or string):
|
||||
- **Description:** Controls whether and how to use sandboxing for tool
|
||||
execution. If set to `true`, Gemini CLI uses a pre-built
|
||||
`gemini-cli-sandbox` Docker image. For more information, see
|
||||
[Sandboxing](#sandboxing).
|
||||
- **Default:** `false`
|
||||
- **Example:** `"sandbox": "docker"`
|
||||
|
||||
- **`toolDiscoveryCommand`** (string):
|
||||
- **Description:** Defines a custom shell command for discovering tools from
|
||||
your project. The shell command must return on `stdout` a JSON array of
|
||||
[function declarations](https://ai.google.dev/gemini-api/docs/function-calling#function-declarations).
|
||||
Tool wrappers are optional.
|
||||
- **Default:** Empty
|
||||
- **Example:** `"toolDiscoveryCommand": "bin/get_tools"`
|
||||
|
||||
- **`toolCallCommand`** (string):
|
||||
- **Description:** Defines a custom shell command for calling a specific tool
|
||||
that was discovered using `toolDiscoveryCommand`. The shell command must
|
||||
meet the following criteria:
|
||||
- It must take function `name` (exactly as in
|
||||
[function declaration](https://ai.google.dev/gemini-api/docs/function-calling#function-declarations))
|
||||
as first command line argument.
|
||||
- It must read function arguments as JSON on `stdin`, analogous to
|
||||
[`functionCall.args`](https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/inference#functioncall).
|
||||
- It must return function output as JSON on `stdout`, analogous to
|
||||
[`functionResponse.response.content`](https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/inference#functionresponse).
|
||||
- **Default:** Empty
|
||||
- **Example:** `"toolCallCommand": "bin/call_tool"`
|
||||
|
||||
- **`mcpServers`** (object):
|
||||
- **Description:** Configures connections to one or more Model-Context
|
||||
Protocol (MCP) servers for discovering and using custom tools. Gemini CLI
|
||||
attempts to connect to each configured MCP server to discover available
|
||||
tools. If multiple MCP servers expose a tool with the same name, the tool
|
||||
names will be prefixed with the server alias you defined in the
|
||||
configuration (e.g., `serverAlias__actualToolName`) to avoid conflicts. Note
|
||||
that the system might strip certain schema properties from MCP tool
|
||||
definitions for compatibility.
|
||||
- **Default:** Empty
|
||||
- **Properties:**
|
||||
- **`<SERVER_NAME>`** (object): The server parameters for the named server.
|
||||
- `command` (string, required): The command to execute to start the MCP
|
||||
server.
|
||||
- `args` (array of strings, optional): Arguments to pass to the command.
|
||||
- `env` (object, optional): Environment variables to set for the server
|
||||
process.
|
||||
- `cwd` (string, optional): The working directory in which to start the
|
||||
server.
|
||||
- `timeout` (number, optional): Timeout in milliseconds for requests to
|
||||
this MCP server.
|
||||
- `trust` (boolean, optional): Trust this server and bypass all tool call
|
||||
confirmations.
|
||||
- `includeTools` (array of strings, optional): List of tool names to
|
||||
include from this MCP server. When specified, only the tools listed here
|
||||
will be available from this server (whitelist behavior). If not
|
||||
specified, all tools from the server are enabled by default.
|
||||
- `excludeTools` (array of strings, optional): List of tool names to
|
||||
exclude from this MCP server. Tools listed here will not be available to
|
||||
the model, even if they are exposed by the server. **Note:**
|
||||
`excludeTools` takes precedence over `includeTools` - if a tool is in
|
||||
both lists, it will be excluded.
|
||||
- **Example:**
|
||||
```json
|
||||
"mcpServers": {
|
||||
"myPythonServer": {
|
||||
"command": "python",
|
||||
"args": ["mcp_server.py", "--port", "8080"],
|
||||
"cwd": "./mcp_tools/python",
|
||||
"timeout": 5000,
|
||||
"includeTools": ["safe_tool", "file_reader"],
|
||||
},
|
||||
"myNodeServer": {
|
||||
"command": "node",
|
||||
"args": ["mcp_server.js"],
|
||||
"cwd": "./mcp_tools/node",
|
||||
"excludeTools": ["dangerous_tool", "file_deleter"]
|
||||
},
|
||||
"myDockerServer": {
|
||||
"command": "docker",
|
||||
"args": ["run", "-i", "--rm", "-e", "API_KEY", "ghcr.io/foo/bar"],
|
||||
"env": {
|
||||
"API_KEY": "$MY_API_TOKEN"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- **`checkpointing`** (object):
|
||||
- **Description:** Configures the checkpointing feature, which allows you to
|
||||
save and restore conversation and file states. See the
|
||||
[Checkpointing documentation](./checkpointing.md) for more details.
|
||||
- **Default:** `{"enabled": false}`
|
||||
- **Properties:**
|
||||
- **`enabled`** (boolean): When `true`, the `/restore` command is available.
|
||||
|
||||
- **`preferredEditor`** (string):
|
||||
- **Description:** Specifies the preferred editor to use for viewing diffs.
|
||||
- **Default:** `vscode`
|
||||
- **Example:** `"preferredEditor": "vscode"`
|
||||
|
||||
- **`telemetry`** (object)
|
||||
- **Description:** Configures logging and metrics collection for Gemini CLI.
|
||||
For more information, see [Telemetry](./telemetry.md).
|
||||
- **Default:**
|
||||
`{"enabled": false, "target": "local", "otlpEndpoint": "http://localhost:4317", "logPrompts": true}`
|
||||
- **Properties:**
|
||||
- **`enabled`** (boolean): Whether or not telemetry is enabled.
|
||||
- **`target`** (string): The destination for collected telemetry. Supported
|
||||
values are `local` and `gcp`.
|
||||
- **`otlpEndpoint`** (string): The endpoint for the OTLP Exporter.
|
||||
- **`logPrompts`** (boolean): Whether or not to include the content of user
|
||||
prompts in the logs.
|
||||
- **Example:**
|
||||
```json
|
||||
"telemetry": {
|
||||
"enabled": true,
|
||||
"target": "local",
|
||||
"otlpEndpoint": "http://localhost:16686",
|
||||
"logPrompts": false
|
||||
}
|
||||
```
|
||||
- **`usageStatisticsEnabled`** (boolean):
|
||||
- **Description:** Enables or disables the collection of usage statistics. See
|
||||
[Usage Statistics](#usage-statistics) for more information.
|
||||
- **Default:** `true`
|
||||
- **Example:**
|
||||
```json
|
||||
"usageStatisticsEnabled": false
|
||||
```
|
||||
|
||||
- **`hideTips`** (boolean):
|
||||
- **Description:** Enables or disables helpful tips in the CLI interface.
|
||||
- **Default:** `false`
|
||||
- **Example:**
|
||||
|
||||
```json
|
||||
"hideTips": true
|
||||
```
|
||||
|
||||
- **`hideBanner`** (boolean):
|
||||
- **Description:** Enables or disables the startup banner (ASCII art logo) in
|
||||
the CLI interface.
|
||||
- **Default:** `false`
|
||||
- **Example:**
|
||||
|
||||
```json
|
||||
"hideBanner": true
|
||||
```
|
||||
|
||||
- **`maxSessionTurns`** (number):
|
||||
- **Description:** Sets the maximum number of turns for a session. If the
|
||||
session exceeds this limit, the CLI will stop processing and start a new
|
||||
chat.
|
||||
- **Default:** `-1` (unlimited)
|
||||
- **Example:**
|
||||
```json
|
||||
"maxSessionTurns": 10
|
||||
```
|
||||
|
||||
- **`summarizeToolOutput`** (object):
|
||||
- **Description:** Enables or disables the summarization of tool output. You
|
||||
can specify the token budget for the summarization using the `tokenBudget`
|
||||
setting.
|
||||
- Note: Currently only the `run_shell_command` tool is supported.
|
||||
- **Default:** `{}` (Disabled by default)
|
||||
- **Example:**
|
||||
```json
|
||||
"summarizeToolOutput": {
|
||||
"run_shell_command": {
|
||||
"tokenBudget": 2000
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- **`excludedProjectEnvVars`** (array of strings):
|
||||
- **Description:** Specifies environment variables that should be excluded
|
||||
from being loaded from project `.env` files. This prevents project-specific
|
||||
environment variables (like `DEBUG=true`) from interfering with gemini-cli
|
||||
behavior. Variables from `.gemini/.env` files are never excluded.
|
||||
- **Default:** `["DEBUG", "DEBUG_MODE"]`
|
||||
- **Example:**
|
||||
```json
|
||||
"excludedProjectEnvVars": ["DEBUG", "DEBUG_MODE", "NODE_ENV"]
|
||||
```
|
||||
|
||||
- **`includeDirectories`** (array of strings):
|
||||
- **Description:** Specifies an array of additional absolute or relative paths
|
||||
to include in the workspace context. This allows you to work with files
|
||||
across multiple directories as if they were one. Paths can use `~` to refer
|
||||
to the user's home directory. This setting can be combined with the
|
||||
`--include-directories` command-line flag.
|
||||
- **Default:** `[]`
|
||||
- **Example:**
|
||||
```json
|
||||
"includeDirectories": [
|
||||
"/path/to/another/project",
|
||||
"../shared-library",
|
||||
"~/common-utils"
|
||||
]
|
||||
```
|
||||
|
||||
- **`loadMemoryFromIncludeDirectories`** (boolean):
|
||||
- **Description:** Controls the behavior of the `/memory refresh` command. If
|
||||
set to `true`, `GEMINI.md` files should be loaded from all directories that
|
||||
are added. If set to `false`, `GEMINI.md` should only be loaded from the
|
||||
current directory.
|
||||
- **Default:** `false`
|
||||
- **Example:**
|
||||
```json
|
||||
"loadMemoryFromIncludeDirectories": true
|
||||
```
|
||||
|
||||
### Example `settings.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"theme": "GitHub",
|
||||
"sandbox": "docker",
|
||||
"toolDiscoveryCommand": "bin/get_tools",
|
||||
"toolCallCommand": "bin/call_tool",
|
||||
"mcpServers": {
|
||||
"mainServer": {
|
||||
"command": "bin/mcp_server.py"
|
||||
},
|
||||
"anotherServer": {
|
||||
"command": "node",
|
||||
"args": ["mcp_server.js", "--verbose"]
|
||||
}
|
||||
},
|
||||
"telemetry": {
|
||||
"enabled": true,
|
||||
"target": "local",
|
||||
"otlpEndpoint": "http://localhost:4317",
|
||||
"logPrompts": true
|
||||
},
|
||||
"usageStatisticsEnabled": true,
|
||||
"hideTips": false,
|
||||
"hideBanner": false,
|
||||
"maxSessionTurns": 10,
|
||||
"summarizeToolOutput": {
|
||||
"run_shell_command": {
|
||||
"tokenBudget": 100
|
||||
}
|
||||
},
|
||||
"excludedProjectEnvVars": ["DEBUG", "DEBUG_MODE", "NODE_ENV"],
|
||||
"includeDirectories": ["path/to/dir1", "~/path/to/dir2", "../path/to/dir3"],
|
||||
"loadMemoryFromIncludeDirectories": true
|
||||
}
|
||||
```
|
||||
|
||||
## Shell History
|
||||
|
||||
The CLI keeps a history of shell commands you run. To avoid conflicts between
|
||||
different projects, this history is stored in a project-specific directory
|
||||
within your user's home folder.
|
||||
|
||||
- **Location:** `~/.gemini/tmp/<project_hash>/shell_history`
|
||||
- `<project_hash>` is a unique identifier generated from your project's root
|
||||
path.
|
||||
- The history is stored in a file named `shell_history`.
|
||||
|
||||
## Environment Variables & `.env` Files
|
||||
|
||||
Environment variables are a common way to configure applications, especially for
|
||||
sensitive information like API keys or for settings that might change between
|
||||
environments.
|
||||
|
||||
The CLI automatically loads environment variables from an `.env` file. The
|
||||
loading order is:
|
||||
|
||||
1. `.env` file in the current working directory.
|
||||
2. If not found, it searches upwards in parent directories until it finds an
|
||||
`.env` file or reaches the project root (identified by a `.git` folder) or
|
||||
the home directory.
|
||||
3. If still not found, it looks for `~/.env` (in the user's home directory).
|
||||
|
||||
**Environment Variable Exclusion:** Some environment variables (like `DEBUG` and
|
||||
`DEBUG_MODE`) are automatically excluded from being loaded from project `.env`
|
||||
files to prevent interference with gemini-cli behavior. Variables from
|
||||
`.gemini/.env` files are never excluded. You can customize this behavior using
|
||||
the `excludedProjectEnvVars` setting in your `settings.json` file.
|
||||
|
||||
- **`GEMINI_API_KEY`** (Required):
|
||||
- Your API key for the Gemini API.
|
||||
- **Crucial for operation.** The CLI will not function without it.
|
||||
- Set this in your shell profile (e.g., `~/.bashrc`, `~/.zshrc`) or an `.env`
|
||||
file.
|
||||
- **`GEMINI_MODEL`**:
|
||||
- Specifies the default Gemini model to use.
|
||||
- Overrides the hardcoded default
|
||||
- Example: `export GEMINI_MODEL="gemini-2.5-flash"`
|
||||
- **`GOOGLE_API_KEY`**:
|
||||
- Your Google Cloud API key.
|
||||
- Required for using Vertex AI in express mode.
|
||||
- Ensure you have the necessary permissions.
|
||||
- Example: `export GOOGLE_API_KEY="YOUR_GOOGLE_API_KEY"`.
|
||||
- **`GOOGLE_CLOUD_PROJECT`**:
|
||||
- Your Google Cloud Project ID.
|
||||
- Required for using Code Assist or Vertex AI.
|
||||
- If using Vertex AI, ensure you have the necessary permissions in this
|
||||
project.
|
||||
- **Cloud Shell Note:** When running in a Cloud Shell environment, this
|
||||
variable defaults to a special project allocated for Cloud Shell users. If
|
||||
you have `GOOGLE_CLOUD_PROJECT` set in your global environment in Cloud
|
||||
Shell, it will be overridden by this default. To use a different project in
|
||||
Cloud Shell, you must define `GOOGLE_CLOUD_PROJECT` in a `.env` file.
|
||||
- Example: `export GOOGLE_CLOUD_PROJECT="YOUR_PROJECT_ID"`.
|
||||
- **`GOOGLE_APPLICATION_CREDENTIALS`** (string):
|
||||
- **Description:** The path to your Google Application Credentials JSON file.
|
||||
- **Example:**
|
||||
`export GOOGLE_APPLICATION_CREDENTIALS="/path/to/your/credentials.json"`
|
||||
- **`OTLP_GOOGLE_CLOUD_PROJECT`**:
|
||||
- Your Google Cloud Project ID for Telemetry in Google Cloud
|
||||
- Example: `export OTLP_GOOGLE_CLOUD_PROJECT="YOUR_PROJECT_ID"`.
|
||||
- **`GOOGLE_CLOUD_LOCATION`**:
|
||||
- Your Google Cloud Project Location (e.g., us-central1).
|
||||
- Required for using Vertex AI in non express mode.
|
||||
- Example: `export GOOGLE_CLOUD_LOCATION="YOUR_PROJECT_LOCATION"`.
|
||||
- **`GEMINI_SANDBOX`**:
|
||||
- Alternative to the `sandbox` setting in `settings.json`.
|
||||
- Accepts `true`, `false`, `docker`, `podman`, or a custom command string.
|
||||
- **`SEATBELT_PROFILE`** (macOS specific):
|
||||
- Switches the Seatbelt (`sandbox-exec`) profile on macOS.
|
||||
- `permissive-open`: (Default) Restricts writes to the project folder (and a
|
||||
few other folders, see
|
||||
`packages/cli/src/utils/sandbox-macos-permissive-open.sb`) but allows other
|
||||
operations.
|
||||
- `strict`: Uses a strict profile that declines operations by default.
|
||||
- `<profile_name>`: Uses a custom profile. To define a custom profile, create
|
||||
a file named `sandbox-macos-<profile_name>.sb` in your project's `.gemini/`
|
||||
directory (e.g., `my-project/.gemini/sandbox-macos-custom.sb`).
|
||||
- **`DEBUG` or `DEBUG_MODE`** (often used by underlying libraries or the CLI
|
||||
itself):
|
||||
- Set to `true` or `1` to enable verbose debug logging, which can be helpful
|
||||
for troubleshooting.
|
||||
- **Note:** These variables are automatically excluded from project `.env`
|
||||
files by default to prevent interference with gemini-cli behavior. Use
|
||||
`.gemini/.env` files if you need to set these for gemini-cli specifically.
|
||||
- **`NO_COLOR`**:
|
||||
- Set to any value to disable all color output in the CLI.
|
||||
- **`CLI_TITLE`**:
|
||||
- Set to a string to customize the title of the CLI.
|
||||
- **`CODE_ASSIST_ENDPOINT`**:
|
||||
- Specifies the endpoint for the code assist server.
|
||||
- This is useful for development and testing.
|
||||
- **`GEMINI_SYSTEM_MD`**:
|
||||
- Overrides the base system prompt with the contents of a Markdown file.
|
||||
- If set to `1` or `true`, it uses the file at `.gemini/system.md`.
|
||||
- If set to a file path, it uses that file. The path can be absolute or
|
||||
relative. `~` is supported for the home directory.
|
||||
- The specified file must exist.
|
||||
- **`GEMINI_WRITE_SYSTEM_MD`**:
|
||||
- Writes the default system prompt to a file. This is useful for getting a
|
||||
template to customize.
|
||||
- If set to `1` or `true`, it writes to `.gemini/system.md`.
|
||||
- If set to a file path, it writes to that path. The path can be absolute or
|
||||
relative. `~` is supported for the home directory. **Note: This will
|
||||
overwrite the file if it already exists.**
|
||||
|
||||
## Command-Line Arguments
|
||||
|
||||
Arguments passed directly when running the CLI can override other configurations
|
||||
for that specific session.
|
||||
|
||||
- **`--model <model_name>`** (**`-m <model_name>`**):
|
||||
- Specifies the Gemini model to use for this session.
|
||||
- Example: `npm start -- --model gemini-1.5-pro-latest`
|
||||
- **`--prompt <your_prompt>`** (**`-p <your_prompt>`**):
|
||||
- Used to pass a prompt directly to the command. This invokes Gemini CLI in a
|
||||
non-interactive mode.
|
||||
- **`--prompt-interactive <your_prompt>`** (**`-i <your_prompt>`**):
|
||||
- Starts an interactive session with the provided prompt as the initial input.
|
||||
- The prompt is processed within the interactive session, not before it.
|
||||
- Cannot be used when piping input from stdin.
|
||||
- Example: `gemini -i "explain this code"`
|
||||
- **`--sandbox`** (**`-s`**):
|
||||
- Enables sandbox mode for this session.
|
||||
- **`--sandbox-image`**:
|
||||
- Sets the sandbox image URI.
|
||||
- **`--debug`** (**`-d`**):
|
||||
- Enables debug mode for this session, providing more verbose output.
|
||||
- **`--all-files`** (**`-a`**):
|
||||
- If set, recursively includes all files within the current directory as
|
||||
context for the prompt.
|
||||
- **`--help`** (or **`-h`**):
|
||||
- Displays help information about command-line arguments.
|
||||
- **`--show-memory-usage`**:
|
||||
- Displays the current memory usage.
|
||||
- **`--yolo`**:
|
||||
- Enables YOLO mode, which automatically approves all tool calls.
|
||||
- **`--telemetry`**:
|
||||
- Enables [telemetry](./telemetry.md).
|
||||
- **`--telemetry-target`**:
|
||||
- Sets the telemetry target. See [telemetry](./telemetry.md) for more
|
||||
information.
|
||||
- **`--telemetry-otlp-endpoint`**:
|
||||
- Sets the OTLP endpoint for telemetry. See [telemetry](./telemetry.md) for
|
||||
more information.
|
||||
- **`--telemetry-log-prompts`**:
|
||||
- Enables logging of prompts for telemetry. See [telemetry](./telemetry.md)
|
||||
for more information.
|
||||
- **`--extensions <extension_name ...>`** (**`-e <extension_name ...>`**):
|
||||
- Specifies a list of extensions to use for the session. If not provided, all
|
||||
available extensions are used.
|
||||
- Use the special term `gemini -e none` to disable all extensions.
|
||||
- Example: `gemini -e my-extension -e my-other-extension`
|
||||
- **`--list-extensions`** (**`-l`**):
|
||||
- Lists all available extensions and exits.
|
||||
- **`--proxy`**:
|
||||
- Sets the proxy for the CLI.
|
||||
- Example: `--proxy http://localhost:7890`.
|
||||
- **`--include-directories <dir1,dir2,...>`**:
|
||||
- Includes additional directories in the workspace for multi-directory
|
||||
support.
|
||||
- Can be specified multiple times or as comma-separated values.
|
||||
- 5 directories can be added at maximum.
|
||||
- Example: `--include-directories /path/to/project1,/path/to/project2` or
|
||||
`--include-directories /path/to/project1 --include-directories /path/to/project2`
|
||||
- **`--version`**:
|
||||
- Displays the version of the CLI.
|
||||
|
||||
## Context Files (Hierarchical Instructional Context)
|
||||
|
||||
While not strictly configuration for the CLI's _behavior_, context files
|
||||
(defaulting to `GEMINI.md` but configurable via the `contextFileName` setting)
|
||||
are crucial for configuring the _instructional context_ (also referred to as
|
||||
"memory") provided to the Gemini model. This powerful feature allows you to give
|
||||
project-specific instructions, coding style guides, or any relevant background
|
||||
information to the AI, making its responses more tailored and accurate to your
|
||||
needs. The CLI includes UI elements, such as an indicator in the footer showing
|
||||
the number of loaded context files, to keep you informed about the active
|
||||
context.
|
||||
|
||||
- **Purpose:** These Markdown files contain instructions, guidelines, or context
|
||||
that you want the Gemini model to be aware of during your interactions. The
|
||||
system is designed to manage this instructional context hierarchically.
|
||||
|
||||
### Example Context File Content (e.g., `GEMINI.md`)
|
||||
|
||||
Here's a conceptual example of what a context file at the root of a TypeScript
|
||||
project might contain:
|
||||
|
||||
```markdown
|
||||
# Project: My Awesome TypeScript Library
|
||||
|
||||
## General Instructions:
|
||||
|
||||
- When generating new TypeScript code, please follow the existing coding style.
|
||||
- Ensure all new functions and classes have JSDoc comments.
|
||||
- Prefer functional programming paradigms where appropriate.
|
||||
- All code should be compatible with TypeScript 5.0 and Node.js 20+.
|
||||
|
||||
## Coding Style:
|
||||
|
||||
- Use 2 spaces for indentation.
|
||||
- Interface names should be prefixed with `I` (e.g., `IUserService`).
|
||||
- Private class members should be prefixed with an underscore (`_`).
|
||||
- Always use strict equality (`===` and `!==`).
|
||||
|
||||
## Specific Component: `src/api/client.ts`
|
||||
|
||||
- This file handles all outbound API requests.
|
||||
- When adding new API call functions, ensure they include robust error handling
|
||||
and logging.
|
||||
- Use the existing `fetchWithRetry` utility for all GET requests.
|
||||
|
||||
## Regarding Dependencies:
|
||||
|
||||
- Avoid introducing new external dependencies unless absolutely necessary.
|
||||
- If a new dependency is required, please state the reason.
|
||||
```
|
||||
|
||||
This example demonstrates how you can provide general project context, specific
|
||||
coding conventions, and even notes about particular files or components. The
|
||||
more relevant and precise your context files are, the better the AI can assist
|
||||
you. Project-specific context files are highly encouraged to establish
|
||||
conventions and context.
|
||||
|
||||
- **Hierarchical Loading and Precedence:** The CLI implements a sophisticated
|
||||
hierarchical memory system by loading context files (e.g., `GEMINI.md`) from
|
||||
several locations. Content from files lower in this list (more specific)
|
||||
typically overrides or supplements content from files higher up (more
|
||||
general). The exact concatenation order and final context can be inspected
|
||||
using the `/memory show` command. The typical loading order is:
|
||||
1. **Global Context File:**
|
||||
- Location: `~/.gemini/<contextFileName>` (e.g., `~/.gemini/GEMINI.md` in
|
||||
your user home directory).
|
||||
- Scope: Provides default instructions for all your projects.
|
||||
2. **Project Root & Ancestors Context Files:**
|
||||
- Location: The CLI searches for the configured context file in the
|
||||
current working directory and then in each parent directory up to either
|
||||
the project root (identified by a `.git` folder) or your home directory.
|
||||
- Scope: Provides context relevant to the entire project or a significant
|
||||
portion of it.
|
||||
3. **Sub-directory Context Files (Contextual/Local):**
|
||||
- Location: The CLI also scans for the configured context file in
|
||||
subdirectories _below_ the current working directory (respecting common
|
||||
ignore patterns like `node_modules`, `.git`, etc.). The breadth of this
|
||||
search is limited to 200 directories by default, but can be configured
|
||||
with a `memoryDiscoveryMaxDirs` field in your `settings.json` file.
|
||||
- Scope: Allows for highly specific instructions relevant to a particular
|
||||
component, module, or subsection of your project.
|
||||
- **Concatenation & UI Indication:** The contents of all found context files are
|
||||
concatenated (with separators indicating their origin and path) and provided
|
||||
as part of the system prompt to the Gemini model. The CLI footer displays the
|
||||
count of loaded context files, giving you a quick visual cue about the active
|
||||
instructional context.
|
||||
- **Importing Content:** You can modularize your context files by importing
|
||||
other Markdown files using the `@path/to/file.md` syntax. For more details,
|
||||
see the [Memory Import Processor documentation](../core/memport.md).
|
||||
- **Commands for Memory Management:**
|
||||
- Use `/memory refresh` to force a re-scan and reload of all context files
|
||||
from all configured locations. This updates the AI's instructional context.
|
||||
- Use `/memory show` to display the combined instructional context currently
|
||||
loaded, allowing you to verify the hierarchy and content being used by the
|
||||
AI.
|
||||
- See the [Commands documentation](./commands.md#memory) for full details on
|
||||
the `/memory` command and its sub-commands (`show` and `refresh`).
|
||||
|
||||
By understanding and utilizing these configuration layers and the hierarchical
|
||||
nature of context files, you can effectively manage the AI's memory and tailor
|
||||
the Gemini CLI's responses to your specific needs and projects.
|
||||
|
||||
## Sandboxing
|
||||
|
||||
The Gemini CLI can execute potentially unsafe operations (like shell commands
|
||||
and file modifications) within a sandboxed environment to protect your system.
|
||||
|
||||
Sandboxing is disabled by default, but you can enable it in a few ways:
|
||||
|
||||
- Using `--sandbox` or `-s` flag.
|
||||
- Setting `GEMINI_SANDBOX` environment variable.
|
||||
- Sandbox is enabled in `--yolo` mode by default.
|
||||
|
||||
By default, it uses a pre-built `gemini-cli-sandbox` Docker image.
|
||||
|
||||
For project-specific sandboxing needs, you can create a custom Dockerfile at
|
||||
`.gemini/sandbox.Dockerfile` in your project's root directory. This Dockerfile
|
||||
can be based on the base sandbox image:
|
||||
|
||||
```dockerfile
|
||||
FROM gemini-cli-sandbox
|
||||
|
||||
# Add your custom dependencies or configurations here
|
||||
# For example:
|
||||
# RUN apt-get update && apt-get install -y some-package
|
||||
# COPY ./my-config /app/my-config
|
||||
```
|
||||
|
||||
When `.gemini/sandbox.Dockerfile` exists, you can use `BUILD_SANDBOX`
|
||||
environment variable when running Gemini CLI to automatically build the custom
|
||||
sandbox image:
|
||||
|
||||
```bash
|
||||
BUILD_SANDBOX=1 gemini -s
|
||||
```
|
||||
|
||||
## Usage Statistics
|
||||
|
||||
To help us improve the Gemini CLI, we collect anonymized usage statistics. This
|
||||
data helps us understand how the CLI is used, identify common issues, and
|
||||
prioritize new features.
|
||||
|
||||
**What we collect:**
|
||||
|
||||
- **Tool Calls:** We log the names of the tools that are called, whether they
|
||||
succeed or fail, and how long they take to execute. We do not collect the
|
||||
arguments passed to the tools or any data returned by them.
|
||||
- **API Requests:** We log the Gemini model used for each request, the duration
|
||||
of the request, and whether it was successful. We do not collect the content
|
||||
of the prompts or responses.
|
||||
- **Session Information:** We collect information about the configuration of the
|
||||
CLI, such as the enabled tools and the approval mode.
|
||||
|
||||
**What we DON'T collect:**
|
||||
|
||||
- **Personally Identifiable Information (PII):** We do not collect any personal
|
||||
information, such as your name, email address, or API keys.
|
||||
- **Prompt and Response Content:** We do not log the content of your prompts or
|
||||
the responses from the Gemini model.
|
||||
- **File Content:** We do not log the content of any files that are read or
|
||||
written by the CLI.
|
||||
|
||||
**How to opt out:**
|
||||
|
||||
You can opt out of usage statistics collection at any time by setting the
|
||||
`usageStatisticsEnabled` property to `false` in your `settings.json` file:
|
||||
|
||||
```json
|
||||
{
|
||||
"usageStatisticsEnabled": false
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,80 @@
|
||||
# Creating Agent Skills
|
||||
|
||||
This guide provides an overview of how to create your own Agent Skills to extend
|
||||
the capabilities of Gemini CLI.
|
||||
|
||||
## Getting started: The `skill-creator` skill
|
||||
|
||||
The recommended way to create a new skill is to use the built-in `skill-creator`
|
||||
skill. To use it, ask Gemini CLI to create a new skill for you.
|
||||
|
||||
**Example prompt:**
|
||||
|
||||
> "create a new skill called 'code-reviewer'"
|
||||
|
||||
Gemini CLI will then use the `skill-creator` to generate the skill:
|
||||
|
||||
1. Generate a new directory for your skill (e.g., `my-new-skill/`).
|
||||
2. Create a `SKILL.md` file with the necessary YAML frontmatter (`name` and
|
||||
`description`).
|
||||
3. Create the standard resource directories: `scripts/`, `references/`, and
|
||||
`assets/`.
|
||||
|
||||
## Manual skill creation
|
||||
|
||||
If you prefer to create skills manually:
|
||||
|
||||
1. **Create a directory** for your skill (e.g., `my-new-skill/`).
|
||||
2. **Create a `SKILL.md` file** inside the new directory.
|
||||
|
||||
To add additional resources that support the skill, refer to the skill
|
||||
structure.
|
||||
|
||||
## Skill structure
|
||||
|
||||
A skill is a directory containing a `SKILL.md` file at its root.
|
||||
|
||||
### Folder structure
|
||||
|
||||
While a `SKILL.md` file is the only required component, we recommend the
|
||||
following structure for organizing your skill's resources:
|
||||
|
||||
```text
|
||||
my-skill/
|
||||
├── SKILL.md (Required) Instructions and metadata
|
||||
├── scripts/ (Optional) Executable scripts
|
||||
├── references/ (Optional) Static documentation
|
||||
└── assets/ (Optional) Templates and other resources
|
||||
```
|
||||
|
||||
### `SKILL.md` file
|
||||
|
||||
The `SKILL.md` file is the core of your skill. This file uses YAML frontmatter
|
||||
for metadata and Markdown for instructions. For example:
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: code-reviewer
|
||||
description:
|
||||
Use this skill to review code. It supports both local changes and remote Pull
|
||||
Requests.
|
||||
---
|
||||
|
||||
# Code Reviewer
|
||||
|
||||
This skill guides the agent in conducting thorough code reviews.
|
||||
|
||||
## Workflow
|
||||
|
||||
### 1. Determine Review Target
|
||||
|
||||
- **Remote PR**: If the user gives a PR number or URL, target that remote PR.
|
||||
- **Local Changes**: If changes are local... ...
|
||||
```
|
||||
|
||||
- **`name`**: A unique identifier for the skill. This should match the directory
|
||||
name.
|
||||
- **`description`**: A description of what the skill does and when Gemini should
|
||||
use it.
|
||||
- **Body**: The Markdown body of the file contains the instructions that guide
|
||||
the agent's behavior when the skill is active.
|
||||
+17
-17
@@ -1,4 +1,4 @@
|
||||
# Custom Commands
|
||||
# Custom commands
|
||||
|
||||
Custom commands let you save and reuse your favorite or most frequently used
|
||||
prompts as personal shortcuts within Gemini CLI. You can create commands that
|
||||
@@ -9,9 +9,9 @@ all your projects, streamlining your workflow and ensuring consistency.
|
||||
|
||||
Gemini CLI discovers commands from two locations, loaded in a specific order:
|
||||
|
||||
1. **User Commands (Global):** Located in `~/.gemini/commands/`. These commands
|
||||
1. **User commands (global):** Located in `~/.gemini/commands/`. These commands
|
||||
are available in any project you are working on.
|
||||
2. **Project Commands (Local):** Located in
|
||||
2. **Project commands (local):** Located in
|
||||
`<your-project-root>/.gemini/commands/`. These commands are specific to the
|
||||
current project and can be checked into version control to be shared with
|
||||
your team.
|
||||
@@ -30,7 +30,7 @@ separator (`/` or `\`) being converted to a colon (`:`).
|
||||
- A file at `<project>/.gemini/commands/git/commit.toml` becomes the namespaced
|
||||
command `/git:commit`.
|
||||
|
||||
## TOML File Format (v1)
|
||||
## TOML file format (v1)
|
||||
|
||||
Your command definition files must be written in the TOML format and use the
|
||||
`.toml` file extension.
|
||||
@@ -50,7 +50,7 @@ Your command definition files must be written in the TOML format and use the
|
||||
## Handling arguments
|
||||
|
||||
Custom commands support two powerful methods for handling arguments. The CLI
|
||||
automatically chooses the correct method based on the content of your command\'s
|
||||
automatically chooses the correct method based on the content of your command's
|
||||
`prompt`.
|
||||
|
||||
### 1. Context-aware injection with `{{args}}`
|
||||
@@ -60,7 +60,7 @@ replace that placeholder with the text the user typed after the command name.
|
||||
|
||||
The behavior of this injection depends on where it is used:
|
||||
|
||||
**A. Raw injection (outside Shell commands)**
|
||||
**A. Raw injection (outside shell commands)**
|
||||
|
||||
When used in the main body of the prompt, the arguments are injected exactly as
|
||||
the user typed them.
|
||||
@@ -77,7 +77,7 @@ prompt = "Please provide a code fix for the issue described here: {{args}}."
|
||||
The model receives:
|
||||
`Please provide a code fix for the issue described here: "Button is misaligned".`
|
||||
|
||||
**B. Using arguments in Shell commands (inside `!{...}` blocks)**
|
||||
**B. Using arguments in shell commands (inside `!{...}` blocks)**
|
||||
|
||||
When you use `{{args}}` inside a shell injection block (`!{...}`), the arguments
|
||||
are automatically **shell-escaped** before replacement. This allows you to
|
||||
@@ -96,13 +96,13 @@ Search Results:
|
||||
"""
|
||||
```
|
||||
|
||||
When you run `/grep-code It\'s complicated`:
|
||||
When you run `/grep-code It's complicated`:
|
||||
|
||||
1. The CLI sees `{{args}}` used both outside and inside `!{...}`.
|
||||
2. Outside: The first `{{args}}` is replaced raw with `It\'s complicated`.
|
||||
2. Outside: The first `{{args}}` is replaced raw with `It's complicated`.
|
||||
3. Inside: The second `{{args}}` is replaced with the escaped version (e.g., on
|
||||
Linux: `"It\'s complicated"`).
|
||||
4. The command executed is `grep -r "It\'s complicated" .`.
|
||||
4. The command executed is `grep -r "It's complicated" .`.
|
||||
5. The CLI prompts you to confirm this exact, secure command before execution.
|
||||
6. The final prompt is sent.
|
||||
|
||||
@@ -129,13 +129,13 @@ format and behavior.
|
||||
# In: <project>/.gemini/commands/changelog.toml
|
||||
# Invoked via: /changelog 1.2.0 added "Support for default argument parsing."
|
||||
|
||||
description = "Adds a new entry to the project\'s CHANGELOG.md file."
|
||||
description = "Adds a new entry to the project's CHANGELOG.md file."
|
||||
prompt = """
|
||||
# Task: Update Changelog
|
||||
|
||||
You are an expert maintainer of this software project. A user has invoked a command to add a new entry to the changelog.
|
||||
|
||||
**The user\'s raw command is appended below your instructions.**
|
||||
**The user's raw command is appended below your instructions.**
|
||||
|
||||
Your task is to parse the `<version>`, `<change_type>`, and `<message>` from their input and use the `write_file` tool to correctly update the `CHANGELOG.md` file.
|
||||
|
||||
@@ -147,7 +147,7 @@ The command follows this format: `/changelog <version> <type> <message>`
|
||||
1. Read the `CHANGELOG.md` file.
|
||||
2. Find the section for the specified `<version>`.
|
||||
3. Add the `<message>` under the correct `<type>` heading.
|
||||
4. If the version or type section doesn\'t exist, create it.
|
||||
4. If the version or type section doesn't exist, create it.
|
||||
5. Adhere strictly to the "Keep a Changelog" format.
|
||||
"""
|
||||
```
|
||||
@@ -156,7 +156,7 @@ When you run `/changelog 1.2.0 added "New feature"`, the final text sent to the
|
||||
model will be the original prompt followed by two newlines and the command you
|
||||
typed.
|
||||
|
||||
### 3. Executing Shell commands with `!{...}`
|
||||
### 3. Executing shell commands with `!{...}`
|
||||
|
||||
You can make your commands dynamic by executing shell commands directly within
|
||||
your `prompt` and injecting their output. This is ideal for gathering context
|
||||
@@ -241,7 +241,7 @@ operate on specific files.
|
||||
**Example (`review.toml`):**
|
||||
|
||||
This command injects the content of a _fixed_ best practices file
|
||||
(`docs/best-practices.md`) and uses the user\'s arguments to provide context for
|
||||
(`docs/best-practices.md`) and uses the user's arguments to provide context for
|
||||
the review.
|
||||
|
||||
```toml
|
||||
@@ -293,7 +293,7 @@ practice.
|
||||
description = "Asks the model to refactor the current context into a pure function."
|
||||
|
||||
prompt = """
|
||||
Please analyze the code I\'ve provided in the current context.
|
||||
Please analyze the code I've provided in the current context.
|
||||
Refactor it into a pure function.
|
||||
|
||||
Your response should include:
|
||||
@@ -302,7 +302,7 @@ Your response should include:
|
||||
"""
|
||||
```
|
||||
|
||||
**3. Run the Command:**
|
||||
**3. Run the command:**
|
||||
|
||||
That's it! You can now run your command in the CLI. First, you might add a file
|
||||
to the context, and then invoke your command:
|
||||
|
||||
+116
-23
@@ -1,11 +1,11 @@
|
||||
# Gemini CLI for the Enterprise
|
||||
# Gemini CLI for the enterprise
|
||||
|
||||
This document outlines configuration patterns and best practices for deploying
|
||||
and managing Gemini CLI in an enterprise environment. By leveraging system-level
|
||||
settings, administrators can enforce security policies, manage tool access, and
|
||||
ensure a consistent experience for all users.
|
||||
|
||||
> **A Note on Security:** The patterns described in this document are intended
|
||||
> **A note on security:** The patterns described in this document are intended
|
||||
> to help administrators create a more controlled and secure environment for
|
||||
> using Gemini CLI. However, they should not be considered a foolproof security
|
||||
> boundary. A determined user with sufficient privileges on their local machine
|
||||
@@ -14,7 +14,7 @@ ensure a consistent experience for all users.
|
||||
> managed environment, not to defend against a malicious actor with local
|
||||
> administrative rights.
|
||||
|
||||
## Centralized Configuration: The System Settings File
|
||||
## Centralized configuration: The system settings file
|
||||
|
||||
The most powerful tools for enterprise administration are the system-wide
|
||||
settings files. These files allow you to define a baseline configuration
|
||||
@@ -33,11 +33,11 @@ settings (like `theme`) is:
|
||||
This means the System Overrides file has the final say. For settings that are
|
||||
arrays (`includeDirectories`) or objects (`mcpServers`), the values are merged.
|
||||
|
||||
**Example of Merging and Precedence:**
|
||||
**Example of merging and precedence:**
|
||||
|
||||
Here is how settings from different levels are combined.
|
||||
|
||||
- **System Defaults `system-defaults.json`:**
|
||||
- **System defaults `system-defaults.json`:**
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -89,7 +89,7 @@ Here is how settings from different levels are combined.
|
||||
}
|
||||
```
|
||||
|
||||
- **System Overrides `settings.json`:**
|
||||
- **System overrides `settings.json`:**
|
||||
```json
|
||||
{
|
||||
"ui": {
|
||||
@@ -108,7 +108,7 @@ Here is how settings from different levels are combined.
|
||||
|
||||
This results in the following merged configuration:
|
||||
|
||||
- **Final Merged Configuration:**
|
||||
- **Final merged configuration:**
|
||||
```json
|
||||
{
|
||||
"ui": {
|
||||
@@ -159,7 +159,68 @@ This results in the following merged configuration:
|
||||
By using the system settings file, you can enforce the security and
|
||||
configuration patterns described below.
|
||||
|
||||
## Restricting Tool Access
|
||||
### Enforcing system settings with a wrapper script
|
||||
|
||||
While the `GEMINI_CLI_SYSTEM_SETTINGS_PATH` environment variable provides
|
||||
flexibility, a user could potentially override it to point to a different
|
||||
settings file, bypassing the centrally managed configuration. To mitigate this,
|
||||
enterprises can deploy a wrapper script or alias that ensures the environment
|
||||
variable is always set to the corporate-controlled path.
|
||||
|
||||
This approach ensures that no matter how the user calls the `gemini` command,
|
||||
the enterprise settings are always loaded with the highest precedence.
|
||||
|
||||
**Example wrapper script:**
|
||||
|
||||
Administrators can create a script named `gemini` and place it in a directory
|
||||
that appears earlier in the user's `PATH` than the actual Gemini CLI binary
|
||||
(e.g., `/usr/local/bin/gemini`).
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
# Enforce the path to the corporate system settings file.
|
||||
# This ensures that the company's configuration is always applied.
|
||||
export GEMINI_CLI_SYSTEM_SETTINGS_PATH="/etc/gemini-cli/settings.json"
|
||||
|
||||
# Find the original gemini executable.
|
||||
# This is a simple example; a more robust solution might be needed
|
||||
# depending on the installation method.
|
||||
REAL_GEMINI_PATH=$(type -aP gemini | grep -v "^$(type -P gemini)$" | head -n 1)
|
||||
|
||||
if [ -z "$REAL_GEMINI_PATH" ]; then
|
||||
echo "Error: The original 'gemini' executable was not found." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Pass all arguments to the real Gemini CLI executable.
|
||||
exec "$REAL_GEMINI_PATH" "$@"
|
||||
```
|
||||
|
||||
By deploying this script, the `GEMINI_CLI_SYSTEM_SETTINGS_PATH` is set within
|
||||
the script's environment, and the `exec` command replaces the script process
|
||||
with the actual Gemini CLI process, which inherits the environment variable.
|
||||
This makes it significantly more difficult for a user to bypass the enforced
|
||||
settings.
|
||||
|
||||
## User isolation in shared environments
|
||||
|
||||
In shared compute environments (like ML experiment runners or shared build
|
||||
servers), you can isolate Gemini CLI state by overriding the user's home
|
||||
directory.
|
||||
|
||||
By default, Gemini CLI stores configuration and history in `~/.gemini`. You can
|
||||
use the `GEMINI_CLI_HOME` environment variable to point to a unique directory
|
||||
for a specific user or job. The CLI will create a `.gemini` folder inside the
|
||||
specified path.
|
||||
|
||||
```bash
|
||||
# Isolate state for a specific job
|
||||
export GEMINI_CLI_HOME="/tmp/gemini-job-123"
|
||||
gemini
|
||||
```
|
||||
|
||||
## Restricting tool access
|
||||
|
||||
You can significantly enhance security by controlling which tools the Gemini
|
||||
model can use. This is achieved through the `tools.core` and `tools.exclude`
|
||||
@@ -197,12 +258,12 @@ environment to a blocklist.
|
||||
}
|
||||
```
|
||||
|
||||
**Security Note:** Blocklisting with `excludeTools` is less secure than
|
||||
**Security note:** Blocklisting with `excludeTools` is less secure than
|
||||
allowlisting with `coreTools`, as it relies on blocking known-bad commands, and
|
||||
clever users may find ways to bypass simple string-based blocks. **Allowlisting
|
||||
is the recommended approach.**
|
||||
|
||||
### Disabling YOLO Mode
|
||||
### Disabling YOLO mode
|
||||
|
||||
To ensure that users cannot bypass the confirmation prompt for tool execution,
|
||||
you can disable YOLO mode at the policy level. This adds a critical layer of
|
||||
@@ -222,14 +283,14 @@ approval.
|
||||
This setting is highly recommended in an enterprise environment to prevent
|
||||
unintended tool execution.
|
||||
|
||||
## Managing Custom Tools (MCP Servers)
|
||||
## Managing custom tools (MCP servers)
|
||||
|
||||
If your organization uses custom tools via
|
||||
[Model-Context Protocol (MCP) servers](../core/tools-api.md), it is crucial to
|
||||
understand how server configurations are managed to apply security policies
|
||||
effectively.
|
||||
|
||||
### How MCP Server Configurations are Merged
|
||||
### How MCP server configurations are merged
|
||||
|
||||
Gemini CLI loads `settings.json` files from three levels: System, Workspace, and
|
||||
User. When it comes to the `mcpServers` object, these configurations are
|
||||
@@ -246,12 +307,12 @@ This means a user **cannot** override the definition of a server that is already
|
||||
defined in the system-level settings. However, they **can** add new servers with
|
||||
unique names.
|
||||
|
||||
### Enforcing a Catalog of Tools
|
||||
### Enforcing a catalog of tools
|
||||
|
||||
The security of your MCP tool ecosystem depends on a combination of defining the
|
||||
canonical servers and adding their names to an allowlist.
|
||||
|
||||
### Restricting Tools Within an MCP Server
|
||||
### Restricting tools within an MCP server
|
||||
|
||||
For even greater security, especially when dealing with third-party MCP servers,
|
||||
you can restrict which specific tools from a server are exposed to the model.
|
||||
@@ -280,7 +341,7 @@ third-party MCP server, even if the server offers other tools like
|
||||
}
|
||||
```
|
||||
|
||||
#### More Secure Pattern: Define and Add to Allowlist in System Settings
|
||||
#### More secure pattern: Define and add to allowlist in system settings
|
||||
|
||||
To create a secure, centrally-managed catalog of tools, the system administrator
|
||||
**must** do both of the following in the system-level `settings.json` file:
|
||||
@@ -293,7 +354,7 @@ To create a secure, centrally-managed catalog of tools, the system administrator
|
||||
any servers that are not on this list. If this setting is omitted, the CLI
|
||||
will merge and allow any server defined by the user.
|
||||
|
||||
**Example System `settings.json`:**
|
||||
**Example system `settings.json`:**
|
||||
|
||||
1. Add the _names_ of all approved servers to an allowlist. This will prevent
|
||||
users from adding their own servers.
|
||||
@@ -322,12 +383,12 @@ Any server a user defines will either be overridden by the system definition (if
|
||||
it has the same name) or blocked because its name is not in the `mcp.allowed`
|
||||
list.
|
||||
|
||||
### Less Secure Pattern: Omitting the Allowlist
|
||||
### Less secure pattern: Omitting the allowlist
|
||||
|
||||
If the administrator defines the `mcpServers` object but fails to also specify
|
||||
the `mcp.allowed` allowlist, users may add their own servers.
|
||||
|
||||
**Example System `settings.json`:**
|
||||
**Example system `settings.json`:**
|
||||
|
||||
This configuration defines servers but does not enforce the allowlist. The
|
||||
administrator has NOT included the "mcp.allowed" setting.
|
||||
@@ -347,7 +408,7 @@ In this scenario, a user can add their own server in their local
|
||||
results, the user's server will be added to the list of available tools and
|
||||
allowed to run.
|
||||
|
||||
## Enforcing Sandboxing for Security
|
||||
## Enforcing sandboxing for security
|
||||
|
||||
To mitigate the risk of potentially harmful operations, you can enforce the use
|
||||
of sandboxing for all tool execution. The sandbox isolates tool execution in a
|
||||
@@ -367,14 +428,14 @@ You can also specify a custom, hardened Docker image for the sandbox by building
|
||||
a custom `sandbox.Dockerfile` as described in the
|
||||
[Sandboxing documentation](./sandbox.md).
|
||||
|
||||
## Controlling Network Access via Proxy
|
||||
## Controlling network access via proxy
|
||||
|
||||
In corporate environments with strict network policies, you can configure Gemini
|
||||
CLI to route all outbound traffic through a corporate proxy. This can be set via
|
||||
an environment variable, but it can also be enforced for custom tools via the
|
||||
`mcpServers` configuration.
|
||||
|
||||
**Example (for an MCP Server):**
|
||||
**Example (for an MCP server):**
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -391,7 +452,7 @@ an environment variable, but it can also be enforced for custom tools via the
|
||||
}
|
||||
```
|
||||
|
||||
## Telemetry and Auditing
|
||||
## Telemetry and auditing
|
||||
|
||||
For auditing and monitoring purposes, you can configure Gemini CLI to send
|
||||
telemetry data to a central location. This allows you to track tool usage and
|
||||
@@ -434,7 +495,39 @@ prompted to switch to the enforced method. In non-interactive mode, the CLI will
|
||||
exit with an error if the configured authentication method does not match the
|
||||
enforced one.
|
||||
|
||||
## Putting It All Together: Example System `settings.json`
|
||||
### Restricting logins to corporate domains
|
||||
|
||||
For enterprises using Google Workspace, you can enforce that users only
|
||||
authenticate with their corporate Google accounts. This is a network-level
|
||||
control that is configured on a proxy server, not within Gemini CLI itself. It
|
||||
works by intercepting authentication requests to Google and adding a special
|
||||
HTTP header.
|
||||
|
||||
This policy prevents users from logging in with personal Gmail accounts or other
|
||||
non-corporate Google accounts.
|
||||
|
||||
For detailed instructions, see the Google Workspace Admin Help article on
|
||||
[blocking access to consumer accounts](https://support.google.com/a/answer/1668854?hl=en#zippy=%2Cstep-choose-a-web-proxy-server%2Cstep-configure-the-network-to-block-certain-accounts).
|
||||
|
||||
The general steps are as follows:
|
||||
|
||||
1. **Intercept Requests**: Configure your web proxy to intercept all requests
|
||||
to `google.com`.
|
||||
2. **Add HTTP Header**: For each intercepted request, add the
|
||||
`X-GoogApps-Allowed-Domains` HTTP header.
|
||||
3. **Specify Domains**: The value of the header should be a comma-separated
|
||||
list of your approved Google Workspace domain names.
|
||||
|
||||
**Example header:**
|
||||
|
||||
```
|
||||
X-GoogApps-Allowed-Domains: my-corporate-domain.com, secondary-domain.com
|
||||
```
|
||||
|
||||
When this header is present, Google's authentication service will only allow
|
||||
logins from accounts belonging to the specified domains.
|
||||
|
||||
## Putting it all together: example system `settings.json`
|
||||
|
||||
Here is an example of a system `settings.json` file that combines several of the
|
||||
patterns discussed above to create a secure, controlled environment for Gemini
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Ignoring Files
|
||||
# Ignoring files
|
||||
|
||||
This document provides an overview of the Gemini Ignore (`.geminiignore`)
|
||||
feature of the Gemini CLI.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Provide Context with GEMINI.md Files
|
||||
# Provide context with GEMINI.md files
|
||||
|
||||
Context files, which use the default name `GEMINI.md`, are a powerful feature
|
||||
for providing instructional context to the Gemini model. You can use these files
|
||||
|
||||
@@ -0,0 +1,210 @@
|
||||
# Advanced Model Configuration
|
||||
|
||||
This guide details the Model Configuration system within the Gemini CLI.
|
||||
Designed for researchers, AI quality engineers, and advanced users, this system
|
||||
provides a rigorous framework for managing generative model hyperparameters and
|
||||
behaviors.
|
||||
|
||||
> **Warning**: This is a power-user feature. Configuration values are passed
|
||||
> directly to the model provider with minimal validation. Incorrect settings
|
||||
> (e.g., incompatible parameter combinations) may result in runtime errors from
|
||||
> the API.
|
||||
|
||||
## 1. System Overview
|
||||
|
||||
The Model Configuration system (`ModelConfigService`) enables deterministic
|
||||
control over model generation. It decouples the requested model identifier
|
||||
(e.g., a CLI flag or agent request) from the underlying API configuration. This
|
||||
allows for:
|
||||
|
||||
- **Precise Hyperparameter Tuning**: Direct control over `temperature`, `topP`,
|
||||
`thinkingBudget`, and other SDK-level parameters.
|
||||
- **Environment-Specific Behavior**: Distinct configurations for different
|
||||
operating contexts (e.g., testing vs. production).
|
||||
- **Agent-Scoped Customization**: Applying specific settings only when a
|
||||
particular agent is active.
|
||||
|
||||
The system operates on two core primitives: **Aliases** and **Overrides**.
|
||||
|
||||
## 2. Configuration Primitives
|
||||
|
||||
These settings are located under the `modelConfigs` key in your configuration
|
||||
file.
|
||||
|
||||
### Aliases (`customAliases`)
|
||||
|
||||
Aliases are named, reusable configuration presets. Users should define their own
|
||||
aliases (or override system defaults) in the `customAliases` map.
|
||||
|
||||
- **Inheritance**: An alias can `extends` another alias (including system
|
||||
defaults like `chat-base`), inheriting its `modelConfig`. Child aliases can
|
||||
overwrite or augment inherited settings.
|
||||
- **Abstract Aliases**: An alias is not required to specify a concrete `model`
|
||||
if it serves purely as a base for other aliases.
|
||||
|
||||
**Example Hierarchy**:
|
||||
|
||||
```json
|
||||
"modelConfigs": {
|
||||
"customAliases": {
|
||||
"base": {
|
||||
"modelConfig": {
|
||||
"generateContentConfig": { "temperature": 0.0 }
|
||||
}
|
||||
},
|
||||
"chat-base": {
|
||||
"extends": "base",
|
||||
"modelConfig": {
|
||||
"generateContentConfig": { "temperature": 0.7 }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Overrides (`overrides`)
|
||||
|
||||
Overrides are conditional rules that inject configuration based on the runtime
|
||||
context. They are evaluated dynamically for each model request.
|
||||
|
||||
- **Match Criteria**: Overrides apply when the request context matches the
|
||||
specified `match` properties.
|
||||
- `model`: Matches the requested model name or alias.
|
||||
- `overrideScope`: Matches the distinct scope of the request (typically the
|
||||
agent name, e.g., `codebaseInvestigator`).
|
||||
|
||||
**Example Override**:
|
||||
|
||||
```json
|
||||
"modelConfigs": {
|
||||
"overrides": [
|
||||
{
|
||||
"match": {
|
||||
"overrideScope": "codebaseInvestigator"
|
||||
},
|
||||
"modelConfig": {
|
||||
"generateContentConfig": { "temperature": 0.1 }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 3. Resolution Strategy
|
||||
|
||||
The `ModelConfigService` resolves the final configuration through a two-step
|
||||
process:
|
||||
|
||||
### Step 1: Alias Resolution
|
||||
|
||||
The requested model string is looked up in the merged map of system `aliases`
|
||||
and user `customAliases`.
|
||||
|
||||
1. If found, the system recursively resolves the `extends` chain.
|
||||
2. Settings are merged from parent to child (child wins).
|
||||
3. This results in a base `ResolvedModelConfig`.
|
||||
4. If not found, the requested string is treated as the raw model name.
|
||||
|
||||
### Step 2: Override Application
|
||||
|
||||
The system evaluates the `overrides` list against the request context (`model`
|
||||
and `overrideScope`).
|
||||
|
||||
1. **Filtering**: All matching overrides are identified.
|
||||
2. **Sorting**: Matches are prioritized by **specificity** (the number of
|
||||
matched keys in the `match` object).
|
||||
- Specific matches (e.g., `model` + `overrideScope`) override broad matches
|
||||
(e.g., `model` only).
|
||||
- Tie-breaking: If specificity is equal, the order of definition in the
|
||||
`overrides` array is preserved (last one wins).
|
||||
3. **Merging**: The configurations from the sorted overrides are merged
|
||||
sequentially onto the base configuration.
|
||||
|
||||
## 4. Configuration Reference
|
||||
|
||||
The configuration follows the `ModelConfigServiceConfig` interface.
|
||||
|
||||
### `ModelConfig` Object
|
||||
|
||||
Defines the actual parameters for the model.
|
||||
|
||||
| Property | Type | Description |
|
||||
| :---------------------- | :------- | :----------------------------------------------------------------- |
|
||||
| `model` | `string` | The identifier of the model to be called (e.g., `gemini-2.5-pro`). |
|
||||
| `generateContentConfig` | `object` | The configuration object passed to the `@google/genai` SDK. |
|
||||
|
||||
### `GenerateContentConfig` (Common Parameters)
|
||||
|
||||
Directly maps to the SDK's `GenerateContentConfig`. Common parameters include:
|
||||
|
||||
- **`temperature`**: (`number`) Controls output randomness. Lower values (0.0)
|
||||
are deterministic; higher values (>0.7) are creative.
|
||||
- **`topP`**: (`number`) Nucleus sampling probability.
|
||||
- **`maxOutputTokens`**: (`number`) Limit on generated response length.
|
||||
- **`thinkingConfig`**: (`object`) Configuration for models with reasoning
|
||||
capabilities (e.g., `thinkingBudget`, `includeThoughts`).
|
||||
|
||||
## 5. Practical Examples
|
||||
|
||||
### Defining a Deterministic Baseline
|
||||
|
||||
Create an alias for tasks requiring high precision, extending the standard chat
|
||||
configuration but enforcing zero temperature.
|
||||
|
||||
```json
|
||||
"modelConfigs": {
|
||||
"customAliases": {
|
||||
"precise-mode": {
|
||||
"extends": "chat-base",
|
||||
"modelConfig": {
|
||||
"generateContentConfig": {
|
||||
"temperature": 0.0,
|
||||
"topP": 1.0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Agent-Specific Parameter Injection
|
||||
|
||||
Enforce extended thinking budgets for a specific agent without altering the
|
||||
global default, e.g. for the `codebaseInvestigator`.
|
||||
|
||||
```json
|
||||
"modelConfigs": {
|
||||
"overrides": [
|
||||
{
|
||||
"match": {
|
||||
"overrideScope": "codebaseInvestigator"
|
||||
},
|
||||
"modelConfig": {
|
||||
"generateContentConfig": {
|
||||
"thinkingConfig": { "thinkingBudget": 4096 }
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Experimental Model Evaluation
|
||||
|
||||
Route traffic for a specific alias to a preview model for A/B testing, without
|
||||
changing client code.
|
||||
|
||||
```json
|
||||
"modelConfigs": {
|
||||
"overrides": [
|
||||
{
|
||||
"match": {
|
||||
"model": "gemini-2.5-pro"
|
||||
},
|
||||
"modelConfig": {
|
||||
"model": "gemini-2.5-pro-experimental-001"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
+17
-17
@@ -1,4 +1,4 @@
|
||||
# Headless Mode
|
||||
# Headless mode
|
||||
|
||||
Headless mode allows you to run Gemini CLI programmatically from command line
|
||||
scripts and automation tools without any interactive UI. This is ideal for
|
||||
@@ -45,9 +45,9 @@ The headless mode provides a headless interface to Gemini CLI that:
|
||||
- Enables automation and scripting workflows
|
||||
- Provides consistent exit codes for error handling
|
||||
|
||||
## Basic Usage
|
||||
## Basic usage
|
||||
|
||||
### Direct Prompts
|
||||
### Direct prompts
|
||||
|
||||
Use the `--prompt` (or `-p`) flag to run in headless mode:
|
||||
|
||||
@@ -55,7 +55,7 @@ Use the `--prompt` (or `-p`) flag to run in headless mode:
|
||||
gemini --prompt "What is machine learning?"
|
||||
```
|
||||
|
||||
### Stdin Input
|
||||
### Stdin input
|
||||
|
||||
Pipe input to Gemini CLI from your terminal:
|
||||
|
||||
@@ -63,7 +63,7 @@ Pipe input to Gemini CLI from your terminal:
|
||||
echo "Explain this code" | gemini
|
||||
```
|
||||
|
||||
### Combining with File Input
|
||||
### Combining with file input
|
||||
|
||||
Read from files and process with Gemini:
|
||||
|
||||
@@ -71,9 +71,9 @@ Read from files and process with Gemini:
|
||||
cat README.md | gemini --prompt "Summarize this documentation"
|
||||
```
|
||||
|
||||
## Output Formats
|
||||
## Output formats
|
||||
|
||||
### Text Output (Default)
|
||||
### Text output (default)
|
||||
|
||||
Standard human-readable output:
|
||||
|
||||
@@ -87,12 +87,12 @@ Response format:
|
||||
The capital of France is Paris.
|
||||
```
|
||||
|
||||
### JSON Output
|
||||
### JSON output
|
||||
|
||||
Returns structured data including response, statistics, and metadata. This
|
||||
format is ideal for programmatic processing and automation scripts.
|
||||
|
||||
#### Response Schema
|
||||
#### Response schema
|
||||
|
||||
The JSON output follows this high-level structure:
|
||||
|
||||
@@ -140,7 +140,7 @@ The JSON output follows this high-level structure:
|
||||
}
|
||||
```
|
||||
|
||||
#### Example Usage
|
||||
#### Example usage
|
||||
|
||||
```bash
|
||||
gemini -p "What is the capital of France?" --output-format json
|
||||
@@ -218,14 +218,14 @@ Response:
|
||||
}
|
||||
```
|
||||
|
||||
### Streaming JSON Output
|
||||
### Streaming JSON output
|
||||
|
||||
Returns real-time events as newline-delimited JSON (JSONL). Each significant
|
||||
action (initialization, messages, tool calls, results) emits immediately as it
|
||||
occurs. This format is ideal for monitoring long-running operations, building
|
||||
UIs with live progress, and creating automation pipelines that react to events.
|
||||
|
||||
#### When to Use Streaming JSON
|
||||
#### When to use streaming JSON
|
||||
|
||||
Use `--output-format stream-json` when you need:
|
||||
|
||||
@@ -237,7 +237,7 @@ Use `--output-format stream-json` when you need:
|
||||
timestamps
|
||||
- **Pipeline integration** - Stream events to logging/monitoring systems
|
||||
|
||||
#### Event Types
|
||||
#### Event types
|
||||
|
||||
The streaming format emits 6 event types:
|
||||
|
||||
@@ -248,7 +248,7 @@ The streaming format emits 6 event types:
|
||||
5. **`error`** - Non-fatal errors and warnings
|
||||
6. **`result`** - Final session outcome with aggregated stats
|
||||
|
||||
#### Basic Usage
|
||||
#### Basic usage
|
||||
|
||||
```bash
|
||||
# Stream events to console
|
||||
@@ -261,7 +261,7 @@ gemini --output-format stream-json --prompt "Analyze this code" > events.jsonl
|
||||
gemini --output-format stream-json --prompt "List files" | jq -r '.type'
|
||||
```
|
||||
|
||||
#### Example Output
|
||||
#### Example output
|
||||
|
||||
Each line is a complete JSON event:
|
||||
|
||||
@@ -274,7 +274,7 @@ Each line is a complete JSON event:
|
||||
{"type":"result","status":"success","stats":{"total_tokens":250,"input_tokens":50,"output_tokens":200,"duration_ms":3000,"tool_calls":1},"timestamp":"2025-10-10T12:00:05.000Z"}
|
||||
```
|
||||
|
||||
### File Redirection
|
||||
### File redirection
|
||||
|
||||
Save output to files or pipe to other commands:
|
||||
|
||||
@@ -292,7 +292,7 @@ gemini -p "Explain microservices" | wc -w
|
||||
gemini -p "List programming languages" | grep -i "python"
|
||||
```
|
||||
|
||||
## Configuration Options
|
||||
## Configuration options
|
||||
|
||||
Key command-line options for headless usage:
|
||||
|
||||
|
||||
+15
-11
@@ -7,17 +7,17 @@ overview of Gemini CLI, see the [main documentation page](../index.md).
|
||||
## Basic features
|
||||
|
||||
- **[Commands](./commands.md):** A reference for all built-in slash commands
|
||||
- **[Custom Commands](./custom-commands.md):** Create your own commands and
|
||||
- **[Custom commands](./custom-commands.md):** Create your own commands and
|
||||
shortcuts for frequently used prompts.
|
||||
- **[Headless Mode](./headless.md):** Use Gemini CLI programmatically for
|
||||
- **[Headless mode](./headless.md):** Use Gemini CLI programmatically for
|
||||
scripting and automation.
|
||||
- **[Model Selection](./model.md):** Configure the Gemini AI model used by the
|
||||
- **[Model selection](./model.md):** Configure the Gemini AI model used by the
|
||||
CLI.
|
||||
- **[Settings](./settings.md):** Configure various aspects of the CLI's behavior
|
||||
and appearance.
|
||||
- **[Themes](./themes.md):** Customizing the CLI's appearance with different
|
||||
themes.
|
||||
- **[Keyboard Shortcuts](./keyboard-shortcuts.md):** A reference for all
|
||||
- **[Keyboard shortcuts](./keyboard-shortcuts.md):** A reference for all
|
||||
keyboard shortcuts to improve your workflow.
|
||||
- **[Tutorials](./tutorials.md):** Step-by-step guides for common tasks.
|
||||
|
||||
@@ -25,19 +25,23 @@ overview of Gemini CLI, see the [main documentation page](../index.md).
|
||||
|
||||
- **[Checkpointing](./checkpointing.md):** Automatically save and restore
|
||||
snapshots of your session and files.
|
||||
- **[Enterprise Configuration](./enterprise.md):** Deploying and manage Gemini
|
||||
CLI in an enterprise environment.
|
||||
- **[Enterprise configuration](./enterprise.md):** Deploy and manage Gemini CLI
|
||||
in an enterprise environment.
|
||||
- **[Sandboxing](./sandbox.md):** Isolate tool execution in a secure,
|
||||
containerized environment.
|
||||
- **[Agent Skills](./skills.md):** Extend the CLI with specialized expertise and
|
||||
procedural workflows.
|
||||
- **[Telemetry](./telemetry.md):** Configure observability to monitor usage and
|
||||
performance.
|
||||
- **[Token Caching](./token-caching.md):** Optimize API costs by caching tokens.
|
||||
- **[Trusted Folders](./trusted-folders.md):** A security feature to control
|
||||
- **[Token caching](./token-caching.md):** Optimize API costs by caching tokens.
|
||||
- **[Trusted folders](./trusted-folders.md):** A security feature to control
|
||||
which projects can use the full capabilities of the CLI.
|
||||
- **[Ignoring Files (.geminiignore)](./gemini-ignore.md):** Exclude specific
|
||||
- **[Ignoring files (.geminiignore)](./gemini-ignore.md):** Exclude specific
|
||||
files and directories from being accessed by tools.
|
||||
- **[Context Files (GEMINI.md)](./gemini-md.md):** Provide persistent,
|
||||
- **[Context files (GEMINI.md)](./gemini-md.md):** Provide persistent,
|
||||
hierarchical context to the model.
|
||||
- **[System prompt override](./system-prompt.md):** Replace the built‑in system
|
||||
instructions using `GEMINI_SYSTEM_MD`.
|
||||
|
||||
## Non-interactive mode
|
||||
|
||||
@@ -58,4 +62,4 @@ gemini -p "What is fine tuning?"
|
||||
```
|
||||
|
||||
For comprehensive documentation on headless usage, scripting, automation, and
|
||||
advanced examples, see the **[Headless Mode](./headless.md)** guide.
|
||||
advanced examples, see the **[Headless mode](./headless.md)** guide.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Gemini CLI Keyboard Shortcuts
|
||||
# Gemini CLI keyboard shortcuts
|
||||
|
||||
Gemini CLI ships with a set of default keyboard shortcuts for editing input,
|
||||
navigating history, and controlling the UI. Use this reference to learn the
|
||||
@@ -8,43 +8,50 @@ available combinations.
|
||||
|
||||
#### Basic Controls
|
||||
|
||||
| Action | Keys |
|
||||
| -------------------------------------------- | ------- |
|
||||
| Confirm the current selection or choice. | `Enter` |
|
||||
| Dismiss dialogs or cancel the current focus. | `Esc` |
|
||||
| Action | Keys |
|
||||
| --------------------------------------------------------------- | ---------- |
|
||||
| Confirm the current selection or choice. | `Enter` |
|
||||
| Dismiss dialogs or cancel the current focus. | `Esc` |
|
||||
| Cancel the current request or quit the CLI when input is empty. | `Ctrl + C` |
|
||||
| Exit the CLI when the input buffer is empty. | `Ctrl + D` |
|
||||
|
||||
#### Cursor Movement
|
||||
|
||||
| Action | Keys |
|
||||
| ----------------------------------------- | ---------------------- |
|
||||
| Move the cursor to the start of the line. | `Ctrl + A`<br />`Home` |
|
||||
| Move the cursor to the end of the line. | `Ctrl + E`<br />`End` |
|
||||
| Action | Keys |
|
||||
| ------------------------------------------- | ------------------------------------------------------------ |
|
||||
| Move the cursor to the start of the line. | `Ctrl + A`<br />`Home (no Shift, Ctrl)` |
|
||||
| Move the cursor to the end of the line. | `Ctrl + E`<br />`End (no Shift, Ctrl)` |
|
||||
| Move the cursor up one line. | `Up Arrow (no Shift, Alt, Ctrl, Cmd)` |
|
||||
| Move the cursor down one line. | `Down Arrow (no Shift, Alt, Ctrl, Cmd)` |
|
||||
| Move the cursor one character to the left. | `Left Arrow (no Shift, Alt, Ctrl, Cmd)` |
|
||||
| Move the cursor one character to the right. | `Right Arrow (no Shift, Alt, Ctrl, Cmd)`<br />`Ctrl + F` |
|
||||
| Move the cursor one word to the left. | `Ctrl + Left Arrow`<br />`Alt + Left Arrow`<br />`Alt + B` |
|
||||
| Move the cursor one word to the right. | `Ctrl + Right Arrow`<br />`Alt + Right Arrow`<br />`Alt + F` |
|
||||
|
||||
#### Editing
|
||||
|
||||
| Action | Keys |
|
||||
| ------------------------------------------------ | ----------------------------------------- |
|
||||
| Delete from the cursor to the end of the line. | `Ctrl + K` |
|
||||
| Delete from the cursor to the start of the line. | `Ctrl + U` |
|
||||
| Clear all text in the input field. | `Ctrl + C` |
|
||||
| Delete the previous word. | `Ctrl + Backspace`<br />`Cmd + Backspace` |
|
||||
|
||||
#### Screen Control
|
||||
|
||||
| Action | Keys |
|
||||
| -------------------------------------------- | ---------- |
|
||||
| Clear the terminal screen and redraw the UI. | `Ctrl + L` |
|
||||
| Action | Keys |
|
||||
| ------------------------------------------------ | ---------------------------------------------------------------- |
|
||||
| Delete from the cursor to the end of the line. | `Ctrl + K` |
|
||||
| Delete from the cursor to the start of the line. | `Ctrl + U` |
|
||||
| Clear all text in the input field. | `Ctrl + C` |
|
||||
| Delete the previous word. | `Ctrl + Backspace`<br />`Alt + Backspace`<br />`Ctrl + W` |
|
||||
| Delete the next word. | `Ctrl + Delete`<br />`Alt + Delete` |
|
||||
| Delete the character to the left. | `Backspace`<br />`Ctrl + H` |
|
||||
| Delete the character to the right. | `Delete`<br />`Ctrl + D` |
|
||||
| Undo the most recent text edit. | `Cmd + Z (no Shift)`<br />`Alt + Z (no Shift)` |
|
||||
| Redo the most recent undone text edit. | `Shift + Ctrl + Z`<br />`Shift + Cmd + Z`<br />`Shift + Alt + Z` |
|
||||
|
||||
#### Scrolling
|
||||
|
||||
| Action | Keys |
|
||||
| ------------------------ | -------------------- |
|
||||
| Scroll content up. | `Shift + Up Arrow` |
|
||||
| Scroll content down. | `Shift + Down Arrow` |
|
||||
| Scroll to the top. | `Home` |
|
||||
| Scroll to the bottom. | `End` |
|
||||
| Scroll up by one page. | `Page Up` |
|
||||
| Scroll down by one page. | `Page Down` |
|
||||
| Action | Keys |
|
||||
| ------------------------ | --------------------------------- |
|
||||
| Scroll content up. | `Shift + Up Arrow` |
|
||||
| Scroll content down. | `Shift + Down Arrow` |
|
||||
| Scroll to the top. | `Ctrl + Home`<br />`Shift + Home` |
|
||||
| Scroll to the bottom. | `Ctrl + End`<br />`Shift + End` |
|
||||
| Scroll up by one page. | `Page Up` |
|
||||
| Scroll down by one page. | `Page Down` |
|
||||
|
||||
#### History & Search
|
||||
|
||||
@@ -53,17 +60,20 @@ available combinations.
|
||||
| Show the previous entry in history. | `Ctrl + P (no Shift)` |
|
||||
| Show the next entry in history. | `Ctrl + N (no Shift)` |
|
||||
| Start reverse search through history. | `Ctrl + R` |
|
||||
| Insert the selected reverse-search match. | `Enter (no Ctrl)` |
|
||||
| Submit the selected reverse-search match. | `Enter (no Ctrl)` |
|
||||
| Accept a suggestion while reverse searching. | `Tab` |
|
||||
| Browse and rewind previous interactions. | `Double Esc` |
|
||||
|
||||
#### Navigation
|
||||
|
||||
| Action | Keys |
|
||||
| -------------------------------- | ------------------------------------------- |
|
||||
| Move selection up in lists. | `Up Arrow (no Shift)` |
|
||||
| Move selection down in lists. | `Down Arrow (no Shift)` |
|
||||
| Move up within dialog options. | `Up Arrow (no Shift)`<br />`K (no Shift)` |
|
||||
| Move down within dialog options. | `Down Arrow (no Shift)`<br />`J (no Shift)` |
|
||||
| Action | Keys |
|
||||
| -------------------------------------------------- | ------------------------------------------- |
|
||||
| Move selection up in lists. | `Up Arrow (no Shift)` |
|
||||
| Move selection down in lists. | `Down Arrow (no Shift)` |
|
||||
| Move up within dialog options. | `Up Arrow (no Shift)`<br />`K (no Shift)` |
|
||||
| Move down within dialog options. | `Down Arrow (no Shift)`<br />`J (no Shift)` |
|
||||
| Move to the next item or question in a dialog. | `Tab (no Shift)` |
|
||||
| Move to the previous item or question in a dialog. | `Shift + Tab` |
|
||||
|
||||
#### Suggestions & Completions
|
||||
|
||||
@@ -77,67 +87,54 @@ available combinations.
|
||||
|
||||
#### Text Input
|
||||
|
||||
| Action | Keys |
|
||||
| ------------------------------------ | ------------------------------------------------------------------------------------------- |
|
||||
| Submit the current prompt. | `Enter (no Ctrl, no Shift, no Cmd, not Paste)` |
|
||||
| Insert a newline without submitting. | `Ctrl + Enter`<br />`Cmd + Enter`<br />`Paste + Enter`<br />`Shift + Enter`<br />`Ctrl + J` |
|
||||
|
||||
#### External Tools
|
||||
|
||||
| Action | Keys |
|
||||
| ---------------------------------------------- | ---------- |
|
||||
| Open the current prompt in an external editor. | `Ctrl + X` |
|
||||
| Paste from the clipboard. | `Ctrl + V` |
|
||||
| Action | Keys |
|
||||
| ---------------------------------------------- | ----------------------------------------------------------------------------------------- |
|
||||
| Submit the current prompt. | `Enter (no Shift, Alt, Ctrl, Cmd)` |
|
||||
| Insert a newline without submitting. | `Ctrl + Enter`<br />`Cmd + Enter`<br />`Alt + Enter`<br />`Shift + Enter`<br />`Ctrl + J` |
|
||||
| Open the current prompt in an external editor. | `Ctrl + X` |
|
||||
| Paste from the clipboard. | `Ctrl + V`<br />`Cmd + V`<br />`Alt + V` |
|
||||
|
||||
#### App Controls
|
||||
|
||||
| Action | Keys |
|
||||
| ----------------------------------------------------------------- | ---------- |
|
||||
| Toggle detailed error information. | `F12` |
|
||||
| Toggle the full TODO list. | `Ctrl + T` |
|
||||
| Toggle IDE context details. | `Ctrl + G` |
|
||||
| Toggle Markdown rendering. | `Cmd + M` |
|
||||
| Toggle copy mode when the terminal is using the alternate buffer. | `Ctrl + S` |
|
||||
| Expand a height-constrained response to show additional lines. | `Ctrl + S` |
|
||||
| Toggle focus between the shell and Gemini input. | `Ctrl + F` |
|
||||
|
||||
#### Session Control
|
||||
|
||||
| Action | Keys |
|
||||
| -------------------------------------------- | ---------- |
|
||||
| Cancel the current request or quit the CLI. | `Ctrl + C` |
|
||||
| Exit the CLI when the input buffer is empty. | `Ctrl + D` |
|
||||
| Action | Keys |
|
||||
| ----------------------------------------------------------------------------------------------------- | -------------------------- |
|
||||
| Toggle detailed error information. | `F12` |
|
||||
| Toggle the full TODO list. | `Ctrl + T` |
|
||||
| Show IDE context details. | `Ctrl + G` |
|
||||
| Toggle Markdown rendering. | `Alt + M` |
|
||||
| Toggle copy mode when in alternate buffer mode. | `Ctrl + S` |
|
||||
| Toggle YOLO (auto-approval) mode for tool calls. | `Ctrl + Y` |
|
||||
| Cycle through approval modes: default (prompt), auto_edit (auto-approve edits), and plan (read-only). | `Shift + Tab` |
|
||||
| Expand a height-constrained response to show additional lines when not in alternate buffer mode. | `Ctrl + O`<br />`Ctrl + S` |
|
||||
| Ctrl+B | `Ctrl + B` |
|
||||
| Ctrl+L | `Ctrl + L` |
|
||||
| Ctrl+K | `Ctrl + K` |
|
||||
| Enter | `Enter` |
|
||||
| Esc | `Esc` |
|
||||
| Shift+Tab | `Shift + Tab` |
|
||||
| Tab | `Tab (no Shift)` |
|
||||
| Tab | `Tab (no Shift)` |
|
||||
| Focus the shell input from the gemini input. | `Tab (no Shift)` |
|
||||
| Focus the Gemini input from the shell input. | `Tab` |
|
||||
| Clear the terminal screen and redraw the UI. | `Ctrl + L` |
|
||||
| Restart the application. | `R` |
|
||||
| Suspend the application (not yet implemented). | `Ctrl + Z` |
|
||||
|
||||
<!-- KEYBINDINGS-AUTOGEN:END -->
|
||||
|
||||
## Additional Context-Specific Shortcuts
|
||||
## Additional context-specific shortcuts
|
||||
|
||||
- `Ctrl+Y`: Toggle YOLO (auto-approval) mode for tool calls.
|
||||
- `Shift+Tab`: Toggle Auto Edit (auto-accept edits) mode.
|
||||
- `Option+M` (macOS): Entering `µ` with Option+M also toggles Markdown
|
||||
rendering, matching `Cmd+M`.
|
||||
- `Option+B/F/M` (macOS only): Are interpreted as `Cmd+B/F/M` even if your
|
||||
terminal isn't configured to send Meta with Option.
|
||||
- `!` on an empty prompt: Enter or exit shell mode.
|
||||
- `\` (at end of a line) + `Enter`: Insert a newline without leaving single-line
|
||||
mode.
|
||||
- `Ctrl+Delete` / `Meta+Delete`: Delete the word to the right of the cursor.
|
||||
- `Ctrl+B` or `Left Arrow`: Move the cursor one character to the left while
|
||||
editing text.
|
||||
- `Ctrl+F` or `Right Arrow`: Move the cursor one character to the right; with an
|
||||
embedded shell attached, `Ctrl+F` still toggles focus.
|
||||
- `Ctrl+D` or `Delete`: Remove the character immediately to the right of the
|
||||
cursor.
|
||||
- `Ctrl+H` or `Backspace`: Remove the character immediately to the left of the
|
||||
cursor.
|
||||
- `Ctrl+Left Arrow` / `Meta+Left Arrow` / `Meta+B`: Move one word to the left.
|
||||
- `Ctrl+Right Arrow` / `Meta+Right Arrow` / `Meta+F`: Move one word to the
|
||||
right.
|
||||
- `Ctrl+W`: Delete the word to the left of the cursor (in addition to
|
||||
`Ctrl+Backspace` / `Cmd+Backspace`).
|
||||
- `Ctrl+Z` / `Ctrl+Shift+Z`: Undo or redo the most recent text edit.
|
||||
- `Meta+Enter`: Open the current input in an external editor (alias for
|
||||
`Ctrl+X`).
|
||||
- `Esc` pressed twice quickly: Clear the current input buffer.
|
||||
- `Esc` pressed twice quickly: Clear the input prompt if it is not empty,
|
||||
otherwise browse and rewind previous interactions.
|
||||
- `Up Arrow` / `Down Arrow`: When the cursor is at the top or bottom of a
|
||||
single-line input, navigate backward or forward through prompt history.
|
||||
- `Number keys (1-9, multi-digit)` inside selection dialogs: Jump directly to
|
||||
the numbered radio option and confirm when the full number is entered.
|
||||
- `Double-click` on a paste placeholder (`[Pasted Text: X lines]`) in alternate
|
||||
buffer mode: Expand to view full content inline. Double-click again to
|
||||
collapse.
|
||||
|
||||
+20
-34
@@ -1,43 +1,32 @@
|
||||
## Model Routing
|
||||
# Model routing
|
||||
|
||||
Gemini CLI includes a model routing feature that automatically switches to a
|
||||
fallback model in case of a model failure. This feature is enabled by default
|
||||
and provides resilience when the primary model is unavailable.
|
||||
|
||||
## How it Works
|
||||
## How it works
|
||||
|
||||
Model routing is not based on prompt complexity, but is a fallback mechanism.
|
||||
Here's how it works:
|
||||
Model routing is managed by the `ModelAvailabilityService`, which monitors model
|
||||
health and automatically routes requests to available models based on defined
|
||||
policies.
|
||||
|
||||
1. **Model Failure:** If the currently selected model fails to respond (for
|
||||
example, due to a server error or other issue), the CLI will initiate the
|
||||
fallback process.
|
||||
1. **Model failure:** If the currently selected model fails (e.g., due to quota
|
||||
or server errors), the CLI will initiate the fallback process.
|
||||
|
||||
2. **User Consent:** The CLI will prompt you to ask if you want to switch to
|
||||
the fallback model. This is handled by the `fallbackModelHandler`.
|
||||
2. **User consent:** Depending on the failure and the model's policy, the CLI
|
||||
may prompt you to switch to a fallback model (by default always prompts
|
||||
you).
|
||||
|
||||
3. **Fallback Activation:** If you consent, the CLI will activate the fallback
|
||||
mode by calling `config.setFallbackMode(true)`.
|
||||
Some internal utility calls (such as prompt completion and classification)
|
||||
use a silent fallback chain for `gemini-2.5-flash-lite` and will fall back
|
||||
to `gemini-2.5-flash` and `gemini-2.5-pro` without prompting or changing the
|
||||
configured model.
|
||||
|
||||
4. **Model Switch:** On the next request, the CLI will use the
|
||||
`DEFAULT_GEMINI_FLASH_MODEL` as the fallback model. This is handled by the
|
||||
`resolveModel` function in
|
||||
`packages/cli/src/zed-integration/zedIntegration.ts` which checks if
|
||||
`isInFallbackMode()` is true.
|
||||
3. **Model switch:** If approved, or if the policy allows for silent fallback,
|
||||
the CLI will use an available fallback model for the current turn or the
|
||||
remainder of the session.
|
||||
|
||||
## Configuration
|
||||
|
||||
Model routing is controlled by the `useModelRouter` setting in your
|
||||
`settings.json` file.
|
||||
|
||||
- **`"experimental.useModelRouter": true` (Default):** Enables the model
|
||||
routing/fallback feature.
|
||||
|
||||
- **`"experimental.useModelRouter": false`:** Disables the model
|
||||
routing/fallback feature. If a model fails, the CLI will not attempt to switch
|
||||
to a fallback model.
|
||||
|
||||
### Model Selection Precedence
|
||||
### Model selection precedence
|
||||
|
||||
The model used by Gemini CLI is determined by the following order of precedence:
|
||||
|
||||
@@ -49,8 +38,5 @@ The model used by Gemini CLI is determined by the following order of precedence:
|
||||
3. **`model.name` in `settings.json`:** If neither of the above are set, the
|
||||
model specified in the `model.name` property of your `settings.json` file
|
||||
will be used.
|
||||
4. **Default Model:** If none of the above are set, the default model will be
|
||||
used. The default model is determined by the `useModelRouter` setting:
|
||||
- If `useModelRouter` is `true`, the default model is `"auto"`.
|
||||
- If `useModelRouter` is `false`, the default model is the standard Gemini
|
||||
model.
|
||||
4. **Default model:** If none of the above are set, the default model will be
|
||||
used. The default model is `auto`
|
||||
|
||||
+33
-29
@@ -1,8 +1,13 @@
|
||||
# Gemini CLI Model Selection (`/model` Command)
|
||||
# Gemini CLI model selection (`/model` command)
|
||||
|
||||
Select your Gemini CLI model. The `/model` command opens a dialog where you can
|
||||
configure the model used by Gemini CLI, giving you more control over your
|
||||
results.
|
||||
Select your Gemini CLI model. The `/model` command lets you configure the model
|
||||
used by Gemini CLI, giving you more control over your results. Use **Pro**
|
||||
models for complex tasks and reasoning, **Flash** models for high speed results,
|
||||
or the (recommended) **Auto** setting to choose the best model for your tasks.
|
||||
|
||||
> **Note:** The `/model` command (and the `--model` flag) does not override the
|
||||
> model used by sub-agents. Consequently, even when using the `/model` flag you
|
||||
> may see other models used in your model usage reports.
|
||||
|
||||
## How to use the `/model` command
|
||||
|
||||
@@ -12,46 +17,45 @@ Use the following command in Gemini CLI:
|
||||
/model
|
||||
```
|
||||
|
||||
Running this command will open a dialog with your model options:
|
||||
Running this command will open a dialog with your options:
|
||||
|
||||
| Option | Description | Models |
|
||||
| ------------------ | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
|
||||
| Auto (recommended) | Let the system choose the best model for your task. | gemini-3-pro-preview (if enabled), gemini-2.5-pro, gemini-2.5-flash, gemini-2.5-flash-lite |
|
||||
| Pro | For complex tasks that require deep reasoning and creativity. | gemini-3-pro-preview (if enabled), gemini-2.5-pro |
|
||||
| Flash | For tasks that need a balance of speed and reasoning. | gemini-2.5-flash |
|
||||
| Flash-Lite | For simple tasks that need to be done quickly. | gemini-2.5-flash-lite |
|
||||
| Option | Description | Models |
|
||||
| ----------------- | -------------------------------------------------------------- | ---------------------------------------------------------------------- |
|
||||
| Auto (Gemini 3) | Let the system choose the best Gemini 3 model for your task. | gemini-3-pro-preview (if enabled), gemini-3-flash-preview (if enabled) |
|
||||
| Auto (Gemini 2.5) | Let the system choose the best Gemini 2.5 model for your task. | gemini-2.5-pro, gemini-2.5-flash |
|
||||
| Manual | Select a specific model. | Any available model. |
|
||||
|
||||
### Gemini 3 Pro and Preview Features
|
||||
We recommend selecting one of the above **Auto** options. However, you can
|
||||
select **Manual** to select a specific model from those available.
|
||||
|
||||
Note: Gemini 3 is not currently available on all account types. To learn more
|
||||
about Gemini 3 access, refer to
|
||||
[Gemini 3 Pro on Gemini CLI](../get-started/gemini-3.md).
|
||||
### Gemini 3 and preview features
|
||||
|
||||
To enable Gemini 3 Pro (if available), enable
|
||||
[**Preview features** by using the `settings` command](../cli/settings.md). Once
|
||||
enabled, Gemini CLI will attempt to use Gemini 3 Pro when you select **Auto** or
|
||||
**Pro**. Both **Auto** and **Pro** will try to use Gemini 3 Pro before falling
|
||||
back to Gemini 2.5 Pro.
|
||||
> **Note:** Gemini 3 is not currently available on all account types. To learn
|
||||
> more about Gemini 3 access, refer to
|
||||
> [Gemini 3 on Gemini CLI](../get-started/gemini-3.md).
|
||||
|
||||
To enable Gemini 3 Pro and Gemini 3 Flash (if available), enable
|
||||
[**Preview Features** by using the `settings` command](../cli/settings.md).
|
||||
|
||||
You can also use the `--model` flag to specify a particular Gemini model on
|
||||
startup. For more details, refer to the
|
||||
[configuration documentation](./configuration.md).
|
||||
[configuration documentation](../get-started/configuration.md).
|
||||
|
||||
Changes to these settings will be applied to all subsequent interactions with
|
||||
Gemini CLI.
|
||||
|
||||
## Best practices for model selection
|
||||
|
||||
- **Default to Auto (recommended).** For most users, the _Auto (recommended)_
|
||||
model provides a balance between speed and performance, automatically
|
||||
selecting the correct model based on the complexity of the task. Example:
|
||||
Developing a web application could include a mix of complex tasks (building
|
||||
architecture and scaffolding the project) and simple tasks (generating CSS).
|
||||
- **Default to Auto.** For most users, the _Auto_ option model provides a
|
||||
balance between speed and performance, automatically selecting the correct
|
||||
model based on the complexity of the task. Example: Developing a web
|
||||
application could include a mix of complex tasks (building architecture and
|
||||
scaffolding the project) and simple tasks (generating CSS).
|
||||
|
||||
- **Switch to Pro if you aren't getting the results you want.** If you think you
|
||||
need your model to be a little "smarter," use Pro. Pro will provide you with
|
||||
the highest levels of reasoning and creativity. Example: A complex or
|
||||
multi-stage debugging task.
|
||||
need your model to be a little "smarter," you can manually select Pro. Pro
|
||||
will provide you with the highest levels of reasoning and creativity. Example:
|
||||
A complex or multi-stage debugging task.
|
||||
|
||||
- **Switch to Flash or Flash-Lite if you need faster results.** If you need a
|
||||
simple response quickly, Flash or Flash-Lite is the best option. Example:
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
# Rewind
|
||||
|
||||
The `/rewind` command allows you to go back to a previous state in your
|
||||
conversation and, optionally, revert any file changes made by the AI during
|
||||
those interactions. This is a powerful tool for undoing mistakes, exploring
|
||||
different approaches, or simply cleaning up your session history.
|
||||
|
||||
## Usage
|
||||
|
||||
To use the rewind feature, simply type `/rewind` into the input prompt and press
|
||||
**Enter**.
|
||||
|
||||
Alternatively, you can use the keyboard shortcut: **Press `Esc` twice**.
|
||||
|
||||
## Interface
|
||||
|
||||
When you trigger a rewind, an interactive list of your previous interactions
|
||||
appears.
|
||||
|
||||
1. **Select Interaction:** Use the **Up/Down arrow keys** to navigate through
|
||||
the list. The most recent interactions are at the bottom.
|
||||
2. **Preview:** As you select an interaction, you'll see a preview of the user
|
||||
prompt and, if applicable, the number of files changed during that step.
|
||||
3. **Confirm Selection:** Press **Enter** on the interaction you want to rewind
|
||||
back to.
|
||||
4. **Action Selection:** After selecting an interaction, you'll be presented
|
||||
with a confirmation dialog with up to three options:
|
||||
- **Rewind conversation and revert code changes:** Reverts both the chat
|
||||
history and the file modifications to the state before the selected
|
||||
interaction.
|
||||
- **Rewind conversation:** Only reverts the chat history. File changes are
|
||||
kept.
|
||||
- **Revert code changes:** Only reverts the file modifications. The chat
|
||||
history is kept.
|
||||
- **Do nothing (esc):** Cancels the rewind operation.
|
||||
|
||||
If no code changes were made since the selected point, the options related to
|
||||
reverting code changes will be hidden.
|
||||
|
||||
## Key Considerations
|
||||
|
||||
- **Destructive Action:** Rewinding is a destructive action for your current
|
||||
session history and potentially your files. Use it with care.
|
||||
- **Agent Awareness:** When you rewind the conversation, the AI model loses all
|
||||
memory of the interactions that were removed. If you only revert code changes,
|
||||
you may need to inform the model that the files have changed.
|
||||
- **Manual Edits:** Rewinding only affects file changes made by the AI's edit
|
||||
tools. It does **not** undo manual edits you've made or changes triggered by
|
||||
the shell tool (`!`).
|
||||
- **Compression:** Rewind works across chat compression points by reconstructing
|
||||
the history from stored session data.
|
||||
+2
-2
@@ -11,7 +11,7 @@ Before using sandboxing, you need to install and set up the Gemini CLI:
|
||||
npm install -g @google/gemini-cli
|
||||
```
|
||||
|
||||
To verify the installation
|
||||
To verify the installation:
|
||||
|
||||
```bash
|
||||
gemini --version
|
||||
@@ -87,7 +87,7 @@ Built-in profiles (set via `SEATBELT_PROFILE` env var):
|
||||
- `restrictive-open`: Strict restrictions, network allowed
|
||||
- `restrictive-closed`: Maximum restrictions
|
||||
|
||||
### Custom Sandbox Flags
|
||||
### Custom sandbox flags
|
||||
|
||||
For container-based sandboxing, you can inject custom flags into the `docker` or
|
||||
`podman` command using the `SANDBOX_FLAGS` environment variable. This is useful
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
# Session Management
|
||||
|
||||
Gemini CLI includes robust session management features that automatically save
|
||||
your conversation history. This allows you to interrupt your work and resume
|
||||
exactly where you left off, review past interactions, and manage your
|
||||
conversation history effectively.
|
||||
|
||||
## Automatic Saving
|
||||
|
||||
Every time you interact with Gemini CLI, your session is automatically saved.
|
||||
This happens in the background without any manual intervention.
|
||||
|
||||
- **What is saved:** The complete conversation history, including:
|
||||
- Your prompts and the model's responses.
|
||||
- All tool executions (inputs and outputs).
|
||||
- Token usage statistics (input/output/cached, etc.).
|
||||
- Assistant thoughts/reasoning summaries (when available).
|
||||
- **Location:** Sessions are stored in `~/.gemini/tmp/<project_hash>/chats/`.
|
||||
- **Scope:** Sessions are project-specific. Switching directories to a different
|
||||
project will switch to that project's session history.
|
||||
|
||||
## Resuming Sessions
|
||||
|
||||
You can resume a previous session to continue the conversation with all prior
|
||||
context restored.
|
||||
|
||||
### From the Command Line
|
||||
|
||||
When starting the CLI, you can use the `--resume` (or `-r`) flag:
|
||||
|
||||
- **Resume latest:**
|
||||
|
||||
```bash
|
||||
gemini --resume
|
||||
```
|
||||
|
||||
This immediately loads the most recent session.
|
||||
|
||||
- **Resume by index:** First, list available sessions (see
|
||||
[Listing Sessions](#listing-sessions)), then use the index number:
|
||||
|
||||
```bash
|
||||
gemini --resume 1
|
||||
```
|
||||
|
||||
- **Resume by ID:** You can also provide the full session UUID:
|
||||
```bash
|
||||
gemini --resume a1b2c3d4-e5f6-7890-abcd-ef1234567890
|
||||
```
|
||||
|
||||
### From the Interactive Interface
|
||||
|
||||
While the CLI is running, you can use the `/resume` slash command to open the
|
||||
**Session Browser**:
|
||||
|
||||
```text
|
||||
/resume
|
||||
```
|
||||
|
||||
This opens an interactive interface where you can:
|
||||
|
||||
- **Browse:** Scroll through a list of your past sessions.
|
||||
- **Preview:** See details like the session date, message count, and the first
|
||||
user prompt.
|
||||
- **Search:** Press `/` to enter search mode, then type to filter sessions by ID
|
||||
or content.
|
||||
- **Select:** Press `Enter` to resume the selected session.
|
||||
|
||||
## Managing Sessions
|
||||
|
||||
### Listing Sessions
|
||||
|
||||
To see a list of all available sessions for the current project from the command
|
||||
line:
|
||||
|
||||
```bash
|
||||
gemini --list-sessions
|
||||
```
|
||||
|
||||
Output example:
|
||||
|
||||
```text
|
||||
Available sessions for this project (3):
|
||||
|
||||
1. Fix bug in auth (2 days ago) [a1b2c3d4]
|
||||
2. Refactor database schema (5 hours ago) [e5f67890]
|
||||
3. Update documentation (Just now) [abcd1234]
|
||||
```
|
||||
|
||||
### Deleting Sessions
|
||||
|
||||
You can remove old or unwanted sessions to free up space or declutter your
|
||||
history.
|
||||
|
||||
**From the Command Line:** Use the `--delete-session` flag with an index or ID:
|
||||
|
||||
```bash
|
||||
gemini --delete-session 2
|
||||
```
|
||||
|
||||
**From the Session Browser:**
|
||||
|
||||
1. Open the browser with `/resume`.
|
||||
2. Navigate to the session you want to remove.
|
||||
3. Press `x`.
|
||||
|
||||
## Configuration
|
||||
|
||||
You can configure how Gemini CLI manages your session history in your
|
||||
`settings.json` file.
|
||||
|
||||
### Session Retention
|
||||
|
||||
To prevent your history from growing indefinitely, you can enable automatic
|
||||
cleanup policies.
|
||||
|
||||
```json
|
||||
{
|
||||
"general": {
|
||||
"sessionRetention": {
|
||||
"enabled": true,
|
||||
"maxAge": "30d", // Keep sessions for 30 days
|
||||
"maxCount": 50 // Keep the 50 most recent sessions
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- **`enabled`**: (boolean) Master switch for session cleanup. Default is
|
||||
`false`.
|
||||
- **`maxAge`**: (string) Duration to keep sessions (e.g., "24h", "7d", "4w").
|
||||
Sessions older than this will be deleted.
|
||||
- **`maxCount`**: (number) Maximum number of sessions to retain. The oldest
|
||||
sessions exceeding this count will be deleted.
|
||||
- **`minRetention`**: (string) Minimum retention period (safety limit). Defaults
|
||||
to `"1d"`; sessions newer than this period are never deleted by automatic
|
||||
cleanup.
|
||||
|
||||
### Session Limits
|
||||
|
||||
You can also limit the length of individual sessions to prevent context windows
|
||||
from becoming too large and expensive.
|
||||
|
||||
```json
|
||||
{
|
||||
"model": {
|
||||
"maxSessionTurns": 100
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- **`maxSessionTurns`**: (number) The maximum number of turns (user + model
|
||||
exchanges) allowed in a single session. Set to `-1` for unlimited (default).
|
||||
|
||||
**Behavior when limit is reached:**
|
||||
- **Interactive Mode:** The CLI shows an informational message and stops
|
||||
sending requests to the model. You must manually start a new session.
|
||||
- **Non-Interactive Mode:** The CLI exits with an error.
|
||||
+89
-61
@@ -1,4 +1,4 @@
|
||||
# Gemini CLI Settings (`/settings` Command)
|
||||
# Gemini CLI settings (`/settings` command)
|
||||
|
||||
Control your Gemini CLI experience with the `/settings` command. The `/settings`
|
||||
command opens a dialog to view and edit all your Gemini CLI settings, including
|
||||
@@ -18,45 +18,54 @@ Note: Workspace settings override user settings.
|
||||
Here is a list of all the available settings, grouped by category and ordered as
|
||||
they appear in the UI.
|
||||
|
||||
<!-- SETTINGS-AUTOGEN:START -->
|
||||
|
||||
### General
|
||||
|
||||
| UI Label | Setting | Description | Default |
|
||||
| ------------------------------- | ---------------------------------- | ---------------------------------------------------------------------------- | ----------- |
|
||||
| Preview Features (e.g., models) | `general.previewFeatures` | Enable preview features (e.g., preview models). | `false` |
|
||||
| Vim Mode | `general.vimMode` | Enable Vim keybindings. | `false` |
|
||||
| Disable Auto Update | `general.disableAutoUpdate` | Disable automatic updates. | `false` |
|
||||
| Enable Prompt Completion | `general.enablePromptCompletion` | Enable AI-powered prompt completion suggestions while typing. | `false` |
|
||||
| Debug Keystroke Logging | `general.debugKeystrokeLogging` | Enable debug logging of keystrokes to the console. | `false` |
|
||||
| Session Retention | `general.sessionRetention` | Settings for automatic session cleanup. This feature is disabled by default. | `undefined` |
|
||||
| Enable Session Cleanup | `general.sessionRetention.enabled` | Enable automatic session cleanup. | `false` |
|
||||
| UI Label | Setting | Description | Default |
|
||||
| ------------------------------- | ---------------------------------- | ------------------------------------------------------------- | ------- |
|
||||
| Preview Features (e.g., models) | `general.previewFeatures` | Enable preview features (e.g., preview models). | `false` |
|
||||
| Vim Mode | `general.vimMode` | Enable Vim keybindings | `false` |
|
||||
| Enable Auto Update | `general.enableAutoUpdate` | Enable automatic updates. | `true` |
|
||||
| Enable Prompt Completion | `general.enablePromptCompletion` | Enable AI-powered prompt completion suggestions while typing. | `false` |
|
||||
| Debug Keystroke Logging | `general.debugKeystrokeLogging` | Enable debug logging of keystrokes to the console. | `false` |
|
||||
| Enable Session Cleanup | `general.sessionRetention.enabled` | Enable automatic session cleanup | `false` |
|
||||
|
||||
### Output
|
||||
|
||||
| UI Label | Setting | Description | Default |
|
||||
| ------------- | --------------- | ------------------------------------------------------ | ------- |
|
||||
| Output Format | `output.format` | The format of the CLI output. Can be `text` or `json`. | `text` |
|
||||
| UI Label | Setting | Description | Default |
|
||||
| ------------- | --------------- | ------------------------------------------------------ | -------- |
|
||||
| Output Format | `output.format` | The format of the CLI output. Can be `text` or `json`. | `"text"` |
|
||||
|
||||
### UI
|
||||
|
||||
| UI Label | Setting | Description | Default |
|
||||
| ------------------------------ | ---------------------------------------- | -------------------------------------------------------------------- | ------- |
|
||||
| Hide Window Title | `ui.hideWindowTitle` | Hide the window title bar. | `false` |
|
||||
| Show Status in Title | `ui.showStatusInTitle` | Show Gemini CLI status and thoughts in the terminal window title. | `false` |
|
||||
| Hide Tips | `ui.hideTips` | Hide helpful tips in the UI. | `false` |
|
||||
| Hide Banner | `ui.hideBanner` | Hide the application banner. | `false` |
|
||||
| Hide Context Summary | `ui.hideContextSummary` | Hide the context summary (GEMINI.md, MCP servers) above the input. | `false` |
|
||||
| Hide CWD | `ui.footer.hideCWD` | Hide the current working directory path in the footer. | `false` |
|
||||
| Hide Sandbox Status | `ui.footer.hideSandboxStatus` | Hide the sandbox status indicator in the footer. | `false` |
|
||||
| Hide Model Info | `ui.footer.hideModelInfo` | Hide the model name and context usage in the footer. | `false` |
|
||||
| Hide Context Window Percentage | `ui.footer.hideContextPercentage` | Hides the context window remaining percentage. | `true` |
|
||||
| Hide Footer | `ui.hideFooter` | Hide the footer from the UI. | `false` |
|
||||
| Show Memory Usage | `ui.showMemoryUsage` | Display memory usage information in the UI. | `false` |
|
||||
| Show Line Numbers | `ui.showLineNumbers` | Show line numbers in the chat. | `false` |
|
||||
| Show Citations | `ui.showCitations` | Show citations for generated text in the chat. | `false` |
|
||||
| Use Full Width | `ui.useFullWidth` | Use the entire width of the terminal for output. | `true` |
|
||||
| Use Alternate Screen Buffer | `ui.useAlternateBuffer` | Use an alternate screen buffer for the UI, preserving shell history. | `true` |
|
||||
| Disable Loading Phrases | `ui.accessibility.disableLoadingPhrases` | Disable loading phrases for accessibility. | `false` |
|
||||
| Screen Reader Mode | `ui.accessibility.screenReader` | Render output in plain-text to be more screen reader accessible. | `false` |
|
||||
| UI Label | Setting | Description | Default |
|
||||
| ------------------------------------ | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
|
||||
| Auto Theme Switching | `ui.autoThemeSwitching` | Automatically switch between default light and dark themes based on terminal background color. | `true` |
|
||||
| Terminal Background Polling Interval | `ui.terminalBackgroundPollingInterval` | Interval in seconds to poll the terminal background color. | `60` |
|
||||
| Hide Window Title | `ui.hideWindowTitle` | Hide the window title bar | `false` |
|
||||
| Show Thoughts in Title | `ui.showStatusInTitle` | Show Gemini CLI model thoughts in the terminal window title during the working phase | `false` |
|
||||
| Dynamic Window Title | `ui.dynamicWindowTitle` | Update the terminal window title with current status icons (Ready: ◇, Action Required: ✋, Working: ✦) | `true` |
|
||||
| Show Home Directory Warning | `ui.showHomeDirectoryWarning` | Show a warning when running Gemini CLI in the home directory. | `true` |
|
||||
| Hide Tips | `ui.hideTips` | Hide helpful tips in the UI | `false` |
|
||||
| Hide Banner | `ui.hideBanner` | Hide the application banner | `false` |
|
||||
| Hide Context Summary | `ui.hideContextSummary` | Hide the context summary (GEMINI.md, MCP servers) above the input. | `false` |
|
||||
| Hide CWD | `ui.footer.hideCWD` | Hide the current working directory path in the footer. | `false` |
|
||||
| Hide Sandbox Status | `ui.footer.hideSandboxStatus` | Hide the sandbox status indicator in the footer. | `false` |
|
||||
| Hide Model Info | `ui.footer.hideModelInfo` | Hide the model name and context usage in the footer. | `false` |
|
||||
| Hide Context Window Percentage | `ui.footer.hideContextPercentage` | Hides the context window remaining percentage. | `true` |
|
||||
| Hide Footer | `ui.hideFooter` | Hide the footer from the UI | `false` |
|
||||
| Show Memory Usage | `ui.showMemoryUsage` | Display memory usage information in the UI | `false` |
|
||||
| Show Line Numbers | `ui.showLineNumbers` | Show line numbers in the chat. | `true` |
|
||||
| Show Citations | `ui.showCitations` | Show citations for generated text in the chat. | `false` |
|
||||
| Show Model Info In Chat | `ui.showModelInfoInChat` | Show the model name in the chat for each model turn. | `false` |
|
||||
| Show User Identity | `ui.showUserIdentity` | Show the logged-in user's identity (e.g. email) in the UI. | `true` |
|
||||
| Use Alternate Screen Buffer | `ui.useAlternateBuffer` | Use an alternate screen buffer for the UI, preserving shell history. | `false` |
|
||||
| Use Background Color | `ui.useBackgroundColor` | Whether to use background colors in the UI. | `true` |
|
||||
| Incremental Rendering | `ui.incrementalRendering` | Enable incremental rendering for the UI. This option will reduce flickering but may cause rendering artifacts. Only supported when useAlternateBuffer is enabled. | `true` |
|
||||
| Show Spinner | `ui.showSpinner` | Show the spinner during operations. | `true` |
|
||||
| Enable Loading Phrases | `ui.accessibility.enableLoadingPhrases` | Enable loading phrases during operations. | `true` |
|
||||
| Screen Reader Mode | `ui.accessibility.screenReader` | Render output in plain-text to be more screen reader accessible | `false` |
|
||||
|
||||
### IDE
|
||||
|
||||
@@ -69,45 +78,64 @@ they appear in the UI.
|
||||
| UI Label | Setting | Description | Default |
|
||||
| ----------------------- | ---------------------------- | -------------------------------------------------------------------------------------- | ------- |
|
||||
| Max Session Turns | `model.maxSessionTurns` | Maximum number of user/model/tool turns to keep in a session. -1 means unlimited. | `-1` |
|
||||
| Compression Threshold | `model.compressionThreshold` | The fraction of context usage at which to trigger context compression (e.g. 0.2, 0.3). | `0.2` |
|
||||
| Compression Threshold | `model.compressionThreshold` | The fraction of context usage at which to trigger context compression (e.g. 0.2, 0.3). | `0.5` |
|
||||
| Disable Loop Detection | `model.disableLoopDetection` | Disable automatic detection and prevention of infinite loops. | `false` |
|
||||
| Skip Next Speaker Check | `model.skipNextSpeakerCheck` | Skip the next speaker check. | `true` |
|
||||
|
||||
### Context
|
||||
|
||||
| UI Label | Setting | Description | Default |
|
||||
| ------------------------------------ | ------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
|
||||
| Memory Discovery Max Dirs | `context.discoveryMaxDirs` | Maximum number of directories to search for memory. | `200` |
|
||||
| Load Memory From Include Directories | `context.loadMemoryFromIncludeDirectories` | Controls how /memory refresh loads GEMINI.md files. When true, include directories are scanned; when false, only the current directory is used. | `false` |
|
||||
| Respect .gitignore | `context.fileFiltering.respectGitIgnore` | Respect .gitignore files when searching. | `true` |
|
||||
| Respect .geminiignore | `context.fileFiltering.respectGeminiIgnore` | Respect .geminiignore files when searching. | `true` |
|
||||
| Enable Recursive File Search | `context.fileFiltering.enableRecursiveFileSearch` | Enable recursive file search functionality when completing @ references in the prompt. | `true` |
|
||||
| Disable Fuzzy Search | `context.fileFiltering.disableFuzzySearch` | Disable fuzzy search when searching for files. | `false` |
|
||||
| UI Label | Setting | Description | Default |
|
||||
| ------------------------------------ | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
|
||||
| Memory Discovery Max Dirs | `context.discoveryMaxDirs` | Maximum number of directories to search for memory. | `200` |
|
||||
| Load Memory From Include Directories | `context.loadMemoryFromIncludeDirectories` | Controls how /memory refresh loads GEMINI.md files. When true, include directories are scanned; when false, only the current directory is used. | `false` |
|
||||
| Respect .gitignore | `context.fileFiltering.respectGitIgnore` | Respect .gitignore files when searching. | `true` |
|
||||
| Respect .geminiignore | `context.fileFiltering.respectGeminiIgnore` | Respect .geminiignore files when searching. | `true` |
|
||||
| Enable Recursive File Search | `context.fileFiltering.enableRecursiveFileSearch` | Enable recursive file search functionality when completing @ references in the prompt. | `true` |
|
||||
| Enable Fuzzy Search | `context.fileFiltering.enableFuzzySearch` | Enable fuzzy search when searching for files. | `true` |
|
||||
| Custom Ignore File Paths | `context.fileFiltering.customIgnoreFilePaths` | Additional ignore file paths to respect. These files take precedence over .geminiignore and .gitignore. Files earlier in the array take precedence over files later in the array, e.g. the first file takes precedence over the second one. | `[]` |
|
||||
|
||||
### Tools
|
||||
|
||||
| UI Label | Setting | Description | Default |
|
||||
| -------------------------------- | ------------------------------------ | --------------------------------------------------------------------------------------------------------------- | ------- |
|
||||
| Enable Interactive Shell | `tools.shell.enableInteractiveShell` | Use node-pty for an interactive shell experience. Fallback to child_process still applies. | `true` |
|
||||
| Show Color | `tools.shell.showColor` | Show color in shell output. | `false` |
|
||||
| Auto Accept | `tools.autoAccept` | Automatically accept and execute tool calls that are considered safe (e.g., read-only operations). | `false` |
|
||||
| Use Ripgrep | `tools.useRipgrep` | Use ripgrep for file content search instead of the fallback implementation. Provides faster search performance. | `true` |
|
||||
| Enable Tool Output Truncation | `tools.enableToolOutputTruncation` | Enable truncation of large tool outputs. | `true` |
|
||||
| Tool Output Truncation Threshold | `tools.truncateToolOutputThreshold` | Truncate tool output if it is larger than this many characters. Set to -1 to disable. | `10000` |
|
||||
| Tool Output Truncation Lines | `tools.truncateToolOutputLines` | The number of lines to keep when truncating tool output. | `100` |
|
||||
| Enable Message Bus Integration | `tools.enableMessageBusIntegration` | Enable policy-based tool confirmation via message bus integration. | `false` |
|
||||
| UI Label | Setting | Description | Default |
|
||||
| -------------------------------- | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------- |
|
||||
| Enable Interactive Shell | `tools.shell.enableInteractiveShell` | Use node-pty for an interactive shell experience. Fallback to child_process still applies. | `true` |
|
||||
| Show Color | `tools.shell.showColor` | Show color in shell output. | `false` |
|
||||
| Approval Mode | `tools.approvalMode` | The default approval mode for tool execution. 'default' prompts for approval, 'auto_edit' auto-approves edit tools, and 'plan' is read-only mode. 'yolo' is not supported yet. | `"default"` |
|
||||
| Use Ripgrep | `tools.useRipgrep` | Use ripgrep for file content search instead of the fallback implementation. Provides faster search performance. | `true` |
|
||||
| Enable Tool Output Truncation | `tools.enableToolOutputTruncation` | Enable truncation of large tool outputs. | `true` |
|
||||
| Tool Output Truncation Threshold | `tools.truncateToolOutputThreshold` | Truncate tool output if it is larger than this many characters. Set to -1 to disable. | `4000000` |
|
||||
| Tool Output Truncation Lines | `tools.truncateToolOutputLines` | The number of lines to keep when truncating tool output. | `1000` |
|
||||
| Disable LLM Correction | `tools.disableLLMCorrection` | Disable LLM-based error correction for edit tools. When enabled, tools will fail immediately if exact string matches are not found, instead of attempting to self-correct. | `true` |
|
||||
|
||||
### Security
|
||||
|
||||
| UI Label | Setting | Description | Default |
|
||||
| -------------------------- | ------------------------------ | -------------------------------------------------- | ------- |
|
||||
| Disable YOLO Mode | `security.disableYoloMode` | Disable YOLO mode, even if enabled by a flag. | `false` |
|
||||
| Blocks extensions from Git | `security.blockGitExtensions` | Blocks installing and loading extensions from Git. | `false` |
|
||||
| Folder Trust | `security.folderTrust.enabled` | Setting to track whether Folder trust is enabled. | `false` |
|
||||
| UI Label | Setting | Description | Default |
|
||||
| ------------------------------------- | ----------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
|
||||
| Disable YOLO Mode | `security.disableYoloMode` | Disable YOLO mode, even if enabled by a flag. | `false` |
|
||||
| Allow Permanent Tool Approval | `security.enablePermanentToolApproval` | Enable the "Allow for all future sessions" option in tool confirmation dialogs. | `false` |
|
||||
| Blocks extensions from Git | `security.blockGitExtensions` | Blocks installing and loading extensions from Git. | `false` |
|
||||
| Extension Source Regex Allowlist | `security.allowedExtensions` | List of Regex patterns for allowed extensions. If nonempty, only extensions that match the patterns in this list are allowed. Overrides the blockGitExtensions setting. | `[]` |
|
||||
| Folder Trust | `security.folderTrust.enabled` | Setting to track whether Folder trust is enabled. | `true` |
|
||||
| Enable Environment Variable Redaction | `security.environmentVariableRedaction.enabled` | Enable redaction of environment variables that may contain secrets. | `false` |
|
||||
|
||||
### Experimental
|
||||
|
||||
| UI Label | Setting | Description | Default |
|
||||
| ----------------------------------- | ------------------------------------------------------- | ----------------------------------------------------------------------------- | ------- |
|
||||
| Use Model Router | `experimental.useModelRouter` | Enable model routing to route requests to the best model based on complexity. | `true` |
|
||||
| Enable Codebase Investigator | `experimental.codebaseInvestigatorSettings.enabled` | Enable the Codebase Investigator agent. | `true` |
|
||||
| Codebase Investigator Max Num Turns | `experimental.codebaseInvestigatorSettings.maxNumTurns` | Maximum number of turns for the Codebase Investigator agent. | `10` |
|
||||
| UI Label | Setting | Description | Default |
|
||||
| ---------------- | ---------------------------- | ----------------------------------------------------------------------------------- | ------- |
|
||||
| Use OSC 52 Paste | `experimental.useOSC52Paste` | Use OSC 52 sequence for pasting instead of clipboardy (useful for remote sessions). | `false` |
|
||||
| Plan | `experimental.plan` | Enable planning features (Plan Mode and tools). | `false` |
|
||||
|
||||
### Skills
|
||||
|
||||
| UI Label | Setting | Description | Default |
|
||||
| ------------------- | ---------------- | -------------------- | ------- |
|
||||
| Enable Agent Skills | `skills.enabled` | Enable Agent Skills. | `true` |
|
||||
|
||||
### HooksConfig
|
||||
|
||||
| UI Label | Setting | Description | Default |
|
||||
| ------------------ | --------------------------- | -------------------------------------------------------------------------------- | ------- |
|
||||
| Enable Hooks | `hooksConfig.enabled` | Canonical toggle for the hooks system. When disabled, no hooks will be executed. | `true` |
|
||||
| Hook Notifications | `hooksConfig.notifications` | Show visual indicators when hooks are executing. | `true` |
|
||||
|
||||
<!-- SETTINGS-AUTOGEN:END -->
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
# Agent Skills
|
||||
|
||||
Agent Skills allow you to extend Gemini CLI with specialized expertise,
|
||||
procedural workflows, and task-specific resources. Based on the
|
||||
[Agent Skills](https://agentskills.io) open standard, a "skill" is a
|
||||
self-contained directory that packages instructions and assets into a
|
||||
discoverable capability.
|
||||
|
||||
## Overview
|
||||
|
||||
Unlike general context files ([`GEMINI.md`](./gemini-md.md)), which provide
|
||||
persistent workspace-wide background, Skills represent **on-demand expertise**.
|
||||
This allows Gemini to maintain a vast library of specialized capabilities—such
|
||||
as security auditing, cloud deployments, or codebase migrations—without
|
||||
cluttering the model's immediate context window.
|
||||
|
||||
Gemini autonomously decides when to employ a skill based on your request and the
|
||||
skill's description. When a relevant skill is identified, the model "pulls in"
|
||||
the full instructions and resources required to complete the task using the
|
||||
`activate_skill` tool.
|
||||
|
||||
## Key Benefits
|
||||
|
||||
- **Shared Expertise:** Package complex workflows (like a specific team's PR
|
||||
review process) into a folder that anyone can use.
|
||||
- **Repeatable Workflows:** Ensure complex multi-step tasks are performed
|
||||
consistently by providing a procedural framework.
|
||||
- **Resource Bundling:** Include scripts, templates, or example data alongside
|
||||
instructions so the agent has everything it needs.
|
||||
- **Progressive Disclosure:** Only skill metadata (name and description) is
|
||||
loaded initially. Detailed instructions and resources are only disclosed when
|
||||
the model explicitly activates the skill, saving context tokens.
|
||||
|
||||
## Skill Discovery Tiers
|
||||
|
||||
Gemini CLI discovers skills from three primary locations:
|
||||
|
||||
1. **Workspace Skills** (`.gemini/skills/`): Workspace-specific skills that are
|
||||
typically committed to version control and shared with the team.
|
||||
2. **User Skills** (`~/.gemini/skills/`): Personal skills available across all
|
||||
your workspaces.
|
||||
3. **Extension Skills**: Skills bundled within installed
|
||||
[extensions](../extensions/index.md).
|
||||
|
||||
**Precedence:** If multiple skills share the same name, higher-precedence
|
||||
locations override lower ones: **Workspace > User > Extension**.
|
||||
|
||||
## Managing Skills
|
||||
|
||||
### In an Interactive Session
|
||||
|
||||
Use the `/skills` slash command to view and manage available expertise:
|
||||
|
||||
- `/skills list` (default): Shows all discovered skills and their status.
|
||||
- `/skills link <path>`: Links agent skills from a local directory via symlink.
|
||||
- `/skills disable <name>`: Prevents a specific skill from being used.
|
||||
- `/skills enable <name>`: Re-enables a disabled skill.
|
||||
- `/skills reload`: Refreshes the list of discovered skills from all tiers.
|
||||
|
||||
_Note: `/skills disable` and `/skills enable` default to the `user` scope. Use
|
||||
`--scope workspace` to manage workspace-specific settings._
|
||||
|
||||
### From the Terminal
|
||||
|
||||
The `gemini skills` command provides management utilities:
|
||||
|
||||
```bash
|
||||
# List all discovered skills
|
||||
gemini skills list
|
||||
|
||||
# Link agent skills from a local directory via symlink
|
||||
# Discovers skills (SKILL.md or */SKILL.md) and creates symlinks in ~/.gemini/skills (user)
|
||||
gemini skills link /path/to/my-skills-repo
|
||||
|
||||
# Link to the workspace scope (.gemini/skills)
|
||||
gemini skills link /path/to/my-skills-repo --scope workspace
|
||||
|
||||
# Install a skill from a Git repository, local directory, or zipped skill file (.skill)
|
||||
# Uses the user scope by default (~/.gemini/skills)
|
||||
gemini skills install https://github.com/user/repo.git
|
||||
gemini skills install /path/to/local/skill
|
||||
gemini skills install /path/to/local/my-expertise.skill
|
||||
|
||||
# Install a specific skill from a monorepo or subdirectory using --path
|
||||
gemini skills install https://github.com/my-org/my-skills.git --path skills/frontend-design
|
||||
|
||||
# Install to the workspace scope (.gemini/skills)
|
||||
gemini skills install /path/to/skill --scope workspace
|
||||
|
||||
# Uninstall a skill by name
|
||||
gemini skills uninstall my-expertise --scope workspace
|
||||
|
||||
# Enable a skill (globally)
|
||||
gemini skills enable my-expertise
|
||||
|
||||
# Disable a skill. Can use --scope to specify workspace or user (defaults to workspace)
|
||||
gemini skills disable my-expertise --scope workspace
|
||||
```
|
||||
|
||||
## How it Works
|
||||
|
||||
1. **Discovery**: At the start of a session, Gemini CLI scans the discovery
|
||||
tiers and injects the name and description of all enabled skills into the
|
||||
system prompt.
|
||||
2. **Activation**: When Gemini identifies a task matching a skill's
|
||||
description, it calls the `activate_skill` tool.
|
||||
3. **Consent**: You will see a confirmation prompt in the UI detailing the
|
||||
skill's name, purpose, and the directory path it will gain access to.
|
||||
4. **Injection**: Upon your approval:
|
||||
- The `SKILL.md` body and folder structure is added to the conversation
|
||||
history.
|
||||
- The skill's directory is added to the agent's allowed file paths, granting
|
||||
it permission to read any bundled assets.
|
||||
5. **Execution**: The model proceeds with the specialized expertise active. It
|
||||
is instructed to prioritize the skill's procedural guidance within reason.
|
||||
|
||||
### Skill activation
|
||||
|
||||
Once a skill is activated (typically by Gemini identifying a task that matches
|
||||
the skill's description and your approval), its specialized instructions and
|
||||
resources are loaded into the agent's context. A skill remains active and its
|
||||
guidance is prioritized for the duration of the session.
|
||||
|
||||
## Creating your own skills
|
||||
|
||||
To create your own skills, see the [Create Agent Skills](./creating-skills.md)
|
||||
guide.
|
||||
@@ -0,0 +1,125 @@
|
||||
# System Prompt Override (GEMINI_SYSTEM_MD)
|
||||
|
||||
The core system instructions that guide Gemini CLI can be completely replaced
|
||||
with your own Markdown file. This feature is controlled via the
|
||||
`GEMINI_SYSTEM_MD` environment variable.
|
||||
|
||||
## Overview
|
||||
|
||||
The `GEMINI_SYSTEM_MD` variable instructs the CLI to use an external Markdown
|
||||
file for its system prompt, completely overriding the built-in default. This is
|
||||
a full replacement, not a merge. If you use a custom file, none of the original
|
||||
core instructions will apply unless you include them yourself.
|
||||
|
||||
This feature is intended for advanced users who need to enforce strict,
|
||||
project-specific behavior or create a customized persona.
|
||||
|
||||
> Tip: You can export the current default system prompt to a file first, review
|
||||
> it, and then selectively modify or replace it (see
|
||||
> [“Export the default prompt”](#export-the-default-prompt-recommended)).
|
||||
|
||||
## How to enable
|
||||
|
||||
You can set the environment variable temporarily in your shell, or persist it
|
||||
via a `.gemini/.env` file. See
|
||||
[Persisting Environment Variables](../get-started/authentication.md#persisting-environment-variables).
|
||||
|
||||
- Use the project default path (`.gemini/system.md`):
|
||||
- `GEMINI_SYSTEM_MD=true` or `GEMINI_SYSTEM_MD=1`
|
||||
- The CLI reads `./.gemini/system.md` (relative to your current project
|
||||
directory).
|
||||
|
||||
- Use a custom file path:
|
||||
- `GEMINI_SYSTEM_MD=/absolute/path/to/my-system.md`
|
||||
- Relative paths are supported and resolved from the current working
|
||||
directory.
|
||||
- Tilde expansion is supported (e.g., `~/my-system.md`).
|
||||
|
||||
- Disable the override (use built‑in prompt):
|
||||
- `GEMINI_SYSTEM_MD=false` or `GEMINI_SYSTEM_MD=0` or unset the variable.
|
||||
|
||||
If the override is enabled but the target file does not exist, the CLI will
|
||||
error with: `missing system prompt file '<path>'`.
|
||||
|
||||
## Quick examples
|
||||
|
||||
- One‑off session using a project file:
|
||||
- `GEMINI_SYSTEM_MD=1 gemini`
|
||||
- Persist for a project using `.gemini/.env`:
|
||||
- Create `.gemini/system.md`, then add to `.gemini/.env`:
|
||||
- `GEMINI_SYSTEM_MD=1`
|
||||
- Use a custom file under your home directory:
|
||||
- `GEMINI_SYSTEM_MD=~/prompts/SYSTEM.md gemini`
|
||||
|
||||
## UI indicator
|
||||
|
||||
When `GEMINI_SYSTEM_MD` is active, the CLI shows a `|⌐■_■|` indicator in the UI
|
||||
to signal custom system‑prompt mode.
|
||||
|
||||
## Variable Substitution
|
||||
|
||||
When using a custom system prompt file, you can use the following variables to
|
||||
dynamically include built-in content:
|
||||
|
||||
- `${AgentSkills}`: Injects a complete section (including header) of all
|
||||
available agent skills.
|
||||
- `${SubAgents}`: Injects a complete section (including header) of available
|
||||
sub-agents.
|
||||
- `${AvailableTools}`: Injects a bulleted list of all currently enabled tool
|
||||
names.
|
||||
- Tool Name Variables: Injects the actual name of a tool using the pattern:
|
||||
`${toolName}_ToolName` (e.g., `${write_file_ToolName}`,
|
||||
`${run_shell_command_ToolName}`).
|
||||
|
||||
This pattern is generated dynamically for all available tools.
|
||||
|
||||
### Example
|
||||
|
||||
```markdown
|
||||
# Custom System Prompt
|
||||
|
||||
You are a helpful assistant. ${AgentSkills}
|
||||
${SubAgents}
|
||||
|
||||
## Tooling
|
||||
|
||||
The following tools are available to you: ${AvailableTools}
|
||||
|
||||
You can use ${write_file_ToolName} to save logs.
|
||||
```
|
||||
|
||||
## Export the default prompt (recommended)
|
||||
|
||||
Before overriding, export the current default prompt so you can review required
|
||||
safety and workflow rules.
|
||||
|
||||
- Write the built‑in prompt to the project default path:
|
||||
- `GEMINI_WRITE_SYSTEM_MD=1 gemini`
|
||||
- Or write to a custom path:
|
||||
- `GEMINI_WRITE_SYSTEM_MD=~/prompts/DEFAULT_SYSTEM.md gemini`
|
||||
|
||||
This creates the file and writes the current built‑in system prompt to it.
|
||||
|
||||
## Best practices: SYSTEM.md vs GEMINI.md
|
||||
|
||||
- SYSTEM.md (firmware):
|
||||
- Non‑negotiable operational rules: safety, tool‑use protocols, approvals, and
|
||||
mechanics that keep the CLI reliable.
|
||||
- Stable across tasks and projects (or per project when needed).
|
||||
- GEMINI.md (strategy):
|
||||
- Persona, goals, methodologies, and project/domain context.
|
||||
- Evolves per task; relies on SYSTEM.md for safe execution.
|
||||
|
||||
Keep SYSTEM.md minimal but complete for safety and tool operation. Keep
|
||||
GEMINI.md focused on high‑level guidance and project specifics.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- Error: `missing system prompt file '…'`
|
||||
- Ensure the referenced path exists and is readable.
|
||||
- For `GEMINI_SYSTEM_MD=1|true`, create `./.gemini/system.md` in your project.
|
||||
- Override not taking effect
|
||||
- Confirm the variable is loaded (use `.gemini/.env` or export in your shell).
|
||||
- Paths are resolved from the current working directory; try an absolute path.
|
||||
- Restore defaults
|
||||
- Unset `GEMINI_SYSTEM_MD` or set it to `0`/`false`.
|
||||
+121
-62
@@ -3,27 +3,30 @@
|
||||
Learn how to enable and setup OpenTelemetry for Gemini CLI.
|
||||
|
||||
- [Observability with OpenTelemetry](#observability-with-opentelemetry)
|
||||
- [Key Benefits](#key-benefits)
|
||||
- [OpenTelemetry Integration](#opentelemetry-integration)
|
||||
- [Key benefits](#key-benefits)
|
||||
- [OpenTelemetry integration](#opentelemetry-integration)
|
||||
- [Configuration](#configuration)
|
||||
- [Google Cloud Telemetry](#google-cloud-telemetry)
|
||||
- [Google Cloud telemetry](#google-cloud-telemetry)
|
||||
- [Prerequisites](#prerequisites)
|
||||
- [Direct Export (Recommended)](#direct-export-recommended)
|
||||
- [Collector-Based Export (Advanced)](#collector-based-export-advanced)
|
||||
- [Local Telemetry](#local-telemetry)
|
||||
- [File-based Output (Recommended)](#file-based-output-recommended)
|
||||
- [Collector-Based Export (Advanced)](#collector-based-export-advanced-1)
|
||||
- [Logs and Metrics](#logs-and-metrics)
|
||||
- [Authenticating with CLI Credentials](#authenticating-with-cli-credentials)
|
||||
- [Direct export (recommended)](#direct-export-recommended)
|
||||
- [Collector-based export (advanced)](#collector-based-export-advanced)
|
||||
- [Monitoring Dashboards](#monitoring-dashboards)
|
||||
- [Local telemetry](#local-telemetry)
|
||||
- [File-based output (recommended)](#file-based-output-recommended)
|
||||
- [Collector-based export (advanced)](#collector-based-export-advanced-1)
|
||||
- [Logs and metrics](#logs-and-metrics)
|
||||
- [Logs](#logs)
|
||||
- [Sessions](#sessions)
|
||||
- [Approval Mode](#approval-mode)
|
||||
- [Tools](#tools)
|
||||
- [Files](#files)
|
||||
- [API](#api)
|
||||
- [Model Routing](#model-routing)
|
||||
- [Chat and Streaming](#chat-and-streaming)
|
||||
- [Model routing](#model-routing)
|
||||
- [Chat and streaming](#chat-and-streaming)
|
||||
- [Resilience](#resilience)
|
||||
- [Extensions](#extensions)
|
||||
- [Agent Runs](#agent-runs)
|
||||
- [Agent runs](#agent-runs)
|
||||
- [IDE](#ide)
|
||||
- [UI](#ui)
|
||||
- [Metrics](#metrics)
|
||||
@@ -31,40 +34,40 @@ Learn how to enable and setup OpenTelemetry for Gemini CLI.
|
||||
- [Sessions](#sessions-1)
|
||||
- [Tools](#tools-1)
|
||||
- [API](#api-1)
|
||||
- [Token Usage](#token-usage)
|
||||
- [Token usage](#token-usage)
|
||||
- [Files](#files-1)
|
||||
- [Chat and Streaming](#chat-and-streaming-1)
|
||||
- [Model Routing](#model-routing-1)
|
||||
- [Agent Runs](#agent-runs-1)
|
||||
- [Chat and streaming](#chat-and-streaming-1)
|
||||
- [Model routing](#model-routing-1)
|
||||
- [Agent runs](#agent-runs-1)
|
||||
- [UI](#ui-1)
|
||||
- [Performance](#performance)
|
||||
- [GenAI Semantic Convention](#genai-semantic-convention)
|
||||
- [GenAI semantic convention](#genai-semantic-convention)
|
||||
|
||||
## Key Benefits
|
||||
## Key benefits
|
||||
|
||||
- **🔍 Usage Analytics**: Understand interaction patterns and feature adoption
|
||||
- **🔍 Usage analytics**: Understand interaction patterns and feature adoption
|
||||
across your team
|
||||
- **⚡ Performance Monitoring**: Track response times, token consumption, and
|
||||
- **⚡ Performance monitoring**: Track response times, token consumption, and
|
||||
resource utilization
|
||||
- **🐛 Real-time Debugging**: Identify bottlenecks, failures, and error patterns
|
||||
- **🐛 Real-time debugging**: Identify bottlenecks, failures, and error patterns
|
||||
as they occur
|
||||
- **📊 Workflow Optimization**: Make informed decisions to improve
|
||||
- **📊 Workflow optimization**: Make informed decisions to improve
|
||||
configurations and processes
|
||||
- **🏢 Enterprise Governance**: Monitor usage across teams, track costs, ensure
|
||||
- **🏢 Enterprise governance**: Monitor usage across teams, track costs, ensure
|
||||
compliance, and integrate with existing monitoring infrastructure
|
||||
|
||||
## OpenTelemetry Integration
|
||||
## OpenTelemetry integration
|
||||
|
||||
Built on **[OpenTelemetry]** — the vendor-neutral, industry-standard
|
||||
observability framework — Gemini CLI's observability system provides:
|
||||
|
||||
- **Universal Compatibility**: Export to any OpenTelemetry backend (Google
|
||||
- **Universal compatibility**: Export to any OpenTelemetry backend (Google
|
||||
Cloud, Jaeger, Prometheus, Datadog, etc.)
|
||||
- **Standardized Data**: Use consistent formats and collection methods across
|
||||
- **Standardized data**: Use consistent formats and collection methods across
|
||||
your toolchain
|
||||
- **Future-Proof Integration**: Connect with existing and future observability
|
||||
- **Future-proof integration**: Connect with existing and future observability
|
||||
infrastructure
|
||||
- **No Vendor Lock-in**: Switch between backends without changing your
|
||||
- **No vendor lock-in**: Switch between backends without changing your
|
||||
instrumentation
|
||||
|
||||
[OpenTelemetry]: https://opentelemetry.io/
|
||||
@@ -74,24 +77,25 @@ observability framework — Gemini CLI's observability system provides:
|
||||
All telemetry behavior is controlled through your `.gemini/settings.json` file.
|
||||
Environment variables can be used to override the settings in the file.
|
||||
|
||||
| Setting | Environment Variable | Description | Values | Default |
|
||||
| -------------- | -------------------------------- | ------------------------------------------------- | ----------------- | ----------------------- |
|
||||
| `enabled` | `GEMINI_TELEMETRY_ENABLED` | Enable or disable telemetry | `true`/`false` | `false` |
|
||||
| `target` | `GEMINI_TELEMETRY_TARGET` | Where to send telemetry data | `"gcp"`/`"local"` | `"local"` |
|
||||
| `otlpEndpoint` | `GEMINI_TELEMETRY_OTLP_ENDPOINT` | OTLP collector endpoint | URL string | `http://localhost:4317` |
|
||||
| `otlpProtocol` | `GEMINI_TELEMETRY_OTLP_PROTOCOL` | OTLP transport protocol | `"grpc"`/`"http"` | `"grpc"` |
|
||||
| `outfile` | `GEMINI_TELEMETRY_OUTFILE` | Save telemetry to file (overrides `otlpEndpoint`) | file path | - |
|
||||
| `logPrompts` | `GEMINI_TELEMETRY_LOG_PROMPTS` | Include prompts in telemetry logs | `true`/`false` | `true` |
|
||||
| `useCollector` | `GEMINI_TELEMETRY_USE_COLLECTOR` | Use external OTLP collector (advanced) | `true`/`false` | `false` |
|
||||
| Setting | Environment Variable | Description | Values | Default |
|
||||
| -------------- | -------------------------------- | --------------------------------------------------- | ----------------- | ----------------------- |
|
||||
| `enabled` | `GEMINI_TELEMETRY_ENABLED` | Enable or disable telemetry | `true`/`false` | `false` |
|
||||
| `target` | `GEMINI_TELEMETRY_TARGET` | Where to send telemetry data | `"gcp"`/`"local"` | `"local"` |
|
||||
| `otlpEndpoint` | `GEMINI_TELEMETRY_OTLP_ENDPOINT` | OTLP collector endpoint | URL string | `http://localhost:4317` |
|
||||
| `otlpProtocol` | `GEMINI_TELEMETRY_OTLP_PROTOCOL` | OTLP transport protocol | `"grpc"`/`"http"` | `"grpc"` |
|
||||
| `outfile` | `GEMINI_TELEMETRY_OUTFILE` | Save telemetry to file (overrides `otlpEndpoint`) | file path | - |
|
||||
| `logPrompts` | `GEMINI_TELEMETRY_LOG_PROMPTS` | Include prompts in telemetry logs | `true`/`false` | `true` |
|
||||
| `useCollector` | `GEMINI_TELEMETRY_USE_COLLECTOR` | Use external OTLP collector (advanced) | `true`/`false` | `false` |
|
||||
| `useCliAuth` | `GEMINI_TELEMETRY_USE_CLI_AUTH` | Use CLI credentials for telemetry (GCP target only) | `true`/`false` | `false` |
|
||||
|
||||
**Note on boolean environment variables:** For the boolean settings (`enabled`,
|
||||
`logPrompts`, `useCollector`), setting the corresponding environment variable to
|
||||
`true` or `1` will enable the feature. Any other value will disable it.
|
||||
|
||||
For detailed information about all configuration options, see the
|
||||
[Configuration Guide](../get-started/configuration.md).
|
||||
[Configuration guide](../get-started/configuration.md).
|
||||
|
||||
## Google Cloud Telemetry
|
||||
## Google Cloud telemetry
|
||||
|
||||
### Prerequisites
|
||||
|
||||
@@ -130,7 +134,35 @@ Before using either method below, complete these steps:
|
||||
--project="$OTLP_GOOGLE_CLOUD_PROJECT"
|
||||
```
|
||||
|
||||
### Direct Export (Recommended)
|
||||
### Authenticating with CLI Credentials
|
||||
|
||||
By default, the telemetry collector for Google Cloud uses Application Default
|
||||
Credentials (ADC). However, you can configure it to use the same OAuth
|
||||
credentials that you use to log in to the Gemini CLI. This is useful in
|
||||
environments where you don't have ADC set up.
|
||||
|
||||
To enable this, set the `useCliAuth` property in your `telemetry` settings to
|
||||
`true`:
|
||||
|
||||
```json
|
||||
{
|
||||
"telemetry": {
|
||||
"enabled": true,
|
||||
"target": "gcp",
|
||||
"useCliAuth": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Important:**
|
||||
|
||||
- This setting requires the use of **Direct Export** (in-process exporters).
|
||||
- It **cannot** be used with `useCollector: true`. If you enable both, telemetry
|
||||
will be disabled and an error will be logged.
|
||||
- The CLI will automatically use your credentials to authenticate with Google
|
||||
Cloud Trace, Metrics, and Logging APIs.
|
||||
|
||||
### Direct export (recommended)
|
||||
|
||||
Sends telemetry directly to Google Cloud services. No collector needed.
|
||||
|
||||
@@ -150,7 +182,7 @@ Sends telemetry directly to Google Cloud services. No collector needed.
|
||||
- Metrics: https://console.cloud.google.com/monitoring/metrics-explorer
|
||||
- Traces: https://console.cloud.google.com/traces/list
|
||||
|
||||
### Collector-Based Export (Advanced)
|
||||
### Collector-based export (advanced)
|
||||
|
||||
For custom processing, filtering, or routing, use an OpenTelemetry collector to
|
||||
forward data to Google Cloud.
|
||||
@@ -184,11 +216,29 @@ forward data to Google Cloud.
|
||||
- Open `~/.gemini/tmp/<projectHash>/otel/collector-gcp.log` to view local
|
||||
collector logs.
|
||||
|
||||
## Local Telemetry
|
||||
### Monitoring Dashboards
|
||||
|
||||
Gemini CLI provides a pre-configured
|
||||
[Google Cloud Monitoring](https://cloud.google.com/monitoring) dashboard to
|
||||
visualize your telemetry.
|
||||
|
||||
This dashboard can be found under **Google Cloud Monitoring Dashboard
|
||||
Templates** as "**Gemini CLI Monitoring**".
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
To learn more, check out this blog post:
|
||||
[Instant insights: Gemini CLI’s new pre-configured monitoring dashboards](https://cloud.google.com/blog/topics/developers-practitioners/instant-insights-gemini-clis-new-pre-configured-monitoring-dashboards/).
|
||||
|
||||
## Local telemetry
|
||||
|
||||
For local development and debugging, you can capture telemetry data locally:
|
||||
|
||||
### File-based Output (Recommended)
|
||||
### File-based output (recommended)
|
||||
|
||||
1. Enable telemetry in your `.gemini/settings.json`:
|
||||
```json
|
||||
@@ -204,7 +254,7 @@ For local development and debugging, you can capture telemetry data locally:
|
||||
2. Run Gemini CLI and send prompts.
|
||||
3. View logs and metrics in the specified file (e.g., `.gemini/telemetry.log`).
|
||||
|
||||
### Collector-Based Export (Advanced)
|
||||
### Collector-based export (advanced)
|
||||
|
||||
1. Run the automation script:
|
||||
```bash
|
||||
@@ -220,7 +270,7 @@ For local development and debugging, you can capture telemetry data locally:
|
||||
3. View traces at http://localhost:16686 and logs/metrics in the collector log
|
||||
file.
|
||||
|
||||
## Logs and Metrics
|
||||
## Logs and metrics
|
||||
|
||||
The following section describes the structure of logs and metrics generated for
|
||||
Gemini CLI.
|
||||
@@ -266,9 +316,23 @@ Captures startup configuration and user prompt submissions.
|
||||
- `prompt` (string; excluded if `telemetry.logPrompts` is `false`)
|
||||
- `auth_type` (string)
|
||||
|
||||
#### Approval Mode
|
||||
|
||||
Tracks changes and duration of approval modes.
|
||||
|
||||
- `approval_mode_switch`: Approval mode was changed.
|
||||
- **Attributes**:
|
||||
- `from_mode` (string)
|
||||
- `to_mode` (string)
|
||||
|
||||
- `approval_mode_duration`: Duration spent in an approval mode.
|
||||
- **Attributes**:
|
||||
- `mode` (string)
|
||||
- `duration_ms` (int)
|
||||
|
||||
#### Tools
|
||||
|
||||
Captures tool executions, output truncation, and Smart Edit behavior.
|
||||
Captures tool executions, output truncation, and Edit behavior.
|
||||
|
||||
- `gemini_cli.tool_call`: Emitted for each tool (function) call.
|
||||
- **Attributes**:
|
||||
@@ -296,11 +360,11 @@ Captures tool executions, output truncation, and Smart Edit behavior.
|
||||
- `lines` (int)
|
||||
- `prompt_id` (string)
|
||||
|
||||
- `gemini_cli.smart_edit_strategy`: Smart Edit strategy chosen.
|
||||
- `gemini_cli.edit_strategy`: Edit strategy chosen.
|
||||
- **Attributes**:
|
||||
- `strategy` (string)
|
||||
|
||||
- `gemini_cli.smart_edit_correction`: Smart Edit correction result.
|
||||
- `gemini_cli.edit_correction`: Edit correction result.
|
||||
- **Attributes**:
|
||||
- `correction` ("success" | "failure")
|
||||
|
||||
@@ -361,6 +425,7 @@ Captures Gemini API requests, responses, and errors.
|
||||
- `response_text` (string, optional)
|
||||
- `prompt_id` (string)
|
||||
- `auth_type` (string)
|
||||
- `finish_reasons` (array of strings)
|
||||
|
||||
- `gemini_cli.api_error`: API request failed.
|
||||
- **Attributes**:
|
||||
@@ -377,9 +442,7 @@ Captures Gemini API requests, responses, and errors.
|
||||
- **Attributes**:
|
||||
- `model` (string)
|
||||
|
||||
#### Model Routing
|
||||
|
||||
Tracks model selections via slash commands and router decisions.
|
||||
#### Model routing
|
||||
|
||||
- `gemini_cli.slash_command`: A slash command was executed.
|
||||
- **Attributes**:
|
||||
@@ -400,9 +463,7 @@ Tracks model selections via slash commands and router decisions.
|
||||
- `failed` (boolean)
|
||||
- `error_message` (string, optional)
|
||||
|
||||
#### Chat and Streaming
|
||||
|
||||
Observes streaming integrity, compression, and retry behavior.
|
||||
#### Chat and streaming
|
||||
|
||||
- `gemini_cli.chat_compression`: Chat context was compressed.
|
||||
- **Attributes**:
|
||||
@@ -488,9 +549,7 @@ Tracks extension lifecycle and settings changes.
|
||||
- `extension_source` (string)
|
||||
- `status` (string)
|
||||
|
||||
#### Agent Runs
|
||||
|
||||
Tracks agent lifecycle and outcomes.
|
||||
#### Agent runs
|
||||
|
||||
- `gemini_cli.agent.start`: Agent run started.
|
||||
- **Attributes**:
|
||||
@@ -566,7 +625,7 @@ Tracks API request volume and latency.
|
||||
- `model`
|
||||
- Note: Overlaps with `gen_ai.client.operation.duration` (GenAI conventions).
|
||||
|
||||
##### Token Usage
|
||||
##### Token usage
|
||||
|
||||
Tracks tokens used by model and type.
|
||||
|
||||
@@ -594,7 +653,7 @@ Counts file operations with basic context.
|
||||
- `function_name`
|
||||
- `type` ("added" or "removed")
|
||||
|
||||
##### Chat and Streaming
|
||||
##### Chat and streaming
|
||||
|
||||
Resilience counters for compression, invalid chunks, and retries.
|
||||
|
||||
@@ -613,7 +672,7 @@ Resilience counters for compression, invalid chunks, and retries.
|
||||
- `gemini_cli.chat.content_retry_failure.count` (Counter, Int): Counts requests
|
||||
where all content retries failed.
|
||||
|
||||
##### Model Routing
|
||||
##### Model routing
|
||||
|
||||
Routing latency/failures and slash-command selections.
|
||||
|
||||
@@ -634,7 +693,7 @@ Routing latency/failures and slash-command selections.
|
||||
- `routing.decision_source` (string)
|
||||
- `routing.error_message` (string)
|
||||
|
||||
##### Agent Runs
|
||||
##### Agent runs
|
||||
|
||||
Agent lifecycle metrics: runs, durations, and turns.
|
||||
|
||||
@@ -726,7 +785,7 @@ Optional performance monitoring for startup, CPU/memory, and phase timing.
|
||||
- `current_value` (number)
|
||||
- `baseline_value` (number)
|
||||
|
||||
#### GenAI Semantic Convention
|
||||
#### GenAI semantic convention
|
||||
|
||||
The following metrics comply with [OpenTelemetry GenAI semantic conventions] for
|
||||
standardized observability across GenAI applications:
|
||||
|
||||
+14
-16
@@ -4,19 +4,19 @@ Gemini CLI supports a variety of themes to customize its color scheme and
|
||||
appearance. You can change the theme to suit your preferences via the `/theme`
|
||||
command or `"theme":` configuration setting.
|
||||
|
||||
## Available Themes
|
||||
## Available themes
|
||||
|
||||
Gemini CLI comes with a selection of pre-defined themes, which you can list
|
||||
using the `/theme` command within Gemini CLI:
|
||||
|
||||
- **Dark Themes:**
|
||||
- **Dark themes:**
|
||||
- `ANSI`
|
||||
- `Atom One`
|
||||
- `Ayu`
|
||||
- `Default`
|
||||
- `Dracula`
|
||||
- `GitHub`
|
||||
- **Light Themes:**
|
||||
- **Light themes:**
|
||||
- `ANSI Light`
|
||||
- `Ayu Light`
|
||||
- `Default Light`
|
||||
@@ -24,7 +24,7 @@ using the `/theme` command within Gemini CLI:
|
||||
- `Google Code`
|
||||
- `Xcode`
|
||||
|
||||
### Changing Themes
|
||||
### Changing themes
|
||||
|
||||
1. Enter `/theme` into Gemini CLI.
|
||||
2. A dialog or selection prompt appears, listing the available themes.
|
||||
@@ -36,7 +36,7 @@ using the `/theme` command within Gemini CLI:
|
||||
by a file path), you must remove the `"theme"` setting from the file before you
|
||||
can change the theme using the `/theme` command.
|
||||
|
||||
### Theme Persistence
|
||||
### Theme persistence
|
||||
|
||||
Selected themes are saved in Gemini CLI's
|
||||
[configuration](../get-started/configuration.md) so your preference is
|
||||
@@ -44,13 +44,13 @@ remembered across sessions.
|
||||
|
||||
---
|
||||
|
||||
## Custom Color Themes
|
||||
## Custom color themes
|
||||
|
||||
Gemini CLI allows you to create your own custom color themes by specifying them
|
||||
in your `settings.json` file. This gives you full control over the color palette
|
||||
used in the CLI.
|
||||
|
||||
### How to Define a Custom Theme
|
||||
### How to define a custom theme
|
||||
|
||||
Add a `customThemes` block to your user, project, or system `settings.json`
|
||||
file. Each custom theme is defined as an object with a unique name and a set of
|
||||
@@ -86,14 +86,13 @@ color keys. For example:
|
||||
- `Gray`
|
||||
- `DiffAdded` (optional, for added lines in diffs)
|
||||
- `DiffRemoved` (optional, for removed lines in diffs)
|
||||
- `DiffModified` (optional, for modified lines in diffs)
|
||||
|
||||
You can also override individual UI text roles by adding a nested `text` object.
|
||||
This object supports the keys `primary`, `secondary`, `link`, `accent`, and
|
||||
`response`. When `text.response` is provided it takes precedence over
|
||||
`text.primary` for rendering model responses in chat.
|
||||
|
||||
**Required Properties:**
|
||||
**Required properties:**
|
||||
|
||||
- `name` (must match the key in the `customThemes` object and be a string)
|
||||
- `type` (must be the string `"custom"`)
|
||||
@@ -117,7 +116,7 @@ for a full list of supported names.
|
||||
You can define multiple custom themes by adding more entries to the
|
||||
`customThemes` object.
|
||||
|
||||
### Loading Themes from a File
|
||||
### Loading themes from a file
|
||||
|
||||
In addition to defining custom themes in `settings.json`, you can also load a
|
||||
theme directly from a JSON file by specifying the file path in your
|
||||
@@ -157,22 +156,21 @@ custom theme defined in `settings.json`.
|
||||
"Gray": "#ABB2BF",
|
||||
"DiffAdded": "#A6E3A1",
|
||||
"DiffRemoved": "#F38BA8",
|
||||
"DiffModified": "#89B4FA",
|
||||
"GradientColors": ["#4796E4", "#847ACE", "#C3677F"]
|
||||
}
|
||||
```
|
||||
|
||||
**Security Note:** For your safety, Gemini CLI will only load theme files that
|
||||
**Security note:** For your safety, Gemini CLI will only load theme files that
|
||||
are located within your home directory. If you attempt to load a theme from
|
||||
outside your home directory, a warning will be displayed and the theme will not
|
||||
be loaded. This is to prevent loading potentially malicious theme files from
|
||||
untrusted sources.
|
||||
|
||||
### Example Custom Theme
|
||||
### Example custom theme
|
||||
|
||||
<img src="../assets/theme-custom.png" alt="Custom theme example" width="600" />
|
||||
|
||||
### Using Your Custom Theme
|
||||
### Using your custom theme
|
||||
|
||||
- Select your custom theme using the `/theme` command in Gemini CLI. Your custom
|
||||
theme will appear in the theme selection dialog.
|
||||
@@ -184,7 +182,7 @@ untrusted sources.
|
||||
|
||||
---
|
||||
|
||||
## Dark Themes
|
||||
## Dark themes
|
||||
|
||||
### ANSI
|
||||
|
||||
@@ -210,7 +208,7 @@ untrusted sources.
|
||||
|
||||
<img src="/assets/theme-github.png" alt="GitHub theme" width="600">
|
||||
|
||||
## Light Themes
|
||||
## Light themes
|
||||
|
||||
### ANSI Light
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Token Caching and Cost Optimization
|
||||
# Token caching and cost optimization
|
||||
|
||||
Gemini CLI automatically optimizes API costs through token caching when using
|
||||
API key authentication (Gemini API key or Vertex AI). This feature reuses
|
||||
|
||||
+16
-16
@@ -5,7 +5,7 @@ which projects can use the full capabilities of the Gemini CLI. It prevents
|
||||
potentially malicious code from running by asking you to approve a folder before
|
||||
the CLI loads any project-specific configurations from it.
|
||||
|
||||
## Enabling the Feature
|
||||
## Enabling the feature
|
||||
|
||||
The Trusted Folders feature is **disabled by default**. To use it, you must
|
||||
first enable it in your settings.
|
||||
@@ -22,7 +22,7 @@ Add the following to your user `settings.json` file:
|
||||
}
|
||||
```
|
||||
|
||||
## How It Works: The Trust Dialog
|
||||
## How it works: The trust dialog
|
||||
|
||||
Once the feature is enabled, the first time you run the Gemini CLI from a
|
||||
folder, a dialog will automatically appear, prompting you to make a choice:
|
||||
@@ -38,58 +38,58 @@ folder, a dialog will automatically appear, prompting you to make a choice:
|
||||
Your choice is saved in a central file (`~/.gemini/trustedFolders.json`), so you
|
||||
will only be asked once per folder.
|
||||
|
||||
## Why Trust Matters: The Impact of an Untrusted Workspace
|
||||
## Why trust matters: The impact of an untrusted workspace
|
||||
|
||||
When a folder is **untrusted**, the Gemini CLI runs in a restricted "safe mode"
|
||||
to protect you. In this mode, the following features are disabled:
|
||||
|
||||
1. **Workspace Settings are Ignored**: The CLI will **not** load the
|
||||
1. **Workspace settings are ignored**: The CLI will **not** load the
|
||||
`.gemini/settings.json` file from the project. This prevents the loading of
|
||||
custom tools and other potentially dangerous configurations.
|
||||
|
||||
2. **Environment Variables are Ignored**: The CLI will **not** load any `.env`
|
||||
2. **Environment variables are ignored**: The CLI will **not** load any `.env`
|
||||
files from the project.
|
||||
|
||||
3. **Extension Management is Restricted**: You **cannot install, update, or
|
||||
3. **Extension management is restricted**: You **cannot install, update, or
|
||||
uninstall** extensions.
|
||||
|
||||
4. **Tool Auto-Acceptance is Disabled**: You will always be prompted before any
|
||||
4. **Tool auto-acceptance is disabled**: You will always be prompted before any
|
||||
tool is run, even if you have auto-acceptance enabled globally.
|
||||
|
||||
5. **Automatic Memory Loading is Disabled**: The CLI will not automatically
|
||||
5. **Automatic memory loading is disabled**: The CLI will not automatically
|
||||
load files into context from directories specified in local settings.
|
||||
|
||||
6. **MCP Servers Do Not Connect**: The CLI will not attempt to connect to any
|
||||
6. **MCP servers do not connect**: The CLI will not attempt to connect to any
|
||||
[Model Context Protocol (MCP)](../tools/mcp-server.md) servers.
|
||||
|
||||
7. **Custom Commands are Not Loaded**: The CLI will not load any custom
|
||||
7. **Custom commands are not loaded**: The CLI will not load any custom
|
||||
commands from .toml files, including both project-specific and global user
|
||||
commands.
|
||||
|
||||
Granting trust to a folder unlocks the full functionality of the Gemini CLI for
|
||||
that workspace.
|
||||
|
||||
## Managing Your Trust Settings
|
||||
## Managing your trust settings
|
||||
|
||||
If you need to change a decision or see all your settings, you have a couple of
|
||||
options:
|
||||
|
||||
- **Change the Current Folder's Trust**: Run the `/permissions` command from
|
||||
- **Change the current folder's trust**: Run the `/permissions` command from
|
||||
within the CLI. This will bring up the same interactive dialog, allowing you
|
||||
to change the trust level for the current folder.
|
||||
|
||||
- **View All Trust Rules**: To see a complete list of all your trusted and
|
||||
- **View all trust rules**: To see a complete list of all your trusted and
|
||||
untrusted folder rules, you can inspect the contents of the
|
||||
`~/.gemini/trustedFolders.json` file in your home directory.
|
||||
|
||||
## The Trust Check Process (Advanced)
|
||||
## The trust check process (advanced)
|
||||
|
||||
For advanced users, it's helpful to know the exact order of operations for how
|
||||
trust is determined:
|
||||
|
||||
1. **IDE Trust Signal**: If you are using the
|
||||
1. **IDE trust signal**: If you are using the
|
||||
[IDE Integration](../ide-integration/index.md), the CLI first asks the IDE
|
||||
if the workspace is trusted. The IDE's response takes highest priority.
|
||||
|
||||
2. **Local Trust File**: If the IDE is not connected, the CLI checks the
|
||||
2. **Local trust file**: If the IDE is not connected, the CLI checks the
|
||||
central `~/.gemini/trustedFolders.json` file.
|
||||
|
||||
@@ -2,13 +2,17 @@
|
||||
|
||||
This page contains tutorials for interacting with Gemini CLI.
|
||||
|
||||
## Agent Skills
|
||||
|
||||
- [Getting Started with Agent Skills](./tutorials/skills-getting-started.md)
|
||||
|
||||
## Setting up a Model Context Protocol (MCP) server
|
||||
|
||||
> [!CAUTION] Before using a third-party MCP server, ensure you trust its source
|
||||
> and understand the tools it provides. Your use of third-party servers is at
|
||||
> your own risk.
|
||||
|
||||
This tutorial demonstrates how to set up a MCP server, using the
|
||||
This tutorial demonstrates how to set up an MCP server, using the
|
||||
[GitHub MCP server](https://github.com/github/github-mcp-server) as an example.
|
||||
The GitHub MCP server provides tools for interacting with GitHub repositories,
|
||||
such as creating issues and commenting on pull requests.
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
# Getting Started with Agent Skills
|
||||
|
||||
Agent Skills allow you to extend Gemini CLI with specialized expertise. This
|
||||
tutorial will guide you through creating your first skill and using it in a
|
||||
session.
|
||||
|
||||
## 1. Create your first skill
|
||||
|
||||
A skill is a directory containing a `SKILL.md` file. Let's create an **API
|
||||
Auditor** skill that helps you verify if local or remote endpoints are
|
||||
responding correctly.
|
||||
|
||||
1. **Create the skill directory structure:**
|
||||
|
||||
```bash
|
||||
mkdir -p .gemini/skills/api-auditor/scripts
|
||||
```
|
||||
|
||||
2. **Create the `SKILL.md` file:** Create a file at
|
||||
`.gemini/skills/api-auditor/SKILL.md` with the following content:
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: api-auditor
|
||||
description:
|
||||
Expertise in auditing and testing API endpoints. Use when the user asks to
|
||||
"check", "test", or "audit" a URL or API.
|
||||
---
|
||||
|
||||
# API Auditor Instructions
|
||||
|
||||
You act as a QA engineer specialized in API reliability. When this skill is
|
||||
active, you MUST:
|
||||
|
||||
1. **Audit**: Use the bundled `scripts/audit.js` utility to check the
|
||||
status of the provided URL.
|
||||
2. **Report**: Analyze the output (status codes, latency) and explain any
|
||||
failures in plain English.
|
||||
3. **Secure**: Remind the user if they are testing a sensitive endpoint
|
||||
without an `https://` protocol.
|
||||
```
|
||||
|
||||
3. **Create the bundled Node.js script:** Create a file at
|
||||
`.gemini/skills/api-auditor/scripts/audit.js`. This script will be used by
|
||||
the agent to perform the actual check:
|
||||
|
||||
```javascript
|
||||
// .gemini/skills/api-auditor/scripts/audit.js
|
||||
const url = process.argv[2];
|
||||
|
||||
if (!url) {
|
||||
console.error('Usage: node audit.js <url>');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log(`Auditing ${url}...`);
|
||||
fetch(url, { method: 'HEAD' })
|
||||
.then((r) => console.log(`Result: Success (Status ${r.status})`))
|
||||
.catch((e) => console.error(`Result: Failed (${e.message})`));
|
||||
```
|
||||
|
||||
## 2. Verify the skill is discovered
|
||||
|
||||
Use the `/skills` slash command (or `gemini skills list` from your terminal) to
|
||||
see if Gemini CLI has found your new skill.
|
||||
|
||||
In a Gemini CLI session:
|
||||
|
||||
```
|
||||
/skills list
|
||||
```
|
||||
|
||||
You should see `api-auditor` in the list of available skills.
|
||||
|
||||
## 3. Use the skill in a chat
|
||||
|
||||
Now, let's see the skill in action. Start a new session and ask a question about
|
||||
an endpoint.
|
||||
|
||||
**User:** "Can you audit http://geminili.com"
|
||||
|
||||
Gemini will recognize the request matches the `api-auditor` description and will
|
||||
ask for your permission to activate it.
|
||||
|
||||
**Model:** (After calling `activate_skill`) "I've activated the **api-auditor**
|
||||
skill. I'll run the audit script now..."
|
||||
|
||||
Gemini will then use the `run_shell_command` tool to execute your bundled Node
|
||||
script:
|
||||
|
||||
`node .gemini/skills/api-auditor/scripts/audit.js http://geminili.com`
|
||||
|
||||
## Next Steps
|
||||
|
||||
- Explore [Agent Skills Authoring Guide](../skills.md#creating-a-skill) to learn
|
||||
about more advanced skill features.
|
||||
- Learn how to share skills via [Extensions](../../extensions/index.md).
|
||||
+19
-1
@@ -35,7 +35,7 @@ _PowerShell_
|
||||
Remove-Item -Path (Join-Path $env:LocalAppData "npm-cache\_npx") -Recurse -Force
|
||||
```
|
||||
|
||||
## Method 2: Using npm (Global Install)
|
||||
## Method 2: Using npm (global install)
|
||||
|
||||
If you installed the CLI globally (e.g., `npm install -g @google/gemini-cli`),
|
||||
use the `npm uninstall` command with the `-g` flag to remove it.
|
||||
@@ -45,3 +45,21 @@ npm uninstall -g @google/gemini-cli
|
||||
```
|
||||
|
||||
This command completely removes the package from your system.
|
||||
|
||||
## Method 3: Homebrew
|
||||
|
||||
If you installed the CLI globally using Homebrew (e.g.,
|
||||
`brew install gemini-cli`), use the `brew uninstall` command to remove it.
|
||||
|
||||
```bash
|
||||
brew uninstall gemini-cli
|
||||
```
|
||||
|
||||
## Method 4: MacPorts
|
||||
|
||||
If you installed the CLI globally using MacPorts (e.g.,
|
||||
`sudo port install gemini-cli`), use the `port uninstall` command to remove it.
|
||||
|
||||
```bash
|
||||
sudo port uninstall gemini-cli
|
||||
```
|
||||
|
||||
+7
-1
@@ -1,4 +1,4 @@
|
||||
# Gemini CLI Core
|
||||
# Gemini CLI core
|
||||
|
||||
Gemini CLI's core package (`packages/core`) is the backend portion of Gemini
|
||||
CLI, handling communication with the Gemini API, managing tools, and processing
|
||||
@@ -7,6 +7,8 @@ requests sent from `packages/cli`. For a general overview of Gemini CLI, see the
|
||||
|
||||
## Navigating this section
|
||||
|
||||
- **[Sub-agents (experimental)](./subagents.md):** Learn how to create and use
|
||||
specialized sub-agents for complex tasks.
|
||||
- **[Core tools API](./tools-api.md):** Information on how tools are defined,
|
||||
registered, and used by the core.
|
||||
- **[Memory Import Processor](./memport.md):** Documentation for the modular
|
||||
@@ -68,6 +70,10 @@ If you are using the default "pro" model and the CLI detects that you are being
|
||||
rate-limited, it automatically switches to the "flash" model for the current
|
||||
session. This allows you to continue working without interruption.
|
||||
|
||||
Internal utility calls that use `gemini-2.5-flash-lite` (for example, prompt
|
||||
completion and classification) silently fall back to `gemini-2.5-flash` and
|
||||
`gemini-2.5-pro` when quota is exhausted, without changing the configured model.
|
||||
|
||||
## File discovery service
|
||||
|
||||
The file discovery service is responsible for finding files in the project that
|
||||
|
||||
+20
-18
@@ -27,21 +27,21 @@ More content here.
|
||||
@./shared/configuration.md
|
||||
```
|
||||
|
||||
## Supported Path Formats
|
||||
## Supported path formats
|
||||
|
||||
### Relative Paths
|
||||
### Relative paths
|
||||
|
||||
- `@./file.md` - Import from the same directory
|
||||
- `@../file.md` - Import from parent directory
|
||||
- `@./components/file.md` - Import from subdirectory
|
||||
|
||||
### Absolute Paths
|
||||
### Absolute paths
|
||||
|
||||
- `@/absolute/path/to/file.md` - Import using absolute path
|
||||
|
||||
## Examples
|
||||
|
||||
### Basic Import
|
||||
### Basic import
|
||||
|
||||
```markdown
|
||||
# My GEMINI.md
|
||||
@@ -55,7 +55,7 @@ Welcome to my project!
|
||||
@./features/overview.md
|
||||
```
|
||||
|
||||
### Nested Imports
|
||||
### Nested imports
|
||||
|
||||
The imported files can themselves contain imports, creating a nested structure:
|
||||
|
||||
@@ -73,9 +73,9 @@ The imported files can themselves contain imports, creating a nested structure:
|
||||
@./shared/title.md
|
||||
```
|
||||
|
||||
## Safety Features
|
||||
## Safety features
|
||||
|
||||
### Circular Import Detection
|
||||
### Circular import detection
|
||||
|
||||
The processor automatically detects and prevents circular imports:
|
||||
|
||||
@@ -83,43 +83,45 @@ The processor automatically detects and prevents circular imports:
|
||||
# file-a.md
|
||||
|
||||
@./file-b.md
|
||||
```
|
||||
|
||||
```markdown
|
||||
# file-b.md
|
||||
|
||||
@./file-a.md <!-- This will be detected and prevented -->
|
||||
```
|
||||
|
||||
### File Access Security
|
||||
### File access security
|
||||
|
||||
The `validateImportPath` function ensures that imports are only allowed from
|
||||
specified directories, preventing access to sensitive files outside the allowed
|
||||
scope.
|
||||
|
||||
### Maximum Import Depth
|
||||
### Maximum import depth
|
||||
|
||||
To prevent infinite recursion, there's a configurable maximum import depth
|
||||
(default: 5 levels).
|
||||
|
||||
## Error Handling
|
||||
## Error handling
|
||||
|
||||
### Missing Files
|
||||
### Missing files
|
||||
|
||||
If a referenced file doesn't exist, the import will fail gracefully with an
|
||||
error comment in the output.
|
||||
|
||||
### File Access Errors
|
||||
### File access errors
|
||||
|
||||
Permission issues or other file system errors are handled gracefully with
|
||||
appropriate error messages.
|
||||
|
||||
## Code Region Detection
|
||||
## Code region detection
|
||||
|
||||
The import processor uses the `marked` library to detect code blocks and inline
|
||||
code spans, ensuring that `@` imports inside these regions are properly ignored.
|
||||
This provides robust handling of nested code blocks and complex Markdown
|
||||
structures.
|
||||
|
||||
## Import Tree Structure
|
||||
## Import tree structure
|
||||
|
||||
The processor returns an import tree that shows the hierarchy of imported files,
|
||||
similar to Claude's `/memory` feature. This helps users debug problems with
|
||||
@@ -143,7 +145,7 @@ Memory Files
|
||||
The tree preserves the order that files were imported and shows the complete
|
||||
import chain for debugging purposes.
|
||||
|
||||
## Comparison to Claude Code's `/memory` (`claude.md`) Approach
|
||||
## Comparison to Claude Code's `/memory` (`claude.md`) approach
|
||||
|
||||
Claude Code's `/memory` feature (as seen in `claude.md`) produces a flat, linear
|
||||
document by concatenating all included files, always marking file boundaries
|
||||
@@ -154,7 +156,7 @@ for reconstructing the hierarchy if needed.
|
||||
> [!NOTE] The import tree is mainly for clarity during development and has
|
||||
> limited relevance to LLM consumption.
|
||||
|
||||
## API Reference
|
||||
## API reference
|
||||
|
||||
### `processImports(content, basePath, debugMode?, importState?)`
|
||||
|
||||
@@ -225,7 +227,7 @@ directory if no `.git` is found)
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
### Common issues
|
||||
|
||||
1. **Import not working**: Check that the file exists and the path is correct
|
||||
2. **Circular import warnings**: Review your import structure for circular
|
||||
@@ -235,7 +237,7 @@ directory if no `.git` is found)
|
||||
4. **Path resolution issues**: Use absolute paths if relative paths aren't
|
||||
resolving correctly
|
||||
|
||||
### Debug Mode
|
||||
### Debug mode
|
||||
|
||||
Enable debug mode to see detailed logging of the import process:
|
||||
|
||||
|
||||
@@ -1,13 +1,32 @@
|
||||
# Policy Engine
|
||||
|
||||
:::note This feature is currently in testing. To enable it, set
|
||||
`tools.enableMessageBusIntegration` to `true` in your `settings.json` file. :::
|
||||
# Policy engine
|
||||
|
||||
The Gemini CLI includes a powerful policy engine that provides fine-grained
|
||||
control over tool execution. It allows users and administrators to define rules
|
||||
that determine whether a tool call should be allowed, denied, or require user
|
||||
confirmation.
|
||||
|
||||
## Quick start
|
||||
|
||||
To create your first policy:
|
||||
|
||||
1. **Create the policy directory** if it doesn't exist:
|
||||
```bash
|
||||
mkdir -p ~/.gemini/policies
|
||||
```
|
||||
2. **Create a new policy file** (e.g., `~/.gemini/policies/my-rules.toml`). You
|
||||
can use any filename ending in `.toml`; all such files in this directory
|
||||
will be loaded and combined:
|
||||
```toml
|
||||
[[rule]]
|
||||
toolName = "run_shell_command"
|
||||
commandPrefix = "git status"
|
||||
decision = "allow"
|
||||
priority = 100
|
||||
```
|
||||
3. **Run a command** that triggers the policy (e.g., ask Gemini CLI to
|
||||
`git status`). The tool will now execute automatically without prompting for
|
||||
confirmation.
|
||||
|
||||
## Core concepts
|
||||
|
||||
The policy engine operates on a set of rules. Each rule is a combination of
|
||||
@@ -49,7 +68,7 @@ The `toolName` in the rule must match the name of the tool being called.
|
||||
wildcard. A `toolName` of `my-server__*` will match any tool from the
|
||||
`my-server` MCP.
|
||||
|
||||
#### Arguments Pattern
|
||||
#### Arguments pattern
|
||||
|
||||
If `argsPattern` is specified, the tool's arguments are converted to a stable
|
||||
JSON string, which is then tested against the provided regular expression. If
|
||||
@@ -64,7 +83,7 @@ There are three possible decisions a rule can enforce:
|
||||
- `ask_user`: The user is prompted to approve or deny the tool call. (In
|
||||
non-interactive mode, this is treated as `deny`.)
|
||||
|
||||
### Priority system & tiers
|
||||
### Priority system and tiers
|
||||
|
||||
The policy engine uses a sophisticated priority system to resolve conflicts when
|
||||
multiple rules match a single tool call. The core principle is simple: **the
|
||||
@@ -112,12 +131,12 @@ outcome.
|
||||
|
||||
A rule matches a tool call if all of its conditions are met:
|
||||
|
||||
1. **Tool Name**: The `toolName` in the rule must match the name of the tool
|
||||
1. **Tool name**: The `toolName` in the rule must match the name of the tool
|
||||
being called.
|
||||
- **Wildcards**: For Model-hosting-protocol (MCP) servers, you can use a
|
||||
wildcard. A `toolName` of `my-server__*` will match any tool from the
|
||||
`my-server` MCP.
|
||||
2. **Arguments Pattern**: If `argsPattern` is specified, the tool's arguments
|
||||
2. **Arguments pattern**: If `argsPattern` is specified, the tool's arguments
|
||||
are converted to a stable JSON string, which is then tested against the
|
||||
provided regular expression. If the arguments don't match the pattern, the
|
||||
rule does not apply.
|
||||
@@ -127,6 +146,38 @@ A rule matches a tool call if all of its conditions are met:
|
||||
Policies are defined in `.toml` files. The CLI loads these files from Default,
|
||||
User, and (if configured) Admin directories.
|
||||
|
||||
### Policy locations
|
||||
|
||||
| Tier | Type | Location |
|
||||
| :-------- | :----- | :-------------------------- |
|
||||
| **User** | Custom | `~/.gemini/policies/*.toml` |
|
||||
| **Admin** | System | _See below (OS specific)_ |
|
||||
|
||||
#### System-wide policies (Admin)
|
||||
|
||||
Administrators can enforce system-wide policies (Tier 3) that override all user
|
||||
and default settings. These policies must be placed in specific, secure
|
||||
directories:
|
||||
|
||||
| OS | Policy Directory Path |
|
||||
| :---------- | :------------------------------------------------ |
|
||||
| **Linux** | `/etc/gemini-cli/policies` |
|
||||
| **macOS** | `/Library/Application Support/GeminiCli/policies` |
|
||||
| **Windows** | `C:\ProgramData\gemini-cli\policies` |
|
||||
|
||||
**Security Requirements:**
|
||||
|
||||
To prevent privilege escalation, the CLI enforces strict security checks on
|
||||
admin directories. If checks fail, system policies are **ignored**.
|
||||
|
||||
- **Linux / macOS:** Must be owned by `root` (UID 0) and NOT writable by group
|
||||
or others (e.g., `chmod 755`).
|
||||
- **Windows:** Must be in `C:\ProgramData`. Standard users (`Users`, `Everyone`)
|
||||
must NOT have `Write`, `Modify`, or `Full Control` permissions. _Tip: If you
|
||||
see a security warning, use the folder properties to remove write permissions
|
||||
for non-admin groups. You may need to "Disable inheritance" in Advanced
|
||||
Security Settings._
|
||||
|
||||
### TOML rule schema
|
||||
|
||||
Here is a breakdown of the fields available in a TOML policy rule:
|
||||
@@ -159,6 +210,10 @@ decision = "ask_user"
|
||||
# The priority of the rule, from 0 to 999.
|
||||
priority = 10
|
||||
|
||||
# (Optional) A custom message to display when a tool call is denied by this rule.
|
||||
# This message is returned to the model and user, useful for explaining *why* it was denied.
|
||||
deny_message = "Deletion is permanent"
|
||||
|
||||
# (Optional) An array of approval modes where this rule is active.
|
||||
modes = ["autoEdit"]
|
||||
```
|
||||
@@ -220,7 +275,7 @@ decision = "allow"
|
||||
priority = 200
|
||||
```
|
||||
|
||||
**2. Using a Wildcard**
|
||||
**2. Using a wildcard**
|
||||
|
||||
To create a rule that applies to _all_ tools on a specific MCP server, specify
|
||||
only the `mcpName`.
|
||||
@@ -231,6 +286,7 @@ only the `mcpName`.
|
||||
mcpName = "untrusted-server"
|
||||
decision = "deny"
|
||||
priority = 500
|
||||
deny_message = "This server is not trusted by the admin."
|
||||
```
|
||||
|
||||
## Default policies
|
||||
@@ -239,6 +295,9 @@ The Gemini CLI ships with a set of default policies to provide a safe
|
||||
out-of-the-box experience.
|
||||
|
||||
- **Read-only tools** (like `read_file`, `glob`) are generally **allowed**.
|
||||
- **Agent delegation** defaults to **`ask_user`** to ensure remote agents can
|
||||
prompt for confirmation, but local sub-agent actions are executed silently and
|
||||
checked individually.
|
||||
- **Write tools** (like `write_file`, `run_shell_command`) default to
|
||||
**`ask_user`**.
|
||||
- In **`yolo`** mode, a high-priority rule allows all tools.
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
# Remote Subagents (experimental)
|
||||
|
||||
Gemini CLI supports connecting to remote subagents using the Agent-to-Agent
|
||||
(A2A) protocol. This allows Gemini CLI to interact with other agents, expanding
|
||||
its capabilities by delegating tasks to remote services.
|
||||
|
||||
Gemini CLI can connect to any compliant A2A agent. You can find samples of A2A
|
||||
agents in the following repositories:
|
||||
|
||||
- [ADK Samples (Python)](https://github.com/google/adk-samples/tree/main/python)
|
||||
- [ADK Python Contributing Samples](https://github.com/google/adk-python/tree/main/contributing/samples)
|
||||
|
||||
> **Note: Remote subagents are currently an experimental feature.**
|
||||
|
||||
## Configuration
|
||||
|
||||
To use remote subagents, you must explicitly enable them in your
|
||||
`settings.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"experimental": {
|
||||
"enableAgents": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Defining remote subagents
|
||||
|
||||
Remote subagents are defined as Markdown files (`.md`) with YAML frontmatter.
|
||||
You can place them in:
|
||||
|
||||
1. **Project-level:** `.gemini/agents/*.md` (Shared with your team)
|
||||
2. **User-level:** `~/.gemini/agents/*.md` (Personal agents)
|
||||
|
||||
### Configuration schema
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
| :--------------- | :----- | :------- | :------------------------------------------------------------------------------------------------------------- |
|
||||
| `kind` | string | Yes | Must be `remote`. |
|
||||
| `name` | string | Yes | A unique name for the agent. Must be a valid slug (lowercase letters, numbers, hyphens, and underscores only). |
|
||||
| `agent_card_url` | string | Yes | The URL to the agent's A2A card endpoint. |
|
||||
|
||||
### Single-subagent example
|
||||
|
||||
```markdown
|
||||
---
|
||||
kind: remote
|
||||
name: my-remote-agent
|
||||
agent_card_url: https://example.com/agent-card
|
||||
---
|
||||
```
|
||||
|
||||
### Multi-subagent example
|
||||
|
||||
The loader explicitly supports multiple remote subagents defined in a single
|
||||
Markdown file.
|
||||
|
||||
```markdown
|
||||
---
|
||||
- kind: remote
|
||||
name: remote-1
|
||||
agent_card_url: https://example.com/1
|
||||
- kind: remote
|
||||
name: remote-2
|
||||
agent_card_url: https://example.com/2
|
||||
---
|
||||
```
|
||||
|
||||
> **Note:** Mixed local and remote agents, or multiple local agents, are not
|
||||
> supported in a single file; the list format is currently remote-only.
|
||||
|
||||
## Managing Subagents
|
||||
|
||||
Users can manage subagents using the following commands within the Gemini CLI:
|
||||
|
||||
- `/agents list`: Displays all available local and remote subagents.
|
||||
- `/agents refresh`: Reloads the agent registry. Use this after adding or
|
||||
modifying agent definition files.
|
||||
- `/agents enable <agent_name>`: Enables a specific subagent.
|
||||
- `/agents disable <agent_name>`: Disables a specific subagent.
|
||||
|
||||
> **Tip:** You can use the `@cli_help` agent within Gemini CLI for assistance
|
||||
> with configuring subagents.
|
||||
@@ -0,0 +1,191 @@
|
||||
# Sub-agents (experimental)
|
||||
|
||||
Sub-agents are specialized agents that operate within your main Gemini CLI
|
||||
session. They are designed to handle specific, complex tasks—like deep codebase
|
||||
analysis, documentation lookup, or domain-specific reasoning—without cluttering
|
||||
the main agent's context or toolset.
|
||||
|
||||
> **Note: Sub-agents are currently an experimental feature.**
|
||||
>
|
||||
> To use custom sub-agents, you must explicitly enable them in your
|
||||
> `settings.json`:
|
||||
>
|
||||
> ```json
|
||||
> {
|
||||
> "experimental": { "enableAgents": true }
|
||||
> }
|
||||
> ```
|
||||
>
|
||||
> **Warning:** Sub-agents currently operate in
|
||||
> ["YOLO mode"](../get-started/configuration.md#command-line-arguments), meaning
|
||||
> they may execute tools without individual user confirmation for each step.
|
||||
> Proceed with caution when defining agents with powerful tools like
|
||||
> `run_shell_command` or `write_file`.
|
||||
|
||||
## What are sub-agents?
|
||||
|
||||
Sub-agents are "specialists" that the main Gemini agent can hire for a specific
|
||||
job.
|
||||
|
||||
- **Focused context:** Each sub-agent has its own system prompt and persona.
|
||||
- **Specialized tools:** Sub-agents can have a restricted or specialized set of
|
||||
tools.
|
||||
- **Independent context window:** Interactions with a sub-agent happen in a
|
||||
separate context loop, which saves tokens in your main conversation history.
|
||||
|
||||
Sub-agents are exposed to the main agent as a tool of the same name. When the
|
||||
main agent calls the tool, it delegates the task to the sub-agent. Once the
|
||||
sub-agent completes its task, it reports back to the main agent with its
|
||||
findings.
|
||||
|
||||
## Built-in sub-agents
|
||||
|
||||
Gemini CLI comes with the following built-in sub-agents:
|
||||
|
||||
### Codebase Investigator
|
||||
|
||||
- **Name:** `codebase_investigator`
|
||||
- **Purpose:** Analyze the codebase, reverse engineer, and understand complex
|
||||
dependencies.
|
||||
- **When to use:** "How does the authentication system work?", "Map out the
|
||||
dependencies of the `AgentRegistry` class."
|
||||
- **Configuration:** Enabled by default. You can configure it in
|
||||
`settings.json`. Example (forcing a specific model):
|
||||
```json
|
||||
{
|
||||
"experimental": {
|
||||
"codebaseInvestigatorSettings": {
|
||||
"enabled": true,
|
||||
"maxNumTurns": 20,
|
||||
"model": "gemini-2.5-pro"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### CLI Help Agent
|
||||
|
||||
- **Name:** `cli_help`
|
||||
- **Purpose:** Get expert knowledge about Gemini CLI itself, its commands,
|
||||
configuration, and documentation.
|
||||
- **When to use:** "How do I configure a proxy?", "What does the `/rewind`
|
||||
command do?"
|
||||
- **Configuration:** Enabled by default.
|
||||
|
||||
### Generalist Agent
|
||||
|
||||
- **Name:** `generalist_agent`
|
||||
- **Purpose:** Route tasks to the appropriate specialized sub-agent.
|
||||
- **When to use:** Implicitly used by the main agent for routing. Not directly
|
||||
invoked by the user.
|
||||
- **Configuration:** Enabled by default. No specific configuration options.
|
||||
|
||||
## Creating custom sub-agents
|
||||
|
||||
You can create your own sub-agents to automate specific workflows or enforce
|
||||
specific personas. To use custom sub-agents, you must enable them in your
|
||||
`settings.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"experimental": {
|
||||
"enableAgents": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Agent definition files
|
||||
|
||||
Custom agents are defined as Markdown files (`.md`) with YAML frontmatter. You
|
||||
can place them in:
|
||||
|
||||
1. **Project-level:** `.gemini/agents/*.md` (Shared with your team)
|
||||
2. **User-level:** `~/.gemini/agents/*.md` (Personal agents)
|
||||
|
||||
### File format
|
||||
|
||||
The file **MUST** start with YAML frontmatter enclosed in triple-dashes `---`.
|
||||
The body of the markdown file becomes the agent's **System Prompt**.
|
||||
|
||||
**Example: `.gemini/agents/security-auditor.md`**
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: security-auditor
|
||||
description: Specialized in finding security vulnerabilities in code.
|
||||
kind: local
|
||||
tools:
|
||||
- read_file
|
||||
- grep_search
|
||||
model: gemini-2.5-pro
|
||||
temperature: 0.2
|
||||
max_turns: 10
|
||||
---
|
||||
|
||||
You are a ruthless Security Auditor. Your job is to analyze code for potential
|
||||
vulnerabilities.
|
||||
|
||||
Focus on:
|
||||
|
||||
1. SQL Injection
|
||||
2. XSS (Cross-Site Scripting)
|
||||
3. Hardcoded credentials
|
||||
4. Unsafe file operations
|
||||
|
||||
When you find a vulnerability, explain it clearly and suggest a fix. Do not fix
|
||||
it yourself; just report it.
|
||||
```
|
||||
|
||||
### Configuration schema
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
| :------------- | :----- | :------- | :------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `name` | string | Yes | Unique identifier (slug) used as the tool name for the agent. Only lowercase letters, numbers, hyphens, and underscores. |
|
||||
| `description` | string | Yes | Short description of what the agent does. This is visible to the main agent to help it decide when to call this sub-agent. |
|
||||
| `kind` | string | No | `local` (default) or `remote`. |
|
||||
| `tools` | array | No | List of tool names this agent can use. If omitted, it may have access to a default set. |
|
||||
| `model` | string | No | Specific model to use (e.g., `gemini-2.5-pro`). Defaults to `inherit` (uses the main session model). |
|
||||
| `temperature` | number | No | Model temperature (0.0 - 2.0). |
|
||||
| `max_turns` | number | No | Maximum number of conversation turns allowed for this agent before it must return. Defaults to `15`. |
|
||||
| `timeout_mins` | number | No | Maximum execution time in minutes. Defaults to `5`. |
|
||||
|
||||
### Optimizing your sub-agent
|
||||
|
||||
The main agent's system prompt encourages it to use an expert sub-agent when one
|
||||
is available. It decides whether an agent is a relevant expert based on the
|
||||
agent's description. You can improve the reliability with which an agent is used
|
||||
by updating the description to more clearly indicate:
|
||||
|
||||
- Its area of expertise.
|
||||
- When it should be used.
|
||||
- Some example scenarios.
|
||||
|
||||
For example, the following sub-agent description should be called fairly
|
||||
consistently for Git operations.
|
||||
|
||||
> Git expert agent which should be used for all local and remote git operations.
|
||||
> For example:
|
||||
>
|
||||
> - Making commits
|
||||
> - Searching for regressions with bisect
|
||||
> - Interacting with source control and issues providers such as GitHub.
|
||||
|
||||
If you need to further tune your sub-agent, you can do so by selecting the model
|
||||
to optimize for with `/model` and then asking the model why it does not think
|
||||
that your sub-agent was called with a specific prompt and the given description.
|
||||
|
||||
## Remote subagents (Agent2Agent) (experimental)
|
||||
|
||||
Gemini CLI can also delegate tasks to remote sub-agents using the Agent-to-Agent
|
||||
(A2A) protocol.
|
||||
|
||||
> **Note: Remote subagents are currently an experimental feature.**
|
||||
|
||||
See the [Remote Subagents documentation](/docs/core/remote-agents) for detailed
|
||||
configuration and usage instructions.
|
||||
|
||||
## Extension sub-agents
|
||||
|
||||
Extensions can bundle and distribute sub-agents. See the
|
||||
[Extensions documentation](../extensions/index.md#sub-agents) for details on how
|
||||
to package agents within an extension.
|
||||
+26
-26
@@ -1,11 +1,11 @@
|
||||
# Gemini CLI Core: Tools API
|
||||
# Gemini CLI core: Tools API
|
||||
|
||||
The Gemini CLI core (`packages/core`) features a robust system for defining,
|
||||
registering, and executing tools. These tools extend the capabilities of the
|
||||
Gemini model, allowing it to interact with the local environment, fetch web
|
||||
content, and perform various actions beyond simple text generation.
|
||||
|
||||
## Core Concepts
|
||||
## Core concepts
|
||||
|
||||
- **Tool (`tools.ts`):** An interface and base class (`BaseTool`) that defines
|
||||
the contract for all tools. Each tool must have:
|
||||
@@ -32,35 +32,35 @@ content, and perform various actions beyond simple text generation.
|
||||
- `returnDisplay`: A user-friendly string (often Markdown) or a special object
|
||||
(like `FileDiff`) for display in the CLI.
|
||||
|
||||
- **Returning Rich Content:** Tools are not limited to returning simple text.
|
||||
- **Returning rich content:** Tools are not limited to returning simple text.
|
||||
The `llmContent` can be a `PartListUnion`, which is an array that can contain
|
||||
a mix of `Part` objects (for images, audio, etc.) and `string`s. This allows a
|
||||
single tool execution to return multiple pieces of rich content.
|
||||
|
||||
- **Tool Registry (`tool-registry.ts`):** A class (`ToolRegistry`) responsible
|
||||
- **Tool registry (`tool-registry.ts`):** A class (`ToolRegistry`) responsible
|
||||
for:
|
||||
- **Registering Tools:** Holding a collection of all available built-in tools
|
||||
- **Registering tools:** Holding a collection of all available built-in tools
|
||||
(e.g., `ReadFileTool`, `ShellTool`).
|
||||
- **Discovering Tools:** It can also discover tools dynamically:
|
||||
- **Command-based Discovery:** If `tools.discoveryCommand` is configured in
|
||||
- **Discovering tools:** It can also discover tools dynamically:
|
||||
- **Command-based discovery:** If `tools.discoveryCommand` is configured in
|
||||
settings, this command is executed. It's expected to output JSON
|
||||
describing custom tools, which are then registered as `DiscoveredTool`
|
||||
instances.
|
||||
- **MCP-based Discovery:** If `mcp.serverCommand` is configured, the
|
||||
- **MCP-based discovery:** If `mcp.serverCommand` is configured, the
|
||||
registry can connect to a Model Context Protocol (MCP) server to list and
|
||||
register tools (`DiscoveredMCPTool`).
|
||||
- **Providing Schemas:** Exposing the `FunctionDeclaration` schemas of all
|
||||
- **Providing schemas:** Exposing the `FunctionDeclaration` schemas of all
|
||||
registered tools to the Gemini model, so it knows what tools are available
|
||||
and how to use them.
|
||||
- **Retrieving Tools:** Allowing the core to get a specific tool by name for
|
||||
- **Retrieving tools:** Allowing the core to get a specific tool by name for
|
||||
execution.
|
||||
|
||||
## Built-in Tools
|
||||
## Built-in tools
|
||||
|
||||
The core comes with a suite of pre-defined tools, typically found in
|
||||
`packages/core/src/tools/`. These include:
|
||||
|
||||
- **File System Tools:**
|
||||
- **File system tools:**
|
||||
- `LSTool` (`ls.ts`): Lists directory contents.
|
||||
- `ReadFileTool` (`read-file.ts`): Reads the content of a single file.
|
||||
- `WriteFileTool` (`write-file.ts`): Writes content to a file.
|
||||
@@ -70,26 +70,26 @@ The core comes with a suite of pre-defined tools, typically found in
|
||||
requiring confirmation).
|
||||
- `ReadManyFilesTool` (`read-many-files.ts`): Reads and concatenates content
|
||||
from multiple files or glob patterns (used by the `@` command in CLI).
|
||||
- **Execution Tools:**
|
||||
- **Execution tools:**
|
||||
- `ShellTool` (`shell.ts`): Executes arbitrary shell commands (requires
|
||||
careful sandboxing and user confirmation).
|
||||
- **Web Tools:**
|
||||
- **Web tools:**
|
||||
- `WebFetchTool` (`web-fetch.ts`): Fetches content from a URL.
|
||||
- `WebSearchTool` (`web-search.ts`): Performs a web search.
|
||||
- **Memory Tools:**
|
||||
- **Memory tools:**
|
||||
- `MemoryTool` (`memoryTool.ts`): Interacts with the AI's memory.
|
||||
|
||||
Each of these tools extends `BaseTool` and implements the required methods for
|
||||
its specific functionality.
|
||||
|
||||
## Tool Execution Flow
|
||||
## Tool execution flow
|
||||
|
||||
1. **Model Request:** The Gemini model, based on the user's prompt and the
|
||||
1. **Model request:** The Gemini model, based on the user's prompt and the
|
||||
provided tool schemas, decides to use a tool and returns a `FunctionCall`
|
||||
part in its response, specifying the tool name and arguments.
|
||||
2. **Core Receives Request:** The core parses this `FunctionCall`.
|
||||
3. **Tool Retrieval:** It looks up the requested tool in the `ToolRegistry`.
|
||||
4. **Parameter Validation:** The tool's `validateToolParams()` method is
|
||||
2. **Core receives request:** The core parses this `FunctionCall`.
|
||||
3. **Tool retrieval:** It looks up the requested tool in the `ToolRegistry`.
|
||||
4. **Parameter validation:** The tool's `validateToolParams()` method is
|
||||
called.
|
||||
5. **Confirmation (if needed):**
|
||||
- The tool's `shouldConfirmExecute()` method is called.
|
||||
@@ -99,27 +99,27 @@ its specific functionality.
|
||||
6. **Execution:** If validated and confirmed (or if no confirmation is needed),
|
||||
the core calls the tool's `execute()` method with the provided arguments and
|
||||
an `AbortSignal` (for potential cancellation).
|
||||
7. **Result Processing:** The `ToolResult` from `execute()` is received by the
|
||||
7. **Result processing:** The `ToolResult` from `execute()` is received by the
|
||||
core.
|
||||
8. **Response to Model:** The `llmContent` from the `ToolResult` is packaged as
|
||||
8. **Response to model:** The `llmContent` from the `ToolResult` is packaged as
|
||||
a `FunctionResponse` and sent back to the Gemini model so it can continue
|
||||
generating a user-facing response.
|
||||
9. **Display to User:** The `returnDisplay` from the `ToolResult` is sent to
|
||||
9. **Display to user:** The `returnDisplay` from the `ToolResult` is sent to
|
||||
the CLI to show the user what the tool did.
|
||||
|
||||
## Extending with Custom Tools
|
||||
## Extending with custom tools
|
||||
|
||||
While direct programmatic registration of new tools by users isn't explicitly
|
||||
detailed as a primary workflow in the provided files for typical end-users, the
|
||||
architecture supports extension through:
|
||||
|
||||
- **Command-based Discovery:** Advanced users or project administrators can
|
||||
- **Command-based discovery:** Advanced users or project administrators can
|
||||
define a `tools.discoveryCommand` in `settings.json`. This command, when run
|
||||
by the Gemini CLI core, should output a JSON array of `FunctionDeclaration`
|
||||
objects. The core will then make these available as `DiscoveredTool`
|
||||
instances. The corresponding `tools.callCommand` would then be responsible for
|
||||
actually executing these custom tools.
|
||||
- **MCP Server(s):** For more complex scenarios, one or more MCP servers can be
|
||||
- **MCP server(s):** For more complex scenarios, one or more MCP servers can be
|
||||
set up and configured via the `mcpServers` setting in `settings.json`. The
|
||||
Gemini CLI core can then discover and use tools exposed by these servers. As
|
||||
mentioned, if you have multiple MCP servers, the tool names will be prefixed
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Example Proxy Script
|
||||
# Example proxy script
|
||||
|
||||
The following is an example of a proxy script that can be used with the
|
||||
`GEMINI_SANDBOX_PROXY_COMMAND` environment variable. This script only allows
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
# Extensions on Gemini CLI: Best practices
|
||||
|
||||
This guide covers best practices for developing, securing, and maintaining
|
||||
Gemini CLI extensions.
|
||||
|
||||
## Development
|
||||
|
||||
Developing extensions for Gemini CLI is intended to be a lightweight, iterative
|
||||
process.
|
||||
|
||||
### Structure your extension
|
||||
|
||||
While simple extensions can just be a few files, we recommend a robust structure
|
||||
for complex extensions:
|
||||
|
||||
```
|
||||
my-extension/
|
||||
├── package.json
|
||||
├── tsconfig.json
|
||||
├── gemini-extension.json
|
||||
├── src/
|
||||
│ ├── index.ts
|
||||
│ └── tools/
|
||||
└── dist/
|
||||
```
|
||||
|
||||
- **Use TypeScript**: We strongly recommend using TypeScript for type safety and
|
||||
better tooling.
|
||||
- **Separate source and build**: Keep your source code in `src` and build to
|
||||
`dist`.
|
||||
- **Bundle dependencies**: If your extension has many dependencies, consider
|
||||
bundling them (e.g., with `esbuild` or `webpack`) to reduce install time and
|
||||
potential conflicts.
|
||||
|
||||
### Iterate with `link`
|
||||
|
||||
Use `gemini extensions link` to develop locally without constantly reinstalling:
|
||||
|
||||
```bash
|
||||
cd my-extension
|
||||
gemini extensions link .
|
||||
```
|
||||
|
||||
Changes to your code (after rebuilding) will be immediately available in the CLI
|
||||
on restart.
|
||||
|
||||
### Use `GEMINI.md` effectively
|
||||
|
||||
Your `GEMINI.md` file provides context to the model. Keep it focused:
|
||||
|
||||
- **Do:** Explain high-level goals and how to use the provided tools.
|
||||
- **Don't:** Dump your entire documentation.
|
||||
- **Do:** Use clear, concise language.
|
||||
|
||||
## Security
|
||||
|
||||
When building a Gemini CLI extension, follow general security best practices
|
||||
(such as least privilege and input validation) to reduce risk.
|
||||
|
||||
### Minimal permissions
|
||||
|
||||
When defining tools in your MCP server, only request the permissions necessary.
|
||||
Avoid giving the model broad access (like full shell access) if a more
|
||||
restricted set of tools will suffice.
|
||||
|
||||
If you must use powerful tools like `run_shell_command`, consider restricting
|
||||
them to specific commands in your `gemini-extension.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "my-safe-extension",
|
||||
"excludeTools": ["run_shell_command(rm -rf *)"]
|
||||
}
|
||||
```
|
||||
|
||||
This ensures that even if the model tries to execute a dangerous command, it
|
||||
will be blocked at the CLI level.
|
||||
|
||||
### Validate inputs
|
||||
|
||||
Your MCP server is running on the user's machine. Always validate inputs to your
|
||||
tools to prevent arbitrary code execution or filesystem access outside the
|
||||
intended scope.
|
||||
|
||||
```typescript
|
||||
// Good: Validating paths
|
||||
if (!path.resolve(inputPath).startsWith(path.resolve(allowedDir) + path.sep)) {
|
||||
throw new Error('Access denied');
|
||||
}
|
||||
```
|
||||
|
||||
### Sensitive settings
|
||||
|
||||
If your extension requires API keys, use the `sensitive: true` option in
|
||||
`gemini-extension.json`. This ensures keys are stored securely in the system
|
||||
keychain and obfuscated in the UI.
|
||||
|
||||
```json
|
||||
"settings": [
|
||||
{
|
||||
"name": "API Key",
|
||||
"envVar": "MY_API_KEY",
|
||||
"sensitive": true
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## Releasing
|
||||
|
||||
You can upload your extension directly to GitHub to list it in the gallery.
|
||||
Gemini CLI extensions also offers support for more complicated
|
||||
[releases](releasing.md).
|
||||
|
||||
### Semantic versioning
|
||||
|
||||
Follow [Semantic Versioning](https://semver.org/).
|
||||
|
||||
- **Major**: Breaking changes (renaming tools, changing arguments).
|
||||
- **Minor**: New features (new tools, commands).
|
||||
- **Patch**: Bug fixes.
|
||||
|
||||
### Release Channels
|
||||
|
||||
Use git branches to manage release channels (e.g., `main` for stable, `dev` for
|
||||
bleeding edge). This allows users to choose their stability level:
|
||||
|
||||
```bash
|
||||
# Stable
|
||||
gemini extensions install github.com/user/repo
|
||||
|
||||
# Dev
|
||||
gemini extensions install github.com/user/repo --ref dev
|
||||
```
|
||||
|
||||
### Clean artifacts
|
||||
|
||||
If you are using GitHub Releases, ensure your release artifacts only contain the
|
||||
necessary files (`dist/`, `gemini-extension.json`, `package.json`). Exclude
|
||||
`node_modules` (users will install them) and `src/` to keep downloads small.
|
||||
+28
-260
@@ -1,277 +1,45 @@
|
||||
# Gemini CLI Extensions
|
||||
# Gemini CLI extensions
|
||||
|
||||
_This documentation is up-to-date with the v0.4.0 release._
|
||||
|
||||
Gemini CLI extensions package prompts, MCP servers, and custom commands into a
|
||||
familiar and user-friendly format. With extensions, you can expand the
|
||||
capabilities of Gemini CLI and share those capabilities with others. They are
|
||||
designed to be easily installable and shareable.
|
||||
Gemini CLI extensions package prompts, MCP servers, custom commands, hooks,
|
||||
sub-agents, and agent skills into a familiar and user-friendly format. With
|
||||
extensions, you can expand the capabilities of Gemini CLI and share those
|
||||
capabilities with others. They are designed to be easily installable and
|
||||
shareable.
|
||||
|
||||
To see examples of extensions, you can browse a gallery of
|
||||
[Gemini CLI extensions](https://geminicli.com/extensions/browse/).
|
||||
|
||||
See [getting started docs](getting-started-extensions.md) for a guide on
|
||||
creating your first extension.
|
||||
## Managing extensions
|
||||
|
||||
See [releasing docs](extension-releasing.md) for an advanced guide on setting up
|
||||
GitHub releases.
|
||||
You can verify your installed extensions and their status using the interactive
|
||||
command:
|
||||
|
||||
## Extension management
|
||||
|
||||
We offer a suite of extension management tools using `gemini extensions`
|
||||
commands.
|
||||
|
||||
Note that these commands are not supported from within the CLI, although you can
|
||||
list installed extensions using the `/extensions list` subcommand.
|
||||
|
||||
Note that all of these commands will only be reflected in active CLI sessions on
|
||||
restart.
|
||||
|
||||
### Installing an extension
|
||||
|
||||
You can install an extension using `gemini extensions install` with either a
|
||||
GitHub URL or a local path.
|
||||
|
||||
Note that we create a copy of the installed extension, so you will need to run
|
||||
`gemini extensions update` to pull in changes from both locally-defined
|
||||
extensions and those on GitHub.
|
||||
|
||||
NOTE: If you are installing an extension from GitHub, you'll need to have `git`
|
||||
installed on your machine. See
|
||||
[git installation instructions](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
|
||||
for help.
|
||||
|
||||
```
|
||||
gemini extensions install <source> [--ref <ref>] [--auto-update] [--pre-release] [--consent]
|
||||
```bash
|
||||
/extensions list
|
||||
```
|
||||
|
||||
- `<source>`: The github URL or local path of the extension to install.
|
||||
- `--ref`: The git ref to install from.
|
||||
- `--auto-update`: Enable auto-update for this extension.
|
||||
- `--pre-release`: Enable pre-release versions for this extension.
|
||||
- `--consent`: Acknowledge the security risks of installing an extension and
|
||||
skip the confirmation prompt.
|
||||
or in noninteractive mode:
|
||||
|
||||
### Uninstalling an extension
|
||||
|
||||
To uninstall, run `gemini extensions uninstall <name>`:
|
||||
|
||||
```
|
||||
gemini extensions uninstall gemini-cli-security
|
||||
```bash
|
||||
gemini extensions list
|
||||
```
|
||||
|
||||
### Disabling an extension
|
||||
## Installation
|
||||
|
||||
Extensions are, by default, enabled across all workspaces. You can disable an
|
||||
extension entirely or for specific workspace.
|
||||
To install a real extension, you can use the `extensions install` command with a
|
||||
GitHub repository URL in noninteractive mode. For example:
|
||||
|
||||
```
|
||||
gemini extensions disable <name> [--scope <scope>]
|
||||
```bash
|
||||
gemini extensions install https://github.com/gemini-cli-extensions/workspace
|
||||
```
|
||||
|
||||
- `<name>`: The name of the extension to disable.
|
||||
- `--scope`: The scope to disable the extension in (`user` or `workspace`).
|
||||
## Next steps
|
||||
|
||||
### Enabling an extension
|
||||
|
||||
You can enable extensions using `gemini extensions enable <name>`. You can also
|
||||
enable an extension for a specific workspace using
|
||||
`gemini extensions enable <name> --scope=workspace` from within that workspace.
|
||||
|
||||
```
|
||||
gemini extensions enable <name> [--scope <scope>]
|
||||
```
|
||||
|
||||
- `<name>`: The name of the extension to enable.
|
||||
- `--scope`: The scope to enable the extension in (`user` or `workspace`).
|
||||
|
||||
### Updating an extension
|
||||
|
||||
For extensions installed from a local path or a git repository, you can
|
||||
explicitly update to the latest version (as reflected in the
|
||||
`gemini-extension.json` `version` field) with `gemini extensions update <name>`.
|
||||
|
||||
You can update all extensions with:
|
||||
|
||||
```
|
||||
gemini extensions update --all
|
||||
```
|
||||
|
||||
### Create a boilerplate extension
|
||||
|
||||
We offer several example extensions `context`, `custom-commands`,
|
||||
`exclude-tools` and `mcp-server`. You can view these examples
|
||||
[here](https://github.com/google-gemini/gemini-cli/tree/main/packages/cli/src/commands/extensions/examples).
|
||||
|
||||
To copy one of these examples into a development directory using the type of
|
||||
your choosing, run:
|
||||
|
||||
```
|
||||
gemini extensions new <path> [template]
|
||||
```
|
||||
|
||||
- `<path>`: The path to create the extension in.
|
||||
- `[template]`: The boilerplate template to use.
|
||||
|
||||
### Link a local extension
|
||||
|
||||
The `gemini extensions link` command will create a symbolic link from the
|
||||
extension installation directory to the development path.
|
||||
|
||||
This is useful so you don't have to run `gemini extensions update` every time
|
||||
you make changes you'd like to test.
|
||||
|
||||
```
|
||||
gemini extensions link <path>
|
||||
```
|
||||
|
||||
- `<path>`: The path of the extension to link.
|
||||
|
||||
## How it works
|
||||
|
||||
On startup, Gemini CLI looks for extensions in `<home>/.gemini/extensions`
|
||||
|
||||
Extensions exist as a directory that contains a `gemini-extension.json` file.
|
||||
For example:
|
||||
|
||||
`<home>/.gemini/extensions/my-extension/gemini-extension.json`
|
||||
|
||||
### `gemini-extension.json`
|
||||
|
||||
The `gemini-extension.json` file contains the configuration for the extension.
|
||||
The file has the following structure:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "my-extension",
|
||||
"version": "1.0.0",
|
||||
"mcpServers": {
|
||||
"my-server": {
|
||||
"command": "node my-server.js"
|
||||
}
|
||||
},
|
||||
"contextFileName": "GEMINI.md",
|
||||
"excludeTools": ["run_shell_command"]
|
||||
}
|
||||
```
|
||||
|
||||
- `name`: The name of the extension. This is used to uniquely identify the
|
||||
extension and for conflict resolution when extension commands have the same
|
||||
name as user or project commands. The name should be lowercase or numbers and
|
||||
use dashes instead of underscores or spaces. This is how users will refer to
|
||||
your extension in the CLI. Note that we expect this name to match the
|
||||
extension directory name.
|
||||
- `version`: The version of the extension.
|
||||
- `mcpServers`: A map of MCP servers to configure. The key is the name of the
|
||||
server, and the value is the server configuration. These servers will be
|
||||
loaded on startup just like MCP servers configured in a
|
||||
[`settings.json` file](../get-started/configuration.md). If both an extension
|
||||
and a `settings.json` file configure an MCP server with the same name, the
|
||||
server defined in the `settings.json` file takes precedence.
|
||||
- Note that all MCP server configuration options are supported except for
|
||||
`trust`.
|
||||
- `contextFileName`: The name of the file that contains the context for the
|
||||
extension. This will be used to load the context from the extension directory.
|
||||
If this property is not used but a `GEMINI.md` file is present in your
|
||||
extension directory, then that file will be loaded.
|
||||
- `excludeTools`: An array of tool names to exclude from the model. You can also
|
||||
specify command-specific restrictions for tools that support it, like the
|
||||
`run_shell_command` tool. For example,
|
||||
`"excludeTools": ["run_shell_command(rm -rf)"]` will block the `rm -rf`
|
||||
command. Note that this differs from the MCP server `excludeTools`
|
||||
functionality, which can be listed in the MCP server config.
|
||||
|
||||
When Gemini CLI starts, it loads all the extensions and merges their
|
||||
configurations. If there are any conflicts, the workspace configuration takes
|
||||
precedence.
|
||||
|
||||
### Settings
|
||||
|
||||
_Note: This is an experimental feature. We do not yet recommend extension
|
||||
authors introduce settings as part of their core flows._
|
||||
|
||||
Extensions can define settings that the user will be prompted to provide upon
|
||||
installation. This is useful for things like API keys, URLs, or other
|
||||
configuration that the extension needs to function.
|
||||
|
||||
To define settings, add a `settings` array to your `gemini-extension.json` file.
|
||||
Each object in the array should have the following properties:
|
||||
|
||||
- `name`: A user-friendly name for the setting.
|
||||
- `description`: A description of the setting and what it's used for.
|
||||
- `envVar`: The name of the environment variable that the setting will be stored
|
||||
as.
|
||||
- `sensitive`: Optional boolean. If true, obfuscates the input the user provides
|
||||
and stores the secret in keychain storage. **Example**
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "my-api-extension",
|
||||
"version": "1.0.0",
|
||||
"settings": [
|
||||
{
|
||||
"name": "API Key",
|
||||
"description": "Your API key for the service.",
|
||||
"envVar": "MY_API_KEY"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
When a user installs this extension, they will be prompted to enter their API
|
||||
key. The value will be saved to a `.env` file in the extension's directory
|
||||
(e.g., `<home>/.gemini/extensions/my-api-extension/.env`).
|
||||
|
||||
### Custom commands
|
||||
|
||||
Extensions can provide [custom commands](../cli/custom-commands.md) by placing
|
||||
TOML files in a `commands/` subdirectory within the extension directory. These
|
||||
commands follow the same format as user and project custom commands and use
|
||||
standard naming conventions.
|
||||
|
||||
**Example**
|
||||
|
||||
An extension named `gcp` with the following structure:
|
||||
|
||||
```
|
||||
.gemini/extensions/gcp/
|
||||
├── gemini-extension.json
|
||||
└── commands/
|
||||
├── deploy.toml
|
||||
└── gcs/
|
||||
└── sync.toml
|
||||
```
|
||||
|
||||
Would provide these commands:
|
||||
|
||||
- `/deploy` - Shows as `[gcp] Custom command from deploy.toml` in help
|
||||
- `/gcs:sync` - Shows as `[gcp] Custom command from sync.toml` in help
|
||||
|
||||
### Conflict resolution
|
||||
|
||||
Extension commands have the lowest precedence. When a conflict occurs with user
|
||||
or project commands:
|
||||
|
||||
1. **No conflict**: Extension command uses its natural name (e.g., `/deploy`)
|
||||
2. **With conflict**: Extension command is renamed with the extension prefix
|
||||
(e.g., `/gcp.deploy`)
|
||||
|
||||
For example, if both a user and the `gcp` extension define a `deploy` command:
|
||||
|
||||
- `/deploy` - Executes the user's deploy command
|
||||
- `/gcp.deploy` - Executes the extension's deploy command (marked with `[gcp]`
|
||||
tag)
|
||||
|
||||
## Variables
|
||||
|
||||
Gemini CLI extensions allow variable substitution in `gemini-extension.json`.
|
||||
This can be useful if e.g., you need the current directory to run an MCP server
|
||||
using `"cwd": "${extensionPath}${/}run.ts"`.
|
||||
|
||||
**Supported variables:**
|
||||
|
||||
| variable | description |
|
||||
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `${extensionPath}` | The fully-qualified path of the extension in the user's filesystem e.g., '/Users/username/.gemini/extensions/example-extension'. This will not unwrap symlinks. |
|
||||
| `${workspacePath}` | The fully-qualified path of the current workspace. |
|
||||
| `${/} or ${pathSeparator}` | The path separator (differs per OS). |
|
||||
- [Writing extensions](writing-extensions.md): Learn how to create your first
|
||||
extension.
|
||||
- [Extensions reference](reference.md): Deeply understand the extension format,
|
||||
commands, and configuration.
|
||||
- [Best practices](best-practices.md): Learn strategies for building great
|
||||
extensions.
|
||||
- [Extensions releasing](releasing.md): Learn how to share your extensions with
|
||||
the world.
|
||||
|
||||
@@ -0,0 +1,336 @@
|
||||
# Extensions reference
|
||||
|
||||
This guide covers the `gemini extensions` commands and the structure of the
|
||||
`gemini-extension.json` configuration file.
|
||||
|
||||
## Extension management
|
||||
|
||||
We offer a suite of extension management tools using `gemini extensions`
|
||||
commands.
|
||||
|
||||
Note that these commands (e.g. `gemini extensions install`) are not supported
|
||||
from within the CLI's **interactive mode**, although you can list installed
|
||||
extensions using the `/extensions list` slash command.
|
||||
|
||||
Note that all of these management operations (including updates to slash
|
||||
commands) will only be reflected in active CLI sessions on **restart**.
|
||||
|
||||
### Installing an extension
|
||||
|
||||
You can install an extension using `gemini extensions install` with either a
|
||||
GitHub URL or a local path.
|
||||
|
||||
Note that we create a copy of the installed extension, so you will need to run
|
||||
`gemini extensions update` to pull in changes from both locally-defined
|
||||
extensions and those on GitHub.
|
||||
|
||||
NOTE: If you are installing an extension from GitHub, you'll need to have `git`
|
||||
installed on your machine. See
|
||||
[git installation instructions](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
|
||||
for help.
|
||||
|
||||
```
|
||||
gemini extensions install <source> [--ref <ref>] [--auto-update] [--pre-release] [--consent]
|
||||
```
|
||||
|
||||
- `<source>`: The github URL or local path of the extension to install.
|
||||
- `--ref`: The git ref to install from.
|
||||
- `--auto-update`: Enable auto-update for this extension.
|
||||
- `--pre-release`: Enable pre-release versions for this extension.
|
||||
- `--consent`: Acknowledge the security risks of installing an extension and
|
||||
skip the confirmation prompt.
|
||||
|
||||
### Uninstalling an extension
|
||||
|
||||
To uninstall one or more extensions, run
|
||||
`gemini extensions uninstall <name...>`:
|
||||
|
||||
```
|
||||
gemini extensions uninstall gemini-cli-security gemini-cli-another-extension
|
||||
```
|
||||
|
||||
### Disabling an extension
|
||||
|
||||
Extensions are, by default, enabled across all workspaces. You can disable an
|
||||
extension entirely or for specific workspace.
|
||||
|
||||
```
|
||||
gemini extensions disable <name> [--scope <scope>]
|
||||
```
|
||||
|
||||
- `<name>`: The name of the extension to disable.
|
||||
- `--scope`: The scope to disable the extension in (`user` or `workspace`).
|
||||
|
||||
### Enabling an extension
|
||||
|
||||
You can enable extensions using `gemini extensions enable <name>`. You can also
|
||||
enable an extension for a specific workspace using
|
||||
`gemini extensions enable <name> --scope=workspace` from within that workspace.
|
||||
|
||||
```
|
||||
gemini extensions enable <name> [--scope <scope>]
|
||||
```
|
||||
|
||||
- `<name>`: The name of the extension to enable.
|
||||
- `--scope`: The scope to enable the extension in (`user` or `workspace`).
|
||||
|
||||
### Updating an extension
|
||||
|
||||
For extensions installed from a local path or a git repository, you can
|
||||
explicitly update to the latest version (as reflected in the
|
||||
`gemini-extension.json` `version` field) with `gemini extensions update <name>`.
|
||||
|
||||
You can update all extensions with:
|
||||
|
||||
```
|
||||
gemini extensions update --all
|
||||
```
|
||||
|
||||
### Create a boilerplate extension
|
||||
|
||||
We offer several example extensions `context`, `custom-commands`,
|
||||
`exclude-tools` and `mcp-server`. You can view these examples
|
||||
[here](https://github.com/google-gemini/gemini-cli/tree/main/packages/cli/src/commands/extensions/examples).
|
||||
|
||||
To copy one of these examples into a development directory using the type of
|
||||
your choosing, run:
|
||||
|
||||
```
|
||||
gemini extensions new <path> [template]
|
||||
```
|
||||
|
||||
- `<path>`: The path to create the extension in.
|
||||
- `[template]`: The boilerplate template to use.
|
||||
|
||||
### Link a local extension
|
||||
|
||||
The `gemini extensions link` command will create a symbolic link from the
|
||||
extension installation directory to the development path.
|
||||
|
||||
This is useful so you don't have to run `gemini extensions update` every time
|
||||
you make changes you'd like to test.
|
||||
|
||||
```
|
||||
gemini extensions link <path>
|
||||
```
|
||||
|
||||
- `<path>`: The path of the extension to link.
|
||||
|
||||
## Extension format
|
||||
|
||||
On startup, Gemini CLI looks for extensions in `<home>/.gemini/extensions`
|
||||
|
||||
Extensions exist as a directory that contains a `gemini-extension.json` file.
|
||||
For example:
|
||||
|
||||
`<home>/.gemini/extensions/my-extension/gemini-extension.json`
|
||||
|
||||
### `gemini-extension.json`
|
||||
|
||||
The `gemini-extension.json` file contains the configuration for the extension.
|
||||
The file has the following structure:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "my-extension",
|
||||
"version": "1.0.0",
|
||||
"description": "My awesome extension",
|
||||
"mcpServers": {
|
||||
"my-server": {
|
||||
"command": "node my-server.js"
|
||||
}
|
||||
},
|
||||
"contextFileName": "GEMINI.md",
|
||||
"excludeTools": ["run_shell_command"]
|
||||
}
|
||||
```
|
||||
|
||||
- `name`: The name of the extension. This is used to uniquely identify the
|
||||
extension and for conflict resolution when extension commands have the same
|
||||
name as user or project commands. The name should be lowercase or numbers and
|
||||
use dashes instead of underscores or spaces. This is how users will refer to
|
||||
your extension in the CLI. Note that we expect this name to match the
|
||||
extension directory name.
|
||||
- `version`: The version of the extension.
|
||||
- `description`: A short description of the extension. This will be displayed on
|
||||
[geminicli.com/extensions](https://geminicli.com/extensions).
|
||||
- `mcpServers`: A map of MCP servers to settings. The key is the name of the
|
||||
server, and the value is the server configuration. These servers will be
|
||||
loaded on startup just like MCP servers settingsd in a
|
||||
[`settings.json` file](../get-started/configuration.md). If both an extension
|
||||
and a `settings.json` file settings an MCP server with the same name, the
|
||||
server defined in the `settings.json` file takes precedence.
|
||||
- Note that all MCP server configuration options are supported except for
|
||||
`trust`.
|
||||
- `contextFileName`: The name of the file that contains the context for the
|
||||
extension. This will be used to load the context from the extension directory.
|
||||
If this property is not used but a `GEMINI.md` file is present in your
|
||||
extension directory, then that file will be loaded.
|
||||
- `excludeTools`: An array of tool names to exclude from the model. You can also
|
||||
specify command-specific restrictions for tools that support it, like the
|
||||
`run_shell_command` tool. For example,
|
||||
`"excludeTools": ["run_shell_command(rm -rf)"]` will block the `rm -rf`
|
||||
command. Note that this differs from the MCP server `excludeTools`
|
||||
functionality, which can be listed in the MCP server config.
|
||||
|
||||
When Gemini CLI starts, it loads all the extensions and merges their
|
||||
configurations. If there are any conflicts, the workspace configuration takes
|
||||
precedence.
|
||||
|
||||
### Settings
|
||||
|
||||
_Note: This is an experimental feature. We do not yet recommend extension
|
||||
authors introduce settings as part of their core flows._
|
||||
|
||||
Extensions can define settings that the user will be prompted to provide upon
|
||||
installation. This is useful for things like API keys, URLs, or other
|
||||
configuration that the extension needs to function.
|
||||
|
||||
To define settings, add a `settings` array to your `gemini-extension.json` file.
|
||||
Each object in the array should have the following properties:
|
||||
|
||||
- `name`: A user-friendly name for the setting.
|
||||
- `description`: A description of the setting and what it's used for.
|
||||
- `envVar`: The name of the environment variable that the setting will be stored
|
||||
as.
|
||||
- `sensitive`: Optional boolean. If true, obfuscates the input the user provides
|
||||
and stores the secret in keychain storage. **Example**
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "my-api-extension",
|
||||
"version": "1.0.0",
|
||||
"settings": [
|
||||
{
|
||||
"name": "API Key",
|
||||
"description": "Your API key for the service.",
|
||||
"envVar": "MY_API_KEY"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
When a user installs this extension, they will be prompted to enter their API
|
||||
key. The value will be saved to a `.env` file in the extension's directory
|
||||
(e.g., `<home>/.gemini/extensions/my-api-extension/.env`).
|
||||
|
||||
You can view a list of an extension's settings by running:
|
||||
|
||||
```
|
||||
gemini extensions list
|
||||
```
|
||||
|
||||
and you can update a given setting using:
|
||||
|
||||
```
|
||||
gemini extensions config <extension name> [setting name] [--scope <scope>]
|
||||
```
|
||||
|
||||
- `--scope`: The scope to set the setting in (`user` or `workspace`). This is
|
||||
optional and will default to `user`.
|
||||
|
||||
### Custom commands
|
||||
|
||||
Extensions can provide [custom commands](../cli/custom-commands.md) by placing
|
||||
TOML files in a `commands/` subdirectory within the extension directory. These
|
||||
commands follow the same format as user and project custom commands and use
|
||||
standard naming conventions.
|
||||
|
||||
**Example**
|
||||
|
||||
An extension named `gcp` with the following structure:
|
||||
|
||||
```
|
||||
.gemini/extensions/gcp/
|
||||
├── gemini-extension.json
|
||||
└── commands/
|
||||
├── deploy.toml
|
||||
└── gcs/
|
||||
└── sync.toml
|
||||
```
|
||||
|
||||
Would provide these commands:
|
||||
|
||||
- `/deploy` - Shows as `[gcp] Custom command from deploy.toml` in help
|
||||
- `/gcs:sync` - Shows as `[gcp] Custom command from sync.toml` in help
|
||||
|
||||
### Hooks
|
||||
|
||||
Extensions can provide [hooks](../hooks/index.md) to intercept and customize
|
||||
Gemini CLI behavior at specific lifecycle events. Hooks provided by an extension
|
||||
must be defined in a `hooks/hooks.json` file within the extension directory.
|
||||
|
||||
> [!IMPORTANT] Hooks are not defined directly in `gemini-extension.json`. The
|
||||
> CLI specifically looks for the `hooks/hooks.json` file.
|
||||
|
||||
### Agent Skills
|
||||
|
||||
Extensions can bundle [Agent Skills](../cli/skills.md) to provide specialized
|
||||
workflows. Skills must be placed in a `skills/` directory within the extension.
|
||||
|
||||
**Example**
|
||||
|
||||
An extension with the following structure:
|
||||
|
||||
```
|
||||
.gemini/extensions/my-extension/
|
||||
├── gemini-extension.json
|
||||
└── skills/
|
||||
└── security-audit/
|
||||
└── SKILL.md
|
||||
```
|
||||
|
||||
Will expose a `security-audit` skill that the model can activate.
|
||||
|
||||
### Sub-agents
|
||||
|
||||
> **Note: Sub-agents are currently an experimental feature.**
|
||||
|
||||
Extensions can provide [sub-agents](../core/subagents.md) that users can
|
||||
delegate tasks to.
|
||||
|
||||
To bundle sub-agents with your extension, create an `agents/` directory in your
|
||||
extension's root folder and add your agent definition files (`.md`) there.
|
||||
|
||||
**Example**
|
||||
|
||||
```
|
||||
.gemini/extensions/my-extension/
|
||||
├── gemini-extension.json
|
||||
└── agents/
|
||||
├── security-auditor.md
|
||||
└── database-expert.md
|
||||
```
|
||||
|
||||
Gemini CLI will automatically discover and load these agents when the extension
|
||||
is installed and enabled.
|
||||
|
||||
### Conflict resolution
|
||||
|
||||
Extension commands have the lowest precedence. When a conflict occurs with user
|
||||
or project commands:
|
||||
|
||||
1. **No conflict**: Extension command uses its natural name (e.g., `/deploy`)
|
||||
2. **With conflict**: Extension command is renamed with the extension prefix
|
||||
(e.g., `/gcp.deploy`)
|
||||
|
||||
For example, if both a user and the `gcp` extension define a `deploy` command:
|
||||
|
||||
- `/deploy` - Executes the user's deploy command
|
||||
- `/gcp.deploy` - Executes the extension's deploy command (marked with `[gcp]`
|
||||
tag)
|
||||
|
||||
## Variables
|
||||
|
||||
Gemini CLI extensions allow variable substitution in both
|
||||
`gemini-extension.json` and `hooks/hooks.json`. This can be useful if e.g., you
|
||||
need the current directory to run an MCP server using an argument like
|
||||
`"args": ["${extensionPath}${/}dist${/}server.js"]`.
|
||||
|
||||
**Supported variables:**
|
||||
|
||||
| variable | description |
|
||||
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `${extensionPath}` | The fully-qualified path of the extension in the user's filesystem e.g., '/Users/username/.gemini/extensions/example-extension'. This will not unwrap symlinks. |
|
||||
| `${workspacePath}` | The fully-qualified path of the current workspace. |
|
||||
| `${/} or ${pathSeparator}` | The path separator (differs per OS). |
|
||||
@@ -1,4 +1,4 @@
|
||||
# Extension Releasing
|
||||
# Extension releasing
|
||||
|
||||
There are two primary ways of releasing extensions to users:
|
||||
|
||||
@@ -64,7 +64,7 @@ If you plan on doing cherry picks, you may want to avoid having your default
|
||||
branch be the stable branch to avoid force-pushing to the default branch which
|
||||
should generally be avoided.
|
||||
|
||||
## Releasing through Github releases
|
||||
## Releasing through GitHub releases
|
||||
|
||||
Gemini CLI extensions can be distributed through
|
||||
[GitHub Releases](https://docs.github.com/en/repositories/releasing-projects-on-github/about-releases).
|
||||
@@ -105,9 +105,9 @@ To ensure Gemini CLI can automatically find the correct release asset for each
|
||||
platform, you must follow this naming convention. The CLI will search for assets
|
||||
in the following order:
|
||||
|
||||
1. **Platform and Architecture-Specific:**
|
||||
1. **Platform and architecture-Specific:**
|
||||
`{platform}.{arch}.{name}.{extension}`
|
||||
2. **Platform-Specific:** `{platform}.{name}.{extension}`
|
||||
2. **Platform-specific:** `{platform}.{name}.{extension}`
|
||||
3. **Generic:** If only one asset is provided, it will be used as a generic
|
||||
fallback.
|
||||
|
||||
+70
-34
@@ -1,4 +1,4 @@
|
||||
# Getting Started with Gemini CLI Extensions
|
||||
# Getting started with Gemini CLI extensions
|
||||
|
||||
This guide will walk you through creating your first Gemini CLI extension.
|
||||
You'll learn how to set up a new extension, add a custom tool via an MCP server,
|
||||
@@ -8,9 +8,21 @@ file.
|
||||
## Prerequisites
|
||||
|
||||
Before you start, make sure you have the Gemini CLI installed and a basic
|
||||
understanding of Node.js and TypeScript.
|
||||
understanding of Node.js.
|
||||
|
||||
## Step 1: Create a New Extension
|
||||
## When to use what
|
||||
|
||||
Extensions offer a variety of ways to customize Gemini CLI.
|
||||
|
||||
| Feature | What it is | When to use it | Invoked by |
|
||||
| :------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------- |
|
||||
| **[MCP server](reference.md#mcp-servers)** | A standard way to expose new tools and data sources to the model. | Use this when you want the model to be able to _do_ new things, like fetching data from an internal API, querying a database, or controlling a local application. We also support MCP resources (which can replace custom commands) and system instructions (which can replace custom context) | Model |
|
||||
| **[Custom commands](../cli/custom-commands.md)** | A shortcut (like `/my-cmd`) that executes a pre-defined prompt or shell command. | Use this for repetitive tasks or to save long, complex prompts that you use frequently. Great for automation. | User |
|
||||
| **[Context file (`GEMINI.md`)](reference.md#contextfilename)** | A markdown file containing instructions that are loaded into the model's context at the start of every session. | Use this to define the "personality" of your extension, set coding standards, or provide essential knowledge that the model should always have. | CLI provides to model |
|
||||
| **[Agent skills](../cli/skills.md)** | A specialized set of instructions and workflows that the model activates only when needed. | Use this for complex, occasional tasks (like "create a PR" or "audit security") to avoid cluttering the main context window when the skill isn't being used. | Model |
|
||||
| **[Hooks](../hooks/index.md)** | A way to intercept and customize the CLI's behavior at specific lifecycle events (e.g., before/after a tool call). | Use this when you want to automate actions based on what the model is doing, like validating tool arguments, logging activity, or modifying the model's input/output. | CLI |
|
||||
|
||||
## Step 1: Create a new extension
|
||||
|
||||
The easiest way to start is by using one of the built-in templates. We'll use
|
||||
the `mcp-server` example as our foundation.
|
||||
@@ -26,13 +38,12 @@ This will create a new directory with the following structure:
|
||||
|
||||
```
|
||||
my-first-extension/
|
||||
├── example.ts
|
||||
├── example.js
|
||||
├── gemini-extension.json
|
||||
├── package.json
|
||||
└── tsconfig.json
|
||||
└── package.json
|
||||
```
|
||||
|
||||
## Step 2: Understand the Extension Files
|
||||
## Step 2: Understand the extension files
|
||||
|
||||
Let's look at the key files in your new extension.
|
||||
|
||||
@@ -43,12 +54,12 @@ and use your extension.
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "my-first-extension",
|
||||
"name": "mcp-server-example",
|
||||
"version": "1.0.0",
|
||||
"mcpServers": {
|
||||
"nodeServer": {
|
||||
"command": "node",
|
||||
"args": ["${extensionPath}${/}dist${/}example.js"],
|
||||
"args": ["${extensionPath}${/}example.js"],
|
||||
"cwd": "${extensionPath}"
|
||||
}
|
||||
}
|
||||
@@ -64,12 +75,12 @@ and use your extension.
|
||||
with the absolute path to your extension's installation directory. This
|
||||
allows your extension to work regardless of where it's installed.
|
||||
|
||||
### `example.ts`
|
||||
### `example.js`
|
||||
|
||||
This file contains the source code for your MCP server. It's a simple Node.js
|
||||
server that uses the `@modelcontextprotocol/sdk`.
|
||||
|
||||
```typescript
|
||||
```javascript
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2025 Google LLC
|
||||
@@ -118,16 +129,15 @@ await server.connect(transport);
|
||||
This server defines a single tool called `fetch_posts` that fetches data from a
|
||||
public API.
|
||||
|
||||
### `package.json` and `tsconfig.json`
|
||||
### `package.json`
|
||||
|
||||
These are standard configuration files for a TypeScript project. The
|
||||
`package.json` file defines dependencies and a `build` script, and
|
||||
`tsconfig.json` configures the TypeScript compiler.
|
||||
This is the standard configuration file for a Node.js project. It defines
|
||||
dependencies and scripts.
|
||||
|
||||
## Step 3: Build and Link Your Extension
|
||||
## Step 3: Link your extension
|
||||
|
||||
Before you can use the extension, you need to compile the TypeScript code and
|
||||
link the extension to your Gemini CLI installation for local development.
|
||||
Before you can use the extension, you need to link it to your Gemini CLI
|
||||
installation for local development.
|
||||
|
||||
1. **Install dependencies:**
|
||||
|
||||
@@ -136,16 +146,7 @@ link the extension to your Gemini CLI installation for local development.
|
||||
npm install
|
||||
```
|
||||
|
||||
2. **Build the server:**
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
This will compile `example.ts` into `dist/example.js`, which is the file
|
||||
referenced in your `gemini-extension.json`.
|
||||
|
||||
3. **Link the extension:**
|
||||
2. **Link the extension:**
|
||||
|
||||
The `link` command creates a symbolic link from the Gemini CLI extensions
|
||||
directory to your development directory. This means any changes you make
|
||||
@@ -158,7 +159,7 @@ link the extension to your Gemini CLI installation for local development.
|
||||
Now, restart your Gemini CLI session. The new `fetch_posts` tool will be
|
||||
available. You can test it by asking: "fetch posts".
|
||||
|
||||
## Step 4: Add a Custom Command
|
||||
## Step 4: Add a custom command
|
||||
|
||||
Custom commands provide a way to create shortcuts for complex prompts. Let's add
|
||||
a command that searches for a pattern in your code.
|
||||
@@ -186,7 +187,7 @@ a command that searches for a pattern in your code.
|
||||
After saving the file, restart the Gemini CLI. You can now run
|
||||
`/fs:grep-code "some pattern"` to use your new command.
|
||||
|
||||
## Step 5: Add a Custom `GEMINI.md`
|
||||
## Step 5: Add a custom `GEMINI.md`
|
||||
|
||||
You can provide persistent context to the model by adding a `GEMINI.md` file to
|
||||
your extension. This is useful for giving the model instructions on how to
|
||||
@@ -212,7 +213,7 @@ need this for extensions built to expose commands and prompts.
|
||||
"mcpServers": {
|
||||
"nodeServer": {
|
||||
"command": "node",
|
||||
"args": ["${extensionPath}${/}dist${/}example.js"],
|
||||
"args": ["${extensionPath}${/}example.js"],
|
||||
"cwd": "${extensionPath}"
|
||||
}
|
||||
}
|
||||
@@ -222,14 +223,48 @@ need this for extensions built to expose commands and prompts.
|
||||
Restart the CLI again. The model will now have the context from your `GEMINI.md`
|
||||
file in every session where the extension is active.
|
||||
|
||||
## Step 6: Releasing Your Extension
|
||||
## (Optional) Step 6: Add an Agent Skill
|
||||
|
||||
Once you are happy with your extension, you can share it with others. The two
|
||||
[Agent Skills](../cli/skills.md) let you bundle specialized expertise and
|
||||
procedural workflows. Unlike `GEMINI.md`, which provides persistent context,
|
||||
skills are activated only when needed, saving context tokens.
|
||||
|
||||
1. Create a `skills` directory and a subdirectory for your skill:
|
||||
|
||||
```bash
|
||||
mkdir -p skills/security-audit
|
||||
```
|
||||
|
||||
2. Create a `skills/security-audit/SKILL.md` file:
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: security-audit
|
||||
description:
|
||||
Expertise in auditing code for security vulnerabilities. Use when the user
|
||||
asks to "check for security issues" or "audit" their changes.
|
||||
---
|
||||
|
||||
# Security Auditor
|
||||
|
||||
You are an expert security researcher. When auditing code:
|
||||
|
||||
1. Look for common vulnerabilities (OWASP Top 10).
|
||||
2. Check for hardcoded secrets or API keys.
|
||||
3. Suggest remediation steps for any findings.
|
||||
```
|
||||
|
||||
Skills bundled with your extension are automatically discovered and can be
|
||||
activated by the model during a session when it identifies a relevant task.
|
||||
|
||||
## Step 7: Release your extension
|
||||
|
||||
Once you're happy with your extension, you can share it with others. The two
|
||||
primary ways of releasing extensions are via a Git repository or through GitHub
|
||||
Releases. Using a public Git repository is the simplest method.
|
||||
|
||||
For detailed instructions on both methods, please refer to the
|
||||
[Extension Releasing Guide](./extension-releasing.md).
|
||||
[Extension Releasing Guide](./releasing.md).
|
||||
|
||||
## Conclusion
|
||||
|
||||
@@ -239,6 +274,7 @@ You've successfully created a Gemini CLI extension! You learned how to:
|
||||
- Add custom tools with an MCP server.
|
||||
- Create convenient custom commands.
|
||||
- Provide persistent context to the model.
|
||||
- Bundle specialized Agent Skills.
|
||||
- Link your extension for local development.
|
||||
|
||||
From here, you can explore more advanced features and build powerful new
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
# Frequently Asked Questions (FAQ)
|
||||
# Frequently asked questions (FAQ)
|
||||
|
||||
This page provides answers to common questions and solutions to frequent
|
||||
problems encountered while using Gemini CLI.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user