| ... | @@ -5,7 +5,6 @@ meta: | ... | @@ -5,7 +5,6 @@ meta: |
| 5 | import './log.css'; | 5 | import './log.css'; |
| 6 | static const repo = "${repo}"; | 6 | static const repo = "${repo}"; |
| 7 | | 7 | |
| 8 | [go back to the home page](/) | | |
| 9 | | 8 | |
| 10 | [git]: https://git.paperclover.net/ | 9 | [git]: https://git.paperclover.net/ |
| 11 | [home infra]: https://git.paperclover.net/clo/home-infra | 10 | [home infra]: https://git.paperclover.net/clo/home-infra |
| ... | @@ -18,16 +17,240 @@ static const repo = "${repo}"; | ... | @@ -18,16 +17,240 @@ static const repo = "${repo}"; |
| 18 | [evil inc]: https://evil.inc/ | 17 | [evil inc]: https://evil.inc/ |
| 19 | [history of japan reanimated]: /history-of-japan-reanimated | 18 | [history of japan reanimated]: /history-of-japan-reanimated |
| 20 | [react mutation]: /history-of-japan-reanimated | 19 | [react mutation]: /history-of-japan-reanimated |
| | 20 | [HOTEWIG reanimated]: /hotewig-reanimated |
| | 21 | [clover creative control]: https://git.paperclover.net/clo/creative-control |
| | 22 | [markodown]: https://git.paperclover.net/clo/markodown |
| 21 | | 23 | |
| 22 | <main> | 24 | <main> |
| 23 | | 25 | |
| | 26 | [go back to the home page](/) |
| | 27 | |
| 24 | # clover's log | 28 | # clover's log |
| 25 | | 29 | |
| 26 | these are like mini blog posts, but more in generally just what the heck i'm up to. | 30 | these are like mini blog posts, but more in generally just what the heck i'm up to. |
| 27 | | 31 | |
| | 32 | ## 2026-03-16 |
| | 33 | |
| | 34 | just chilling. at work i replaced `bun install` with `pnpm`. pretty peak. in the |
| | 35 | night, i worked on [this page][this site], and worked a bit on [hexiflare]'s |
| | 36 | local llm system. |
| | 37 | |
| | 38 | ## 2026-03-15 |
| | 39 | |
| | 40 | tags: [clover creative control] |
| | 41 | |
| | 42 | this is sort of the new version of what i've called "creative toolkit." it's now |
| | 43 | a TypeScript library that controls REAPER and the DaVinci Resolve Speed Editor. |
| | 44 | the two layers are the library layer and the configuration layer. the config |
| | 45 | layer is meant to be trivial, editable and instantly-reloadable at a moments notice. |
| | 46 | |
| | 47 | ```ts |
| | 48 | export default config.forApp("com.cockos.reaper", ({ speededitor: se, mac }) => { |
| | 49 | const reaper = new Reaper(); |
| | 50 | |
| | 51 | // Sync state to LEDs |
| | 52 | reaper.on("transport", (transport) => { |
| | 53 | se.leds.cut = transport.recording; |
| | 54 | se.leds.dissolve = transport.recording; |
| | 55 | se.leds.smoothCut = transport.recording; |
| | 56 | }); |
| | 57 | |
| | 58 | // Keyboard Actions |
| | 59 | se.onPress("stopPlay", () => { |
| | 60 | if (reaper.transport.recording) { |
| | 61 | reaper.runAction("transport-stop-save-all-recorded-media"); |
| | 62 | } else { |
| | 63 | reaper.runAction("transport-play-stop"); |
| | 64 | } |
| | 65 | }); |
| | 66 | se.onPress("cut", () => { |
| | 67 | if (reaper.transport.recording) { |
| | 68 | reaper.runAction("transport-stop-delete-all-recorded-media"); |
| | 69 | reaper.runAction("transport-record"); |
| | 70 | } else { |
| | 71 | reaper.runAction("transport-record"); |
| | 72 | } |
| | 73 | }); |
| | 74 | se.onPress("dissolve", () => { |
| | 75 | reaper.runAction("transport-stop-delete-all-recorded-media"); |
| | 76 | }); |
| | 77 | se.onPress("smoothCut", () => { |
| | 78 | if (reaper.transport.recording) { |
| | 79 | reaper.runAction("transport-stop-save-all-recorded-media"); |
| | 80 | reaper.runAction("transport-record"); |
| | 81 | } |
| | 82 | }); |
| | 83 | se.onPress("videoOnly", () => { |
| | 84 | if (mac.window?.title.startsWith("FX:") && mac.mainWindow) { |
| | 85 | mac.focusMainWindow(); |
| | 86 | return; |
| | 87 | } |
| | 88 | reaper.runAction("track-view-fx-chain-for-current-last-touched-track"); |
| | 89 | }); |
| | 90 | }); |
| | 91 | ``` |
| | 92 | |
| | 93 | the winning workflow here for recording audio has been the bottom three keys being mapped to |
| | 94 | |
| | 95 | - start a recording. or if one is already going, delete and restart it |
| | 96 | - discard the currently recording take and stop |
| | 97 | - accept the currently recording and start a new one |
| | 98 | |
| | 99 | this is better than just having keys on the main keyboard, no modifiers! *and* i |
| | 100 | don't have to lose out on any existing keybinds. |
| | 101 | |
| | 102 | i used to have a setup like this with multiple external keyboards, but i am |
| | 103 | keeping that on hold until i run out of macro keys. what's also interesting to |
| | 104 | note is each app gets its own layer of bindings. |
| | 105 | |
| | 106 | ## 2026-03-14 |
| | 107 | |
| | 108 | tags: [album] |
| | 109 | |
| | 110 | i've made some beautiful progress on the album, i finished another song. it is |
| | 111 | one of my best creative works i've ever done. i'm personally very happy with my |
| | 112 | singing and vocal editing skills improving. will be holding it captive except in |
| | 113 | some small circles (who have all said it is amazing) |
| | 114 | |
| | 115 | ## 2026-03-11 |
| | 116 | |
| | 117 | tags: [react mutation] |
| | 118 | |
| | 119 | my coworker was working on something that needed a feature for react mutation. i |
| | 120 | also needed his approval on some code i was working on, but he wouldn't give me |
| | 121 | any attention. so as a bribe, i released a new patch of the library. my PR was |
| | 122 | reviewed, and everything was great. the changelog |
| | 123 | |
| | 124 | - tanstack query integration |
| | 125 | - [feat: `arrayUpsert` and `objArrayUpsert`](https://git.paperclover.net/clo/react-mutation/commit/47304f56e98bf841b757d16e472fb64a01c99fd2) |
| | 126 | - [fix: allow spreading `TanstackQueryOptimisticHelpers`](https://git.paperclover.net/clo/react-mutation/commit/4b09ff4dba5fad5b7e2b44a0bdc2789918f74561) |
| | 127 | - mutation buttons |
| | 128 | - [pass `args={null}` to disable the button UI](https://git.paperclover.net/clo/react-mutation/commit/ec65067d04a72a51b71b63d3b4569843b8fd0dad) |
| | 129 | |
| | 130 | ## 2026-03-10 |
| | 131 | |
| | 132 | tags: [hexiflare] |
| | 133 | |
| | 134 | with the hexi bot with just two users eating my entire at-work anthropic |
| | 135 | subscription, i was messing with getting hexi to work as much on local models as |
| | 136 | possible. the results are very promising, but it is very much becoming a |
| | 137 | manually designed and written project, which is good (slop is bad). but that |
| | 138 | does mean i can't spent a lot of time on it, as i have other desires. |
| | 139 | |
| | 140 | anyways, the local model chat system works by having a qwen model with an insane |
| | 141 | "personality" prompt. and then it goes through another qwen model with an |
| | 142 | equally insane "review". the results are pretty good. |
| | 143 | |
| | 144 | ``` |
| | 145 | you> what u been up to? |
| | 146 | hexi> not much lol |
| | 147 | hexi> messing w/ some css animations rn breaking them is kinda fun though |
| | 148 | you> omg can i see? |
| | 149 | hexi> hold on lemme whip up a lil demo page real quick |
| | 150 | [triggers sandboxed agent task] |
| | 151 | ``` |
| | 152 | |
| | 153 | benefit of doing it this way instead of through a stupid wrapper, the latency |
| | 154 | can be brought down a ton. but the full system isn't wired up, and i frankly |
| | 155 | don't trust anyone but myself to do this task. |
| | 156 | |
| | 157 | ## 2026-03-05 |
| | 158 | |
| | 159 | tags: [work], [hexiflare] |
| | 160 | |
| | 161 | i wrote a beautiful dialog component for use at work and in the hexiflare |
| | 162 | template. the usage is like this: |
| | 163 | |
| | 164 | ```ts |
| | 165 | showTextDialog({ |
| | 166 | title: "Hello hiii heelloooo.", |
| | 167 | description: "Enter something important" |
| | 168 | onConfirm: async (reason) => { |
| | 169 | // do something with `reason` |
| | 170 | }, |
| | 171 | onCancel: "close", |
| | 172 | }); |
| | 173 | ``` |
| | 174 | |
| | 175 | it's certainly better than copying the Radix Dialog everywhere. that component |
| | 176 | is a great primitive but it isn't nice to spam it. |
| | 177 | |
| | 178 | |
| | 179 | ## 2026-02-25 |
| | 180 | |
| | 181 | tags: [hexiflare] |
| | 182 | |
| | 183 | i was starting to work on an ai project, a chatbot that is absurdly tuned to the |
| | 184 | format of texting. in addition to this, it has full access to a (sandboxed) |
| | 185 | computing environment where it can run any command, browser use, and also can |
| | 186 | deploy web apps. |
| | 187 | |
| | 188 | this whole thing is based on a friend's project, named "clungus", which was |
| | 189 | literally just a wrapper around claude code. his could deploy static websites, |
| | 190 | which was really cool since you could just ask it for some little thing and it |
| | 191 | would just make it. and you send your bug reports as text messages. |
| | 192 | |
| | 193 | in both bots, the interface is much more natural than using claude code, |
| | 194 | chatgpt, or another application. and with mine particularly, i was working on |
| | 195 | making the base app template as high quality as possible, so that the apps. so |
| | 196 | at a minimum, we now have one of the best tanstack start templates ever. at |
| | 197 | best, i might be able to automate some apps i never would've cared to write |
| | 198 | manually. |
| | 199 | |
| | 200 | ## 2026-02-25 |
| | 201 | |
| | 202 | ## 2026-02-18 |
| | 203 | |
| | 204 | tags: [this site], [markodown] |
| | 205 | |
| | 206 | i finally closed [issue #1](https://git.paperclover.net/clo/sitegen/issues/1) on |
| | 207 | my website, eliminating the MDX compiler in its entirety on my website. |
| | 208 | |
| | 209 | i don't think MDX is a great format to work with. and on top of that, it adds |
| | 210 | 111 transitive dependencies to my website. and what, all for a medium markdown |
| | 211 | language. markdown is inherently concise, so pairing it with Marko felt like it |
| | 212 | would be a nicer format to work in. the answer: it is! i made "markodown", by |
| | 213 | using rust, a bit of llm slop, and used it a ton to ensure a good api. the |
| | 214 | result is beautiful. |
| | 215 | |
| | 216 | my favorite part of this language is automatic header tracking being built in. |
| | 217 | alongside Marko's id shorthand, i can type something like this: |
| | 218 | |
| | 219 | ```ts |
| | 220 | <h2#technical-review>A Technical Review: What are Server Components?</> |
| | 221 | ``` |
| | 222 | |
| | 223 | and the compiler will track this properly, emitting it as |
| | 224 | `<Heading level=2 id="technical-review">` and including it in the generated |
| | 225 | table of contents. i can then include the table of contents with a |
| | 226 | `<table-of-contents />` element |
| | 227 | |
| | 228 | a little bit tough because i did spend a whole week on it. but it's done, and i |
| | 229 | love it. after this port, i also axed some other dependencies in favor of |
| | 230 | lighter alternatives: |
| | 231 | |
| | 232 | - `puppeteer` with `playwright` |
| | 233 | - `codemirror` with `<textarea />` |
| | 234 | - panning to replace `msgpackr` with a custom format that handles the types needed |
| | 235 | |
| | 236 | and the biggest of all, deprecating my HTML rendering framework, in favor of |
| | 237 | using Marko. this is technically a complexity increase, except for the part |
| | 238 | where i already supported Marko. |
| | 239 | |
| | 240 | ## 2026-02-08 |
| | 241 | |
| | 242 | tags: [HOTEWIG reanimated] |
| | 243 | |
| | 244 | i am on the team of people organizing "history of the entire world, i guess - |
| | 245 | reanimated." not much news yet, but it will be exciting. please fill out the |
| | 246 | form if you are interested, and please send it to anyone you may think would be |
| | 247 | interested. |
| | 248 | |
| 28 | ## 2026-02-06 | 249 | ## 2026-02-06 |
| 29 | | 250 | |
| 30 | spent yesterday and today cathing up with this page and preparing to get | 251 | tags: [this site] |
| | 252 | |
| | 253 | spent yesterday and today catching up with this page and preparing to get |
| 31 | writing heavy on the blog. i also fixed a bug on the video player where it | 254 | writing heavy on the blog. i also fixed a bug on the video player where it |
| 32 | wouldnt work on latest chrome on non-av1 accelerated hardware. | 255 | wouldnt work on latest chrome on non-av1 accelerated hardware. |
| 33 | | 256 | |