)]}'
{
  "log": [
    {
      "commit": "b5739403b1b6ec6fac909b258bd47ce5a338940e",
      "tree": "0dcc652908a7978912d1e5c20d6b95431da2a6e0",
      "parents": [
        "364f741483c1bd2c18cb3ff2ad255c9042c5362d"
      ],
      "author": {
        "name": "Philip Zeyliger",
        "email": "philip@bold.dev",
        "time": "Mon Jun 02 07:04:34 2025 -0700"
      },
      "committer": {
        "name": "Philip Zeyliger",
        "email": "philip@bold.dev",
        "time": "Mon Jun 02 07:04:34 2025 -0700"
      },
      "message": "Add end session user feedback survey with skaband client coordination\n\nImplement comprehensive end session feedback system with thumbs up/down rating,\noptional text comments, and proper coordination with skaband clients to ensure\nfeedback delivery before process termination.\n\n- Add EndFeedback struct with Happy boolean and Comment string fields\n- Extend Agent struct with endFeedback field and GetEndFeedback/SetEndFeedback methods\n- Update State struct to include End field for exposing feedback in API\n- Modify /end handler to accept survey data (happy, comment fields)\n- Add skaband client coordination with WaitGroup and wait_for_end parameter\n\n- Replace simple window.confirm with custom modal dialog\n- Create comprehensive survey UI with thumbs up/down buttons\n- Add optional textarea for detailed feedback\n- Implement proper button state management and validation\n- Maintain existing redirect behavior after successful end request\n\n- Track clients connecting with /stream?wait_for_end\u003dtrue parameter\n- Use WaitGroup to coordinate end session messaging\n- Proper WaitGroup management with conditional defer to prevent double-decrement\n- Smart timeout handling: measure elapsed time and ensure minimum 100ms response delay\n- Wait up to 2 seconds for waiting clients, timeout gracefully if needed\n\n**Survey Dialog Features:**\n- Modal overlay with centered positioning and backdrop click handling\n- Visual feedback for thumbs up/down selection with color coding\n- Expandable textarea for optional detailed comments\n- Cancel option to abort end session process\n- Proper event handling and cleanup\n\n**State Management:**\n- EndFeedback data flows through Agent -\u003e State -\u003e SSE streams\n- Clients waiting for end automatically receive feedback via state updates\n- WaitGroup ensures coordinated shutdown after notification delivery\n- Exactly one Done() call per Add() to prevent race conditions\n\n**API Contract:**\nPOST /end now accepts:\n{\n  \"reason\": \"user requested end of session\",\n  \"happy\": true,  // optional boolean\n  \"comment\": \"Great experience!\"  // optional string\n}\n\n**Error Handling:**\n- Survey submission proceeds even if rating not selected (null happy value)\n- Empty comments are handled gracefully\n- Network failures fall back to existing error reporting\n- Proper resource cleanup and thread-safe operations\n\n**Testing:**\n- Added comprehensive unit tests for EndFeedback functionality\n- Updated mockAgent to implement new CodingAgent interface methods\n- All existing tests continue to pass\n- Manual API testing confirmed survey data flows correctly\n\nThis enhances user experience by collecting valuable feedback while maintaining\nrobust session termination and proper coordination with external monitoring\nsystems via the skaband protocol.\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: s16561e134e8e81aak\n"
    },
    {
      "commit": "112b92376c97b8da64cc1c954896957cfc479f3d",
      "tree": "1497eb8b2927f1334d712aabb19625db11a148bf",
      "parents": [
        "d203b7de7d49cc5da03440d5a00b2efd0f8bb2c8"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Fri May 23 11:26:33 2025 -0700"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Thu May 29 12:50:41 2025 -0700"
      },
      "message": "loop: add todo checklist\n\nThis should improve Sketch\u0027s executive function and user communication."
    },
    {
      "commit": "c5848f3cb9753e94feddc04b8910b4ff113a458c",
      "tree": "8b3eb330c645e4f020a9ef7f10e78491474ec8ab",
      "parents": [
        "6e4636006501be61b940388381cd75a8ad00e6b5"
      ],
      "author": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed May 28 18:50:58 2025 +0000"
      },
      "committer": {
        "name": "Josh Bleecher Snyder",
        "email": "josharian@gmail.com",
        "time": "Wed May 28 12:01:29 2025 -0700"
      },
      "message": "loop: use repo root instead of working directory for git diff support\n\nChange all git HTTP endpoints to use RepoRoot() instead of WorkingDir()\nto resolve failures when sketch is started from different directories than\nwhere the Docker container was created.\n\nThe issue occurred because:\n- WorkingDir() returns current working directory (could be /app/subdir)\n- Git tools need repository root directory (/app) for relative file paths\n- When Docker sets working directory to subdirectory, git operations fail\n\nChanges include:\n\n1. Added RepoRoot() method to Agent and CodingAgent interface:\n   - Returns a.repoRoot (the git repository root directory)\n   - Complements existing WorkingDir() method\n\n2. Updated all git HTTP endpoints to use RepoRoot():\n   - handleGitCat: fixes GitCat file access from subdirectories\n   - handleGitRawDiff: ensures diff operations work correctly\n   - handleGitShow: ensures show operations work correctly\n   - handleGitSave: ensures file saving works correctly\n   - handleGitRecentLog: ensures log operations work correctly\n\nThe fix ensures git ls-files and other git operations work reliably\nregardless of which directory sketch was started from, resolving the\nreported GitCat directory issue where files couldn\u0027t be found when\nstarting sketch from different locations.\n\nTesting confirmed GitCat now works correctly when repository root is\nused instead of working directory, and git operations succeed from\nany starting directory.\n\nFixes #119\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: sb73dac311df0c78dk"
    },
    {
      "commit": "9bca61ef623ea8cd72a906752be73af572af02a9",
      "tree": "4d6488b6e6e8543c3f0b5e1682d11e0927c27d1b",
      "parents": [
        "75bd37d2a3067b6f431d56e891064b73dc2def2c"
      ],
      "author": {
        "name": "Philip Zeyliger",
        "email": "philip@bold.dev",
        "time": "Thu May 22 12:40:06 2025 -0700"
      },
      "committer": {
        "name": "Philip Zeyliger",
        "email": "philip@bold.dev",
        "time": "Thu May 22 12:44:59 2025 -0700"
      },
      "message": "feat: enhance UI with commit pulsing animation and improved copy icon\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: s80fdaac660ea645ek\n"
    },
    {
      "commit": "75bd37d2a3067b6f431d56e891064b73dc2def2c",
      "tree": "69580944c24bd99c5286ae0611cf2998a3b85035",
      "parents": [
        "8c3b53a97ae2a204842c0c86ca859947ce20b1dd"
      ],
      "author": {
        "name": "Philip Zeyliger",
        "email": "philip@bold.dev",
        "time": "Thu May 22 18:49:14 2025 +0000"
      },
      "committer": {
        "name": "Philip Zeyliger",
        "email": "philip@bold.dev",
        "time": "Thu May 22 12:40:44 2025 -0700"
      },
      "message": "loop: auto-commit changes when saving in diff view\n\nWhat I\u0027ve done is create a git commit whenever the user edits things,\nand amend if possible. The existing detection logic pushes the commits\nto the host, BUT, I had to do some plumbing to make that happen. The\nagent state machine would be out of sorts if I did this (since we\u0027re\ndoing things outside of the loop), but, I didn\u0027t tell it, so... it\u0027s ok!\n\nIf the user has the agent running when editing, everyone can get\nconfused. There\u0027s no atomicity for the git operations, etc.\nI suspect in practice this will all be as fine as everything else is.\n\nI\u0027m not running the autoformatters. That\u0027s a weird editing experience.\n\nThe alternative was to do what the diff comments does, and let the agent\ndeal with the changes by sending it a message. I chose not to do that:\nfirst of all, I want the push to happen fast, since I don\u0027t like losing\nuser data. Second, the latency on an operation is distracting sometimes,\nand sometimes what I do next is just cherrypick my changes over, and I\u0027m\nnot interested in the pedantry of the agent and the code formatters and\nso forth. If they were faster, maybe.\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: sec50af415124810bk\n"
    },
    {
      "commit": "d3ac112a45111abf0e57c327d55e2cc66a136abb",
      "tree": "7d2cab01515d7c482be1a39cc0492e9d9ac657e7",
      "parents": [
        "8bdf627180b64b0dc09018bf512f6ebf192ab674"
      ],
      "author": {
        "name": "Philip Zeyliger",
        "email": "philip@bold.dev",
        "time": "Wed May 14 02:54:18 2025 +0000"
      },
      "committer": {
        "name": "Philip Zeyliger",
        "email": "philip@bold.dev",
        "time": "Fri May 16 14:51:40 2025 -0700"
      },
      "message": "git_tools: Implement git diff and show API\n\nAdded git_tools package providing structured access to git diff and show commands. Exposed these methods via HTTP endpoints in loophttp.\n\nThis is a stepping stone to a better diff view.\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: se75f0a1b2c3d4e5k\n"
    },
    {
      "commit": "49edc92f95cab092a7ee62c350c6e69275b50cc8",
      "tree": "946b8359f6187ed630c4d08fa05e91fe1bc5a48d",
      "parents": [
        "52eeb15cf2f70caaadc4e0722a3b687ad9a91981"
      ],
      "author": {
        "name": "Philip Zeyliger",
        "email": "philip@bold.dev",
        "time": "Wed May 14 09:45:45 2025 -0700"
      },
      "committer": {
        "name": "Autoformatter",
        "email": "bot@sketch.dev",
        "time": "Wed May 14 16:46:49 2025 +0000"
      },
      "message": "agent: move \"sketch-base\" into git\n\nThe agent\u0027s notion of \"initial commit\" is kind of special, in that it\nis used as the \"base\" for a bunch of git operations. It\u0027s hard for\nthe user to change (we only provide a workflow via restart), yet\nsometimes you want to do just that.\n\nSo, instead we put it as data inside of it, named as a tag sketch-base.\nIt\u0027s abusing tags, but branches are no better.\n"
    },
    {
      "commit": "eab12def4e6aacfd50bf8a460c714d20300706b7",
      "tree": "4db97e5dfb30f73fc47435f3651eee55876a6b0b",
      "parents": [
        "8a1b89a210d3c48c6f02f0c8cf1feebb03cdffd5"
      ],
      "author": {
        "name": "Philip Zeyliger",
        "email": "philip@bold.dev",
        "time": "Wed May 14 02:35:53 2025 +0000"
      },
      "committer": {
        "name": "Philip Zeyliger",
        "email": "philip@bold.dev",
        "time": "Wed May 14 02:36:01 2025 +0000"
      },
      "message": "loop: Add StateTransitionIterator and stream state updates\n\nImplement CodingAgent.NewStateTransitionIterator to observe state transitions.\nUpdate the /stream endpoint to send state updates when transitions occur.\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: s4b4f9a0689c94c54k\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\nChange-ID: s4b4f9a0689c94c54k\n"
    },
    {
      "commit": "25f6ff1b44e739e64d8b86cc4ea11bf8c631265c",
      "tree": "2255018ca38ba211e57eb9e76e87b82d61a0c826",
      "parents": [
        "d01d1341abf9b2e62f0b4cc821277dc4c40c6225"
      ],
      "author": {
        "name": "Philip Zeyliger",
        "email": "philip@bold.dev",
        "time": "Fri May 02 04:24:10 2025 +0000"
      },
      "committer": {
        "name": "Philip Zeyliger",
        "email": "philip@bold.dev",
        "time": "Fri May 02 14:25:31 2025 -0700"
      },
      "message": "Implement Server-Sent Events (SSE) for Real-time Agent Communication\n\n- Add server-side SSE endpoint (/stream?from\u003dN) for streaming state updates and messages\n- Replace polling with SSE in frontend for real-time updates with significant performance improvements\n- Implement efficient connection handling with backoff strategy for reconnections\n- Add visual network status indicator in UI to show connection state\n- Use non-blocking goroutine with channel pattern to handle SSE message delivery\n- Ensure proper message sequencing and state synchronization between client and server\n- Fix test suite to accommodate the new streaming architecture\n- Update mocks to use conversation.Budget instead of ant.Budget\n\nCo-Authored-By: sketch \u003chello@sketch.dev\u003e\n"
    }
  ]
}
