├── .envrc ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── README.md ├── devenv.lock ├── devenv.nix ├── devenv.yaml ├── schema.sql └── src └── main.rs /.envrc: -------------------------------------------------------------------------------- 1 | source_url "https://raw.githubusercontent.com/cachix/devenv/d1f7b48e35e6dee421cfd0f51481d17f77586997/direnvrc" "sha256-YBzqskFZxmNb3kYVoKD9ZixoPXJh1C9ZvTLGFRkauZ0=" 2 | 3 | use devenv -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Devenv 3 | .devenv* 4 | devenv.local.nix 5 | .env 6 | 7 | # direnv 8 | .direnv 9 | 10 | # pre-commit 11 | .pre-commit-config.yaml 12 | 13 | 14 | 15 | # Added by cargo 16 | 17 | /target 18 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "aho-corasick" 7 | version = "1.1.2" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" 10 | dependencies = [ 11 | "memchr", 12 | ] 13 | 14 | [[package]] 15 | name = "atty" 16 | version = "0.2.14" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" 19 | dependencies = [ 20 | "hermit-abi", 21 | "libc", 22 | "winapi", 23 | ] 24 | 25 | [[package]] 26 | name = "autocfg" 27 | version = "1.1.0" 28 | source = "registry+https://github.com/rust-lang/crates.io-index" 29 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 30 | 31 | [[package]] 32 | name = "base64" 33 | version = "0.12.3" 34 | source = "registry+https://github.com/rust-lang/crates.io-index" 35 | checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" 36 | 37 | [[package]] 38 | name = "bitflags" 39 | version = "1.3.2" 40 | source = "registry+https://github.com/rust-lang/crates.io-index" 41 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 42 | 43 | [[package]] 44 | name = "cc" 45 | version = "1.0.89" 46 | source = "registry+https://github.com/rust-lang/crates.io-index" 47 | checksum = "a0ba8f7aaa012f30d5b2861462f6708eccd49c3c39863fe083a308035f63d723" 48 | 49 | [[package]] 50 | name = "cfg-if" 51 | version = "1.0.0" 52 | source = "registry+https://github.com/rust-lang/crates.io-index" 53 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 54 | 55 | [[package]] 56 | name = "clap" 57 | version = "3.2.25" 58 | source = "registry+https://github.com/rust-lang/crates.io-index" 59 | checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" 60 | dependencies = [ 61 | "atty", 62 | "bitflags", 63 | "clap_derive", 64 | "clap_lex", 65 | "indexmap", 66 | "once_cell", 67 | "strsim", 68 | "termcolor", 69 | "textwrap", 70 | ] 71 | 72 | [[package]] 73 | name = "clap_derive" 74 | version = "3.2.25" 75 | source = "registry+https://github.com/rust-lang/crates.io-index" 76 | checksum = "ae6371b8bdc8b7d3959e9cf7b22d4435ef3e79e138688421ec654acf8c81b008" 77 | dependencies = [ 78 | "heck", 79 | "proc-macro-error", 80 | "proc-macro2", 81 | "quote", 82 | "syn 1.0.109", 83 | ] 84 | 85 | [[package]] 86 | name = "clap_lex" 87 | version = "0.2.4" 88 | source = "registry+https://github.com/rust-lang/crates.io-index" 89 | checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" 90 | dependencies = [ 91 | "os_str_bytes", 92 | ] 93 | 94 | [[package]] 95 | name = "getrandom" 96 | version = "0.2.12" 97 | source = "registry+https://github.com/rust-lang/crates.io-index" 98 | checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" 99 | dependencies = [ 100 | "cfg-if", 101 | "libc", 102 | "wasi", 103 | ] 104 | 105 | [[package]] 106 | name = "gpt-comments" 107 | version = "0.1.0" 108 | dependencies = [ 109 | "clap", 110 | "openai-api-rs", 111 | "tree-sitter", 112 | "tree-sitter-javascript", 113 | "tree-sitter-python", 114 | "tree-sitter-rust", 115 | "tree-sitter-sql", 116 | ] 117 | 118 | [[package]] 119 | name = "hashbrown" 120 | version = "0.12.3" 121 | source = "registry+https://github.com/rust-lang/crates.io-index" 122 | checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" 123 | 124 | [[package]] 125 | name = "heck" 126 | version = "0.4.1" 127 | source = "registry+https://github.com/rust-lang/crates.io-index" 128 | checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" 129 | 130 | [[package]] 131 | name = "hermit-abi" 132 | version = "0.1.19" 133 | source = "registry+https://github.com/rust-lang/crates.io-index" 134 | checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" 135 | dependencies = [ 136 | "libc", 137 | ] 138 | 139 | [[package]] 140 | name = "indexmap" 141 | version = "1.9.3" 142 | source = "registry+https://github.com/rust-lang/crates.io-index" 143 | checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" 144 | dependencies = [ 145 | "autocfg", 146 | "hashbrown", 147 | ] 148 | 149 | [[package]] 150 | name = "itoa" 151 | version = "1.0.10" 152 | source = "registry+https://github.com/rust-lang/crates.io-index" 153 | checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" 154 | 155 | [[package]] 156 | name = "libc" 157 | version = "0.2.153" 158 | source = "registry+https://github.com/rust-lang/crates.io-index" 159 | checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" 160 | 161 | [[package]] 162 | name = "log" 163 | version = "0.4.21" 164 | source = "registry+https://github.com/rust-lang/crates.io-index" 165 | checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" 166 | 167 | [[package]] 168 | name = "memchr" 169 | version = "2.7.1" 170 | source = "registry+https://github.com/rust-lang/crates.io-index" 171 | checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" 172 | 173 | [[package]] 174 | name = "minreq" 175 | version = "2.11.0" 176 | source = "registry+https://github.com/rust-lang/crates.io-index" 177 | checksum = "cb3371dfc7b772c540da1380123674a8e20583aca99907087d990ca58cf44203" 178 | dependencies = [ 179 | "base64", 180 | "log", 181 | "once_cell", 182 | "rustls", 183 | "rustls-webpki", 184 | "serde", 185 | "serde_json", 186 | "webpki-roots", 187 | ] 188 | 189 | [[package]] 190 | name = "once_cell" 191 | version = "1.19.0" 192 | source = "registry+https://github.com/rust-lang/crates.io-index" 193 | checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" 194 | 195 | [[package]] 196 | name = "openai-api-rs" 197 | version = "4.0.7" 198 | source = "registry+https://github.com/rust-lang/crates.io-index" 199 | checksum = "8fd07c011932f7e6f1541a0a4d1ac8aa084981176ab5cc0eaae52164f3018a1f" 200 | dependencies = [ 201 | "minreq", 202 | "serde", 203 | "serde_json", 204 | ] 205 | 206 | [[package]] 207 | name = "os_str_bytes" 208 | version = "6.6.1" 209 | source = "registry+https://github.com/rust-lang/crates.io-index" 210 | checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" 211 | 212 | [[package]] 213 | name = "proc-macro-error" 214 | version = "1.0.4" 215 | source = "registry+https://github.com/rust-lang/crates.io-index" 216 | checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" 217 | dependencies = [ 218 | "proc-macro-error-attr", 219 | "proc-macro2", 220 | "quote", 221 | "syn 1.0.109", 222 | "version_check", 223 | ] 224 | 225 | [[package]] 226 | name = "proc-macro-error-attr" 227 | version = "1.0.4" 228 | source = "registry+https://github.com/rust-lang/crates.io-index" 229 | checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" 230 | dependencies = [ 231 | "proc-macro2", 232 | "quote", 233 | "version_check", 234 | ] 235 | 236 | [[package]] 237 | name = "proc-macro2" 238 | version = "1.0.78" 239 | source = "registry+https://github.com/rust-lang/crates.io-index" 240 | checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" 241 | dependencies = [ 242 | "unicode-ident", 243 | ] 244 | 245 | [[package]] 246 | name = "quote" 247 | version = "1.0.35" 248 | source = "registry+https://github.com/rust-lang/crates.io-index" 249 | checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" 250 | dependencies = [ 251 | "proc-macro2", 252 | ] 253 | 254 | [[package]] 255 | name = "regex" 256 | version = "1.10.3" 257 | source = "registry+https://github.com/rust-lang/crates.io-index" 258 | checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" 259 | dependencies = [ 260 | "aho-corasick", 261 | "memchr", 262 | "regex-automata", 263 | "regex-syntax", 264 | ] 265 | 266 | [[package]] 267 | name = "regex-automata" 268 | version = "0.4.6" 269 | source = "registry+https://github.com/rust-lang/crates.io-index" 270 | checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" 271 | dependencies = [ 272 | "aho-corasick", 273 | "memchr", 274 | "regex-syntax", 275 | ] 276 | 277 | [[package]] 278 | name = "regex-syntax" 279 | version = "0.8.2" 280 | source = "registry+https://github.com/rust-lang/crates.io-index" 281 | checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" 282 | 283 | [[package]] 284 | name = "ring" 285 | version = "0.17.8" 286 | source = "registry+https://github.com/rust-lang/crates.io-index" 287 | checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" 288 | dependencies = [ 289 | "cc", 290 | "cfg-if", 291 | "getrandom", 292 | "libc", 293 | "spin", 294 | "untrusted", 295 | "windows-sys", 296 | ] 297 | 298 | [[package]] 299 | name = "rustls" 300 | version = "0.21.10" 301 | source = "registry+https://github.com/rust-lang/crates.io-index" 302 | checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" 303 | dependencies = [ 304 | "log", 305 | "ring", 306 | "rustls-webpki", 307 | "sct", 308 | ] 309 | 310 | [[package]] 311 | name = "rustls-webpki" 312 | version = "0.101.7" 313 | source = "registry+https://github.com/rust-lang/crates.io-index" 314 | checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" 315 | dependencies = [ 316 | "ring", 317 | "untrusted", 318 | ] 319 | 320 | [[package]] 321 | name = "ryu" 322 | version = "1.0.17" 323 | source = "registry+https://github.com/rust-lang/crates.io-index" 324 | checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" 325 | 326 | [[package]] 327 | name = "sct" 328 | version = "0.7.1" 329 | source = "registry+https://github.com/rust-lang/crates.io-index" 330 | checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" 331 | dependencies = [ 332 | "ring", 333 | "untrusted", 334 | ] 335 | 336 | [[package]] 337 | name = "serde" 338 | version = "1.0.197" 339 | source = "registry+https://github.com/rust-lang/crates.io-index" 340 | checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" 341 | dependencies = [ 342 | "serde_derive", 343 | ] 344 | 345 | [[package]] 346 | name = "serde_derive" 347 | version = "1.0.197" 348 | source = "registry+https://github.com/rust-lang/crates.io-index" 349 | checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" 350 | dependencies = [ 351 | "proc-macro2", 352 | "quote", 353 | "syn 2.0.52", 354 | ] 355 | 356 | [[package]] 357 | name = "serde_json" 358 | version = "1.0.114" 359 | source = "registry+https://github.com/rust-lang/crates.io-index" 360 | checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" 361 | dependencies = [ 362 | "itoa", 363 | "ryu", 364 | "serde", 365 | ] 366 | 367 | [[package]] 368 | name = "spin" 369 | version = "0.9.8" 370 | source = "registry+https://github.com/rust-lang/crates.io-index" 371 | checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" 372 | 373 | [[package]] 374 | name = "strsim" 375 | version = "0.10.0" 376 | source = "registry+https://github.com/rust-lang/crates.io-index" 377 | checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" 378 | 379 | [[package]] 380 | name = "syn" 381 | version = "1.0.109" 382 | source = "registry+https://github.com/rust-lang/crates.io-index" 383 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 384 | dependencies = [ 385 | "proc-macro2", 386 | "quote", 387 | "unicode-ident", 388 | ] 389 | 390 | [[package]] 391 | name = "syn" 392 | version = "2.0.52" 393 | source = "registry+https://github.com/rust-lang/crates.io-index" 394 | checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" 395 | dependencies = [ 396 | "proc-macro2", 397 | "quote", 398 | "unicode-ident", 399 | ] 400 | 401 | [[package]] 402 | name = "termcolor" 403 | version = "1.4.1" 404 | source = "registry+https://github.com/rust-lang/crates.io-index" 405 | checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" 406 | dependencies = [ 407 | "winapi-util", 408 | ] 409 | 410 | [[package]] 411 | name = "textwrap" 412 | version = "0.16.1" 413 | source = "registry+https://github.com/rust-lang/crates.io-index" 414 | checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" 415 | 416 | [[package]] 417 | name = "tree-sitter" 418 | version = "0.20.10" 419 | source = "registry+https://github.com/rust-lang/crates.io-index" 420 | checksum = "e747b1f9b7b931ed39a548c1fae149101497de3c1fc8d9e18c62c1a66c683d3d" 421 | dependencies = [ 422 | "cc", 423 | "regex", 424 | ] 425 | 426 | [[package]] 427 | name = "tree-sitter-javascript" 428 | version = "0.20.3" 429 | source = "registry+https://github.com/rust-lang/crates.io-index" 430 | checksum = "38d1463af5be7052171161db7cfe45c7621ed959ae533972ab47a09b1ed70ec0" 431 | dependencies = [ 432 | "cc", 433 | "tree-sitter", 434 | ] 435 | 436 | [[package]] 437 | name = "tree-sitter-python" 438 | version = "0.20.4" 439 | source = "registry+https://github.com/rust-lang/crates.io-index" 440 | checksum = "e6c93b1b1fbd0d399db3445f51fd3058e43d0b4dcff62ddbdb46e66550978aa5" 441 | dependencies = [ 442 | "cc", 443 | "tree-sitter", 444 | ] 445 | 446 | [[package]] 447 | name = "tree-sitter-rust" 448 | version = "0.20.4" 449 | source = "registry+https://github.com/rust-lang/crates.io-index" 450 | checksum = "b0832309b0b2b6d33760ce5c0e818cb47e1d72b468516bfe4134408926fa7594" 451 | dependencies = [ 452 | "cc", 453 | "tree-sitter", 454 | ] 455 | 456 | [[package]] 457 | name = "tree-sitter-sql" 458 | version = "0.0.2" 459 | source = "git+https://github.com/m-novikov/tree-sitter-sql.git#587f30d184b058450be2a2330878210c5f33b3f9" 460 | dependencies = [ 461 | "cc", 462 | "tree-sitter", 463 | ] 464 | 465 | [[package]] 466 | name = "unicode-ident" 467 | version = "1.0.12" 468 | source = "registry+https://github.com/rust-lang/crates.io-index" 469 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 470 | 471 | [[package]] 472 | name = "untrusted" 473 | version = "0.9.0" 474 | source = "registry+https://github.com/rust-lang/crates.io-index" 475 | checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" 476 | 477 | [[package]] 478 | name = "version_check" 479 | version = "0.9.4" 480 | source = "registry+https://github.com/rust-lang/crates.io-index" 481 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 482 | 483 | [[package]] 484 | name = "wasi" 485 | version = "0.11.0+wasi-snapshot-preview1" 486 | source = "registry+https://github.com/rust-lang/crates.io-index" 487 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 488 | 489 | [[package]] 490 | name = "webpki-roots" 491 | version = "0.25.4" 492 | source = "registry+https://github.com/rust-lang/crates.io-index" 493 | checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" 494 | 495 | [[package]] 496 | name = "winapi" 497 | version = "0.3.9" 498 | source = "registry+https://github.com/rust-lang/crates.io-index" 499 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 500 | dependencies = [ 501 | "winapi-i686-pc-windows-gnu", 502 | "winapi-x86_64-pc-windows-gnu", 503 | ] 504 | 505 | [[package]] 506 | name = "winapi-i686-pc-windows-gnu" 507 | version = "0.4.0" 508 | source = "registry+https://github.com/rust-lang/crates.io-index" 509 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 510 | 511 | [[package]] 512 | name = "winapi-util" 513 | version = "0.1.6" 514 | source = "registry+https://github.com/rust-lang/crates.io-index" 515 | checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" 516 | dependencies = [ 517 | "winapi", 518 | ] 519 | 520 | [[package]] 521 | name = "winapi-x86_64-pc-windows-gnu" 522 | version = "0.4.0" 523 | source = "registry+https://github.com/rust-lang/crates.io-index" 524 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 525 | 526 | [[package]] 527 | name = "windows-sys" 528 | version = "0.52.0" 529 | source = "registry+https://github.com/rust-lang/crates.io-index" 530 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 531 | dependencies = [ 532 | "windows-targets", 533 | ] 534 | 535 | [[package]] 536 | name = "windows-targets" 537 | version = "0.52.4" 538 | source = "registry+https://github.com/rust-lang/crates.io-index" 539 | checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" 540 | dependencies = [ 541 | "windows_aarch64_gnullvm", 542 | "windows_aarch64_msvc", 543 | "windows_i686_gnu", 544 | "windows_i686_msvc", 545 | "windows_x86_64_gnu", 546 | "windows_x86_64_gnullvm", 547 | "windows_x86_64_msvc", 548 | ] 549 | 550 | [[package]] 551 | name = "windows_aarch64_gnullvm" 552 | version = "0.52.4" 553 | source = "registry+https://github.com/rust-lang/crates.io-index" 554 | checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" 555 | 556 | [[package]] 557 | name = "windows_aarch64_msvc" 558 | version = "0.52.4" 559 | source = "registry+https://github.com/rust-lang/crates.io-index" 560 | checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" 561 | 562 | [[package]] 563 | name = "windows_i686_gnu" 564 | version = "0.52.4" 565 | source = "registry+https://github.com/rust-lang/crates.io-index" 566 | checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" 567 | 568 | [[package]] 569 | name = "windows_i686_msvc" 570 | version = "0.52.4" 571 | source = "registry+https://github.com/rust-lang/crates.io-index" 572 | checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" 573 | 574 | [[package]] 575 | name = "windows_x86_64_gnu" 576 | version = "0.52.4" 577 | source = "registry+https://github.com/rust-lang/crates.io-index" 578 | checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" 579 | 580 | [[package]] 581 | name = "windows_x86_64_gnullvm" 582 | version = "0.52.4" 583 | source = "registry+https://github.com/rust-lang/crates.io-index" 584 | checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" 585 | 586 | [[package]] 587 | name = "windows_x86_64_msvc" 588 | version = "0.52.4" 589 | source = "registry+https://github.com/rust-lang/crates.io-index" 590 | checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" 591 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "gpt-comments" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | clap = { version = "3", features = ["derive"] } 10 | openai-api-rs = "4.0.7" 11 | tree-sitter = "0.20" 12 | tree-sitter-javascript = "0.20.0" 13 | tree-sitter-python = "0.20.4" 14 | tree-sitter-rust = "0.20.4" 15 | tree-sitter-sql = { git = "https://github.com/m-novikov/tree-sitter-sql.git", version = "0.0.2" } 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GPTComment 2 | 3 | It scans your source code for a comment beginning with GPTComment: and executes the instruction that comes after it against the current file. 4 | 5 | For example, if you have `schema.sql`: 6 | 7 | ```sql 8 | -- GPTComment: download https://launchbylunch.com/posts/2014/Feb/16/sql-naming-conventions/ and apply conventions 9 | 10 | CREATE TABLE house ( 11 | id SERIAL PRIMARY KEY, 12 | fullName VARCHAR(255) NOT NULL, 13 | address VARCHAR(255) NOT NULL, 14 | city VARCHAR(255) NOT NULL, 15 | state VARCHAR(255) NOT NULL, 16 | zip VARCHAR(255) NOT NULL, 17 | price INTEGER NOT NULL 18 | ); 19 | ``` 20 | 21 | Running `gptcomment schema.sql` will change it to: 22 | 23 | ```sql 24 | CREATE TABLE houses ( 25 | house_id SERIAL PRIMARY KEY, 26 | full_name VARCHAR(255) NOT NULL, 27 | address VARCHAR(255) NOT NULL, 28 | city VARCHAR(255) NOT NULL, 29 | state VARCHAR(255) NOT NULL, 30 | zip_code VARCHAR(255) NOT NULL, 31 | price INTEGER NOT NULL 32 | ); 33 | ``` 34 | 35 | It's meant to be used as a pre-commit hook to enforce code conventions and best practices. -------------------------------------------------------------------------------- /devenv.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "devenv": { 4 | "locked": { 5 | "dir": "src/modules", 6 | "lastModified": 1709711120, 7 | "narHash": "sha256-Xjv4mAX1MJOsmzTKzjxY8UXBd4NeL7OK0T06F4afHd0=", 8 | "owner": "cachix", 9 | "repo": "devenv", 10 | "rev": "acc01d3eac2c858887f44df96c8121b70d3b03cc", 11 | "type": "github" 12 | }, 13 | "original": { 14 | "dir": "src/modules", 15 | "owner": "cachix", 16 | "repo": "devenv", 17 | "type": "github" 18 | } 19 | }, 20 | "flake-compat": { 21 | "flake": false, 22 | "locked": { 23 | "lastModified": 1696426674, 24 | "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", 25 | "owner": "edolstra", 26 | "repo": "flake-compat", 27 | "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", 28 | "type": "github" 29 | }, 30 | "original": { 31 | "owner": "edolstra", 32 | "repo": "flake-compat", 33 | "type": "github" 34 | } 35 | }, 36 | "flake-utils": { 37 | "inputs": { 38 | "systems": "systems" 39 | }, 40 | "locked": { 41 | "lastModified": 1701680307, 42 | "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", 43 | "owner": "numtide", 44 | "repo": "flake-utils", 45 | "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", 46 | "type": "github" 47 | }, 48 | "original": { 49 | "owner": "numtide", 50 | "repo": "flake-utils", 51 | "type": "github" 52 | } 53 | }, 54 | "gitignore": { 55 | "inputs": { 56 | "nixpkgs": [ 57 | "pre-commit-hooks", 58 | "nixpkgs" 59 | ] 60 | }, 61 | "locked": { 62 | "lastModified": 1703887061, 63 | "narHash": "sha256-gGPa9qWNc6eCXT/+Z5/zMkyYOuRZqeFZBDbopNZQkuY=", 64 | "owner": "hercules-ci", 65 | "repo": "gitignore.nix", 66 | "rev": "43e1aa1308018f37118e34d3a9cb4f5e75dc11d5", 67 | "type": "github" 68 | }, 69 | "original": { 70 | "owner": "hercules-ci", 71 | "repo": "gitignore.nix", 72 | "type": "github" 73 | } 74 | }, 75 | "nixpkgs": { 76 | "locked": { 77 | "lastModified": 1709641832, 78 | "narHash": "sha256-bzzRc3DiV8Cm/67HDa39pyBymqF45ISgUbXqjrMk2UE=", 79 | "owner": "NixOS", 80 | "repo": "nixpkgs", 81 | "rev": "bfa8b30043892dc2b660d403faa159bab7b65898", 82 | "type": "github" 83 | }, 84 | "original": { 85 | "owner": "NixOS", 86 | "ref": "nixpkgs-unstable", 87 | "repo": "nixpkgs", 88 | "type": "github" 89 | } 90 | }, 91 | "nixpkgs-stable": { 92 | "locked": { 93 | "lastModified": 1704874635, 94 | "narHash": "sha256-YWuCrtsty5vVZvu+7BchAxmcYzTMfolSPP5io8+WYCg=", 95 | "owner": "NixOS", 96 | "repo": "nixpkgs", 97 | "rev": "3dc440faeee9e889fe2d1b4d25ad0f430d449356", 98 | "type": "github" 99 | }, 100 | "original": { 101 | "owner": "NixOS", 102 | "ref": "nixos-23.11", 103 | "repo": "nixpkgs", 104 | "type": "github" 105 | } 106 | }, 107 | "pre-commit-hooks": { 108 | "inputs": { 109 | "flake-compat": "flake-compat", 110 | "flake-utils": "flake-utils", 111 | "gitignore": "gitignore", 112 | "nixpkgs": [ 113 | "nixpkgs" 114 | ], 115 | "nixpkgs-stable": "nixpkgs-stable" 116 | }, 117 | "locked": { 118 | "lastModified": 1708018599, 119 | "narHash": "sha256-M+Ng6+SePmA8g06CmUZWi1AjG2tFBX9WCXElBHEKnyM=", 120 | "owner": "cachix", 121 | "repo": "pre-commit-hooks.nix", 122 | "rev": "5df5a70ad7575f6601d91f0efec95dd9bc619431", 123 | "type": "github" 124 | }, 125 | "original": { 126 | "owner": "cachix", 127 | "repo": "pre-commit-hooks.nix", 128 | "type": "github" 129 | } 130 | }, 131 | "root": { 132 | "inputs": { 133 | "devenv": "devenv", 134 | "nixpkgs": "nixpkgs", 135 | "pre-commit-hooks": "pre-commit-hooks" 136 | } 137 | }, 138 | "systems": { 139 | "locked": { 140 | "lastModified": 1681028828, 141 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 142 | "owner": "nix-systems", 143 | "repo": "default", 144 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 145 | "type": "github" 146 | }, 147 | "original": { 148 | "owner": "nix-systems", 149 | "repo": "default", 150 | "type": "github" 151 | } 152 | } 153 | }, 154 | "root": "root", 155 | "version": 7 156 | } 157 | -------------------------------------------------------------------------------- /devenv.nix: -------------------------------------------------------------------------------- 1 | { pkgs, ... }: 2 | 3 | { 4 | languages.rust.enable = true; 5 | } -------------------------------------------------------------------------------- /devenv.yaml: -------------------------------------------------------------------------------- 1 | inputs: 2 | nixpkgs: 3 | url: github:NixOS/nixpkgs/nixpkgs-unstable 4 | -------------------------------------------------------------------------------- /schema.sql: -------------------------------------------------------------------------------- 1 | -- GPTComment: download https://launchbylunch.com/posts/2014/Feb/16/sql-naming-conventions/ and apply conventions 2 | 3 | CREATE TABLE house ( 4 | id SERIAL PRIMARY KEY, 5 | fullName VARCHAR(255) NOT NULL, 6 | address VARCHAR(255) NOT NULL, 7 | city VARCHAR(255) NOT NULL, 8 | state VARCHAR(255) NOT NULL, 9 | zip VARCHAR(255) NOT NULL, 10 | price INTEGER NOT NULL 11 | ); 12 | 13 | CREATE TABLE agent ( 14 | id SERIAL PRIMARY KEY, 15 | fullName VARCHAR(255) NOT NULL, 16 | email VARCHAR(255) NOT NULL, 17 | phone VARCHAR(255) NOT NULL 18 | house INTEGER REFERENCES house(id) 19 | ); -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | use clap::{Parser}; 2 | use std::path::PathBuf; 3 | use openai_api_rs::v1::api::Client; 4 | use openai_api_rs::v1::chat_completion::{self, ChatCompletionRequest}; 5 | use openai_api_rs::v1::common::GPT4; 6 | use std::env; 7 | 8 | 9 | #[derive(Parser, Debug)] 10 | #[clap(author, version, about, long_about = None)] 11 | struct Cli { 12 | #[clap(required = true)] 13 | files: Vec, 14 | } 15 | 16 | fn main() { 17 | let cli = Cli::parse(); 18 | 19 | let client = Client::new(env::var("OPENAI_API_KEY").expect("OPENAI_API_KEY not set")); 20 | 21 | for file in cli.files { 22 | if let Some(extension) = file.extension().and_then(|e| e.to_str()) { 23 | let lang = match extension { 24 | "js" => tree_sitter_javascript::language(), 25 | "sql" => tree_sitter_sql::language(), 26 | "rs" => tree_sitter_rust::language(), 27 | "py" => tree_sitter_python::language(), 28 | _ => { 29 | println!("Unsupported file type {}, please contribute it to https://github.com/cachix/gptcomment", file.display()); 30 | continue 31 | } 32 | }; 33 | parse_file(&file, lang, &client); 34 | } else { 35 | println!("File without extension: {}", file.display()); 36 | } 37 | } 38 | } 39 | 40 | fn parse_file(file_path: &PathBuf, language: tree_sitter::Language, client: &Client) { 41 | let mut parser = tree_sitter::Parser::new(); 42 | parser.set_language(language).expect("Error setting language"); 43 | 44 | let code = std::fs::read(file_path).expect("Error reading file"); 45 | 46 | let tree = parser.parse(&code, None).expect("Error parsing file"); 47 | let root_node = tree.root_node(); 48 | 49 | process_node(root_node, &code, client, file_path); 50 | } 51 | 52 | 53 | fn process_node(node: tree_sitter::Node, code: &Vec, client: &Client, file_path: &PathBuf) { 54 | if node.kind().contains("comment") { 55 | let content = node.utf8_text(code).unwrap(); 56 | 57 | if content.contains("GPTComment:") { 58 | let instruction = content.split("GPTComment:").collect::>()[1]; 59 | println!("Processing '{}' in {}", instruction, file_path.display()); 60 | let msg = format!("If there are changes needed, respond only with the code snippet, no other text. If there are no changes needed, respond with OK.\n\n Apply {} to this file: {}", instruction, code.iter().map(|&c| c as char).collect::()); 61 | let req = ChatCompletionRequest::new( 62 | GPT4.to_string(), 63 | vec![chat_completion::ChatCompletionMessage { 64 | role: chat_completion::MessageRole::user, 65 | content: chat_completion::Content::Text(msg), 66 | name: None, 67 | }], 68 | ); 69 | let result = client.chat_completion(req).unwrap(); 70 | let snippet = result.choices[0].message.content.as_ref().unwrap(); 71 | if snippet != "OK" { 72 | println!("Updating file {}", file_path.display()); 73 | std::fs::write(file_path, snippet).expect("Error writing file"); 74 | } 75 | } 76 | } 77 | for child in node.children(&mut node.walk()) { 78 | process_node(child, code, client, file_path); 79 | } 80 | } 81 | --------------------------------------------------------------------------------