)]}'
{
  "log": [
    {
      "commit": "10bd3a6439c272113f524cea4487cc0c5c5e2b44",
      "tree": "3314bdd14a3b7334b929486ccbe5ce99fde1f98e",
      "parents": [
        "c4b78b4778f21f6a02d2a4c597fb156d8a231880"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 30 23:55:50 2025 +0000"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 30 17:09:11 2025 -0700"
      },
      "message": "webui: suppress patch edit count when tool call fails\n\nInstead of showing misleading edit counts like \u002766 edits\u0027 when a patch\ntool call fails, now shows \u0027failed\u0027 when tool_error is true.\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: s8ccc88517ab9d41ak\n"
    },
    {
      "commit": "c4b78b4778f21f6a02d2a4c597fb156d8a231880",
      "tree": "75d6f115e9822aafb929160addc59277788a6bda",
      "parents": [
        "d1c1ace819bdb69e59abaa6c675312a3ea32605c"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 30 16:40:00 2025 -0700"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 30 16:40:19 2025 -0700"
      },
      "message": "skabandclient: remove stray debug print\n"
    },
    {
      "commit": "d1c1ace819bdb69e59abaa6c675312a3ea32605c",
      "tree": "d6b287771346776439b2a35f10ef9084d4defb35",
      "parents": [
        "f31d72d72ccaecc832ff66d352c2fe8fd1296435"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Tue Jul 29 00:16:27 2025 +0000"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 30 16:07:30 2025 -0700"
      },
      "message": "cmd/sketch: add skaband-supported qwen\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: scbc3e984d79ceda6k\n"
    },
    {
      "commit": "f31d72d72ccaecc832ff66d352c2fe8fd1296435",
      "tree": "c140fed7fa408683c12c965cabbae7581af13984",
      "parents": [
        "d1d4bea8ede1f4c676763d28e9f9e03fa7bdc1e3"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 30 15:35:28 2025 -0700"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 30 15:55:59 2025 -0700"
      },
      "message": "dockerimg: delete non-actionable startup print\n"
    },
    {
      "commit": "d1d4bea8ede1f4c676763d28e9f9e03fa7bdc1e3",
      "tree": "e9df9977514941c4f8f7a52c20b02f411a948646",
      "parents": [
        "38707678bca1807a3350b01cae952293517750da"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 30 14:50:24 2025 -0700"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 30 15:55:59 2025 -0700"
      },
      "message": "cmd/sketch: trim trailing / from skaband-addr\n\nOtherwise the redirects that Go\u0027s mux does\nmakes for very confusing error messages.\n"
    },
    {
      "commit": "38707678bca1807a3350b01cae952293517750da",
      "tree": "e5813a760f2b7ed985a4e1060632be244b9ded77",
      "parents": [
        "051c3cdbf801bc84d5e9a71c90acc1a985c9215c"
      ],
      "author": {
        "name": "banksean",
        "email": "banksean@gmail.com",
        "time": "Wed Jul 30 20:18:39 2025 +0000"
      },
      "committer": {
        "name": "banksean",
        "email": "banksean@gmail.com",
        "time": "Wed Jul 30 13:29:02 2025 -0700"
      },
      "message": "webui: add dark mode support to sketch-tool-calls render\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: sab350b872b2e9fc0k\n"
    },
    {
      "commit": "051c3cdbf801bc84d5e9a71c90acc1a985c9215c",
      "tree": "79aafef6c4ab483ed0c6abb280492e63e0a17f81",
      "parents": [
        "66f45a6e299d2d0b758584f3c61e248f7c1ddaa8"
      ],
      "author": {
        "name": "banksean",
        "email": "banksean@gmail.com",
        "time": "Wed Jul 30 13:23:03 2025 -0700"
      },
      "committer": {
        "name": "banksean",
        "email": "banksean@gmail.com",
        "time": "Wed Jul 30 13:23:03 2025 -0700"
      },
      "message": "webui fix external message demo\n"
    },
    {
      "commit": "66f45a6e299d2d0b758584f3c61e248f7c1ddaa8",
      "tree": "5493a445d4797f419a0247171fdf6bade654af4f",
      "parents": [
        "6b1ceb1b40de83ac2bdbb83dd9aa38feeb69a17e"
      ],
      "author": {
        "name": "banksean",
        "email": "banksean@gmail.com",
        "time": "Wed Jul 30 13:11:25 2025 -0700"
      },
      "committer": {
        "name": "Autoformatter",
        "email": "bot@sketch.dev",
        "time": "Wed Jul 30 20:12:11 2025 +0000"
      },
      "message": "webui: fix rendering for gh worfkow events\n"
    },
    {
      "commit": "6b1ceb1b40de83ac2bdbb83dd9aa38feeb69a17e",
      "tree": "0c4292301139d00979e28898df3d94a419946a0a",
      "parents": [
        "136b66dbe453549cc411abc6e6b2144cfb368add"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 30 12:09:43 2025 -0700"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 30 12:19:56 2025 -0700"
      },
      "message": "webui: fix patch display whitespace (again)\n\nThanks, prettier, for breaking my code. Again.\n"
    },
    {
      "commit": "136b66dbe453549cc411abc6e6b2144cfb368add",
      "tree": "49565876ae80d0cc06564b4fd301946f1027d267",
      "parents": [
        "04f16a5af290588dd05f9f71da1f320711f625ff"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 30 11:48:58 2025 -0700"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 30 12:19:56 2025 -0700"
      },
      "message": "claudetool: accept relative paths in patch tool\n"
    },
    {
      "commit": "04f16a5af290588dd05f9f71da1f320711f625ff",
      "tree": "32ab42aecb00ef87a989de9b7287e500deeee38e",
      "parents": [
        "bdc6889f886667b06236fb20c5d080e3ac1f1eb8"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 30 11:46:25 2025 -0700"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 30 12:19:56 2025 -0700"
      },
      "message": "claudetool: make it easier to parameterize patch tool\n"
    },
    {
      "commit": "bdc6889f886667b06236fb20c5d080e3ac1f1eb8",
      "tree": "f86ee68725cba394d1df667723a9a3dad49c35a7",
      "parents": [
        "6fe809c2282f5d7e258ab60f4ff4d0b3e0739332"
      ],
      "author": {
        "name": "banksean",
        "email": "banksean@gmail.com",
        "time": "Mon Jul 28 17:28:13 2025 -0700"
      },
      "committer": {
        "name": "Autoformatter",
        "email": "bot@sketch.dev",
        "time": "Wed Jul 30 18:53:52 2025 +0000"
      },
      "message": "sketch: add support for \u0027external\u0027 message types\n\n- adds a new CodingAgentMessageType for loop.AgentMessage\n- adds an new /external handler to loophttp.go\n- modifies Agent to pass the .TextContent of ExternalMessage into the convo\n  as though it came from the user.\n- adds sketch-external-message web component, with a template for\n  github workflow run events specifically.\n- adds demos for sketch-external-message\n"
    },
    {
      "commit": "6fe809c2282f5d7e258ab60f4ff4d0b3e0739332",
      "tree": "1f9a0bccf5ab23ff15eb38c26bda8c9d4e3dfb3d",
      "parents": [
        "4a370aa1fe7a2fcafc41c0cd1bb4bf59bfb070a2"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Thu Jul 24 16:22:51 2025 -0700"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 30 11:30:10 2025 -0700"
      },
      "message": "claude: bash tool smorgasbord\n\nThis is a combination of a bunch of changes and bug fixes\naccumulated over a week. It decided not to spend a bunch of time\nteasing it apart into its components. I apologize.\n\nSignificant changes include:\n\n- clean up background bash execution\n- improve documentation\n- remove TODO we\u0027re not gonna do\n- add a \"process completed\" note to stderr\n- convert background result printing to xml-ish\n- combine stdout and stderr in background bash to match foreground use\n- hint to sketch to kill the process group\n- add missing timeouts propagation\n- tell agent that bash calls are stateless\n- thread pwd through explicitly\n- unify command creation\n- speed up missing command installation\n    I tried a bunch of different ways to prompt engineer this to be faster.\n    But Claude will be Claude. Solution: switch from agent to one-shot.\n\n    This is marginally more brittle, and can only use a package manager,\n    but that also prevents a bunch of possible curl|bash mess, etc.\n    And this was always best-effort anyway.\n\n    It\u0027s now MUCH faster to fail on non-existent commands, and about 2x\n    faster on the real commands I tried (yamllint, htop)...now mostly down\n    to the irreducible work involved in actually doing the installation.\n- remove SKETCH_ from bash env, except SKETCH_PROXY_ID\n- delay kill instructions until actually needed\n- add simple GIT_SEQUENCE_EDITOR\n- overhaul cancellation\n- explicitly disable EDITOR to prevent hangs\n    I have big plans here, but this will do for now.\n- simplify and unify handling of long outputs\n- switch to center trunctation of long outputs\n- add zombie process cleanup using unix.Wait4\n    Wow, I tried a bunch of things here.\n\n    When running as PID 1, we are responsible for reaping zombies.\n    Unfortunately, we can\u0027t do this in the simple/obvious way,\n    because simply listening for SIGCHILD and reaping races\n    with running cmd.Wait. We can\u0027t use a separate init process\n    or double-init sketch, because then we lose our seccomp\n    protection, and there\u0027s no particularly good way to extend it.\n\n    Instead, (h/t to Philip asking a good question), observe\n    that we are in a very controlled environment, and pretty much\n    the only way to get zombies is via the bash tool.\n    So we add reaping tied specifically to process groups started\n    by the bash tool, with an explicit understanding of their lifecycle.\n\n    Auto-installation of tools still creates zombies.\n    We now know how to fix it, but it is rare, so who cares.\n"
    },
    {
      "commit": "4a370aa1fe7a2fcafc41c0cd1bb4bf59bfb070a2",
      "tree": "995171cbf32df2c5b5973a942def8456f075c533",
      "parents": [
        "c3e6df8e2eb874b6ddc59beac72a1557c5fef7e1"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Mon Jul 28 23:19:48 2025 +0000"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 30 10:25:01 2025 -0700"
      },
      "message": "loop/server: add /debug/system-prompt, move logs to /debug/logs\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: sdadfdbbcd1589be1k\n"
    },
    {
      "commit": "c3e6df8e2eb874b6ddc59beac72a1557c5fef7e1",
      "tree": "5c5a998f5444a92a654b91c6b7665b8ce07114ab",
      "parents": [
        "3f129dbdeb0bab93adc1c63ba1bc830beb4256a5"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Tue Jul 29 16:15:38 2025 +0000"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 30 10:21:23 2025 -0700"
      },
      "message": "goreleaser: remove darwin/amd64 from build matrix\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: s4dd517a98a016dd0k\n"
    },
    {
      "commit": "3f129dbdeb0bab93adc1c63ba1bc830beb4256a5",
      "tree": "5b9a703dcae4b547563802b813cb28542676814d",
      "parents": [
        "aabca2e901349b88391b3bd5c255687012ae52bd"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 30 10:06:34 2025 -0700"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 30 10:13:12 2025 -0700"
      },
      "message": "Revert \"readme: add homebrew installation instructions\"\n\nUntil we get notarization going, we shouldn\u0027t recommend using homebrew.\nThis was submitted by accident.\n\nThis reverts commit 99b661859fa3dfe0dcf2c95efc6cf77dfcf43d9e.\n"
    },
    {
      "commit": "aabca2e901349b88391b3bd5c255687012ae52bd",
      "tree": "17e84913c0a40336929834cc92179307387776ba",
      "parents": [
        "72cf08c81fb2a2c64c654d9ca660b30a0cd4d284"
      ],
      "author": {
        "name": "Euan Kemp",
        "email": "euank@euank.com",
        "time": "Mon Jul 21 05:44:44 2025 +0000"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 30 09:57:11 2025 -0700"
      },
      "message": "all: update shebangs for more portability\n\nNixOS by default doesn\u0027t ship with /bin/bash, rather /usr/bin/env bash is the way to get the right bash.\n\nThis caused two issues on NixOS:\n\n1. The `push` button on the web interface would fail with ` ! [remote rejected] \u003ccommit\u003e -\u003e \u003cbranch\u003e (pre-receive hook declined)`\n2. `make` would result in an error\n\nOn the host side, for 1 you could see `fatal: cannot exec \u0027/tmp/sketch-git-hooks-3993344797/pre-receive\u0027: No such file or directory`, and for 2, you could similarly see `make: ./build/webui.sh: No such file or directory`\n\nThis fixes both of those errors by updating to more portable shebangs.\n```\n"
    },
    {
      "commit": "72cf08c81fb2a2c64c654d9ca660b30a0cd4d284",
      "tree": "2b1eea9c8093f3257b796a416a899ae539f728d9",
      "parents": [
        "1e5516701e0135557a5de6604a7bf9631a4b3a67"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 16 11:58:45 2025 -0700"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 30 09:56:42 2025 -0700"
      },
      "message": "readme: add homebrew installation instructions"
    },
    {
      "commit": "1e5516701e0135557a5de6604a7bf9631a4b3a67",
      "tree": "255d53b03dc42a313b94c9565aeb6c1e334063e6",
      "parents": [
        "9b1c003e7374003edd7f7316c08d494a8aa06b2b"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 30 03:16:54 2025 +0000"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 30 09:46:27 2025 -0700"
      },
      "message": "sketch: add fetch-on-launch flag for git fetch on startup\n\nDefaults to true, i.e. no changes.\n\nBut now I can turn it off so that running Sketch\ndoesn\u0027t pop 1password asking for ssh keys.\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: s494a69769c279ad8k\n"
    },
    {
      "commit": "9b1c003e7374003edd7f7316c08d494a8aa06b2b",
      "tree": "351d13bf0611697514fcc6e1616db81e36e5f8d4",
      "parents": [
        "2d832196004efc3ba31a83fdb207550d997b5e7b"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Sat Jul 26 17:53:09 2025 -0700"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 30 09:44:21 2025 -0700"
      },
      "message": "webui: silence more build spam\n"
    },
    {
      "commit": "2d832196004efc3ba31a83fdb207550d997b5e7b",
      "tree": "ebcabedc8a7371325b90d5e869a8e8ce3e6239b4",
      "parents": [
        "a77889bc1a0710acfb3fab612fc941d7a1b2f087"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Mon Jul 28 23:03:59 2025 +0000"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 30 09:44:21 2025 -0700"
      },
      "message": "webui: filter out empty messages\n\nThis shouldn\u0027t happen, but they do sometimes.\nThey\u0027re ugly but are harmless (or so it appears).\nFilter them away.\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: sc3177fd6d7337586k\n"
    },
    {
      "commit": "a77889bc1a0710acfb3fab612fc941d7a1b2f087",
      "tree": "c826bdef55ef8b6fdd2ec40e7e637931b5636295",
      "parents": [
        "b39bfc72dccbb5bb9757f2dd23be7957e0a7baf7"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Mon Jul 28 13:08:14 2025 -0700"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 30 09:44:20 2025 -0700"
      },
      "message": "termui: trim prompt down to just the slug\n\nhelps me remember in a sea of terminals what i was up to.\n"
    },
    {
      "commit": "b39bfc72dccbb5bb9757f2dd23be7957e0a7baf7",
      "tree": "7428bd044745f5c4e8e0dfd03efa086585157f10",
      "parents": [
        "cd26ab6a39f0b21cb37e68a0c7342edfc91284b6"
      ],
      "author": {
        "name": "David Crawshaw",
        "email": "david@zentus.com",
        "time": "Wed Jul 30 07:21:36 2025 -0700"
      },
      "committer": {
        "name": "David Crawshaw",
        "email": "david@zentus.com",
        "time": "Wed Jul 30 07:21:36 2025 -0700"
      },
      "message": ".clabot: add euank\n"
    },
    {
      "commit": "cd26ab6a39f0b21cb37e68a0c7342edfc91284b6",
      "tree": "28efbb874ce14e437b511552717910887a92536a",
      "parents": [
        "561174077c5bce5c49f0c986696c547685f4f8ae"
      ],
      "author": {
        "name": "Philip Zeyliger",
        "email": "philip@bold.dev",
        "time": "Tue Jul 29 11:54:35 2025 -0700"
      },
      "committer": {
        "name": "Philip Zeyliger",
        "email": "philip@bold.dev",
        "time": "Tue Jul 29 11:54:57 2025 -0700"
      },
      "message": "sketchdev mcp: fix missing env variable for MCP substitution\n"
    },
    {
      "commit": "561174077c5bce5c49f0c986696c547685f4f8ae",
      "tree": "57dc3d82470448fb5c94a5b307e73da5f107553a",
      "parents": [
        "aea6a8c80969ed4f495f7451301488d2814c01ab"
      ],
      "author": {
        "name": "philz",
        "email": "philip.zeyliger@gmail.com",
        "time": "Tue Jul 29 16:18:07 2025 +0000"
      },
      "committer": {
        "name": "Philip Zeyliger",
        "email": "philip@bold.dev",
        "time": "Tue Jul 29 11:37:34 2025 -0700"
      },
      "message": "skabandclient: remove unused methods\n\n- Remove ListRecentSketchSessionsMarkdown method\n- Remove ReadSketchSession method\n- Remove unused SketchSession struct\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: s104a1c26dede5a66k\n"
    },
    {
      "commit": "aea6a8c80969ed4f495f7451301488d2814c01ab",
      "tree": "06bb233d8ed47aa3c98749869c2e94d866090a3d",
      "parents": [
        "3d1308e3468915212bea595ddef14952eb82f7fc"
      ],
      "author": {
        "name": "Philip Zeyliger",
        "email": "philip@bold.dev",
        "time": "Tue Jul 29 11:30:34 2025 -0700"
      },
      "committer": {
        "name": "Philip Zeyliger",
        "email": "philip@bold.dev",
        "time": "Tue Jul 29 11:30:58 2025 -0700"
      },
      "message": "gh actions: capture test timing\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: sf1e7bc4f4c01d45ck\n"
    },
    {
      "commit": "3d1308e3468915212bea595ddef14952eb82f7fc",
      "tree": "de337e13601c4f73496f529bcd0ddfa6fc6d2cf5",
      "parents": [
        "5c86165937d556a7a37f51f609661d9c4910087e"
      ],
      "author": {
        "name": "banksean",
        "email": "banksean@gmail.com",
        "time": "Tue Jul 29 17:20:10 2025 +0000"
      },
      "committer": {
        "name": "Autoformatter",
        "email": "bot@sketch.dev",
        "time": "Tue Jul 29 17:23:01 2025 +0000"
      },
      "message": "webui: dark mode support to demo fmwk, tool cards\n\nDemo framework fixes:\n- sketch-push-button.demo.ts: add dark variants for bg, border, text colors\n- chat-input.ts: add dark variants for message containers and status sections\n- demo-runner.ts: replace inline error styles with Tailwind dark mode classes\n- sketch-call-status.demo.ts: fix hardcoded white backgrounds in status cards\n- sketch-diff-range-picker.demo.ts: add dark variants to picker and status displays\n- sketch-timeline-message.demo.ts: fix message container backgrounds\n- sketch-view-mode-select.demo.ts: comprehensive dark mode for all scenarios\n\nTool card fixes:\n- Update shared createPreElement function with dark:bg-gray-700/dark:text-gray-100\n- bash tool: fix command display and result areas\n- think tool: fix input content area with proper dark background\n- patch tool: comprehensive diff rendering with dark variants for added/removed/context lines\n- codereview tool: inherits dark mode through shared utilities\n\nAll components now use consistent dark mode patterns with proper contrast:\nbg-white dark:bg-gray-800, border-gray-200 dark:border-gray-700,\ntext-gray-600 dark:text-gray-300, matching existing components.\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: s8ac5253d0cbaa3ack\n"
    },
    {
      "commit": "5c86165937d556a7a37f51f609661d9c4910087e",
      "tree": "665944b890553e3d87da6bc7178aa62ed903acaf",
      "parents": [
        "0eff94f27145fc2d6709208ff2329b8e6d557c32"
      ],
      "author": {
        "name": "crawshaw",
        "email": "david@zentus.com",
        "time": "Tue Jul 29 16:34:52 2025 +0000"
      },
      "committer": {
        "name": "crawshaw",
        "email": "david@zentus.com",
        "time": "Tue Jul 29 16:34:59 2025 +0000"
      },
      "message": "oai: retry once for TLS bad record MAC errors\n\nAdd automatic retry logic for the specific TLS error \"tls: bad record MAC\"\nthat occurs occasionally with Fireworks API. The first occurrence triggers\nan automatic retry, only failing to the user after a second consecutive failure.\n\nThis addresses intermittent connection issues without requiring manual\nintervention for transient TLS handshake problems.\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: s701f83a97373c925k\n"
    },
    {
      "commit": "0eff94f27145fc2d6709208ff2329b8e6d557c32",
      "tree": "b4d547635ece4f9f2914b6ab508858ecc74ce195",
      "parents": [
        "c3aa7427c4cc3b40c0b700e84737cfc24e085cc4"
      ],
      "author": {
        "name": "Philip Zeyliger",
        "email": "philip@bold.dev",
        "time": "Mon Jul 28 20:24:25 2025 -0700"
      },
      "committer": {
        "name": "Philip Zeyliger",
        "email": "philip@bold.dev",
        "time": "Mon Jul 28 20:24:25 2025 -0700"
      },
      "message": "cmd/sketch: fix skaband MCP server config in container mode (again)\n\nUnsafe/innie/outtie modes are so confusing. Trying again!\n"
    },
    {
      "commit": "c3aa7427c4cc3b40c0b700e84737cfc24e085cc4",
      "tree": "96b7e3cfd2fe08c146f9403fc7094cec030f16c9",
      "parents": [
        "bb020f5b1074873e125164ec77de0228c2687a4c"
      ],
      "author": {
        "name": "Philip Zeyliger",
        "email": "philip@bold.dev",
        "time": "Mon Jul 28 20:11:16 2025 -0700"
      },
      "committer": {
        "name": "Philip Zeyliger",
        "email": "philip@bold.dev",
        "time": "Mon Jul 28 20:11:16 2025 -0700"
      },
      "message": "Revert \"cmd/sketch: fix skaband MCP server config in container mode\"\n\nThis reverts commit 741f12c123b4f591a35d345b0d8a30303b0d5190.\n"
    },
    {
      "commit": "bb020f5b1074873e125164ec77de0228c2687a4c",
      "tree": "277cf3471e95d23dac46dc7cea9e4a77b043f924",
      "parents": [
        "440fd83d5b7f41195f645771bfd735d5dca106ab"
      ],
      "author": {
        "name": "Philip Zeyliger",
        "email": "philip@bold.dev",
        "time": "Mon Jul 28 19:41:55 2025 -0700"
      },
      "committer": {
        "name": "Commit Queue Bot",
        "email": "bot@sketch.dev",
        "time": "Mon Jul 28 19:41:55 2025 -0700"
      },
      "message": "Revert \"gh actions: run formatters in parallel\"\n\nThis reverts commit 07cdd551613643a6f4ecfa6169448625705573c7.\n"
    },
    {
      "commit": "440fd83d5b7f41195f645771bfd735d5dca106ab",
      "tree": "06c68a323a425cb7b4f454925c44bba5547e93c8",
      "parents": [
        "80ff717f2679b9298932d5dd7281270bcb51a16f"
      ],
      "author": {
        "name": "Philip Zeyliger",
        "email": "philip@bold.dev",
        "time": "Mon Jul 28 19:50:00 2025 -0700"
      },
      "committer": {
        "name": "Philip Zeyliger",
        "email": "philip@bold.dev",
        "time": "Mon Jul 28 19:50:00 2025 -0700"
      },
      "message": "gh actions: Removing queue-dev.yml.\n"
    },
    {
      "commit": "80ff717f2679b9298932d5dd7281270bcb51a16f",
      "tree": "fca523bfd75f62993c4971b8a9d543f70e98e808",
      "parents": [
        "a8d37da0a203582777cc06b13fef1003ee950522"
      ],
      "author": {
        "name": "Philip Zeyliger",
        "email": "philip@bold.dev",
        "time": "Mon Jul 28 15:26:02 2025 -0700"
      },
      "committer": {
        "name": "Philip Zeyliger",
        "email": "philip@bold.dev",
        "time": "Mon Jul 28 15:26:02 2025 -0700"
      },
      "message": "gh actions: run formatters in parallel\n\nWe can run gofmt and prettier in parallel, so let\u0027s do that.\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: s8536e19843fdb5b6k\n"
    },
    {
      "commit": "a8d37da0a203582777cc06b13fef1003ee950522",
      "tree": "a44fda0d71010d87ba09475cb99bf3b509d01f8f",
      "parents": [
        "83cf606957e8d05f1dc690991a178b302d848877"
      ],
      "author": {
        "name": "Philip Zeyliger",
        "email": "philip@bold.dev",
        "time": "Mon Jul 28 19:50:36 2025 +0000"
      },
      "committer": {
        "name": "Philip Zeyliger",
        "email": "philip@bold.dev",
        "time": "Mon Jul 28 14:28:35 2025 -0700"
      },
      "message": "cmd/sketch: fix skaband MCP server config in container mode\n\nIn container mode, the skaband MCP server configuration was not being\nadded when a skaband address was provided, breaking the automatic\nconfiguration of sketch.dev integration tools.\n\nThe issue was introduced in commit f3c5d6ac when code was refactored to\ncreate the resolveModel function for de-duplication between runInHostMode\nand runInUnsafeMode, but runInContainerMode was not updated to include\nthe skaband MCP configuration logic.\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: s213332d8c6723b25k\n"
    },
    {
      "commit": "83cf606957e8d05f1dc690991a178b302d848877",
      "tree": "e5b0bd4133847e0c551520a52e618c0b39148648",
      "parents": [
        "02f4820e4a5245f545293c34e121d52640d3cb11"
      ],
      "author": {
        "name": "philz",
        "email": "philip.zeyliger@gmail.com",
        "time": "Mon Jul 28 14:23:04 2025 -0700"
      },
      "committer": {
        "name": "Philip Zeyliger",
        "email": "philip@bold.dev",
        "time": "Mon Jul 28 14:23:04 2025 -0700"
      },
      "message": "loop: add /debug/tools handler for mcp and tool inspection\n\nAdds a new debug endpoint at /debug/tools that displays all available\ntools including their names, descriptions, JSON schemas, and metadata.\nShows both built-in Claude tools and MCP tools with proper type indication.\nIncludes nicely formatted HTML with syntax highlighting for schemas.\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: s10d266ddbc5a7fc0k\n"
    },
    {
      "commit": "02f4820e4a5245f545293c34e121d52640d3cb11",
      "tree": "53ca4cb172e9c84ec0238c2ccb7095c08100e12f",
      "parents": [
        "a8ac1500f4313203d0b0d453a59aa016a2b93859"
      ],
      "author": {
        "name": "philz",
        "email": "philip.zeyliger@gmail.com",
        "time": "Mon Jul 28 21:02:07 2025 +0000"
      },
      "committer": {
        "name": "philz",
        "email": "philip.zeyliger@gmail.com",
        "time": "Mon Jul 28 21:16:02 2025 +0000"
      },
      "message": "webui: expand patch tool cards by default\n\nMade patch tool cards expand by default to show inline diffs\nimmediately, similar to screenshot tool cards.\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: s56bd70ba6302978dk\n"
    },
    {
      "commit": "a8ac1500f4313203d0b0d453a59aa016a2b93859",
      "tree": "2fe098765aa9f7115b3bcfbde6e70138b480f0fa",
      "parents": [
        "693c9503f202a76c41f96aa6fd501664a1f8f134"
      ],
      "author": {
        "name": "Philip Zeyliger",
        "email": "philip@bold.dev",
        "time": "Sun Jul 27 21:24:42 2025 -0700"
      },
      "committer": {
        "name": "Philip Zeyliger",
        "email": "philip@bold.dev",
        "time": "Sun Jul 27 21:24:42 2025 -0700"
      },
      "message": "sketch/mcp: fix mcp sse stream context cancellation\n\nThe SSE stream was being started with a timeout context that got canceled\nimmediately after connection establishment, causing \u0027context canceled\u0027 errors\nand breaking MCP tool execution with \u0027Could not find session\u0027 errors.\n\nSeparate connection establishment timeout from long-running SSE stream context:\n- Use agent\u0027s main context for mcpClient.Start() (SSE stream lifecycle)\n- Use separate timeout context for Initialize() and ListTools() (connection only)\n\nFixes SSE stream persistence and enables successful MCP tool execution.\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: sb595ea17e6f1205ck\n"
    },
    {
      "commit": "693c9503f202a76c41f96aa6fd501664a1f8f134",
      "tree": "e1923e690cb165fd65c438f25b62ffa0b700a0d3",
      "parents": [
        "c36d1da8758dc128c6ef9b33a6e99a798cc17653"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Fri Jul 25 22:22:19 2025 -0700"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Fri Jul 25 22:22:19 2025 -0700"
      },
      "message": "Revert \"cmd/sketch: add a process reaper\"\n\nThe reaper was too fast, and it was reaping processes\nthat we started with os/exec before os/exec could Wait\non them, which caused Wait to return an error.\n\nMost of our error handling for Wait causes bad things to happen:\nsketch exits, diffs look scary, etc.\n\nRevert now, and I\u0027ll resubmit later when it\u0027s more robust.\n\nThis reverts commit 587b57dce0d2301e5628ed3d39e62f20d58d7f48.\n"
    },
    {
      "commit": "c36d1da8758dc128c6ef9b33a6e99a798cc17653",
      "tree": "b11cb2b34b855446d78570ac19d27054ad86e6e5",
      "parents": [
        "9224eb0571146da5fce2c1ec0f7f13a72f30cc3a"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Fri Jul 25 18:00:12 2025 -0700"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Fri Jul 25 21:59:27 2025 -0700"
      },
      "message": "cmd/sketch: add a process reaper\n\nWhen we\u0027re PID 1 in a container, reaping zombies\nis our responsibility, which we were shirking.\n\nNo longer! Now we 🥷 all the 🧟 into ☠️, and not 🐢 either.\n"
    },
    {
      "commit": "9224eb0571146da5fce2c1ec0f7f13a72f30cc3a",
      "tree": "e1923e690cb165fd65c438f25b62ffa0b700a0d3",
      "parents": [
        "7cae9d5d4c629d3c1f85aaab974632e093a8959d"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Sat Jul 26 04:45:05 2025 +0000"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Fri Jul 25 21:47:02 2025 -0700"
      },
      "message": "loop: change current_datetime to current_date\n\nSo that we don\u0027t always invalidate the k/v cache.\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: s330e5fc0212d37d4k\n"
    },
    {
      "commit": "7cae9d5d4c629d3c1f85aaab974632e093a8959d",
      "tree": "d2dab86b28c19100b55a14d06f9c631860d77860",
      "parents": [
        "e34ffd60e0a8dfc5ba55be35d68a396a73d53750"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Tue Jul 22 23:08:39 2025 +0000"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Fri Jul 25 13:36:14 2025 -0700"
      },
      "message": "webui: add JavaScript alert for file save failures\n\nNow that Philip fixed #213, this should be safe to unleash on everyone.\n\nJavaScript alerts are ugly, but:\n\n- this shouldn\u0027t happen\n- if it does, the user should really know that their edits are in peril\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: s95d29aed61ef60f6k\n"
    },
    {
      "commit": "e34ffd60e0a8dfc5ba55be35d68a396a73d53750",
      "tree": "208c68febe0f077054d1709cc732192aee367413",
      "parents": [
        "783ab31ae38604be5331ec030264dcec08574aae"
      ],
      "author": {
        "name": "Philip Zeyliger",
        "email": "philip@bold.dev",
        "time": "Fri Jul 25 13:20:49 2025 -0700"
      },
      "committer": {
        "name": "Philip Zeyliger",
        "email": "philip@bold.dev",
        "time": "Fri Jul 25 13:23:37 2025 -0700"
      },
      "message": "sketch: fix diff view editing of gitignore\u0027d files and forward more http errors to logs\n\nFixes https://github.com/boldsoftware/sketch/issues/213\n\nWe had \"sketch\" git ignored, so \"git add sketch/cmd/sketch/main.go\" was\nfailing when a user was editing it in diff view. The gitignore was\nincorrectly specified. (\"git ls-files -i -c --exclude-standard\"\nreturning main.go should have tipped us off, but who knew!)\n\nAnyway, fixed that, and improved the logging.\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: s3ed65211dd497f76k\n"
    },
    {
      "commit": "783ab31ae38604be5331ec030264dcec08574aae",
      "tree": "39b46c979117377be2676c995b38f8854eb0cd8b",
      "parents": [
        "8a0de526a223c834cb7323b4e1717f40f0d514d4"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Fri Jul 25 07:22:38 2025 -0700"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Fri Jul 25 13:02:34 2025 -0700"
      },
      "message": "loop: tone down some date handling\n\nLest it get out of control.\n24 hours is a long time.\n"
    },
    {
      "commit": "8a0de526a223c834cb7323b4e1717f40f0d514d4",
      "tree": "4a2cdef6e018d52b94d57ec6769f038bca70aea2",
      "parents": [
        "40c9da832c33b2d807c06f54eeccabb38fbe01d1"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Thu Jul 24 19:29:07 2025 +0000"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Fri Jul 25 13:02:34 2025 -0700"
      },
      "message": "loop: add current datetime to agent system prompt\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: s1fb7648c40f24f62k\n"
    },
    {
      "commit": "40c9da832c33b2d807c06f54eeccabb38fbe01d1",
      "tree": "8ecfb88d6504bc1accaf9c65fca7ae995411fb07",
      "parents": [
        "ab3702caa60dbf7845b0b9f928b9741e34d84d04"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Thu Jul 24 21:08:20 2025 +0000"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Fri Jul 25 12:08:45 2025 -0700"
      },
      "message": "llm/oai: fix tool error handling in openai translation layer\n\nTool errors were being swallowed because the OAI provider always set\nToolError\u003dfalse when converting tool results back to llm.Content. This\ncaused failed tool calls to appear as successful to the LLM.\n\nFix by modifying fromLLMMessage to prefix error content with \u0027Error: \u0027\nwhen ToolError\u003dtrue, since OpenAI doesn\u0027t have an explicit error field\nfor tool results. This ensures tool failures are properly communicated\nto the LLM so it can respond appropriately.\n\nThe fix resolves tool call error swallowing and makes JSON decode errors\nvisible to the LLM for proper error handling.\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: s6bc264a7abf25c7bk\n"
    },
    {
      "commit": "ab3702caa60dbf7845b0b9f928b9741e34d84d04",
      "tree": "30f786c5c91567a5805bf8078108b22dacb0839b",
      "parents": [
        "4571fd6d06f65195341791b46d84dc80bb0676b3"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Thu Jul 24 20:22:50 2025 +0000"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Fri Jul 25 12:08:40 2025 -0700"
      },
      "message": "llm/oai: add qwen3-coder-fireworks model\n"
    },
    {
      "commit": "4571fd6d06f65195341791b46d84dc80bb0676b3",
      "tree": "6e61da4d6a9ed29891c0b84f503ff5ccb5441741",
      "parents": [
        "c540df7f730eb0e07a5aa543ec128dba38a7cf81"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Fri Jul 25 16:56:02 2025 +0000"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Fri Jul 25 12:06:18 2025 -0700"
      },
      "message": "webui: add model name to info popup k/v pairs\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: s89edebe17dd6d6edk\n"
    },
    {
      "commit": "c540df7f730eb0e07a5aa543ec128dba38a7cf81",
      "tree": "02c00aabebdb39b72cc272a33c3d787f1809a602",
      "parents": [
        "e67e3b65003d21f68c3736a563a94e5ad1ba26b0"
      ],
      "author": {
        "name": "Philip Zeyliger",
        "email": "philip@bold.dev",
        "time": "Fri Jul 25 09:21:56 2025 -0700"
      },
      "committer": {
        "name": "Philip Zeyliger",
        "email": "philip@bold.dev",
        "time": "Fri Jul 25 09:21:56 2025 -0700"
      },
      "message": "sketch/mcp: increase connection and tool timeouts\n"
    },
    {
      "commit": "e67e3b65003d21f68c3736a563a94e5ad1ba26b0",
      "tree": "07f9899eb261dfc31d045192ee7e8e58d03ac9c4",
      "parents": [
        "9c74cb9f4865a28d468fdeab0e5755a882e55409"
      ],
      "author": {
        "name": "Philip Zeyliger",
        "email": "philip@bold.dev",
        "time": "Thu Jul 24 16:54:21 2025 -0700"
      },
      "committer": {
        "name": "Philip Zeyliger",
        "email": "philip@bold.dev",
        "time": "Thu Jul 24 16:55:19 2025 -0700"
      },
      "message": "loop: nudge to install platform tools\n"
    },
    {
      "commit": "9c74cb9f4865a28d468fdeab0e5755a882e55409",
      "tree": "c53473ee57a0ccfdfdd7549bc43a6b6f33554da1",
      "parents": [
        "b7bd8d861748ee16a13bd9537a34d13336bd0fc1"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Thu Jul 24 12:52:04 2025 -0700"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Thu Jul 24 15:16:46 2025 -0700"
      },
      "message": "loop: rework done tool\n\nSmaller, simpler schema.\nEliminates $ref, which some LLMs don\u0027t like / don\u0027t understand.\nSeems to work just as well.\n"
    },
    {
      "commit": "b7bd8d861748ee16a13bd9537a34d13336bd0fc1",
      "tree": "df282a99727c41003ab0cd78582c47670549a8cf",
      "parents": [
        "b01a3f9401f21e3d5b0cdb9a50a53ad139e56ed5"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Thu Jul 24 12:08:18 2025 -0700"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Thu Jul 24 12:20:54 2025 -0700"
      },
      "message": "cmd/sketch: look up openai keys via envvars in resolveModel\n\nWe ignored their existence, thereby treating them an Anthropic.\n"
    },
    {
      "commit": "b01a3f9401f21e3d5b0cdb9a50a53ad139e56ed5",
      "tree": "fc4d41870837cf33284a4abb2e402c074371b17e",
      "parents": [
        "938600913f90918c64f35c330b61711983ac35fe"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 23 13:29:50 2025 -0700"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Thu Jul 24 12:20:54 2025 -0700"
      },
      "message": "cmd/sketch: allow using other models in safe mode\n"
    },
    {
      "commit": "938600913f90918c64f35c330b61711983ac35fe",
      "tree": "2d93cd90776cd2dc2e16df101526109b993b3824",
      "parents": [
        "7764c5ebfb4175354e65286ed3673a54793798bd"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 23 13:24:14 2025 -0700"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Thu Jul 24 12:20:54 2025 -0700"
      },
      "message": "dockerimg: always pass -llm-api-key\n\nIt is constructed correctly.\nJust use it.\nFewer places to have to think about.\n"
    },
    {
      "commit": "7764c5ebfb4175354e65286ed3673a54793798bd",
      "tree": "01ae4595358f945c895bf677b7123140920d572f",
      "parents": [
        "d2fe3ba95b876365fa62e084dbdbae8153a2327c"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 23 13:19:07 2025 -0700"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Thu Jul 24 12:20:54 2025 -0700"
      },
      "message": "cmd/sketch: de-dup some code\n\nNo functional changes.\n"
    },
    {
      "commit": "d2fe3ba95b876365fa62e084dbdbae8153a2327c",
      "tree": "6ad8209a974d956d6242b42dd02c2a6fdf20e20a",
      "parents": [
        "0530da0092392838ce75df3ec366b32e24dddf20"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 23 13:05:47 2025 -0700"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Thu Jul 24 12:20:54 2025 -0700"
      },
      "message": "llm/ant: add claude userName helpers\n\nThis moves us towards functional opus support.\nIt also is a baby step towards restoring sanity to this code.\n\nAlso, stop treating model\u003d\"\" as \"sonnet\".\nThere\u0027s a default for the flag.\n"
    },
    {
      "commit": "0530da0092392838ce75df3ec366b32e24dddf20",
      "tree": "906852cb1cf168373ad12479bf64fef36505fd2e",
      "parents": [
        "44dfdce5edac084927f122988b6f5b783d67c93a"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 23 03:47:43 2025 +0000"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Thu Jul 24 12:20:54 2025 -0700"
      },
      "message": "llm/oai: make Model a value type\n"
    },
    {
      "commit": "44dfdce5edac084927f122988b6f5b783d67c93a",
      "tree": "dae838d2e9f89908f34edbc88c1019de10b5bf23",
      "parents": [
        "0d04c13e27e0008e9da1eb458a74ff8f7a55f682"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 23 13:02:29 2025 -0700"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Thu Jul 24 12:20:54 2025 -0700"
      },
      "message": "llm/ant: add APIKeyEnv\n"
    },
    {
      "commit": "0d04c13e27e0008e9da1eb458a74ff8f7a55f682",
      "tree": "e68017c0f21336b64902bb27096fc24c55e3dcd4",
      "parents": [
        "d64bc91c50a8cb172ce82388c786f9382de19d51"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 23 13:02:12 2025 -0700"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Thu Jul 24 12:20:54 2025 -0700"
      },
      "message": "cmd/sketch: move a function\n\nMoves the runIn* functions closer together,\nfor when humans need to step in and un-****\nthis code.\n"
    },
    {
      "commit": "d64bc91c50a8cb172ce82388c786f9382de19d51",
      "tree": "120defb3e1d3a2c52b8300ae4d9958d10bc8afb6",
      "parents": [
        "aeaf892c3a40e99c699c006dbccbe9c859e0cc69"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Thu Jul 24 11:42:33 2025 -0700"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Thu Jul 24 11:42:33 2025 -0700"
      },
      "message": "loop: put each tool on its own line\n\nCosts nothing, prevents merge conflicts for me.\n"
    },
    {
      "commit": "aeaf892c3a40e99c699c006dbccbe9c859e0cc69",
      "tree": "f0db4d9b4f9826ceb527976e1846c7e64bbcd44e",
      "parents": [
        "01bf5ae0d7249d83735e65b916c776825983aa34"
      ],
      "author": {
        "name": "Autoformatter",
        "email": "bot@sketch.dev",
        "time": "Thu Jul 24 18:31:16 2025 +0000"
      },
      "committer": {
        "name": "Autoformatter",
        "email": "bot@sketch.dev",
        "time": "Thu Jul 24 18:31:16 2025 +0000"
      },
      "message": "all: fix formatting\n"
    },
    {
      "commit": "01bf5ae0d7249d83735e65b916c776825983aa34",
      "tree": "8f83cd0ac09452ab66aaf20169d5d7dfdabb0457",
      "parents": [
        "beaa86a1fa821ce5874f3a2dd6a1609f7bd79698"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Thu Jul 24 17:50:00 2025 +0000"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Thu Jul 24 11:30:37 2025 -0700"
      },
      "message": "webui: restore command+enter keyboard shortcut for diff comments\n\nThis used to exist. I missed it. Bring it back.\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: s6cd4f7fa81a2ee71k\n"
    },
    {
      "commit": "beaa86a1fa821ce5874f3a2dd6a1609f7bd79698",
      "tree": "acab6693c4e740b8908ad16327418a3578eaee06",
      "parents": [
        "141547d1d7169bf1c9a9d156eb6b585f1d9d398c"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 23 03:37:21 2025 +0000"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Thu Jul 24 11:30:35 2025 -0700"
      },
      "message": "all: delete commit-message-style tool\n\nIt added significant latency.\nAll the caching options were unappealing.\n\nInstead, let users specify in dear_llm.md if they care,\nand default to simple, concise messages.\n\nAt some point (soon?), we will likely\nmake it easier in the UI to edit commit messages.\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: sbcd1f38735d091aek\n"
    },
    {
      "commit": "141547d1d7169bf1c9a9d156eb6b585f1d9d398c",
      "tree": "e21b530b625a3433653a08fa6ec581a0b2add8a6",
      "parents": [
        "568bebf2f2a23917ac6ce7d2f2f30aba54a57eca"
      ],
      "author": {
        "name": "banksean",
        "email": "banksean@gmail.com",
        "time": "Thu Jul 24 09:21:18 2025 -0700"
      },
      "committer": {
        "name": "Autoformatter",
        "email": "bot@sketch.dev",
        "time": "Thu Jul 24 16:25:01 2025 +0000"
      },
      "message": "sketch-app-shell: nav to /messages/ on sessionEnd\n\nFixes https://github.com/boldsoftware/bold/issues/457\n"
    },
    {
      "commit": "568bebf2f2a23917ac6ce7d2f2f30aba54a57eca",
      "tree": "0fa126370bdc31193834bd00b2d0ed36b952b82b",
      "parents": [
        "7fe76973f6cba7c7a51f4b896444c2ce3c1ce0d5"
      ],
      "author": {
        "name": "banksean",
        "email": "banksean@gmail.com",
        "time": "Thu Jul 24 02:44:54 2025 +0000"
      },
      "committer": {
        "name": "banksean",
        "email": "banksean@gmail.com",
        "time": "Thu Jul 24 02:51:34 2025 +0000"
      },
      "message": "webui: fix IDLE/DISCONNECTED oscillation by replacing initialLoadComplete misuse\n\nFix DataManager session_ended handler that caused rapid status switching\nbetween IDLE and DISCONNECTED when sessions ended.\n\nIssue Description:\nWhen a session ended, the UI\u0027s sketch-call-status component would rapidly\noscillate between IDLE and DISCONNECTED states, suggesting continued\nconnection attempts despite the session being over.\n\nRoot Cause Analysis:\nThe primary issue was session_ended handler improperly firing initialLoadComplete\nevent, confusing timeline component state management. The initialLoadComplete event\nwas added for newsessions functionality but broke assumptions in regular sketch\nsessions. The timeline component expects initialLoadComplete to signal new page\nloads, not ended sessions.\n\nWhen fired for ended sessions, this caused UI re-render cycles and state confusion\nthat interfered with connection status display, creating the oscillation effect.\n\nImplementation Changes:\n- Added sessionDataReady event type for ended session data readiness\n- Modified session_ended handler to emit sessionDataReady instead of\n  initialLoadComplete for ended sessions\n- Preserved initialLoadComplete semantics for active session data loading\n- Added clarifying comment to existing isSessionEnded guard in connect()\n\nSecurity \u0026 Compatibility:\n- No security implications, purely UI state management fix\n- Newsessions component unaffected (doesn\u0027t use initialLoadComplete)\n- Timeline component behavior restored to expected state\n- All existing event handling preserved\n\nThis fix eliminates the connection status oscillation while maintaining\nproper separation of concerns between live session loading and ended\nsession display states.\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: scd1b437c8ae7c381k\n"
    },
    {
      "commit": "7fe76973f6cba7c7a51f4b896444c2ce3c1ce0d5",
      "tree": "619c0b433cd856fd2b0a977a3453dd9b79105d54",
      "parents": [
        "3dd3e4144d2e0b9fec6b5e0039ed12e2c0170265"
      ],
      "author": {
        "name": "banksean",
        "email": "banksean@gmail.com",
        "time": "Wed Jul 23 19:19:01 2025 -0700"
      },
      "committer": {
        "name": "banksean",
        "email": "banksean@gmail.com",
        "time": "Wed Jul 23 19:19:01 2025 -0700"
      },
      "message": "data.ts: add missing .isSessionEnded check in .connect()\n"
    },
    {
      "commit": "3dd3e4144d2e0b9fec6b5e0039ed12e2c0170265",
      "tree": "11eb418a7980cb9f7faa6b1a20dee2e811a24b13",
      "parents": [
        "a6b995b83277dd730e35a8f5be14c139d82a544e"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Tue Jul 22 20:32:03 2025 -0700"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 23 17:53:58 2025 -0700"
      },
      "message": "webui: add diff display for patches\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: s2e9bdfb014ddec3ck\n"
    },
    {
      "commit": "a6b995b83277dd730e35a8f5be14c139d82a544e",
      "tree": "2cb9d54d6c38916a6639061e2086f24055e68ecf",
      "parents": [
        "57afbca4ac1dbd4351aae93302e34ee45b36a25f"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Thu Jul 24 00:45:05 2025 +0000"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 23 17:53:58 2025 -0700"
      },
      "message": "webui: kill eslint\u0027s no-explicit-any warning dead dead dead\n\nA sign that it maybe it\u0027s not a good fit for us\nis the fact that it was sprinkled around our codebase\nas prolifically as blinding snow in an Antarctic blizzard.\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: s79f40917a73a3320k\n"
    },
    {
      "commit": "57afbca4ac1dbd4351aae93302e34ee45b36a25f",
      "tree": "6c9222f0c81394c3f1089ceb040a4ca1a0ed9eb0",
      "parents": [
        "aa22eb7947ae6bb09ce558bcfa52a1d8b2b3286a"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 23 13:29:59 2025 -0700"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 23 17:19:23 2025 -0700"
      },
      "message": "llm: rename -dump-ant-calls to -dump-llm\n\nAnd tweak behavior.\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: s1605a29b744ae5f1k\n"
    },
    {
      "commit": "aa22eb7947ae6bb09ce558bcfa52a1d8b2b3286a",
      "tree": "89a95de4ba4f9e7889f6133dea31a7e5f73f54c6",
      "parents": [
        "9dc2f62c6d44f53e057bd7319ffbcbc00ef5f2a0"
      ],
      "author": {
        "name": "Autoformatter",
        "email": "bot@sketch.dev",
        "time": "Wed Jul 23 19:59:36 2025 +0000"
      },
      "committer": {
        "name": "Autoformatter",
        "email": "bot@sketch.dev",
        "time": "Wed Jul 23 19:59:36 2025 +0000"
      },
      "message": "all: fix formatting\n"
    },
    {
      "commit": "9dc2f62c6d44f53e057bd7319ffbcbc00ef5f2a0",
      "tree": "753ea15307dd1ee834ae6973f1a363858e09f4b5",
      "parents": [
        "ddd22da04ed405520012089ffb2bc244b82e41e7"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 23 01:04:00 2025 +0000"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 23 12:58:52 2025 -0700"
      },
      "message": "all: remove multiplechoice tool\n\nIt\u0027s rarely used; doesn\u0027t pull its weight.\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: s11d827ec20c6ddb8k\n"
    },
    {
      "commit": "ddd22da04ed405520012089ffb2bc244b82e41e7",
      "tree": "56289a404f162c80f848fccacb0a53dec4b0891f",
      "parents": [
        "359273758d4651ec7212d49b963b56b9a7db1e34"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Tue Jul 22 20:14:50 2025 -0700"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 23 12:58:45 2025 -0700"
      },
      "message": "claudetool: add detail to keyword search error message\n"
    },
    {
      "commit": "359273758d4651ec7212d49b963b56b9a7db1e34",
      "tree": "62bfa9444e6d87f6a883f1f967155d7ae6d2750a",
      "parents": [
        "c67d7bced3a3619cbf031075fa8442a696381c4a"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Tue Jul 22 21:38:17 2025 -0700"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed Jul 23 12:58:13 2025 -0700"
      },
      "message": "git_tools: add even more detail when commit fails\n\nFollow-up to 32577b177e34bc7b23183df22d375c9ada146613\n"
    },
    {
      "commit": "c67d7bced3a3619cbf031075fa8442a696381c4a",
      "tree": "27e8b6990244865fd3d020ea1fd4ef56f61fc603",
      "parents": [
        "3b44cc3120b595e82dcc2a6081b8a07fc24c739e"
      ],
      "author": {
        "name": "banksean",
        "email": "banksean@gmail.com",
        "time": "Wed Jul 23 10:59:02 2025 -0700"
      },
      "committer": {
        "name": "Autoformatter",
        "email": "bot@sketch.dev",
        "time": "Wed Jul 23 19:09:31 2025 +0000"
      },
      "message": "webui/src/data: handle ended and read-only sessions\n"
    },
    {
      "commit": "3b44cc3120b595e82dcc2a6081b8a07fc24c739e",
      "tree": "3d4f3c2911390428c0c89aa8dcd13dbfb035ce31",
      "parents": [
        "f18aafd177a90b928b1c1babbe5e763f85eab56d"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Tue Jul 22 02:28:14 2025 +0000"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Tue Jul 22 20:10:27 2025 -0700"
      },
      "message": "loop: do slug generation outside the agent loop\n\n[This commit message written entirely by a human; it is all useful.]\n\nWe can make a slug based on the first message.\nIt\u0027s good enough.\nThat keeps it--and the slug tool--out of the agent\u0027s context.\nIt\u0027s also one fewer step for extremely short Sketch runs,\nwhich is the straw that broke this particular camel\u0027s back.\n\nThis is a mild UI regression, in that there\u0027s a slight stall\nafter the user types their first message, during which\nthe slug is being generated. See (2) below.\n\nWhile we\u0027re here, add handling of compaction agent messages.\n\nThis leaves two big TODOs outstanding:\n\n1.\n\nUntangle the awful rats nest that is slug and branch management;\nwe have callbacks back and forth and layers and locking and it\u0027s all confusing.\nOne visible for that this ugliness takes is that every time the agent tries out a slug,\nthe top bar in the webui updates, even if we then reject that slug as a duplicate.\nthere are other forms of ugliness, just less visible.\n\n2.\n\nMake slug generation concurrent with the rest of the agent,\nto avoid a short stall right after the user\u0027s first request (ick).\n\nWhen we make slug setting concurrent, we\u0027ll likely need to resuscitate\nthe bashPermissionCheck, except it\u0027ll be \"silently block and wait for\nbackground slug generation to complete\", rather than \"reject the tool call\".\nDitto for about_sketch, and any other tool call that expects\nthe slug or branch name to be set.\n\nGenerally, before undertaking this effort, we should fix (1) above,\nmake convos generally concurrency safe (maybe COW?), and\nfigure out to get race-enabled innie builds.\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: s8ac5f6a9faa611ebk\n"
    },
    {
      "commit": "f18aafd177a90b928b1c1babbe5e763f85eab56d",
      "tree": "84fdd856884c956139be6af5cab76a0c4e1a93be",
      "parents": [
        "1ee0bc6c8f6ee7a6d0b26189815879f7455069c6"
      ],
      "author": {
        "name": "Philip Zeyliger",
        "email": "philip@bold.dev",
        "time": "Mon Jul 21 15:15:54 2025 -0700"
      },
      "committer": {
        "name": "Philip Zeyliger",
        "email": "philip@bold.dev",
        "time": "Tue Jul 22 19:29:50 2025 -0700"
      },
      "message": "Diff view: include boundary commits.\n\nIn a nearly empty repo, you want to include the boundary commits for the\ndiff view list commit list.\n"
    },
    {
      "commit": "1ee0bc6c8f6ee7a6d0b26189815879f7455069c6",
      "tree": "9779a6c73738efb9375887d2dcd6de84a3ddcbc6",
      "parents": [
        "d37f7a73a0b77329d4701edee3d6d9a6b79d4e47"
      ],
      "author": {
        "name": "banksean",
        "email": "banksean@gmail.com",
        "time": "Tue Jul 22 23:24:18 2025 +0000"
      },
      "committer": {
        "name": "Autoformatter",
        "email": "bot@sketch.dev",
        "time": "Tue Jul 22 23:31:38 2025 +0000"
      },
      "message": "webui: add dark mode support to demo server\n\nCore Component Dark Mode Support:\n- sketch-timeline.ts: Welcome box, loading indicators, thinking bubbles, navigation\n- sketch-tool-card-base.ts: Status icons, elapsed time, hover states, details panel\n- All 14 sketch-tool-card-* components: Consistent dark styling for tool results\n\nDemo System Infrastructure:\n- Enhanced demo runner (demo.html) with complete dark theme CSS variables\n- Added sketch-theme-toggle integration in sidebar for easy theme switching\n- Extended demo-fixtures utilities with semantic color system (8 new CSS variables)\n- Comprehensive color mappings: backgrounds, text, borders, controls, buttons\n\nDemo File Compatibility (13 files updated):\n- Fixed 60+ instances of hardcoded colors across all demo components\n- Replaced light-mode-only colors (#24292f, #f6f8fa, etc.) with CSS variables\n- Updated text colors, backgrounds, borders for proper contrast in both themes\n- Maintained visual hierarchy while ensuring accessibility\n\nTechnical Implementation:\n- CSS custom properties system with automatic :root/.dark theme switching\n- GitHub-inspired dark color palette for professional appearance\n- Smooth 0.2s transitions for seamless theme changes\n- Semantic variable naming for maintainability and consistency\n\nKey Features Added:\n- Theme toggle accessible from any demo (no need to navigate to Theme Toggle demo)\n- Complete visual consistency between light and dark modes\n- Proper contrast ratios throughout for accessibility\n- Tool card demos showcase dark mode styling with realistic content\n\nComponents Updated:\nTimeline: Welcome messages, loading states, thinking indicators, jump button\nTool Cards: Status icons, input/output display, hover states, detailed views\nDemos: Labels, backgrounds, instruction panels, control elements, text content\n\nThe demo system now provides a complete, professional dark mode experience\nthat matches modern development tool standards with excellent usability\nand visual consistency across all components and demonstrations.\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: s97589e2fe2fdeeb3k\n"
    },
    {
      "commit": "d37f7a73a0b77329d4701edee3d6d9a6b79d4e47",
      "tree": "07e5bb969f7a1e48292fa8c4674f4f1cb9fce58c",
      "parents": [
        "488e8a476fccf2514f3703d0d576c35989987b34"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Tue Jul 22 13:43:52 2025 +0000"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Tue Jul 22 06:54:08 2025 -0700"
      },
      "message": "webui: make diff UI update after data loads\n\nSometimes diff content would load quickly but the UI would stay stuck\nshowing \u0027Loading...\u0027 for many seconds until some external action\n(like clicking in console) triggered a repaint.\n\nRoot cause: Lit wasn\u0027t automatically detecting that it needed to re-render\nwhen the async loadDiffData() completed and this.loading changed from\ntrue to false.\n\nFix: Explicitly call requestUpdate() to force a re-render after loading\ncompletes, ensuring the UI immediately shows the loaded diff content.\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: s6ba963f401c89febk\n"
    },
    {
      "commit": "488e8a476fccf2514f3703d0d576c35989987b34",
      "tree": "6e4935a8e789057408d1c8037fbca5ab2cbd51b9",
      "parents": [
        "d1b7dd616f47c873e241d2354f03feacce46e637"
      ],
      "author": {
        "name": "Autoformatter",
        "email": "bot@sketch.dev",
        "time": "Tue Jul 22 02:47:29 2025 +0000"
      },
      "committer": {
        "name": "Autoformatter",
        "email": "bot@sketch.dev",
        "time": "Tue Jul 22 02:47:29 2025 +0000"
      },
      "message": "all: fix formatting\n"
    },
    {
      "commit": "d1b7dd616f47c873e241d2354f03feacce46e637",
      "tree": "ca542f2d24021707404ccea1083a8b9bff0b8a9a",
      "parents": [
        "43b60b9b6906a2077175bcb1c3ea53b90d92a9f8"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Mon Jul 21 19:36:23 2025 -0700"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Mon Jul 21 19:46:45 2025 -0700"
      },
      "message": "loop: skip TestPortMonitor_ShouldIgnoreProcess on macOS\n\nIt doesn\u0027t work, and can\u0027t be made to work.\n"
    },
    {
      "commit": "43b60b9b6906a2077175bcb1c3ea53b90d92a9f8",
      "tree": "14ecadd5c94db811087f97b0e7858f1482ff5f4e",
      "parents": [
        "95354b15c6469f871ecabd778c04304bcce16195"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Mon Jul 21 14:57:10 2025 -0700"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Mon Jul 21 19:46:45 2025 -0700"
      },
      "message": "llm: make Tool.Run return ToolOut\n\nThis is preliminary work towards\nallowing tools to add additional information.\nNo functional changes (at least, that\u0027s the intent).\n"
    },
    {
      "commit": "95354b15c6469f871ecabd778c04304bcce16195",
      "tree": "0cf43e5b9d0d071df1557bf158828c4c93626c2f",
      "parents": [
        "e75d0eac125c8b72f8fa899c7d6eb64d6bdedb9e"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Tue Jul 22 00:03:50 2025 +0000"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Mon Jul 21 19:46:45 2025 -0700"
      },
      "message": "git_tools: add more detail when commit fails\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: sae1162580ef7ab85k\n"
    },
    {
      "commit": "e75d0eac125c8b72f8fa899c7d6eb64d6bdedb9e",
      "tree": "261087d7f452f5e99b75bada3643fc0da9cc5427",
      "parents": [
        "f2b5ee0011655cae4e3c977eaec6255ae46a5b88"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Mon Jul 21 23:50:44 2025 +0000"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Mon Jul 21 19:46:45 2025 -0700"
      },
      "message": "llm/ant: convert dumpText constant to dump-ant-calls command line flag\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: sd58268f97ed95de8k\n"
    },
    {
      "commit": "f2b5ee0011655cae4e3c977eaec6255ae46a5b88",
      "tree": "c0ccbaa55962839542939083521b0a344a71c1d3",
      "parents": [
        "44de46c38652047d3ff70b59f69d00bad4985561"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Mon Jul 21 16:42:53 2025 -0700"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Mon Jul 21 19:46:45 2025 -0700"
      },
      "message": "llm/ant: dump debug to files, not stdout\n\n- doesn\u0027t break termui\n- easier to tell apart different requests\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: s0e399715e9573285k\n"
    },
    {
      "commit": "44de46c38652047d3ff70b59f69d00bad4985561",
      "tree": "ada533469ed18d0e3ccc29870a620e5b5edef219",
      "parents": [
        "15a0ffa7a68f5915eaed6044260edc794c806283"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Mon Jul 21 16:14:34 2025 -0700"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Mon Jul 21 19:46:45 2025 -0700"
      },
      "message": "mcp: fix ineffectual break\n\nCaught by gopls, surfaced by sketch.\n"
    },
    {
      "commit": "15a0ffa7a68f5915eaed6044260edc794c806283",
      "tree": "20f7b89d99ff320f89ebb7025cc71aa2bcef3597",
      "parents": [
        "0f00427c39583c905df906ed16843dadce8e19bd"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Mon Jul 21 15:53:48 2025 -0700"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Mon Jul 21 19:46:45 2025 -0700"
      },
      "message": "webui: improve reconnection delays\n\n- make them a lot more aggressive,\n  as the user is likely sitting and staring at the screen\n- make the numbers rounder (easier to grok)\n- add some jitter\n"
    },
    {
      "commit": "0f00427c39583c905df906ed16843dadce8e19bd",
      "tree": "bedcfe4b085e781317c7f2a40998094423b168fe",
      "parents": [
        "106f6f5472c233011b6abee307cb6cd0e962f718"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Mon Jul 21 22:40:03 2025 +0000"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Mon Jul 21 19:46:45 2025 -0700"
      },
      "message": "webui: refactor reconnection timeout logic to use lookup table\n\nNo functional changes.\nJust a lot clearer, and a lot easier to reason about and edit.\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: s3faf2c10280df867k\n"
    },
    {
      "commit": "106f6f5472c233011b6abee307cb6cd0e962f718",
      "tree": "06caf9e7ab2a1ecafebdc6d9a3a9846d8cfe161c",
      "parents": [
        "cf724583660cf683efa7fd8eb9b32e120e88beb7"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Mon Jul 21 15:22:00 2025 -0700"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Mon Jul 21 19:46:45 2025 -0700"
      },
      "message": "claudetool: tweak bashkit error message when changing branches\n\n- remove reference to outie (normal sketch sessions\n  don\u0027t have the concept introduced in the prompt anywhere)\n- tweak wording for precision\n- add some extra details\n- point out the Push button\n- let claude rewrite a bit for concision\n"
    },
    {
      "commit": "cf724583660cf683efa7fd8eb9b32e120e88beb7",
      "tree": "ca8f4072f3e131ace3400552698caa04786a155c",
      "parents": [
        "4432056dc2db2f4b9b1120a890255a540a4c8537"
      ],
      "author": {
        "name": "banksean",
        "email": "banksean@gmail.com",
        "time": "Mon Jul 21 22:22:57 2025 +0000"
      },
      "committer": {
        "name": "Autoformatter",
        "email": "bot@sketch.dev",
        "time": "Mon Jul 21 22:45:56 2025 +0000"
      },
      "message": "skaband: move timeline viewer from sketch/webui to resolve bundle conflicts\n\nMove read-only timeline viewer functionality from sketch/webui to skaband\nto eliminate custom element registration conflicts when using newsessions\nwith newui\u003dtrue parameter.\n\nChanges made:\n- Created skaband/sketch-timeline-readonly.ts with timeline viewer functionality\n- Updated skaband/messages.gohtml to use local sketch-timeline-readonly.js bundle\n- Removed messages-viewer.ts from sketch/webui build configuration\n- Updated Makefile to remove messages-viewer bundle extraction steps\n- Added sketch-timeline-readonly.ts to skaband build.js entry points\n\nFiles created:\n- skaband/sketch-timeline-readonly.ts: Timeline viewer component for archived sessions\n- skaband/sketch-timeline-readonly.test.ts: Test coverage for timeline functionality\n\nFiles removed:\n- sketch/webui/src/messages-viewer.ts: Relocated to skaband\n- sketch/webui/src/messages-viewer.test.ts: Relocated to skaband\n\nBuild configuration updates:\n- sketch/webui/esbuild.go: Remove messages-viewer.ts from bundleTs arrays\n- sketch/webui/package.json: Remove messages-viewer.js export\n- skaband/build.js: Add sketch-timeline-readonly.ts entry point\n- Makefile: Remove messages-viewer bundle extraction from build and prepare-deploy\n\nThe timeline viewer is only used by skaband for archived session viewing,\nso co-locating it with skaband eliminates the architectural issue where\nboth messages-viewer.js and newsessions-components.js contained overlapping\ncustom elements (sketch-timeline, sketch-tool-card-*, etc.) causing\nregistration conflicts.\n\nThis change resolves bundle conflicts on /newsessions?newui\u003dtrue while\nmaintaining identical functionality for archived message viewing.\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: sd62ec3594672899ek\n"
    },
    {
      "commit": "4432056dc2db2f4b9b1120a890255a540a4c8537",
      "tree": "8e9738b3335fb5112ddb2ebfe70fe3aa8fb23f44",
      "parents": [
        "d8eb4649835351b57d0143242b96547e8e67a14a"
      ],
      "author": {
        "name": "banksean",
        "email": "banksean@gmail.com",
        "time": "Mon Jul 21 11:09:38 2025 -0700"
      },
      "committer": {
        "name": "Autoformatter",
        "email": "bot@sketch.dev",
        "time": "Mon Jul 21 18:10:38 2025 +0000"
      },
      "message": "webui: update DEAR_LLM.md, rm .shadowRoot refs\n"
    },
    {
      "commit": "d8eb4649835351b57d0143242b96547e8e67a14a",
      "tree": "14130199c24d7b38777288b0d9849d36dac8d4c2",
      "parents": [
        "44f7616740655a904c6b0319d739bfce97f4951b"
      ],
      "author": {
        "name": "banksean",
        "email": "banksean@gmail.com",
        "time": "Mon Jul 21 03:04:52 2025 +0000"
      },
      "committer": {
        "name": "Autoformatter",
        "email": "bot@sketch.dev",
        "time": "Mon Jul 21 17:50:00 2025 +0000"
      },
      "message": "webui: migrate sketch-monaco-view to tailind\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: s2b8f6e849aabb45fk\n"
    },
    {
      "commit": "44f7616740655a904c6b0319d739bfce97f4951b",
      "tree": "6728e7919443b389c53009365efc881089e47671",
      "parents": [
        "581bd795582ab99b1aa81a39466a8433c14d4485"
      ],
      "author": {
        "name": "banksean",
        "email": "banksean@gmail.com",
        "time": "Mon Jul 21 03:04:52 2025 +0000"
      },
      "committer": {
        "name": "Autoformatter",
        "email": "bot@sketch.dev",
        "time": "Mon Jul 21 03:09:20 2025 +0000"
      },
      "message": "webui: remove sketch-network-status component\n\nRemove legacy sketch-network-status component that was emptied in\nprevious commits. The component has been superseded by sketch-call-status\nwhich handles all connection status functionality.\n\nFiles removed:\n- sketch-network-status.ts: Component with empty render (display: none)\n- sketch-network-status.test.ts: Test file for invisible component\n- sketch-network-status.demo.ts: Demo file for non-functional component\n\nUpdated references:\n- sketch-app-shell-base.ts: Remove import and component usage\n- status-indicators.demo.ts: Remove unused import\n- demo-framework/demo-runner.ts: Remove from component list\n- index-generated.html: Regenerated without network status demo\n\nConnection status functionality is now fully handled by sketch-call-status\ncomponent which properly displays IDLE/WORKING/DISCONNECTED states with\nvisual indicators and animations. This removal eliminates dead code and\nreduces the LitElement migration scope to just sketch-monaco-view.ts.\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: s2b8f6e849aabb45fk\n"
    },
    {
      "commit": "581bd795582ab99b1aa81a39466a8433c14d4485",
      "tree": "ce1e1b90c6800486ad94c8f1fa58cf2cbbce9e05",
      "parents": [
        "d52d39d31ad33400b6bdb0ff678a6739de92b2eb"
      ],
      "author": {
        "name": "banksean",
        "email": "banksean@gmail.com",
        "time": "Sun Jul 20 18:30:12 2025 -0700"
      },
      "committer": {
        "name": "banksean",
        "email": "banksean@gmail.com",
        "time": "Sun Jul 20 18:34:11 2025 -0700"
      },
      "message": "webui: s/demo-runner/demo/g\n"
    },
    {
      "commit": "d52d39d31ad33400b6bdb0ff678a6739de92b2eb",
      "tree": "a777c975562ee7ace6e3459a4701f6098c80fa8c",
      "parents": [
        "23a35b8da9da135ad130bee89a1f96cac4d02bf6"
      ],
      "author": {
        "name": "banksean",
        "email": "banksean@gmail.com",
        "time": "Sun Jul 20 14:57:38 2025 -0700"
      },
      "committer": {
        "name": "Autoformatter",
        "email": "bot@sketch.dev",
        "time": "Mon Jul 21 01:16:10 2025 +0000"
      },
      "message": "webui: clean up component demos\n"
    },
    {
      "commit": "23a35b8da9da135ad130bee89a1f96cac4d02bf6",
      "tree": "5d76d0de2217cd78ba33ed0dd3fa00f725bac90d",
      "parents": [
        "9ee3042aa7826d9ae662c86743a5f87468972d27"
      ],
      "author": {
        "name": "banksean",
        "email": "banksean@gmail.com",
        "time": "Sun Jul 20 21:18:31 2025 +0000"
      },
      "committer": {
        "name": "Autoformatter",
        "email": "bot@sketch.dev",
        "time": "Sun Jul 20 21:49:21 2025 +0000"
      },
      "message": "webui: migrate mobile components to SketchTailwindElement\n\nComplete migration of all mobile web components from LitElement to\nSketchTailwindElement base class with Tailwind CSS styling:\n\nComponents migrated:\n- mobile-chat-input.ts: Chat input with file upload, textarea auto-resize\n- mobile-chat.ts: Message display with markdown rendering and tool calls\n- mobile-diff.ts: Git diff viewer with Monaco editor integration\n- mobile-shell.ts: Main container coordinating mobile UI layout\n- mobile-title.ts: Header with connection status and view switching\n\nKey changes:\n- Replaced LitElement inheritance with SketchTailwindElement\n- Converted all CSS-in-JS styles to Tailwind utility classes\n- Removed static styles blocks and shadow DOM styling\n- Added custom animations via document.head for non-Tailwind effects\n- Preserved all existing functionality and component interactions\n\nTechnical improvements:\n- Consistent iOS safe area support with env() CSS functions\n- Proper flexbox layouts for mobile responsive design\n- Maintained accessibility with proper ARIA labels and focus states\n- Enhanced hover and active states using Tailwind modifiers\n- Optimized touch interactions with -webkit-overflow-scrolling\n\nThe mobile components now follow the established SketchTailwindElement\npattern while maintaining full feature parity with the original\nshadow DOM implementations.\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: s21f840091392b02ek\n"
    },
    {
      "commit": "9ee3042aa7826d9ae662c86743a5f87468972d27",
      "tree": "a669fecd906f39e504508cf2c8c31c3a26726322",
      "parents": [
        "3eaa43377ddaec484ea3564f178078a84dc6e02d"
      ],
      "author": {
        "name": "banksean",
        "email": "banksean@gmail.com",
        "time": "Sat Jul 19 12:57:45 2025 -0700"
      },
      "committer": {
        "name": "banksean",
        "email": "banksean@gmail.com",
        "time": "Sat Jul 19 12:57:45 2025 -0700"
      },
      "message": "default to light mode instead of system, for now\n"
    },
    {
      "commit": "3eaa43377ddaec484ea3564f178078a84dc6e02d",
      "tree": "79c226b85a10f50cf554b87899828e318d63f46f",
      "parents": [
        "d082fdceb0378ddbceb81f51ab77ac1af904d57c"
      ],
      "author": {
        "name": "banksean",
        "email": "banksean@gmail.com",
        "time": "Sat Jul 19 02:19:06 2025 +0000"
      },
      "committer": {
        "name": "Autoformatter",
        "email": "bot@sketch.dev",
        "time": "Sat Jul 19 18:44:56 2025 +0000"
      },
      "message": "webui: implement comprehensive dark mode support\n\nAdd complete dark mode implementation across all web UI components with\ntheme initialization and consistent styling:\n\nCore infrastructure:\n- Update DARK_MODE.md documentation with current implementation details\n- Add theme initialization to sketch-app-shell-base component\n- Implement ThemeService integration with existing theme toggle system\n\nComponent updates with dark mode variants:\n- sketch-app-shell: Main container backgrounds and text colors\n- sketch-app-shell-base: Top banner, todo panel container with gradient backgrounds\n- sketch-chat-input: Input fields, buttons, overlay messages, and drop zones\n- sketch-container-status: Info panels, SSH connection displays, and expandable details\n- sketch-call-status: Status indicators, banners, and activity states\n- sketch-view-mode-select: Tab container, button states, and active tab styling\n- sketch-timeline-message: Message bubbles, markdown content, code blocks, and commit info\n- sketch-push-button: Overlay popup, form controls, and result containers\n- sketch-todo-panel: Todo items, headers, comment modal, and form elements\n- sketch-diff-range-picker: Dropdown interface, commit display, and git reference badges\n\nCSS and styling improvements:\n- Comprehensive markdown content styling for dark theme\n- Code block backgrounds and syntax highlighting adjustments\n- Mermaid diagram container styling for dark mode\n- Auto-generated link styling with proper contrast\n- Git reference badge colors (tags: amber, branches: green, sketch-base: blue)\n\nInteractive element enhancements:\n- Consistent hover states across light and dark themes\n- Proper focus indicators with accessible contrast ratios\n- Loading spinners and progress indicators adapted for dark backgrounds\n- Error and success message styling with semantic color preservation\n\nKey implementation details:\n- Consistent color mappings: white→gray-900, gray-100→gray-800, gray-200→gray-700\n- Preserved brand colors (blue-500, red-600, green-600) that work in both themes\n- Maintained semantic color coding for success/error/warning states\n- Ensured accessibility with proper contrast ratios throughout\n- Theme system integration enables seamless switching without page reload\n\nThe web UI now provides a complete, professional dark mode experience\nwith excellent usability and visual consistency while preserving all\nexisting functionality and accessibility standards.\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: s8219557c3ecba46dk\n"
    },
    {
      "commit": "d082fdceb0378ddbceb81f51ab77ac1af904d57c",
      "tree": "85ebda02944618e18dfc4612fe8954f58ff05c29",
      "parents": [
        "ae3724ef039833e1227714412e2c5289ad8875c8"
      ],
      "author": {
        "name": "banksean",
        "email": "banksean@gmail.com",
        "time": "Fri Jul 18 13:31:52 2025 -0700"
      },
      "committer": {
        "name": "banksean",
        "email": "banksean@gmail.com",
        "time": "Fri Jul 18 13:33:10 2025 -0700"
      },
      "message": "claudetool/bashkit: don\u0027t mention set-slug when blocking sketch-wip renames\n"
    },
    {
      "commit": "ae3724ef039833e1227714412e2c5289ad8875c8",
      "tree": "7242aaea3ef677a86ace50e7c805935f27890d94",
      "parents": [
        "19a32eaa120562170595e42584f3fc4b40828b97"
      ],
      "author": {
        "name": "banksean",
        "email": "banksean@gmail.com",
        "time": "Fri Jul 18 16:52:37 2025 +0000"
      },
      "committer": {
        "name": "Autoformatter",
        "email": "bot@sketch.dev",
        "time": "Fri Jul 18 20:29:23 2025 +0000"
      },
      "message": "webui: add dark mode implementation plan\n\nAlso implements phase 1 of the plan, which just lays the foundation\nfor implementing the user-visible changes. This does not include\nany dark-mode theme settings for the rest of the web UI, and\nwhile it does inlcude a \"sketch-theme-toggle\" element, this is\nonly included in the demo:runner vite server for interactive testing.\nIt\u0027s not included in the app shell base yet.\n\n-SM\n\n---\n\nDocuments comprehensive strategy for implementing dark mode in Sketch\u0027s\nweb UI using Tailwind CSS class-based approach.\n\nThe plan covers:\n- Foundation setup (Tailwind config, theme service, toggle component)\n- Systematic component updates with dark mode variants\n- Accessibility considerations and testing checklist\n- 4-week implementation timeline\n\nKey technical decisions:\n- Uses SketchTailwindElement base class following existing patterns\n- Singleton theme service with event system for component coordination\n- Respects system preferences while allowing user override\n- Persistent theme storage in localStorage\n\nThis provides a roadmap for adding dark mode support while maintaining\nconsistency with Sketch\u0027s existing web component architecture.\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: s6b69ad95a4394f98k\n"
    },
    {
      "commit": "19a32eaa120562170595e42584f3fc4b40828b97",
      "tree": "eaa6cac6a052a02a97a94a62a2fc13adadd50a6e",
      "parents": [
        "2be768e4f4d28dc56c7e0b10df342c607ef04833"
      ],
      "author": {
        "name": "banksean",
        "email": "banksean@gmail.com",
        "time": "Fri Jul 18 18:29:31 2025 +0000"
      },
      "committer": {
        "name": "banksean",
        "email": "banksean@gmail.com",
        "time": "Fri Jul 18 12:04:31 2025 -0700"
      },
      "message": "claudetool/bashkit: add sketch-wip branch protection with process-level tracking\n\nAdd a best-effort check to reject git commands that would change the\ncontainer-side \u0027sketch-wip\u0027 git branch. The protection prevents:\n\n1. Branch renaming: git branch -m sketch-wip newname\n2. Branch switching: git checkout otherbranch, git switch otherbranch\n3. Force branch renaming: git branch -M sketch-wip newname\n\nThe check allows legitimate operations like:\n- File checkout: git checkout -- file.txt\n- Path operations: git checkout src/main.go\n- Branch creation: git switch -c newbranch\n- Standard git operations: git commit, git status, etc.\n\nKey features:\n- Process-level tracking: Shows warning only once per process\n- Informative error message explaining why it\u0027s blocked\n- Suggests using \u0027set-slug\u0027 tool for external branch naming\n- Tells user they can repeat the command if really needed\n\nImplementation:\n- Added process-aware check alongside existing static checks\n- Process-level tracking via mutex-protected boolean\n- Comprehensive test coverage including edge cases\n- Maintains backward compatibility with existing Check() function\n\nThis prevents agents from inadvertently breaking the outie\u0027s ability\nto detect and push changes to GitHub by changing the expected branch name.\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: s3bb00ecac8a4badek\n"
    },
    {
      "commit": "2be768e4f4d28dc56c7e0b10df342c607ef04833",
      "tree": "0ee35d42338c188b6d88fb60f00700a3c07e3264",
      "parents": [
        "5681b7c857682006489780fca02384e1db26ceab"
      ],
      "author": {
        "name": "banksean",
        "email": "banksean@gmail.com",
        "time": "Fri Jul 18 16:41:39 2025 +0000"
      },
      "committer": {
        "name": "Autoformatter",
        "email": "bot@sketch.dev",
        "time": "Fri Jul 18 18:59:33 2025 +0000"
      },
      "message": "webui: convert SketchDiffRangePicker to SketchTailwindElement\n\nChanges the sketch-diff-range-picker component to extend SketchTailwindElement\ninstead of LitElement. This removes the shadow DOM and allows Tailwind CSS\nclasses to work properly with the component.\n\nChanges:\n- Updated imports to include SketchTailwindElement\n- Removed LitElement import\n- Changed class inheritance from LitElement to SketchTailwindElement\n- Added test file to verify the conversion works correctly\n- Added demo HTML file for manual testing\n\nThe component functionality remains unchanged - this is purely a refactoring\nto use the project\u0027s standard base class for web components.\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: se92a5fe960a4312dk\n"
    }
  ],
  "next": "5681b7c857682006489780fca02384e1db26ceab"
}
