diff --git a/.github/workflows/publish-docker.yml b/.github/workflows/publish-docker.yml new file mode 100644 index 00000000000..d13ace7bd6f --- /dev/null +++ b/.github/workflows/publish-docker.yml @@ -0,0 +1,62 @@ +name: publish-docker + +on: + workflow_dispatch: + inputs: + version: + description: "Version tag (e.g., v1.0.0)" + required: true + type: string + push: + tags: + - 'v*' + +permissions: + contents: read + packages: write + +jobs: + build-and-push: + runs-on: ubuntu-latest + strategy: + matrix: + image: + - name: opencode-functions + dockerfile: Dockerfile.functions-selfhost + - name: opencode-web + dockerfile: Dockerfile.web + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ghcr.io/${{ github.repository_owner }}/${{ matrix.image.name }} + tags: | + type=ref,event=tag + type=raw,value=${{ github.event.inputs.version || github.ref_name }} + + - name: Build and push + uses: docker/build-push-action@v5 + with: + context: . + file: ./docker/${{ matrix.image.dockerfile }} + platforms: linux/amd64,linux/arm64 + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max \ No newline at end of file diff --git a/.gitignore b/.gitignore index f69a7079669..3b5af85b9b4 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ dist .turbo **/.serena .serena/ +data/ diff --git a/STATS.md b/STATS.md index 56d6d39fdc9..5926e73e84a 100644 --- a/STATS.md +++ b/STATS.md @@ -1,134 +1,187 @@ # Download Stats -| Date | GitHub Downloads | npm Downloads | Total | -| ---------- | ----------------- | ----------------- | ------------------- | -| 2025-06-29 | 18,789 (+0) | 39,420 (+0) | 58,209 (+0) | -| 2025-06-30 | 20,127 (+1,338) | 41,059 (+1,639) | 61,186 (+2,977) | -| 2025-07-01 | 22,108 (+1,981) | 43,745 (+2,686) | 65,853 (+4,667) | -| 2025-07-02 | 24,814 (+2,706) | 46,168 (+2,423) | 70,982 (+5,129) | -| 2025-07-03 | 27,834 (+3,020) | 49,955 (+3,787) | 77,789 (+6,807) | -| 2025-07-04 | 30,608 (+2,774) | 54,758 (+4,803) | 85,366 (+7,577) | -| 2025-07-05 | 32,524 (+1,916) | 58,371 (+3,613) | 90,895 (+5,529) | -| 2025-07-06 | 33,766 (+1,242) | 59,694 (+1,323) | 93,460 (+2,565) | -| 2025-07-08 | 38,052 (+4,286) | 64,468 (+4,774) | 102,520 (+9,060) | -| 2025-07-09 | 40,924 (+2,872) | 67,935 (+3,467) | 108,859 (+6,339) | -| 2025-07-10 | 43,796 (+2,872) | 71,402 (+3,467) | 115,198 (+6,339) | -| 2025-07-11 | 46,982 (+3,186) | 77,462 (+6,060) | 124,444 (+9,246) | -| 2025-07-12 | 49,302 (+2,320) | 82,177 (+4,715) | 131,479 (+7,035) | -| 2025-07-13 | 50,803 (+1,501) | 86,394 (+4,217) | 137,197 (+5,718) | -| 2025-07-14 | 53,283 (+2,480) | 87,860 (+1,466) | 141,143 (+3,946) | -| 2025-07-15 | 57,590 (+4,307) | 91,036 (+3,176) | 148,626 (+7,483) | -| 2025-07-16 | 62,313 (+4,723) | 95,258 (+4,222) | 157,571 (+8,945) | -| 2025-07-17 | 66,684 (+4,371) | 100,048 (+4,790) | 166,732 (+9,161) | -| 2025-07-18 | 70,379 (+3,695) | 102,587 (+2,539) | 172,966 (+6,234) | -| 2025-07-19 | 73,497 (+3,117) | 105,904 (+3,317) | 179,401 (+6,434) | -| 2025-07-20 | 76,453 (+2,956) | 109,044 (+3,140) | 185,497 (+6,096) | -| 2025-07-21 | 80,197 (+3,744) | 113,537 (+4,493) | 193,734 (+8,237) | -| 2025-07-22 | 84,251 (+4,054) | 118,073 (+4,536) | 202,324 (+8,590) | -| 2025-07-23 | 88,589 (+4,338) | 121,436 (+3,363) | 210,025 (+7,701) | -| 2025-07-24 | 92,469 (+3,880) | 124,091 (+2,655) | 216,560 (+6,535) | -| 2025-07-25 | 96,417 (+3,948) | 126,985 (+2,894) | 223,402 (+6,842) | -| 2025-07-26 | 100,646 (+4,229) | 131,411 (+4,426) | 232,057 (+8,655) | -| 2025-07-27 | 102,644 (+1,998) | 134,736 (+3,325) | 237,380 (+5,323) | -| 2025-07-28 | 105,446 (+2,802) | 136,016 (+1,280) | 241,462 (+4,082) | -| 2025-07-29 | 108,998 (+3,552) | 137,542 (+1,526) | 246,540 (+5,078) | -| 2025-07-30 | 113,544 (+4,546) | 140,317 (+2,775) | 253,861 (+7,321) | -| 2025-07-31 | 118,339 (+4,795) | 143,344 (+3,027) | 261,683 (+7,822) | -| 2025-08-01 | 123,539 (+5,200) | 146,680 (+3,336) | 270,219 (+8,536) | -| 2025-08-02 | 127,864 (+4,325) | 149,236 (+2,556) | 277,100 (+6,881) | -| 2025-08-03 | 131,397 (+3,533) | 150,451 (+1,215) | 281,848 (+4,748) | -| 2025-08-04 | 136,266 (+4,869) | 153,260 (+2,809) | 289,526 (+7,678) | -| 2025-08-05 | 141,596 (+5,330) | 155,752 (+2,492) | 297,348 (+7,822) | -| 2025-08-06 | 147,067 (+5,471) | 158,309 (+2,557) | 305,376 (+8,028) | -| 2025-08-07 | 152,591 (+5,524) | 160,889 (+2,580) | 313,480 (+8,104) | -| 2025-08-08 | 158,187 (+5,596) | 163,448 (+2,559) | 321,635 (+8,155) | -| 2025-08-09 | 162,770 (+4,583) | 165,721 (+2,273) | 328,491 (+6,856) | -| 2025-08-10 | 165,695 (+2,925) | 167,109 (+1,388) | 332,804 (+4,313) | -| 2025-08-11 | 169,297 (+3,602) | 167,953 (+844) | 337,250 (+4,446) | -| 2025-08-12 | 176,307 (+7,010) | 171,876 (+3,923) | 348,183 (+10,933) | -| 2025-08-13 | 182,997 (+6,690) | 177,182 (+5,306) | 360,179 (+11,996) | -| 2025-08-14 | 189,063 (+6,066) | 179,741 (+2,559) | 368,804 (+8,625) | -| 2025-08-15 | 193,608 (+4,545) | 181,792 (+2,051) | 375,400 (+6,596) | -| 2025-08-16 | 198,118 (+4,510) | 184,558 (+2,766) | 382,676 (+7,276) | -| 2025-08-17 | 201,299 (+3,181) | 186,269 (+1,711) | 387,568 (+4,892) | -| 2025-08-18 | 204,559 (+3,260) | 187,399 (+1,130) | 391,958 (+4,390) | -| 2025-08-19 | 209,814 (+5,255) | 189,668 (+2,269) | 399,482 (+7,524) | -| 2025-08-20 | 214,497 (+4,683) | 191,481 (+1,813) | 405,978 (+6,496) | -| 2025-08-21 | 220,465 (+5,968) | 194,784 (+3,303) | 415,249 (+9,271) | -| 2025-08-22 | 225,899 (+5,434) | 197,204 (+2,420) | 423,103 (+7,854) | -| 2025-08-23 | 229,005 (+3,106) | 199,238 (+2,034) | 428,243 (+5,140) | -| 2025-08-24 | 232,098 (+3,093) | 201,157 (+1,919) | 433,255 (+5,012) | -| 2025-08-25 | 236,607 (+4,509) | 202,650 (+1,493) | 439,257 (+6,002) | -| 2025-08-26 | 242,783 (+6,176) | 205,242 (+2,592) | 448,025 (+8,768) | -| 2025-08-27 | 248,409 (+5,626) | 205,242 (+0) | 453,651 (+5,626) | -| 2025-08-28 | 252,796 (+4,387) | 205,242 (+0) | 458,038 (+4,387) | -| 2025-08-29 | 256,045 (+3,249) | 211,075 (+5,833) | 467,120 (+9,082) | -| 2025-08-30 | 258,863 (+2,818) | 212,397 (+1,322) | 471,260 (+4,140) | -| 2025-08-31 | 262,004 (+3,141) | 213,944 (+1,547) | 475,948 (+4,688) | -| 2025-09-01 | 265,359 (+3,355) | 215,115 (+1,171) | 480,474 (+4,526) | -| 2025-09-02 | 270,483 (+5,124) | 217,075 (+1,960) | 487,558 (+7,084) | -| 2025-09-03 | 274,793 (+4,310) | 219,755 (+2,680) | 494,548 (+6,990) | -| 2025-09-04 | 280,430 (+5,637) | 222,103 (+2,348) | 502,533 (+7,985) | -| 2025-09-05 | 283,769 (+3,339) | 223,793 (+1,690) | 507,562 (+5,029) | -| 2025-09-06 | 286,245 (+2,476) | 225,036 (+1,243) | 511,281 (+3,719) | -| 2025-09-07 | 288,623 (+2,378) | 225,866 (+830) | 514,489 (+3,208) | -| 2025-09-08 | 293,341 (+4,718) | 227,073 (+1,207) | 520,414 (+5,925) | -| 2025-09-09 | 300,036 (+6,695) | 229,788 (+2,715) | 529,824 (+9,410) | -| 2025-09-10 | 307,287 (+7,251) | 233,435 (+3,647) | 540,722 (+10,898) | -| 2025-09-11 | 314,083 (+6,796) | 237,356 (+3,921) | 551,439 (+10,717) | -| 2025-09-12 | 321,046 (+6,963) | 240,728 (+3,372) | 561,774 (+10,335) | -| 2025-09-13 | 324,894 (+3,848) | 245,539 (+4,811) | 570,433 (+8,659) | -| 2025-09-14 | 328,876 (+3,982) | 248,245 (+2,706) | 577,121 (+6,688) | -| 2025-09-15 | 334,201 (+5,325) | 250,983 (+2,738) | 585,184 (+8,063) | -| 2025-09-16 | 342,609 (+8,408) | 255,264 (+4,281) | 597,873 (+12,689) | -| 2025-09-17 | 351,117 (+8,508) | 260,970 (+5,706) | 612,087 (+14,214) | -| 2025-09-18 | 358,717 (+7,600) | 266,922 (+5,952) | 625,639 (+13,552) | -| 2025-09-19 | 365,401 (+6,684) | 271,859 (+4,937) | 637,260 (+11,621) | -| 2025-09-20 | 372,092 (+6,691) | 276,917 (+5,058) | 649,009 (+11,749) | -| 2025-09-21 | 377,079 (+4,987) | 280,261 (+3,344) | 657,340 (+8,331) | -| 2025-09-22 | 382,492 (+5,413) | 284,009 (+3,748) | 666,501 (+9,161) | -| 2025-09-23 | 387,008 (+4,516) | 289,129 (+5,120) | 676,137 (+9,636) | -| 2025-09-24 | 393,325 (+6,317) | 294,927 (+5,798) | 688,252 (+12,115) | -| 2025-09-25 | 398,879 (+5,554) | 301,663 (+6,736) | 700,542 (+12,290) | -| 2025-09-26 | 404,334 (+5,455) | 306,713 (+5,050) | 711,047 (+10,505) | -| 2025-09-27 | 411,618 (+7,284) | 317,763 (+11,050) | 729,381 (+18,334) | -| 2025-09-28 | 414,910 (+3,292) | 322,522 (+4,759) | 737,432 (+8,051) | -| 2025-09-29 | 419,919 (+5,009) | 328,033 (+5,511) | 747,952 (+10,520) | -| 2025-09-30 | 427,991 (+8,072) | 336,472 (+8,439) | 764,463 (+16,511) | -| 2025-10-01 | 433,591 (+5,600) | 341,742 (+5,270) | 775,333 (+10,870) | -| 2025-10-02 | 440,852 (+7,261) | 348,099 (+6,357) | 788,951 (+13,618) | -| 2025-10-03 | 446,829 (+5,977) | 359,937 (+11,838) | 806,766 (+17,815) | -| 2025-10-04 | 452,561 (+5,732) | 370,386 (+10,449) | 822,947 (+16,181) | -| 2025-10-05 | 455,559 (+2,998) | 374,745 (+4,359) | 830,304 (+7,357) | -| 2025-10-06 | 460,927 (+5,368) | 379,489 (+4,744) | 840,416 (+10,112) | -| 2025-10-07 | 467,336 (+6,409) | 385,438 (+5,949) | 852,774 (+12,358) | -| 2025-10-08 | 474,643 (+7,307) | 394,139 (+8,701) | 868,782 (+16,008) | -| 2025-10-09 | 479,203 (+4,560) | 400,526 (+6,387) | 879,729 (+10,947) | -| 2025-10-10 | 484,374 (+5,171) | 406,015 (+5,489) | 890,389 (+10,660) | -| 2025-10-11 | 488,427 (+4,053) | 414,699 (+8,684) | 903,126 (+12,737) | -| 2025-10-12 | 492,125 (+3,698) | 418,745 (+4,046) | 910,870 (+7,744) | -| 2025-10-14 | 505,130 (+13,005) | 429,286 (+10,541) | 934,416 (+23,546) | -| 2025-10-15 | 512,717 (+7,587) | 439,290 (+10,004) | 952,007 (+17,591) | -| 2025-10-16 | 517,719 (+5,002) | 447,137 (+7,847) | 964,856 (+12,849) | -| 2025-10-17 | 526,239 (+8,520) | 457,467 (+10,330) | 983,706 (+18,850) | -| 2025-10-18 | 531,564 (+5,325) | 465,272 (+7,805) | 996,836 (+13,130) | -| 2025-10-19 | 536,209 (+4,645) | 469,078 (+3,806) | 1,005,287 (+8,451) | -| 2025-10-20 | 541,264 (+5,055) | 472,952 (+3,874) | 1,014,216 (+8,929) | -| 2025-10-21 | 548,721 (+7,457) | 479,703 (+6,751) | 1,028,424 (+14,208) | -| 2025-10-22 | 557,949 (+9,228) | 491,395 (+11,692) | 1,049,344 (+20,920) | -| 2025-10-23 | 564,716 (+6,767) | 498,736 (+7,341) | 1,063,452 (+14,108) | -| 2025-10-24 | 572,692 (+7,976) | 506,905 (+8,169) | 1,079,597 (+16,145) | -| 2025-10-25 | 578,927 (+6,235) | 516,129 (+9,224) | 1,095,056 (+15,459) | -| 2025-10-26 | 584,409 (+5,482) | 521,179 (+5,050) | 1,105,588 (+10,532) | -| 2025-10-27 | 589,999 (+5,590) | 526,001 (+4,822) | 1,116,000 (+10,412) | -| 2025-10-28 | 595,776 (+5,777) | 532,438 (+6,437) | 1,128,214 (+12,214) | -| 2025-10-29 | 606,259 (+10,483) | 542,064 (+9,626) | 1,148,323 (+20,109) | -| 2025-10-30 | 613,746 (+7,487) | 542,064 (+0) | 1,155,810 (+7,487) | -| 2025-10-30 | 617,846 (+4,100) | 555,026 (+12,962) | 1,172,872 (+17,062) | -| 2025-10-31 | 626,612 (+8,766) | 564,579 (+9,553) | 1,191,191 (+18,319) | -| 2025-11-01 | 636,100 (+9,488) | 581,806 (+17,227) | 1,217,906 (+26,715) | -| 2025-11-02 | 644,067 (+7,967) | 590,004 (+8,198) | 1,234,071 (+16,165) | -| 2025-11-03 | 653,130 (+9,063) | 597,139 (+7,135) | 1,250,269 (+16,198) | -| 2025-11-04 | 663,912 (+10,782) | 608,056 (+10,917) | 1,271,968 (+21,699) | -| 2025-11-05 | 675,074 (+11,162) | 619,690 (+11,634) | 1,294,764 (+22,796) | -| 2025-11-06 | 686,252 (+11,178) | 630,885 (+11,195) | 1,317,137 (+22,373) | +| Date | GitHub Downloads | npm Downloads | Total | +| ---------- | ------------------- | ------------------- | ------------------- | +| 2025-06-29 | 18,789 (+0) | 39,420 (+0) | 58,209 (+0) | +| 2025-06-30 | 20,127 (+1,338) | 41,059 (+1,639) | 61,186 (+2,977) | +| 2025-07-01 | 22,108 (+1,981) | 43,745 (+2,686) | 65,853 (+4,667) | +| 2025-07-02 | 24,814 (+2,706) | 46,168 (+2,423) | 70,982 (+5,129) | +| 2025-07-03 | 27,834 (+3,020) | 49,955 (+3,787) | 77,789 (+6,807) | +| 2025-07-04 | 30,608 (+2,774) | 54,758 (+4,803) | 85,366 (+7,577) | +| 2025-07-05 | 32,524 (+1,916) | 58,371 (+3,613) | 90,895 (+5,529) | +| 2025-07-06 | 33,766 (+1,242) | 59,694 (+1,323) | 93,460 (+2,565) | +| 2025-07-08 | 38,052 (+4,286) | 64,468 (+4,774) | 102,520 (+9,060) | +| 2025-07-09 | 40,924 (+2,872) | 67,935 (+3,467) | 108,859 (+6,339) | +| 2025-07-10 | 43,796 (+2,872) | 71,402 (+3,467) | 115,198 (+6,339) | +| 2025-07-11 | 46,982 (+3,186) | 77,462 (+6,060) | 124,444 (+9,246) | +| 2025-07-12 | 49,302 (+2,320) | 82,177 (+4,715) | 131,479 (+7,035) | +| 2025-07-13 | 50,803 (+1,501) | 86,394 (+4,217) | 137,197 (+5,718) | +| 2025-07-14 | 53,283 (+2,480) | 87,860 (+1,466) | 141,143 (+3,946) | +| 2025-07-15 | 57,590 (+4,307) | 91,036 (+3,176) | 148,626 (+7,483) | +| 2025-07-16 | 62,313 (+4,723) | 95,258 (+4,222) | 157,571 (+8,945) | +| 2025-07-17 | 66,684 (+4,371) | 100,048 (+4,790) | 166,732 (+9,161) | +| 2025-07-18 | 70,379 (+3,695) | 102,587 (+2,539) | 172,966 (+6,234) | +| 2025-07-19 | 73,497 (+3,117) | 105,904 (+3,317) | 179,401 (+6,434) | +| 2025-07-20 | 76,453 (+2,956) | 109,044 (+3,140) | 185,497 (+6,096) | +| 2025-07-21 | 80,197 (+3,744) | 113,537 (+4,493) | 193,734 (+8,237) | +| 2025-07-22 | 84,251 (+4,054) | 118,073 (+4,536) | 202,324 (+8,590) | +| 2025-07-23 | 88,589 (+4,338) | 121,436 (+3,363) | 210,025 (+7,701) | +| 2025-07-24 | 92,469 (+3,880) | 124,091 (+2,655) | 216,560 (+6,535) | +| 2025-07-25 | 96,417 (+3,948) | 126,985 (+2,894) | 223,402 (+6,842) | +| 2025-07-26 | 100,646 (+4,229) | 131,411 (+4,426) | 232,057 (+8,655) | +| 2025-07-27 | 102,644 (+1,998) | 134,736 (+3,325) | 237,380 (+5,323) | +| 2025-07-28 | 105,446 (+2,802) | 136,016 (+1,280) | 241,462 (+4,082) | +| 2025-07-29 | 108,998 (+3,552) | 137,542 (+1,526) | 246,540 (+5,078) | +| 2025-07-30 | 113,544 (+4,546) | 140,317 (+2,775) | 253,861 (+7,321) | +| 2025-07-31 | 118,339 (+4,795) | 143,344 (+3,027) | 261,683 (+7,822) | +| 2025-08-01 | 123,539 (+5,200) | 146,680 (+3,336) | 270,219 (+8,536) | +| 2025-08-02 | 127,864 (+4,325) | 149,236 (+2,556) | 277,100 (+6,881) | +| 2025-08-03 | 131,397 (+3,533) | 150,451 (+1,215) | 281,848 (+4,748) | +| 2025-08-04 | 136,266 (+4,869) | 153,260 (+2,809) | 289,526 (+7,678) | +| 2025-08-05 | 141,596 (+5,330) | 155,752 (+2,492) | 297,348 (+7,822) | +| 2025-08-06 | 147,067 (+5,471) | 158,309 (+2,557) | 305,376 (+8,028) | +| 2025-08-07 | 152,591 (+5,524) | 160,889 (+2,580) | 313,480 (+8,104) | +| 2025-08-08 | 158,187 (+5,596) | 163,448 (+2,559) | 321,635 (+8,155) | +| 2025-08-09 | 162,770 (+4,583) | 165,721 (+2,273) | 328,491 (+6,856) | +| 2025-08-10 | 165,695 (+2,925) | 167,109 (+1,388) | 332,804 (+4,313) | +| 2025-08-11 | 169,297 (+3,602) | 167,953 (+844) | 337,250 (+4,446) | +| 2025-08-12 | 176,307 (+7,010) | 171,876 (+3,923) | 348,183 (+10,933) | +| 2025-08-13 | 182,997 (+6,690) | 177,182 (+5,306) | 360,179 (+11,996) | +| 2025-08-14 | 189,063 (+6,066) | 179,741 (+2,559) | 368,804 (+8,625) | +| 2025-08-15 | 193,608 (+4,545) | 181,792 (+2,051) | 375,400 (+6,596) | +| 2025-08-16 | 198,118 (+4,510) | 184,558 (+2,766) | 382,676 (+7,276) | +| 2025-08-17 | 201,299 (+3,181) | 186,269 (+1,711) | 387,568 (+4,892) | +| 2025-08-18 | 204,559 (+3,260) | 187,399 (+1,130) | 391,958 (+4,390) | +| 2025-08-19 | 209,814 (+5,255) | 189,668 (+2,269) | 399,482 (+7,524) | +| 2025-08-20 | 214,497 (+4,683) | 191,481 (+1,813) | 405,978 (+6,496) | +| 2025-08-21 | 220,465 (+5,968) | 194,784 (+3,303) | 415,249 (+9,271) | +| 2025-08-22 | 225,899 (+5,434) | 197,204 (+2,420) | 423,103 (+7,854) | +| 2025-08-23 | 229,005 (+3,106) | 199,238 (+2,034) | 428,243 (+5,140) | +| 2025-08-24 | 232,098 (+3,093) | 201,157 (+1,919) | 433,255 (+5,012) | +| 2025-08-25 | 236,607 (+4,509) | 202,650 (+1,493) | 439,257 (+6,002) | +| 2025-08-26 | 242,783 (+6,176) | 205,242 (+2,592) | 448,025 (+8,768) | +| 2025-08-27 | 248,409 (+5,626) | 205,242 (+0) | 453,651 (+5,626) | +| 2025-08-28 | 252,796 (+4,387) | 205,242 (+0) | 458,038 (+4,387) | +| 2025-08-29 | 256,045 (+3,249) | 211,075 (+5,833) | 467,120 (+9,082) | +| 2025-08-30 | 258,863 (+2,818) | 212,397 (+1,322) | 471,260 (+4,140) | +| 2025-08-31 | 262,004 (+3,141) | 213,944 (+1,547) | 475,948 (+4,688) | +| 2025-09-01 | 265,359 (+3,355) | 215,115 (+1,171) | 480,474 (+4,526) | +| 2025-09-02 | 270,483 (+5,124) | 217,075 (+1,960) | 487,558 (+7,084) | +| 2025-09-03 | 274,793 (+4,310) | 219,755 (+2,680) | 494,548 (+6,990) | +| 2025-09-04 | 280,430 (+5,637) | 222,103 (+2,348) | 502,533 (+7,985) | +| 2025-09-05 | 283,769 (+3,339) | 223,793 (+1,690) | 507,562 (+5,029) | +| 2025-09-06 | 286,245 (+2,476) | 225,036 (+1,243) | 511,281 (+3,719) | +| 2025-09-07 | 288,623 (+2,378) | 225,866 (+830) | 514,489 (+3,208) | +| 2025-09-08 | 293,341 (+4,718) | 227,073 (+1,207) | 520,414 (+5,925) | +| 2025-09-09 | 300,036 (+6,695) | 229,788 (+2,715) | 529,824 (+9,410) | +| 2025-09-10 | 307,287 (+7,251) | 233,435 (+3,647) | 540,722 (+10,898) | +| 2025-09-11 | 314,083 (+6,796) | 237,356 (+3,921) | 551,439 (+10,717) | +| 2025-09-12 | 321,046 (+6,963) | 240,728 (+3,372) | 561,774 (+10,335) | +| 2025-09-13 | 324,894 (+3,848) | 245,539 (+4,811) | 570,433 (+8,659) | +| 2025-09-14 | 328,876 (+3,982) | 248,245 (+2,706) | 577,121 (+6,688) | +| 2025-09-15 | 334,201 (+5,325) | 250,983 (+2,738) | 585,184 (+8,063) | +| 2025-09-16 | 342,609 (+8,408) | 255,264 (+4,281) | 597,873 (+12,689) | +| 2025-09-17 | 351,117 (+8,508) | 260,970 (+5,706) | 612,087 (+14,214) | +| 2025-09-18 | 358,717 (+7,600) | 266,922 (+5,952) | 625,639 (+13,552) | +| 2025-09-19 | 365,401 (+6,684) | 271,859 (+4,937) | 637,260 (+11,621) | +| 2025-09-20 | 372,092 (+6,691) | 276,917 (+5,058) | 649,009 (+11,749) | +| 2025-09-21 | 377,079 (+4,987) | 280,261 (+3,344) | 657,340 (+8,331) | +| 2025-09-22 | 382,492 (+5,413) | 284,009 (+3,748) | 666,501 (+9,161) | +| 2025-09-23 | 387,008 (+4,516) | 289,129 (+5,120) | 676,137 (+9,636) | +| 2025-09-24 | 393,325 (+6,317) | 294,927 (+5,798) | 688,252 (+12,115) | +| 2025-09-25 | 398,879 (+5,554) | 301,663 (+6,736) | 700,542 (+12,290) | +| 2025-09-26 | 404,334 (+5,455) | 306,713 (+5,050) | 711,047 (+10,505) | +| 2025-09-27 | 411,618 (+7,284) | 317,763 (+11,050) | 729,381 (+18,334) | +| 2025-09-28 | 414,910 (+3,292) | 322,522 (+4,759) | 737,432 (+8,051) | +| 2025-09-29 | 419,919 (+5,009) | 328,033 (+5,511) | 747,952 (+10,520) | +| 2025-09-30 | 427,991 (+8,072) | 336,472 (+8,439) | 764,463 (+16,511) | +| 2025-10-01 | 433,591 (+5,600) | 341,742 (+5,270) | 775,333 (+10,870) | +| 2025-10-02 | 440,852 (+7,261) | 348,099 (+6,357) | 788,951 (+13,618) | +| 2025-10-03 | 446,829 (+5,977) | 359,937 (+11,838) | 806,766 (+17,815) | +| 2025-10-04 | 452,561 (+5,732) | 370,386 (+10,449) | 822,947 (+16,181) | +| 2025-10-05 | 455,559 (+2,998) | 374,745 (+4,359) | 830,304 (+7,357) | +| 2025-10-06 | 460,927 (+5,368) | 379,489 (+4,744) | 840,416 (+10,112) | +| 2025-10-07 | 467,336 (+6,409) | 385,438 (+5,949) | 852,774 (+12,358) | +| 2025-10-08 | 474,643 (+7,307) | 394,139 (+8,701) | 868,782 (+16,008) | +| 2025-10-09 | 479,203 (+4,560) | 400,526 (+6,387) | 879,729 (+10,947) | +| 2025-10-10 | 484,374 (+5,171) | 406,015 (+5,489) | 890,389 (+10,660) | +| 2025-10-11 | 488,427 (+4,053) | 414,699 (+8,684) | 903,126 (+12,737) | +| 2025-10-12 | 492,125 (+3,698) | 418,745 (+4,046) | 910,870 (+7,744) | +| 2025-10-14 | 505,130 (+13,005) | 429,286 (+10,541) | 934,416 (+23,546) | +| 2025-10-15 | 512,717 (+7,587) | 439,290 (+10,004) | 952,007 (+17,591) | +| 2025-10-16 | 517,719 (+5,002) | 447,137 (+7,847) | 964,856 (+12,849) | +| 2025-10-17 | 526,239 (+8,520) | 457,467 (+10,330) | 983,706 (+18,850) | +| 2025-10-18 | 531,564 (+5,325) | 465,272 (+7,805) | 996,836 (+13,130) | +| 2025-10-19 | 536,209 (+4,645) | 469,078 (+3,806) | 1,005,287 (+8,451) | +| 2025-10-20 | 541,264 (+5,055) | 472,952 (+3,874) | 1,014,216 (+8,929) | +| 2025-10-21 | 548,721 (+7,457) | 479,703 (+6,751) | 1,028,424 (+14,208) | +| 2025-10-22 | 557,949 (+9,228) | 491,395 (+11,692) | 1,049,344 (+20,920) | +| 2025-10-23 | 564,716 (+6,767) | 498,736 (+7,341) | 1,063,452 (+14,108) | +| 2025-10-24 | 572,692 (+7,976) | 506,905 (+8,169) | 1,079,597 (+16,145) | +| 2025-10-25 | 578,927 (+6,235) | 516,129 (+9,224) | 1,095,056 (+15,459) | +| 2025-10-26 | 584,409 (+5,482) | 521,179 (+5,050) | 1,105,588 (+10,532) | +| 2025-10-27 | 589,999 (+5,590) | 526,001 (+4,822) | 1,116,000 (+10,412) | +| 2025-10-28 | 595,776 (+5,777) | 532,438 (+6,437) | 1,128,214 (+12,214) | +| 2025-10-29 | 606,259 (+10,483) | 542,064 (+9,626) | 1,148,323 (+20,109) | +| 2025-10-30 | 613,746 (+7,487) | 542,064 (+0) | 1,155,810 (+7,487) | +| 2025-10-30 | 617,846 (+4,100) | 555,026 (+12,962) | 1,172,872 (+17,062) | +| 2025-10-31 | 626,612 (+8,766) | 564,579 (+9,553) | 1,191,191 (+18,319) | +| 2025-11-01 | 636,100 (+9,488) | 581,806 (+17,227) | 1,217,906 (+26,715) | +| 2025-11-02 | 644,067 (+7,967) | 590,004 (+8,198) | 1,234,071 (+16,165) | +| 2025-11-03 | 653,130 (+9,063) | 597,139 (+7,135) | 1,250,269 (+16,198) | +| 2025-11-04 | 663,912 (+10,782) | 608,056 (+10,917) | 1,271,968 (+21,699) | +| 2025-11-05 | 675,074 (+11,162) | 619,690 (+11,634) | 1,294,764 (+22,796) | +| 2025-11-06 | 686,252 (+11,178) | 630,885 (+11,195) | 1,317,137 (+22,373) | +| 2025-11-07 | 696,648 (+10,396) | 642,146 (+11,261) | 1,338,794 (+21,657) | +| 2025-11-08 | 706,036 (+9,388) | 653,489 (+11,343) | 1,359,525 (+20,731) | +| 2025-11-09 | 713,467 (+7,431) | 660,459 (+6,970) | 1,373,926 (+14,401) | +| 2025-11-10 | 722,288 (+8,821) | 668,225 (+7,766) | 1,390,513 (+16,587) | +| 2025-11-11 | 729,771 (+7,483) | 677,501 (+9,276) | 1,407,272 (+16,759) | +| 2025-11-12 | 740,185 (+10,414) | 686,454 (+8,953) | 1,426,639 (+19,367) | +| 2025-11-13 | 749,905 (+9,720) | 696,157 (+9,703) | 1,446,062 (+19,423) | +| 2025-11-14 | 759,931 (+10,026) | 705,237 (+9,080) | 1,465,168 (+19,106) | +| 2025-11-15 | 765,958 (+6,027) | 712,870 (+7,633) | 1,478,828 (+13,660) | +| 2025-11-16 | 771,073 (+5,115) | 716,596 (+3,726) | 1,487,669 (+8,841) | +| 2025-11-17 | 780,163 (+9,090) | 723,339 (+6,743) | 1,503,502 (+15,833) | +| 2025-11-18 | 791,567 (+11,404) | 732,544 (+9,205) | 1,524,111 (+20,609) | +| 2025-11-19 | 804,415 (+12,848) | 747,624 (+15,080) | 1,552,039 (+27,928) | +| 2025-11-20 | 814,621 (+10,206) | 757,907 (+10,283) | 1,572,528 (+20,489) | +| 2025-11-21 | 826,309 (+11,688) | 769,307 (+11,400) | 1,595,616 (+23,088) | +| 2025-11-22 | 837,270 (+10,961) | 780,996 (+11,689) | 1,618,266 (+22,650) | +| 2025-11-23 | 846,613 (+9,343) | 795,069 (+14,073) | 1,641,682 (+23,416) | +| 2025-11-24 | 856,739 (+10,126) | 804,033 (+8,964) | 1,660,772 (+19,090) | +| 2025-11-25 | 869,424 (+12,685) | 817,339 (+13,306) | 1,686,763 (+25,991) | +| 2025-11-26 | 881,417 (+11,993) | 832,518 (+15,179) | 1,713,935 (+27,172) | +| 2025-11-27 | 893,964 (+12,547) | 846,180 (+13,662) | 1,740,144 (+26,209) | +| 2025-11-28 | 901,741 (+7,777) | 856,482 (+10,302) | 1,758,223 (+18,079) | +| 2025-11-29 | 908,692 (+6,951) | 863,361 (+6,879) | 1,772,053 (+13,830) | +| 2025-11-30 | 916,402 (+7,710) | 870,194 (+6,833) | 1,786,596 (+14,543) | +| 2025-12-01 | 925,897 (+9,495) | 876,500 (+6,306) | 1,802,397 (+15,801) | +| 2025-12-02 | 939,252 (+13,355) | 890,919 (+14,419) | 1,830,171 (+27,774) | +| 2025-12-03 | 952,253 (+13,001) | 903,713 (+12,794) | 1,855,966 (+25,795) | +| 2025-12-04 | 965,617 (+13,364) | 916,471 (+12,758) | 1,882,088 (+26,122) | +| 2025-12-05 | 977,998 (+12,381) | 930,616 (+14,145) | 1,908,614 (+26,526) | +| 2025-12-06 | 987,886 (+9,888) | 943,773 (+13,157) | 1,931,659 (+23,045) | +| 2025-12-07 | 994,047 (+6,161) | 951,425 (+7,652) | 1,945,472 (+13,813) | +| 2025-12-08 | 1,000,901 (+6,854) | 957,149 (+5,724) | 1,958,050 (+12,578) | +| 2025-12-09 | 1,011,497 (+10,596) | 973,922 (+16,773) | 1,985,419 (+27,369) | +| 2025-12-10 | 1,025,893 (+14,396) | 991,708 (+17,786) | 2,017,601 (+32,182) | +| 2025-12-11 | 1,045,116 (+19,223) | 1,010,559 (+18,851) | 2,055,675 (+38,074) | +| 2025-12-12 | 1,061,342 (+16,226) | 1,030,838 (+20,279) | 2,092,180 (+36,505) | +| 2025-12-13 | 1,073,572 (+12,230) | 1,044,608 (+13,770) | 2,118,180 (+26,000) | +| 2025-12-14 | 1,082,048 (+8,476) | 1,052,425 (+7,817) | 2,134,473 (+16,293) | +| 2025-12-15 | 1,093,635 (+11,587) | 1,059,078 (+6,653) | 2,152,713 (+18,240) | +| 2025-12-16 | 1,120,479 (+26,844) | 1,078,022 (+18,944) | 2,198,501 (+45,788) | +| 2025-12-17 | 1,151,074 (+30,595) | 1,097,661 (+19,639) | 2,248,735 (+50,234) | +| 2025-12-18 | 1,178,445 (+27,371) | 1,113,418 (+15,757) | 2,291,863 (+43,128) | +| 2025-12-19 | 1,203,487 (+25,042) | 1,129,698 (+16,280) | 2,333,185 (+41,322) | +| 2025-12-20 | 1,223,009 (+19,522) | 1,146,258 (+16,560) | 2,369,267 (+36,082) | +| 2025-12-21 | 1,242,680 (+19,671) | 1,158,909 (+12,651) | 2,401,589 (+32,322) | +| 2025-12-22 | 1,262,525 (+19,845) | 1,169,121 (+10,212) | 2,431,646 (+30,057) | +| 2025-12-23 | 1,286,557 (+24,032) | 1,186,439 (+17,318) | 2,472,996 (+41,350) | +| 2025-12-24 | 1,309,323 (+22,766) | 1,203,767 (+17,328) | 2,513,090 (+40,094) | +| 2025-12-25 | 1,333,037 (+23,714) | 1,217,283 (+13,516) | 2,550,320 (+37,230) | +| 2025-12-26 | 1,352,373 (+19,336) | 1,227,615 (+10,332) | 2,579,988 (+29,668) | +| 2025-12-27 | 1,371,774 (+19,401) | 1,238,236 (+10,621) | 2,610,010 (+30,022) | +| 2025-12-28 | 1,390,416 (+18,642) | 1,245,690 (+7,454) | 2,636,106 (+26,096) | +| 2025-12-29 | 1,415,571 (+25,155) | 1,257,101 (+11,411) | 2,672,672 (+36,566) | diff --git a/bun.lock b/bun.lock index 8dd6cae29b0..a00c0af4027 100644 --- a/bun.lock +++ b/bun.lock @@ -165,6 +165,18 @@ "typescript": "catalog:", }, }, + "packages/function-selfhost": { + "name": "@opencode-ai/function-selfhost", + "version": "1.0.35", + "dependencies": { + "hono": "catalog:", + "opendal": "^0.45.0", + }, + "devDependencies": { + "@types/node": "catalog:", + "typescript": "catalog:", + }, + }, "packages/opencode": { "name": "opencode", "version": "1.0.35", @@ -323,6 +335,7 @@ "dependencies": { "@astrojs/cloudflare": "12.6.3", "@astrojs/markdown-remark": "6.3.1", + "@astrojs/node": "9.1.0", "@astrojs/solid-js": "5.1.0", "@astrojs/starlight": "0.34.3", "@fontsource/ibm-plex-mono": "5.2.5", @@ -436,6 +449,8 @@ "@astrojs/mdx": ["@astrojs/mdx@4.3.9", "", { "dependencies": { "@astrojs/markdown-remark": "6.3.8", "@mdx-js/mdx": "^3.1.1", "acorn": "^8.15.0", "es-module-lexer": "^1.7.0", "estree-util-visit": "^2.0.0", "hast-util-to-html": "^9.0.5", "picocolors": "^1.1.1", "rehype-raw": "^7.0.0", "remark-gfm": "^4.0.1", "remark-smartypants": "^3.0.2", "source-map": "^0.7.6", "unist-util-visit": "^5.0.0", "vfile": "^6.0.3" }, "peerDependencies": { "astro": "^5.0.0" } }, "sha512-80LHiM4z3FxAjATHNgFpa8nlTNSprAWB4UUKnr/QG56Pwk7uRnJWrXlok4wSCi/3fg8kTZ98A408Q91M+iqJdw=="], + "@astrojs/node": ["@astrojs/node@9.1.0", "", { "dependencies": { "@astrojs/internal-helpers": "0.5.1", "send": "^1.1.0", "server-destroy": "^1.0.1" }, "peerDependencies": { "astro": "^5.3.0" } }, "sha512-7fDsawWci/j4prDVVwOFGuArG+YK+io54/5ksKL+lbSZ8xA4h6TB36RA4INmNatralEOKlgCxmbZdwewYcsFWA=="], + "@astrojs/prism": ["@astrojs/prism@3.2.0", "", { "dependencies": { "prismjs": "^1.29.0" } }, "sha512-GilTHKGCW6HMq7y3BUv9Ac7GMe/MO9gi9GW62GzKtth0SwukCu/qp2wLiGpEujhY+VVhaG9v7kv/5vFzvf4NYw=="], "@astrojs/sitemap": ["@astrojs/sitemap@3.6.0", "", { "dependencies": { "sitemap": "^8.0.0", "stream-replace-string": "^2.0.0", "zod": "^3.25.76" } }, "sha512-4aHkvcOZBWJigRmMIAJwRQXBS+ayoP5z40OklTXYXhUDhwusz+DyDl+nSshY6y9DvkVEavwNcFO8FD81iGhXjg=="], @@ -948,6 +963,8 @@ "@opencode-ai/function": ["@opencode-ai/function@workspace:packages/function"], + "@opencode-ai/function-selfhost": ["@opencode-ai/function-selfhost@workspace:packages/function-selfhost"], + "@opencode-ai/plugin": ["@opencode-ai/plugin@workspace:packages/plugin"], "@opencode-ai/script": ["@opencode-ai/script@workspace:packages/script"], @@ -960,6 +977,18 @@ "@opencode-ai/web": ["@opencode-ai/web@workspace:packages/web"], + "@opendal/lib-darwin-arm64": ["@opendal/lib-darwin-arm64@0.45.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-aYiGPQSAbqNfIgmW3DLMnDySYhcaWNOub2gC5HyaBjh7EV8gKmSwYlDdESfbhSlxoUC6mTm9aOy9zJs3Lf4tVg=="], + + "@opendal/lib-linux-arm64-gnu": ["@opendal/lib-linux-arm64-gnu@0.45.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-JrtXICywnwwy+VraY0pMzLyYgebXVe8E3GGZQ72j0xemiXXOQ8IzTovlTfVo/qsl+eU077EKNv+HYGD981niyQ=="], + + "@opendal/lib-linux-arm64-musl": ["@opendal/lib-linux-arm64-musl@0.45.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-5uvNQOy4PZTFmGr+vPr/HapLftOEsfS3YtG8YfeD2ZQTu/eKaOqUYlclD96PvAdwb7SoPRQ/oW+DfdD1NctBmA=="], + + "@opendal/lib-linux-x64-gnu": ["@opendal/lib-linux-x64-gnu@0.45.2", "", { "os": "linux", "cpu": "x64" }, "sha512-dF0iFCIkGTgqqaB8+s2owtyRrSAcYuweZ0lu4rQ02qR4RvVz13v79s9ZElJPDaAtPQqh4RG6duUxJBURYHQmfA=="], + + "@opendal/lib-win32-arm64-msvc": ["@opendal/lib-win32-arm64-msvc@0.45.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-88jImCBgO6l4WC6teG2X7zpCk5t+19bBl9bmN5uayfGTKMA67q8BrlHeGpIIzNEMejApy6uafZfKlYYrXinXmg=="], + + "@opendal/lib-win32-x64-msvc": ["@opendal/lib-win32-x64-msvc@0.45.2", "", { "os": "win32", "cpu": "x64" }, "sha512-76lZwMIm6auc2aPJaQ//ML/K0a/Uo0N0vlZte4ohQr5dyZVj9+tyJYviilh0Z+quInZvILJKbF0XFCK0+sV8Ig=="], + "@opentelemetry/api": ["@opentelemetry/api@1.9.0", "", {}, "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg=="], "@opentui/core": ["@opentui/core@0.1.36", "", { "dependencies": { "bun-ffi-structs": "^0.1.0", "jimp": "1.6.0", "yoga-layout": "3.2.1" }, "optionalDependencies": { "@dimforge/rapier2d-simd-compat": "^0.17.3", "@opentui/core-darwin-arm64": "0.1.36", "@opentui/core-darwin-x64": "0.1.36", "@opentui/core-linux-arm64": "0.1.36", "@opentui/core-linux-x64": "0.1.36", "@opentui/core-win32-arm64": "0.1.36", "@opentui/core-win32-x64": "0.1.36", "bun-webgpu": "0.1.3", "planck": "^1.4.2", "three": "0.177.0" }, "peerDependencies": { "web-tree-sitter": "0.25.10" } }, "sha512-urDrj33udJ0dJGkZv+T5U0mCFBOOvUt9Tvqkrj8aRvi6kN0Bc5d2COuWcpAKo0TO9/PvjSwHC+CMnw2Sr46/ug=="], @@ -2780,6 +2809,8 @@ "opencontrol": ["opencontrol@0.0.6", "", { "dependencies": { "@modelcontextprotocol/sdk": "1.6.1", "@tsconfig/bun": "1.0.7", "hono": "4.7.4", "zod": "3.24.2", "zod-to-json-schema": "3.24.3" }, "bin": { "opencontrol": "bin/index.mjs" } }, "sha512-QeCrpOK5D15QV8kjnGVeD/BHFLwcVr+sn4T6KKmP0WAMs2pww56e4h+eOGHb5iPOufUQXbdbBKi6WV2kk7tefQ=="], + "opendal": ["opendal@0.45.2", "", { "optionalDependencies": { "@opendal/lib-darwin-arm64": "0.45.2", "@opendal/lib-darwin-x64": "0.45.2", "@opendal/lib-linux-arm64-gnu": "0.45.2", "@opendal/lib-linux-arm64-musl": "0.45.2", "@opendal/lib-linux-x64-gnu": "0.45.2", "@opendal/lib-win32-arm64-msvc": "0.45.2", "@opendal/lib-win32-x64-msvc": "0.45.2" } }, "sha512-W5JnwVn497mGEE/BULsXGhWNLb/oBCg4x5A2LM/phoQ5VpLdpc+jdToaDtSEgJxbM6d7XxG5g/wv5vRR44UoOQ=="], + "openid-client": ["openid-client@5.6.4", "", { "dependencies": { "jose": "^4.15.4", "lru-cache": "^6.0.0", "object-hash": "^2.2.0", "oidc-token-hash": "^5.0.3" } }, "sha512-T1h3B10BRPKfcObdBklX639tVz+xh34O7GjofqrqiAQdm7eHsQ00ih18x6wuJ/E6FxdtS2u3FmUGPDeEcMwzNA=="], "own-keys": ["own-keys@1.0.1", "", { "dependencies": { "get-intrinsic": "^1.2.6", "object-keys": "^1.1.1", "safe-push-apply": "^1.0.0" } }, "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg=="], @@ -3092,7 +3123,7 @@ "semver": ["semver@7.7.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="], - "send": ["send@0.19.0", "", { "dependencies": { "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", "http-errors": "2.0.0", "mime": "1.6.0", "ms": "2.1.3", "on-finished": "2.4.1", "range-parser": "~1.2.1", "statuses": "2.0.1" } }, "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw=="], + "send": ["send@1.2.0", "", { "dependencies": { "debug": "^4.3.5", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "fresh": "^2.0.0", "http-errors": "^2.0.0", "mime-types": "^3.0.1", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", "statuses": "^2.0.1" } }, "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw=="], "seq-queue": ["seq-queue@0.0.5", "", {}, "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q=="], @@ -3106,6 +3137,8 @@ "serve-static": ["serve-static@1.16.2", "", { "dependencies": { "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", "send": "0.19.0" } }, "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw=="], + "server-destroy": ["server-destroy@1.0.1", "", {}, "sha512-rb+9B5YBIEzYcD6x2VKidaa+cqYBJQKnU4oe4E3ANwRRN56yk/ua1YCJT1n21NTS8w6CcOclAKNP3PhdCXKYtQ=="], + "set-function-length": ["set-function-length@1.2.2", "", { "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", "has-property-descriptors": "^1.0.2" } }, "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg=="], "set-function-name": ["set-function-name@2.0.2", "", { "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", "functions-have-names": "^1.2.3", "has-property-descriptors": "^1.0.2" } }, "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ=="], @@ -3516,7 +3549,7 @@ "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="], - "ws": ["ws@7.5.10", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ=="], + "ws": ["ws@8.18.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw=="], "xdg-basedir": ["xdg-basedir@5.1.0", "", {}, "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ=="], @@ -3594,6 +3627,8 @@ "@astrojs/mdx/@astrojs/markdown-remark": ["@astrojs/markdown-remark@6.3.8", "", { "dependencies": { "@astrojs/internal-helpers": "0.7.4", "@astrojs/prism": "3.3.0", "github-slugger": "^2.0.0", "hast-util-from-html": "^2.0.3", "hast-util-to-text": "^4.0.2", "import-meta-resolve": "^4.2.0", "js-yaml": "^4.1.0", "mdast-util-definitions": "^6.0.0", "rehype-raw": "^7.0.0", "rehype-stringify": "^10.0.1", "remark-gfm": "^4.0.1", "remark-parse": "^11.0.0", "remark-rehype": "^11.1.2", "remark-smartypants": "^3.0.2", "shiki": "^3.13.0", "smol-toml": "^1.4.2", "unified": "^11.0.5", "unist-util-remove-position": "^5.0.0", "unist-util-visit": "^5.0.0", "unist-util-visit-parents": "^6.0.1", "vfile": "^6.0.3" } }, "sha512-uFNyFWadnULWK2cOw4n0hLKeu+xaVWeuECdP10cQ3K2fkybtTlhb7J7TcScdjmS8Yps7oje9S/ehYMfZrhrgCg=="], + "@astrojs/node/@astrojs/internal-helpers": ["@astrojs/internal-helpers@0.5.1", "", {}, "sha512-M7rAge1n2+aOSxNvKUFa0u/KFn0W+sZy7EW91KOSERotm2Ti8qs+1K0xx3zbOxtAVrmJb5/J98eohVvvEqtNkw=="], + "@astrojs/sitemap/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], "@astrojs/solid-js/vite": ["vite@6.4.1", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g=="], @@ -3750,6 +3785,8 @@ "@slack/socket-mode/eventemitter3": ["eventemitter3@5.0.1", "", {}, "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA=="], + "@slack/socket-mode/ws": ["ws@7.5.10", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ=="], + "@slack/web-api/@slack/logger": ["@slack/logger@3.0.0", "", { "dependencies": { "@types/node": ">=12.0.0" } }, "sha512-DTuBFbqu4gGfajREEMrkq5jBhcnskinhr4+AnfJEk48zhVeEv3XnUKGIX98B74kxhYsIMfApGGySTn7V3b5yBA=="], "@slack/web-api/eventemitter3": ["eventemitter3@3.1.2", "", {}, "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q=="], @@ -3878,6 +3915,8 @@ "express/qs": ["qs@6.13.0", "", { "dependencies": { "side-channel": "^1.0.6" } }, "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg=="], + "express/send": ["send@0.19.0", "", { "dependencies": { "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", "http-errors": "2.0.0", "mime": "1.6.0", "ms": "2.1.3", "on-finished": "2.4.1", "range-parser": "~1.2.1", "statuses": "2.0.1" } }, "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw=="], + "fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], "finalhandler/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], @@ -3930,8 +3969,6 @@ "miniflare/undici": ["undici@7.14.0", "", {}, "sha512-Vqs8HTzjpQXZeXdpsfChQTlafcMQaaIwnGwLam1wudSSjlJeQ3bw1j+TLPePgrCnCpUXx7Ba5Pdpf5OBih62NQ=="], - "miniflare/ws": ["ws@8.18.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw=="], - "miniflare/youch": ["youch@4.1.0-beta.10", "", { "dependencies": { "@poppinss/colors": "^4.1.5", "@poppinss/dumper": "^0.6.4", "@speed-highlight/core": "^1.2.7", "cookie": "^1.0.2", "youch-core": "^0.3.3" } }, "sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ=="], "miniflare/zod": ["zod@3.22.3", "", {}, "sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug=="], @@ -4026,11 +4063,9 @@ "safe-push-apply/isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="], - "send/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], + "send/fresh": ["fresh@2.0.0", "", {}, "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A=="], - "send/encodeurl": ["encodeurl@1.0.2", "", {}, "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="], - - "send/mime": ["mime@1.6.0", "", { "bin": { "mime": "cli.js" } }, "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="], + "serve-static/send": ["send@0.19.0", "", { "dependencies": { "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", "http-errors": "2.0.0", "mime": "1.6.0", "ms": "2.1.3", "on-finished": "2.4.1", "range-parser": "~1.2.1", "statuses": "2.0.1" } }, "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw=="], "sitemap/sax": ["sax@1.4.3", "", {}, "sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ=="], @@ -4290,8 +4325,6 @@ "@modelcontextprotocol/sdk/express/merge-descriptors": ["merge-descriptors@2.0.0", "", {}, "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g=="], - "@modelcontextprotocol/sdk/express/send": ["send@1.2.0", "", { "dependencies": { "debug": "^4.3.5", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "fresh": "^2.0.0", "http-errors": "^2.0.0", "mime-types": "^3.0.1", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", "statuses": "^2.0.1" } }, "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw=="], - "@modelcontextprotocol/sdk/express/serve-static": ["serve-static@2.2.0", "", { "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" } }, "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ=="], "@modelcontextprotocol/sdk/express/type-is": ["type-is@2.0.1", "", { "dependencies": { "content-type": "^1.0.5", "media-typer": "^1.1.0", "mime-types": "^3.0.0" } }, "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw=="], @@ -4470,6 +4503,10 @@ "express/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], + "express/send/encodeurl": ["encodeurl@1.0.2", "", {}, "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="], + + "express/send/mime": ["mime@1.6.0", "", { "bin": { "mime": "cli.js" } }, "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="], + "finalhandler/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], "form-data/mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], @@ -4510,8 +4547,6 @@ "nitropack/h3/cookie-es": ["cookie-es@1.2.2", "", {}, "sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg=="], - "nitropack/serve-static/send": ["send@1.2.0", "", { "dependencies": { "debug": "^4.3.5", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "fresh": "^2.0.0", "http-errors": "^2.0.0", "mime-types": "^3.0.1", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", "statuses": "^2.0.1" } }, "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw=="], - "nypm/pkg-types/confbox": ["confbox@0.1.8", "", {}, "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w=="], "opencontrol/@modelcontextprotocol/sdk/express": ["express@5.1.0", "", { "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.0", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "finalhandler": "^2.1.0", "fresh": "^2.0.0", "http-errors": "^2.0.0", "merge-descriptors": "^2.0.0", "mime-types": "^3.0.0", "on-finished": "^2.4.1", "once": "^1.4.0", "parseurl": "^1.3.3", "proxy-addr": "^2.0.7", "qs": "^6.14.0", "range-parser": "^1.2.1", "router": "^2.2.0", "send": "^1.1.0", "serve-static": "^2.2.0", "statuses": "^2.0.1", "type-is": "^2.0.1", "vary": "^1.1.2" } }, "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA=="], @@ -4544,7 +4579,11 @@ "rollup-plugin-visualizer/yargs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], - "send/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], + "serve-static/send/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], + + "serve-static/send/encodeurl": ["encodeurl@1.0.2", "", {}, "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="], + + "serve-static/send/mime": ["mime@1.6.0", "", { "bin": { "mime": "cli.js" } }, "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="], "string-width-cjs/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], @@ -4722,8 +4761,6 @@ "nitropack/c12/giget/nypm": ["nypm@0.6.2", "", { "dependencies": { "citty": "^0.1.6", "consola": "^3.4.2", "pathe": "^2.0.3", "pkg-types": "^2.3.0", "tinyexec": "^1.0.1" }, "bin": { "nypm": "dist/cli.mjs" } }, "sha512-7eM+hpOtrKrBDCh7Ypu2lJ9Z7PNZBdi/8AT3AX8xoCj43BBVHD0hPSTEvMtkMpfs8FCqBGhxB+uToIQimA111g=="], - "nitropack/serve-static/send/fresh": ["fresh@2.0.0", "", {}, "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A=="], - "opencontrol/@modelcontextprotocol/sdk/express/accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="], "opencontrol/@modelcontextprotocol/sdk/express/body-parser": ["body-parser@2.2.0", "", { "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", "debug": "^4.4.0", "http-errors": "^2.0.0", "iconv-lite": "^0.6.3", "on-finished": "^2.4.1", "qs": "^6.14.0", "raw-body": "^3.0.0", "type-is": "^2.0.0" } }, "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg=="], @@ -4740,8 +4777,6 @@ "opencontrol/@modelcontextprotocol/sdk/express/merge-descriptors": ["merge-descriptors@2.0.0", "", {}, "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g=="], - "opencontrol/@modelcontextprotocol/sdk/express/send": ["send@1.2.0", "", { "dependencies": { "debug": "^4.3.5", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "fresh": "^2.0.0", "http-errors": "^2.0.0", "mime-types": "^3.0.1", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", "statuses": "^2.0.1" } }, "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw=="], - "opencontrol/@modelcontextprotocol/sdk/express/serve-static": ["serve-static@2.2.0", "", { "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" } }, "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ=="], "opencontrol/@modelcontextprotocol/sdk/express/type-is": ["type-is@2.0.1", "", { "dependencies": { "content-type": "^1.0.5", "media-typer": "^1.1.0", "mime-types": "^3.0.0" } }, "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw=="], @@ -4760,6 +4795,8 @@ "rollup-plugin-visualizer/yargs/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + "serve-static/send/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], + "sucrase/glob/path-scurry/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], "tw-to-css/tailwindcss/chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000000..954d7bce04f --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,27 @@ +services: + functions-api: + build: + context: . + dockerfile: docker/Dockerfile.functions-selfhost + container_name: opencode-functions-api + ports: + - "3000:3000" + volumes: + - ./data:/app/data + environment: + - HOST=0.0.0.0 + - WEB_URL=http://localhost:4321 + restart: unless-stopped + + web: + build: + context: . + dockerfile: docker/Dockerfile.web + container_name: opencode-web + ports: + - "4321:4321" + environment: + - VITE_PUBLIC_API_URL=http://localhost:3000 + - VITE_API_URL=http://functions-api:3000 + - HOST=0.0.0.0 + restart: unless-stopped diff --git a/docker/.dockerignore b/docker/.dockerignore new file mode 100644 index 00000000000..8cd061f06e2 --- /dev/null +++ b/docker/.dockerignore @@ -0,0 +1,50 @@ +# Dependencies (will be reinstalled) +node_modules/ +**/node_modules/ + +# Build outputs +dist/ +build/ +**/dist/ +**/build/ +.turbo/ + +# Development +.git/ +.github/ +.husky/ +*.log +logs/ + +# Environment +.env +.env.* +!.env.example + +# IDE +.vscode/ +.idea/ + +# Testing +coverage/ +**/coverage/ +test/ +**/test/ + +# Misc - keep package files needed for workspace +*.md + +# Specific packages we don't need (keep function-selfhost) +packages/console/ +packages/desktop/ +packages/web/ +packages/ui/ +packages/opencode/ +packages/plugin/ +packages/slack/ +packages/function/ +packages/script/ +packages/sdk/ +sdks/ +specs/ +infra/ diff --git a/docker/Dockerfile.functions-selfhost b/docker/Dockerfile.functions-selfhost new file mode 100644 index 00000000000..2417d7e856f --- /dev/null +++ b/docker/Dockerfile.functions-selfhost @@ -0,0 +1,32 @@ +FROM oven/bun:1.3-debian AS base +WORKDIR /app + +# Copy package.json files to resolve catalog references +COPY package.json ./root.json +COPY packages/function-selfhost/package.json ./pkg.json + +# Auto-resolve catalog references into standalone package.json +RUN bun -e "\ +const root = await Bun.file('root.json').json(); \ +const pkg = await Bun.file('pkg.json').json(); \ +const catalog = root.workspaces.catalog; \ +const resolve = (deps) => Object.fromEntries(Object.entries(deps || {}).map(([k,v]) => [k, v === 'catalog:' ? catalog[k] : v])); \ +const output = { name: pkg.name, type: pkg.type, dependencies: resolve(pkg.dependencies) }; \ +await Bun.write('package.json', JSON.stringify(output, null, 2)); \ +" + +# Install dependencies +RUN bun install --production + +# Copy TypeScript configuration and source code +COPY packages/function-selfhost/tsconfig.json ./tsconfig.json +COPY packages/function-selfhost/src ./src + +# Build the TypeScript code +RUN bun build src/index.ts --outdir dist --target bun + +# Expose port 3000 +EXPOSE 3000 + +# Run the built application +CMD ["bun", "dist/index.js"] diff --git a/docker/Dockerfile.web b/docker/Dockerfile.web new file mode 100644 index 00000000000..4028628981a --- /dev/null +++ b/docker/Dockerfile.web @@ -0,0 +1,55 @@ +FROM oven/bun:1.3-alpine AS base +WORKDIR /app + +FROM base AS deps +# Copy package.json files to resolve catalog references +COPY package.json ./root.json +COPY packages/web/package.json ./pkg.json + +# Auto-resolve catalog references into standalone package.json +RUN bun -e "\ +const root = await Bun.file('root.json').json(); \ +const pkg = await Bun.file('pkg.json').json(); \ +const catalog = root.workspaces.catalog; \ +const resolve = (deps) => Object.fromEntries(Object.entries(deps || {}).map(([k,v]) => [k, v === 'catalog:' ? catalog[k] : v]).filter(([k,v]) => !v.startsWith('workspace:'))); \ +const output = { \ + name: pkg.name, \ + type: pkg.type, \ + dependencies: resolve(pkg.dependencies), \ + devDependencies: resolve(pkg.devDependencies) \ +}; \ +await Bun.write('package.json', JSON.stringify(output, null, 2)); \ +" + +# Install dependencies +RUN bun install --production + +FROM base AS build +# Copy source files +COPY packages/web ./ + +# Copy installed dependencies from deps stage +COPY --from=deps /app/node_modules ./node_modules + +# Set adapter to node for Docker deployment +ENV ASTRO_ADAPTER=node + +# Build the Astro site +# API URLs will be set at runtime, not build time +RUN bun run build + +FROM base AS runtime +# Copy built output +COPY --from=build /app/dist ./dist + +# Copy node_modules needed at runtime +COPY --from=deps /app/node_modules ./node_modules + +EXPOSE 4321 + +# Runtime environment variables (set these when running the container): +# - VITE_API_URL: Backend API URL for server-side requests +# - VITE_PUBLIC_API_URL: Public API URL for client-side WebSocket connections + +# Start the server using Bun +CMD ["bun", "./dist/server/entry.mjs"] diff --git a/packages/function-selfhost/package.json b/packages/function-selfhost/package.json new file mode 100644 index 00000000000..0beb2817288 --- /dev/null +++ b/packages/function-selfhost/package.json @@ -0,0 +1,15 @@ +{ + "name": "@opencode-ai/function-selfhost", + "version": "1.0.35", + "$schema": "https://json.schemastore.org/package.json", + "private": true, + "type": "module", + "devDependencies": { + "@types/node": "catalog:", + "typescript": "catalog:" + }, + "dependencies": { + "hono": "catalog:", + "opendal": "^0.45.0" + } +} diff --git a/packages/function-selfhost/src/api.ts b/packages/function-selfhost/src/api.ts new file mode 100644 index 00000000000..474204fc335 --- /dev/null +++ b/packages/function-selfhost/src/api.ts @@ -0,0 +1,177 @@ +import { Hono } from "hono" +import { createBunWebSocket } from "hono/bun" +import { Operator } from "opendal" +import { SyncServer } from "./sync-server" +import type { ServerWebSocket } from "bun" + +const operator = new Operator("fs", { root: "./data" }) +const syncServer = new SyncServer(operator) + +const { upgradeWebSocket, websocket } = createBunWebSocket() + +const app = new Hono() + +app.get("/", (c) => c.text("OpenCode Self-Hosted Function Server")) + +app.post("/share_create", async (c) => { + try { + const body = await c.req.json<{ sessionID: string }>() + const sessionID = body.sessionID + const short = SyncServer.shortName(sessionID) + const secret = await syncServer.share(sessionID) + + const response = { + secret, + url: `${process.env.WEB_URL || "http://localhost:4321"}/s/${short}`, + } + return c.json(response) + } catch (error) { + console.error(`Error in /share_create:`, error) + return c.json({ error: error instanceof Error ? error.message : "Unknown error" }, { status: 500 }) + } +}) + +app.post("/share_delete", async (c) => { + try { + const body = await c.req.json<{ sessionID: string; secret: string }>() + const sessionID = body.sessionID + const secret = body.secret + const short = SyncServer.shortName(sessionID) + + await syncServer.assertSecret(short, secret) + await syncServer.clear(short) + return c.json({}) + } catch (error) { + console.error(`Error in /share_delete:`, error) + return c.json({ error: error instanceof Error ? error.message : "Unknown error" }, { status: 500 }) + } +}) + +app.post("/share_sync", async (c) => { + try { + const body = await c.req.json<{ + sessionID: string + secret: string + key: string + content: any + }>() + const short = SyncServer.shortName(body.sessionID) + + await syncServer.assertSecret(short, body.secret) + await syncServer.publish(short, body.key, body.content) + + const topic = `session:${short}` + const message = JSON.stringify({ key: body.key, content: body.content }) + + syncServer.publishToWebSockets(topic, message) + + return c.json({}) + } catch (error) { + console.error(`Error in /share_sync:`, error) + return c.json({ error: error instanceof Error ? error.message : "Unknown error" }, { status: 500 }) + } +}) + +app.get("/share_data", async (c) => { + try { + const id = c.req.query("id") + if (!id) return c.text("Error: Share ID is required", { status: 400 }) + + await syncServer.loadSession(id) + const data = await syncServer.getData(id) + + let info + const messages: Record = {} + const parts: Array<{ messageID: string; content: any }> = [] + + // First pass: collect info and messages, save parts for later + for (let i = data.length - 1; i >= 0; i--) { + const d = data[i] + const [root, type] = d.key.split("/") + if (root !== "session") continue + + if (type === "info") { + info = d.content + data.splice(i, 1) + } else if (type === "message") { + messages[d.content.id] = { + parts: [], + ...d.content, + } + data.splice(i, 1) + } else if (type === "part") { + parts.push({ messageID: d.content.messageID, content: d.content }) + data.splice(i, 1) + } + } + + // Second pass: add parts to their messages + for (const part of parts) { + const message = messages[part.messageID] + if (message) { + message.parts.push(part.content) + } + } + + return c.json({ info, messages }) + } catch (error) { + console.error(`Error in /share_data:`, error) + return c.json({ error: error instanceof Error ? error.message : "Unknown error" }, { status: 500 }) + } +}) + +app.get( + "/share_poll", + upgradeWebSocket((c) => { + const sessionId = c.req.query("id") + + if (!sessionId) { + return { + onOpen(_event, ws) { + ws.close(1008, "Session ID required") + } + } + } + + return { + onOpen: async (_event, ws) => { + + const topic = `session:${sessionId}` + const rawWs = ws.raw as ServerWebSocket + rawWs.subscribe(topic) + syncServer.subscribeWebSocket(topic, rawWs) + + const sessionData = await syncServer.getSessionData(sessionId) + if (sessionData) { + const data = await syncServer.getData(sessionId) + data.forEach(({ key, content }) => ws.send(JSON.stringify({ key, content }))) + } + }, + + onMessage(_event, _ws) { + }, + + onClose(_event, ws) { + const topic = `session:${sessionId}` + const rawWs = ws.raw as ServerWebSocket + rawWs.unsubscribe(topic) + syncServer.unsubscribeWebSocket(topic, rawWs) + }, + + onError(event, _ws) { + console.error("WebSocket error:", event) + } + } + }) +) + +app.get("/s/:sessionId", async (c) => { + const sessionId = c.req.param("sessionId"); + const data = await syncServer.getSessionData(sessionId); + if (!data) return c.text("Not Found", 404); + return c.json(data); +}); + +app.all("*", (c) => c.text("Not Found", { status: 404 })) + +export { app, syncServer, websocket } diff --git a/packages/function-selfhost/src/index.ts b/packages/function-selfhost/src/index.ts new file mode 100644 index 00000000000..bc9b3dbc3b0 --- /dev/null +++ b/packages/function-selfhost/src/index.ts @@ -0,0 +1,15 @@ +import { app, websocket } from "./api" + +const port = Number(process.env.PORT) || 3000 +const host = process.env.HOST || "127.0.0.1" + +console.log(`OpenCode Self-Hosted Function Server running on ${host}:${port}`) +console.log(`Data directory: ./data`) +console.log(`WebSocket endpoint: ws://${host}:${port}/share_poll?id=`) + +export default { + port, + hostname: host, + fetch: app.fetch, + websocket, +} \ No newline at end of file diff --git a/packages/function-selfhost/src/sync-server.ts b/packages/function-selfhost/src/sync-server.ts new file mode 100644 index 00000000000..707b52b38aa --- /dev/null +++ b/packages/function-selfhost/src/sync-server.ts @@ -0,0 +1,148 @@ +import { randomUUID } from "node:crypto" +import { Operator } from "opendal" +import type { ServerWebSocket } from "bun" + +interface SessionData { + secret?: string + sessionID?: string +} + +export class SyncServer { + private operator: Operator + private subscribers = new Map>>() + + constructor(operator: Operator) { + this.operator = operator + } + + async getSessionData(sessionId: string): Promise { + try { + const data = await this.operator.read(`shares/${sessionId}/secret.json`) + return JSON.parse(data.toString()) + } catch { + return null + } + } + + async publish(sessionId: string, key: string, content: any) { + const sessionData = await this.getSessionData(sessionId) + if (!sessionData?.sessionID) { + throw new Error("Session not found") + } + + if ( + !key.startsWith(`session/info/${sessionData.sessionID}`) && + !key.startsWith(`session/message/${sessionData.sessionID}/`) && + !key.startsWith(`session/part/${sessionData.sessionID}/`) + ) { + throw new Error("Invalid key") + } + + const storageKey = `share/${key}.json` + await this.operator.write(storageKey, JSON.stringify(content)) + } + + async share(sessionID: string) { + const shortName = SyncServer.shortName(sessionID) + const existingSession = await this.getSessionData(shortName) + + if (existingSession?.secret) return existingSession.secret + + const secret = randomUUID() + const sessionData = { secret, sessionID } + await this.operator.write(`shares/${shortName}/secret.json`, JSON.stringify(sessionData)) + + return secret + } + + async getData(sessionId: string): Promise> { + const sessionData = await this.getSessionData(sessionId) + if (!sessionData?.sessionID) return [] + + const entries = await this.operator.list("share/", { recursive: true }) + const result: Array<{key: string, content: any}> = [] + for (const entry of entries) { + const path = entry.path() + if (path.startsWith("share/session/") && path.includes(sessionData.sessionID!) && path.endsWith(".json")) { + const content = await this.operator.read(path) + const key = path.replace("share/", "").replace(".json", "") + result.push({ key, content: JSON.parse(content.toString()) }) + } + } + return result.sort((a, b) => { + const aType = a.key.split("/")[1] + const bType = b.key.split("/")[1] + if (aType === "info" && bType !== "info") return -1 + if (aType !== "info" && bType === "info") return 1 + if (aType === "message" && bType === "part") return -1 + if (aType === "part" && bType === "message") return 1 + return a.key.localeCompare(b.key) + }) + } + + async assertSecret(sessionId: string, secret: string) { + const sessionData = await this.getSessionData(sessionId) + if (!sessionData || sessionData.secret !== secret) { + throw new Error("Invalid secret") + } + } + + async clear(sessionId: string) { + const sessionData = await this.getSessionData(sessionId) + if (!sessionData?.sessionID) return + + try { + const prefix = `session/message/${sessionData.sessionID}/` + const entries = await this.operator.list(prefix) + for (const entry of entries) { + await this.operator.delete(entry.path()) + } + + await this.operator.delete(`session/info/${sessionData.sessionID}`) + } catch (error) { + console.error("Error clearing session data:", error) + } + } + + async loadSession(sessionId: string): Promise { + try { + const data = await this.operator.read(`shares/${sessionId}/secret.json`) + return JSON.parse(data.toString()) + } catch (error) { + console.error("Failed to load session:", error) + return null + } + } + + static shortName(id: string) { + return id.substring(id.length - 8) + } + + subscribeWebSocket(topic: string, ws: ServerWebSocket) { + if (!this.subscribers.has(topic)) { + this.subscribers.set(topic, new Set()) + } + this.subscribers.get(topic)!.add(ws) + } + + unsubscribeWebSocket(topic: string, ws: ServerWebSocket) { + const subscribers = this.subscribers.get(topic) + if (subscribers) { + subscribers.delete(ws) + if (subscribers.size === 0) { + this.subscribers.delete(topic) + } + } + } + + publishToWebSockets(topic: string, message: string) { + const subscribers = this.subscribers.get(topic) + if (subscribers) { + subscribers.forEach(ws => { + if (ws.readyState === 1) { // OPEN state + ws.send(message) + } + }) + } + } +} \ No newline at end of file diff --git a/packages/function-selfhost/tsconfig.json b/packages/function-selfhost/tsconfig.json new file mode 100644 index 00000000000..1a4a91ff753 --- /dev/null +++ b/packages/function-selfhost/tsconfig.json @@ -0,0 +1,17 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "extends": "@tsconfig/node22/tsconfig.json", + "compilerOptions": { + "module": "ESNext", + "moduleResolution": "bundler", + "types": ["bun-types"], + "outDir": "./dist", + "rootDir": "./src", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] +} \ No newline at end of file diff --git a/packages/web/astro.config.mjs b/packages/web/astro.config.mjs index 24987ca350c..bf3a3c85270 100644 --- a/packages/web/astro.config.mjs +++ b/packages/web/astro.config.mjs @@ -9,14 +9,25 @@ import { rehypeHeadingIds } from "@astrojs/markdown-remark" import rehypeAutolinkHeadings from "rehype-autolink-headings" import { spawnSync } from "child_process" +// Conditionally load adapter based on environment +const getAdapter = async () => { + if (process.env.ASTRO_ADAPTER === "node") { + try { + const node = await import("@astrojs/node") + return node.default({ mode: "standalone" }) + } catch { + console.warn("@astrojs/node not found, falling back to cloudflare adapter") + } + } + return cloudflare({ imageService: "passthrough" }) +} + // https://astro.build/config export default defineConfig({ site: config.url, base: "/docs", output: "server", - adapter: cloudflare({ - imageService: "passthrough", - }), + adapter: await getAdapter(), devToolbar: { enabled: false, }, diff --git a/packages/web/package.json b/packages/web/package.json index df95ff76ff9..bbf847cf31d 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -13,6 +13,7 @@ "dependencies": { "@astrojs/cloudflare": "12.6.3", "@astrojs/markdown-remark": "6.3.1", + "@astrojs/node": "9.1.0", "@astrojs/solid-js": "5.1.0", "@astrojs/starlight": "0.34.3", "@fontsource/ibm-plex-mono": "5.2.5", diff --git a/packages/web/src/components/Share.tsx b/packages/web/src/components/Share.tsx index 062449712ed..b0efc69711f 100644 --- a/packages/web/src/components/Share.tsx +++ b/packages/web/src/components/Share.tsx @@ -37,7 +37,7 @@ function getStatusText(status: [Status, string?]): string { } } -export default function Share(props: { id: string; api: string; info: Session.Info }) { +export default function Share(props: { id: string; api: string; publicApi?: string; info: Session.Info }) { let lastScrollY = 0 let hasScrolledToAnchor = false let scrollTimeout: number | undefined @@ -73,7 +73,7 @@ export default function Share(props: { id: string; api: string; info: Session.In }) onMount(() => { - const apiUrl = props.api + const apiUrl = props.publicApi || props.api if (!props.id) { setConnectionStatus(["error", "id not found"]) @@ -98,9 +98,16 @@ export default function Share(props: { id: string; api: string; info: Session.In setConnectionStatus(["connecting"]) - // Always use secure WebSocket protocol (wss) - const wsBaseUrl = apiUrl.replace(/^https?:\/\//, "wss://") - const wsUrl = `${wsBaseUrl}/share_poll?id=${props.id}` + let wsUrl: string + try { + const url = new URL(apiUrl) + const protocol = url.protocol === 'https:' ? 'wss:' : 'ws:' + wsUrl = `${protocol}//${url.host}/share_poll?id=${props.id}` + } catch { + const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:' + wsUrl = `${protocol}//${window.location.host}/share_poll?id=${props.id}` + } + console.log("Connecting to WebSocket URL:", wsUrl) // Create WebSocket connection diff --git a/packages/web/src/pages/s/[id].astro b/packages/web/src/pages/s/[id].astro index df39f0070fa..1044cd85ffa 100644 --- a/packages/web/src/pages/s/[id].astro +++ b/packages/web/src/pages/s/[id].astro @@ -5,7 +5,8 @@ import config from '../../../config.mjs' import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro'; import Share from "../../components/Share.tsx"; -const apiUrl = import.meta.env.VITE_API_URL; +const apiUrl = import.meta.env.VITE_API_URL || process.env.VITE_API_URL; +const publicApiUrl = import.meta.env.VITE_PUBLIC_API_URL || process.env.VITE_PUBLIC_API_URL || apiUrl; const { id } = Astro.params; const res = await fetch(`${apiUrl}/share_data?id=${id}`); @@ -93,6 +94,7 @@ const ogImage = `${config.socialCard}/opencode-share/${encodedTitle}.png?model=$