charmbracelet

Stars and mentions

Last 30 days, Oct 4 – Nov 2

GitHub stars1,612
mentions62
0306090120Oct 4Oct 18Nov 2
UTC days · repositories charmbracelet owns20 repositories

Package downloads

No package download history available yet.

Top repositories

charmbracelet’s repositories ranked by new stars, as on trending.

Loading

Contributes to

Repositories outside charmbracelet’s account where charmbracelet opened or reviewed pull requests in the past 365 days.

Who noticed charmbracelet

Everyone who starred or forked charmbracelet’s repositories since the archive began in 2011.

Notable accounts

Ordered by the stars their own repositories have received.

Biggest fans

Accounts that starred the most of these repositories.

Breakout weeks

Each repository’s best week of new stars, with the release published around it.

Mentions

62posts
Nov 33 posts
  1. If you need to record terminal videos or GIFs, I can recommend `vhs` Let your agent write the script and rerun it until the take is clean charmbracelet/vhs

    2 likes · 114 views
  2. Go でブログ API を15分で作る 「15分でブログを作る」と聞くと、Rails のデモを思い浮かべる方もいると思います。 Go でも、モデルを書いて、記事を作成できるようにして、コメントを追加して、最後にテストを通す。そんな流れを見せたくて、ブログの JSON API を作るデモを用意しました。 動画は 14分48秒。自作のコードジェネレータ群 kanna を使い、SQL の実行や行の読み取り、バリデーション、モデルからレスポンスへの変換、依存の組み立て、テストデータの作成を生成コードに任せています。 この記事では、デモの流れに沿って、何を書いて、どこを生成するのかを紹介します。 動画とソースコード youtube.com 手順とソースコードは チュートリアル にまとめています。 動画では Vim でコードを書き、生成コマンドを実行し、curl で動作を確認します。完成させるのは、次の機能を持つ API です。 記事の作成・一覧・詳細・更新・削除 記事へのコメント投稿 記事とコメントをまとめた JSON レスポンス タイトルとコメントのバリデーション PostgreSQL を使った統合テスト 録画には VHS を使っています。Vim への入力から生成、テスト、API の呼び出しまで、同じ台本で再実行できます。入力は台本どおりに自動で行っているので、15分は録画の長さです。手元で初めて試すときは、もう少しかかります。 DB の起動、依存のダウンロード、共通の HTTP ヘルパー、不正なリクエストのテストは事前に用意し、動画ではモデルの作成から始めています。 まずは記事のモデルと操作を定義する 最初に書くのは Post です。タイトルと本文、整数の ID、作成・更新日時を持つ、普通の Go の構造体です。 type Post struct { ID int64 Title string validate:"required,max=200" Body string CreatedAt time.Time UpdatedAt time.Time } 次に、記事の保存や取得に必要な操作を、repository パッケージの interface として定義します。 //go:generate go tool kanna-orm -destination ../postgres //kanna:repository table=posts type Post interface { Get(ctx context.Context, id int64, s ...scopes.Post) (model.Post, error) List(ctx context.Context, s ...scopes.Post) ([]model.Post, error) Insert(ctx context.Context, post model.Post) (model.Post, error) Update(ctx context.Context, post model.Post) error Delete(ctx context.Context, id int64) error } kanna-orm はモデルと interface、DB のスキーマ情報から、postgres パッケージに実装を生成します。引数にある scopes には、検索条件や並び順、関連の読み込みを指定する型が生成されます。 go tool kanna-orm describe ./... go generate ./scopes ./repository describe で DB のスキーマを kanna-orm.snapshot.json に保存しておくと、以降の生成では DB に接続しません。生成されたファイルには、INSERT や UPDATE の SQL、取得した行をモデルに読み込む Go のコードが入っています。何を実行しているかは、生成されたファイルを開いて確認できます。 kanna-orm は PostgreSQL と MySQL に対応しています。今回のデモでは PostgreSQL を使います。テーブルの定義は SQL で書き、ID の採番は DB に任せ、作成・更新日時はアプリで設定しています。 入力の検証とレスポンスへの変換を生成する 記事を作成・更新する入力は、モデルとは別に定義します。 //kanna:validate type SavePost struct { Title string json:"title" validate:"required,max=200" Body string json:"body" } kanna-validate を実行すると、validate タグに対応する検証コードが生成されます。検証時に reflection を使わず、生成された Go のコードでチェックします。デモでは、空のタイトルを送ると HTTP 422 と項目ごとのエラーが返るところまで確認します。 レスポンスも PostResponse として定義し、モデルからの変換を宣言します。 //kanna:mapper type _ interface { PostToResponse(model.Post) PostResponse } kanna-mapper が、対応するフィールドを代入する関数を生成します。ハンドラーからは mapper.PostToResponse(post) を呼びます。 HTTP のハンドラーや処理の順番は自分で書きます。「入力を検証する」「保存する」「レスポンスに変換する」という流れを書きながら、その間に必要になる定型コードを減らしていく形です。 依存を宣言して API を起動する ルーティングには標準ライブラリの http.ServeMux を使います。API が必要とする依存は、構造体のフィールドで宣言します。 //kanna:container type API struct { _ *pgxpool.Pool di:"arg" posts repository.Post di:"with=postgres.NewPost" } func provideDBTX(pool *pgxpool.Pool) postgres.DBTX { return pool } kanna-di は、この宣言と、プールを postgres.DBTX として返す provideDBTX から、NewAPI(pool) というコンストラクタを生成します。_ のフィールドはプールを引数として受け取るだけで、API には保持しません。依存を組み立てる処理も、生成された Go のコードとして読めます。 ここで一度 API を起動し、記事を作成・取得・更新します。コメント機能を足す前に、記事だけのブログが動くところを見せます。 動くブログにコメントを足す 次は、記事にひも付く Comment モデルを追加します。DB には記事を参照する外部キーを定義し、Post には次のフィールドを足します。 Comments []Comment レスポンスにも []CommentResponse を追加します。PostToResponse の宣言は変えずに mapper を再生成すると、コメントを含む入れ子の変換コードが生成されます。 外部キーと Comments フィールドから、kanna-orm は関連を読み込むスコープ WithComments() を生成します。記事の取得では、これを指定します。 post, err := a.posts.Get(r.Context(), id, scopes.Posts().WithComments()) respond(w, http.StatusOK, mapper.PostToResponse(post), err) respond は事前に用意したヘルパーで、エラーがあればレスポンスの代わりに 404 や 500 を返します。 コメントの保存処理や投稿用のルートも追加し、コードを再生成します。これで、記事とコメントをまとめた JSON を返せるようになります。 このデモで一番見せたいのは、モデルやレスポンスに項目を足したときに、SQL の実装や変換処理を手で追いかける量を減らせるところです。 fixture を生成して DB でテストする 最後に、kanna-fixture でテストデータを返す関数を生成します。fixture.Post() は、最初に Post に付けた validate タグを満たす値で、全フィールドを埋めた記事を返します。 post, err := posts.Insert(t.Context(), fixture.Post()) 記事にひも付くコメントを作るときは、必要な項目だけ上書きできます。 comment, err := comments.Insert(t.Context(), fixture.Comment(func(c *model.Comment) { c.PostID = post.ID })) テストは実際の PostgreSQL に接続し、トランザクション内で実行します。記事の保存・更新・取得、コメントの関連取得、入れ子のレスポンスへの変換を検証し、最後にロールバックします。 あわせて、記事を削除するとコメントも消えることを確認します。これは DB の ON DELETE CASCADE に任せています。 テストが通ったら API をもう一度起動し、コメント投稿、バリデーションエラー、記事の削除、削除後の 404 まで確認して完成です。 自分のコードで試してみてください kanna では、アプリ固有の型や interface を自分で定義しながら、繰り返し書く実装を生成コードに任せられるようにしています。今回使ったのは、orm・validate・mapper・di・fixture の 5 つです。 「Go のコードは好きだけれど、フィールドの代入や DB の読み取り処理を何度も書くのは面倒」と感じる方に、まず動画で書き心地を見てもらえたらうれしいです。 手元で試す手順と動画の台本は、チュートリアル に置いています。各ジェネレータは個別に使えるので、必要なものから試せます。 試してみて、どの部分が楽になったか、逆にどこで引っかかったかを、この記事のコメントや GitHub の Issue で聞かせてください。

  3. Reddit · · r/u_MrWillow78 · u/MrWillow78 · charmbracelet/gum

    Free GitHub tool: add choices to a shell script with Gum A free GitHub tool for making a terminal script easier to use: Gum by Charmbracelet. It adds interactive prompts, choices and other terminal controls without needing to write Go. On a Mac with Homebrew installed, run `brew install gum`. Try `gum choose "docs" "code" "quit"` to pick one option in the terminal. In a shell script, the selected value can be stored in a variable for the next step. Gum is MIT licensed and the local choice prompt needs no account or paid API. As with any script, read what it will run before executing it. I have not tested this on your machine. Official repo: charmbracelet/gum

    1 point
  4. GHSA-FGXM-5HVV-X4VH: GHSA-fgxm-5hvv-x4vh: Private Repository Enumeration via Go Module Discovery and HTTP Response… GHSA-fgxm-5hvv-x4vh: Private Repository Enumeration via Go Module Discovery and HTTP Response Discrepancies in Soft Serve > Vulnerability ID: GHSA-FGXM-5HVV-X4VH > CVSS Score: 5.3 > Published: 2026-10-30 Charmbracelet Soft Serve versions 0.5.0 through 0.12.2 contain an authorization bypass and observable response discrepancy vulnerability in the HTTP Git server. Remote attackers can determine the existence, exact names, and clone URLs of private repositories by issuing crafted Go remote import path discovery requests (?go-get=1) or by observing differential HTTP status codes across Git Smart HTTP, Dumb HTTP, and Git LFS endpoints. TL;DR Soft Serve versions 0.5.0 to 0.12.2 disclose private repository names and clone URLs over HTTP. An authorization bypass in the ?go-get=1 handler allows unauthenticated or low-privileged users to resolve private repository metadata via sub-path queries. Additionally, inconsistent HTTP status codes (401/403 vs. 404) across Git and LFS endpoints act as an oracle for repository existence. Upgrading to v0.12.3 resolves these issues. --- Technical Details - Vulnerability ID: GHSA-fgxm-5hvv-x4vh - Primary CWE: CWE-200 / CWE-203 / CWE-285 - CVSS v3.1 Score: 5.3 Medium (AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N) - Attack Vector: Network (HTTP Git / LFS / Go Import Handlers) - Impact: Private Repository Name & Clone URL Disclosure - Affected Versions: >= 0.5.0, < 0.12.3 - Patched Version: v0.12.3 - Exploit Status: No Public Exploits / Trivial via HTTP Client Affected Systems - github.com/charmbracelet/soft-serve - Soft Serve (github.com/charmbracelet/soft-serve): >= 0.5.0, < 0.12.3 (Fixed in: 0.12.3) Code Analysis Commit: 74e4154 fix: stop go-get requests from revealing private repository names // pkg/web/git.go - r.Handle(basePrefix, withParams(withAccess(access.ReadOnlyAccess, http.HandlerFunc(GoGetHandler)))).Methods(http.MethodGet) + r.Handle(basePrefix, withParams(withCaller(http.HandlerFunc(GoGetHandler)))).Methods(http.MethodGet) // pkg/web/goget.go + user := proto.UserFromContext(ctx) for { - if _, err := be.Repository(ctx, repo); err == nil { + if _, err := be.Repository(ctx, repo); err == nil && be.AccessLevelForUser(ctx, repo, user) >= access.ReadOnlyAccess { break } repo = path.Dir(repo) Commit: dc351aa fix: answer the same for private and missing repositories over HTTP // pkg/web/git.go +func denyRead(w http.ResponseWriter, r *http.Request, err error, lfsJSON bool) { + switch { + case badCredentials(err) && lfsJSON: + renderJSON(w, http.StatusForbidden, lfs.ErrorResponse{Message: "bad credentials"}) + case badCredentials(err): + renderForbidden(w, r) + case proto.UserFromContext(r.Context()) == nil && lfsJSON: + askCredentials(w, r) + renderJSON(w, http.StatusUnauthorized, lfs.ErrorResponse{Message: "credentials needed"}) + case proto.UserFromContext(r.Context()) == nil: + askCredentials(w, r) + renderUnauthorized(w, r) + case lfsJSON: + renderJSON(w, http.StatusNotFound, lfs.ErrorResponse{Message: "repository not found"}) + default: + renderNotFound(w, r) + } +} Mitigation Strategies - Upgrade Soft Serve to version v0.12.3 or later to enforce authorization checks during go-get resolution and unify HTTP error responses. - Disable the Soft Serve HTTP listener if Git operations can be restricted exclusively to SSH. - Set anonymous access (anon-access) to no-access to prevent unauthenticated ?go-get=1 sub-path traversal. - Block requests containing the ?go-get=1 query parameter at the reverse proxy or WAF layer if Go module discovery is not required. Remediation Steps: 1. Download the Soft Serve v0.12.3 binary from the official GitHub release page (github.com/charmbracelet/soft-serve/releases/tag/…) or build via go install github.com/charmbracelet/soft-serve/cmd/soft@v0.12.3. 2. Stop the running Soft Serve service, replace the binary with v0.12.3, and restart the service. 3. Verify the fix by issuing an unauthenticated HTTP GET request to a non-existent repository path (GET /nonexistent-repo.git/info/refs?service=git-upload-pack) and confirming the server returns 401 Unauthorized rather than 404 Not Found. References - GitHub Security Advisory: GHSA-fgxm-5hvv-x4vh - Charmbracelet Soft Serve Release v0.12.3 - Fix Commit: stop go-get requests from revealing private repository names - Fix Commit: answer the same for private and missing repositories over HTTP - Charmbracelet Soft Serve Source Repository --- Read the full report for GHSA-FGXM-5HVV-X4VH on our website for more details including interactive diagrams and full exploit analysis.

  5. GHSA-F3FJ-9625-RV3M: GHSA-f3fj-9625-rv3m: Race Condition in Soft Serve Repository Cache Invalidation GHSA-f3fj-9625-rv3m: Race Condition in Soft Serve Repository Cache Invalidation > Vulnerability ID: GHSA-F3FJ-9625-RV3M > CVSS Score: 5.9 > Published: 2026-10-30 A Time-of-Check to Time-of-Use (TOCTOU) race condition in Charmbracelet Soft Serve versions 0.6.0 through 0.12.2 allows unauthenticated users to retain read access to repositories after their visibility is changed from public to private. The flaw stems from premature cache invalidation in the SetPrivate method prior to committing the visibility update to the underlying database. Concurrent read requests arriving during the database transaction window repopulate the non-expiring in-memory LRU cache with stale public metadata, bypassing access controls across HTTP, SSH, and Git protocols until the server process is restarted. TL;DR Soft Serve versions >= 0.6.0 and < 0.12.3 contain a cache invalidation race condition in the SetPrivate repository method. Evicting the in-memory LRU cache before committing the database transaction allows concurrent unauthenticated requests to re-cache the stale public state, leaving private repositories perpetually readable by anonymous users. Upgrade to version 0.12.3, which removes the in-memory repository cache entirely. --- ⚠️ Exploit Status: POC Technical Details - Advisory ID: GHSA-f3fj-9625-rv3m - Vulnerability Class: CWE-362 / CWE-367 (TOCTOU Race Condition) - CVSS v3.1 Score: 5.9 Medium (CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N) - Affected Versions: github.com/charmbracelet/soft-serve >= 0.6.0, < 0.12.3 - Patched Version: 0.12.3 - Attack Vector: Network (HTTP, SSH, and git:// protocols) - Security Impact: Unauthenticated read access to private Git repositories - Exploit Status: Proof-of-Concept in unit tests (No KEV listing) Affected Systems - github.com/charmbracelet/soft-serve - soft-serve: >= 0.6.0, < 0.12.3 (Fixed in: 0.12.3) Code Analysis Commit: 5b307b4 fix: keep a repository private after its visibility changes (GHSA-f3fj-9625-rv3m) Commit: 0a4e6f0 fix: send the visibility webhook only when visibility changes Commit: e398b4d refactor: implement database module and abstract backend (Introduced vulnerability) Mitigation Strategies - Upgrade Soft Serve to version 0.12.3 or later to eliminate the vulnerable in-memory repository cache. - Restart the Soft Serve server process immediately after changing any repository's visibility from public to private to flush stale in-memory cache entries. - Create confidential repositories with the private flag (-p) enabled at initialization rather than toggling visibility after creation. - Disable anonymous read access globally by setting anon_access to no-access if unauthenticated public access is not required. Remediation Steps: 1. Update the Soft Serve binary or Go module to v0.12.3 using 'go get -u github.com/charmbracelet/soft-serve@v0.12.3' or via system package managers. 2. Restart all running Soft Serve service instances ('systemctl restart soft-serve') to ensure the updated binary is active and any previously cached in-memory state is cleared. 3. Audit server access logs for any unauthenticated Git read operations (such as GET requests to /<repo>.git/info/refs) that occurred after a repository was marked private. References - Soft Serve Security Advisory GHSA-f3fj-9625-rv3m - GitHub Advisory Database: GHSA-f3fj-9625-rv3m - Fix Commit: Remove in-memory repository cache (5b307b4da4db285f797cc028b381ba4d3d853019) - Fix Commit: Send visibility webhook only when visibility changes (0a4e6f0b7e063927c7128756e1c1b3db871edabf) - Prior Commit: Implement database module and abstract backend (e398b4dde723437f637b06710e0938d349b360e8) - Soft Serve Release v0.12.3 - Reporter Profile: sondt99 --- Read the full report for GHSA-F3FJ-9625-RV3M on our website for more details including interactive diagrams and full exploit analysis.

  6. Use crush 😄 charmbracelet/crush In all seriousness, Crush does feel better for my usage with more features and just satisfaction from usage. We have a lot of stuff in the oven for the "mega AI users" twitter.com

  7. Use crush 😄 charmbracelet/crush In all seriousness, Crush does feel better for my usage with more features and just satisfaction from usage. We have a lot of stuff in the oven for the "mega AI users" twitter.com

  8. building something with charmbracelet/wish sounds fun

    1 like
  9. I've got some really nice stuff coming up for Crush charmbracelet/crush Stay tuned for the most innovative things no one has done yet

  10. I've got some really nice stuff coming up for Crush charmbracelet/crush Stay tuned for the most innovative things no one has done yet

Trending awards, every completed day and week
Gold
141st place finishes
Silver
92nd place finishes
Bronze
103rd place finishes
Awarded repositories
6Owned by charmbracelet now

Repositories

Ordered by gold, then silver, then bronze.

  1. gumBest: 1st by stars, 3,562 stars441
  2. vhsBest: 1st by stars, 1,515 stars413
  3. glowBest: 1st by stars, 571 stars310
  4. bubbleteaBest: 1st by stars, 589 stars203
  5. crushBest: 1st by stars, 937 stars113
  6. lipglossBest: 2nd by stars, 591 stars020

A repository earns an award for finishing first, second or third in a completed trending day or week, ranked by new stars, new forks or pull request authors. Awards follow a repository through renames and transfers and count toward its current owner. Weeks run Monday to Sunday, UTC.