From d10a52384b5a6b3a526b2d39fb78e8c16809a69c Mon Sep 17 00:00:00 2001 From: terra tauri Date: Fri, 2 Oct 2026 13:55:55 -0700 Subject: [PATCH] share: upload a .diff/.patch as a diff pin, with --title and --desc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The server has rendered text/x-diff with an X-Pin-Title banner and an X-Pin-Description PR description since diffview landed, but the CLI only sent HTML or MDX (a .diff got 415), so a diff pin needed a hand-rolled request with a bearer token. --desc travels base64-encoded, as the server documents, so it may span lines. Used 2026-10-02 to prove pin#47 (goldmark 1.8.6) on production: a diff pin described "See (https://example.org/)." renders href="https://example.org/", not the old "…/)". Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01Sn3acTQsYfyvVidkmhCC5j --- main.go | 46 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/main.go b/main.go index d99c5dc..c27824e 100644 --- a/main.go +++ b/main.go @@ -83,7 +83,8 @@ func usage() { Usage: pin login [--device] Sign in via Google. Use --device on SSH/headless. - pin share Upload an HTML or MDX file. Prints the share URL. + pin share Upload an HTML, MDX or .diff/.patch file. Prints the share URL. + A diff takes --title and --desc (markdown, the PR description). pin get Fetch a share's MDX source to stdout. --html for the rendered HTML form. pin publish Make a share publicly viewable (no login) via a @@ -396,10 +397,29 @@ func runWhoami(_ []string) int { // ----- share ----- func runShare(args []string) int { - if len(args) != 1 { - fmt.Fprintln(os.Stderr, "usage: pin share ") + // pin share [--title T] [--desc D]. --title and --desc apply to a .diff/.patch: the server renders a + // diff with an optional banner title and a markdown PR description (X-Pin-Title, X-Pin-Description). + var file, title, desc string + for i := 0; i < len(args); i++ { + switch { + case args[i] == "--title" && i+1 < len(args): + title = args[i+1] + i++ + case args[i] == "--desc" && i+1 < len(args): + desc = args[i+1] + i++ + case file == "": + file = args[i] + default: + fmt.Fprintln(os.Stderr, "usage: pin share [--title T] [--desc D]") + return 2 + } + } + if file == "" { + fmt.Fprintln(os.Stderr, "usage: pin share [--title T] [--desc D]") return 2 } + args = []string{file} body, err := os.ReadFile(args[0]) if err != nil { fmt.Fprintf(os.Stderr, "pin share: %v\n", err) @@ -425,14 +445,32 @@ func runShare(args []string) int { // agents can fetch via GET /p/{id}.mdx instead of paying tokens for // the rendered markup. contentType := "text/html; charset=utf-8" - if strings.HasSuffix(strings.ToLower(args[0]), ".mdx") { + lower := strings.ToLower(args[0]) + isDiff := strings.HasSuffix(lower, ".diff") || strings.HasSuffix(lower, ".patch") + switch { + case strings.HasSuffix(lower, ".mdx"): contentType = "text/mdx; charset=utf-8" + case isDiff: + // A patch renders as a side-by-side diff (diffview), with the PR description as markdown. + contentType = "text/x-diff; charset=utf-8" + } + if !isDiff && (title != "" || desc != "") { + fmt.Fprintln(os.Stderr, "pin share: --title and --desc apply to a .diff or .patch") + return 2 } req, _ := http.NewRequestWithContext(ctx, http.MethodPut, c.Issuer+"/api/pins", bytes.NewReader(body)) req.Header.Set("Content-Type", contentType) req.Header.Set("Authorization", "Bearer "+c.AccessToken) req.Header.Set("X-Agent", agent()) + if title != "" { + req.Header.Set("X-Pin-Title", title) + } + if desc != "" { + // Headers cannot carry newlines, so the description travels base64-encoded, which the server decodes. + req.Header.Set("X-Pin-Description", base64.StdEncoding.EncodeToString([]byte(desc))) + req.Header.Set("X-Pin-Description-Encoding", "base64") + } resp, err := http.DefaultClient.Do(req) if err != nil {