Sign in

Laurynas Keturakis

@laulau.land
905 followers 638 following 229 posts

Technical mutt. Interface enjoyer. Building software factory at fp.dev. Exploring and building tools in version control, open protocols, retrieval systems, mechinterp. Also: split keyboards. He/him

PostsRepliesMedia
Laurynas Keturakis @laulau.land · 22/03/2026
marimo notebook making my m1 pro go brrr
a table showing training loss decreasing row by row
010
Laurynas Keturakis @laulau.land · 13/03/2026
vacation reading on computational literacy: finding diSessa’s framing “building tools to build intuition” especially relatable lately (book: “Changing Minds: Computers, Learning, and Literacy”)
000
Laurynas Keturakis @laulau.land · 06/02/2026
just released a small update to jj-hunk - programmatic hunk selector for your jj-using agent New: -r flag. Split any revision, not just your working copy. support for YAML specs stable hunk IDs you can install it with: cargo install jj-hunk npx skills add laulauland/jj-hunk
000
Laurynas Keturakis @laulau.land · 25/01/2026
and of course it has the ace jump functionality too
000
Laurynas Keturakis @laulau.land · 25/01/2026
added revision search to Tatami that supports search by change id, keywords in messages, and also niche but fun stuff like revset queries (you can query "pol-" to go to the parent of "pol" revision)
100
Laurynas Keturakis @laulau.land · 18/01/2026
getting to the point where I'm really liking the experience of Tatami - a GUI I'm building for jj - uses jjui/vim-style keybindings for navigation - has overview and detail screens - fast! Uses @tanstack.com DB to interface via @tauri.app IPC - uses diffs.com of course
110
Laurynas Keturakis @laulau.land · 04/12/2025
it's atuin wrapped time! story of my 2025 shell is that I adopted jj halfway through the year (you can see lg - lazygit - decline) and mostly switched projects from pnpm (shorthand: pn) to bun
030
Laurynas Keturakis @laulau.land · 07/10/2025
Claude's thinking hat but it says "comprehensive"
000
Laurynas Keturakis @laulau.land · 07/10/2025
you need to link resources with your UI components and you need to wire up your resources with tools - it's odd that they chose to link the latter using a special _meta field rather than MCP embedded/linked resources but maybe I'm missing something
The image shows a code snippet written in JavaScript (or TypeScript). It defines a tool registration using server.registerTool with the name "pizza-albums". The tool has a title "Show Pizza Album" and metadata (_meta) that includes an openai/outputTemplate field pointing to "ui://widget/pizza-albums.html", along with two other fields for invocation messages: "Hand–tossing an album" and "Served a fresh album". The tool expects an input schema with one field pizzaTopping of type string. The async function returns an object with content (an array containing a text message: "Rendered a pizza album!") and an empty structuredContent object.

A highlighted line draws attention to the "openai/outputTemplate": "ui://widget/pizza-albums.html", entry.
130
Laurynas Keturakis @laulau.land · 18/07/2025
use your ai browsers to buy from artists
020
Laurynas Keturakis @laulau.land · 16/07/2025
"hey i got it working can you give my PR a quick look?
A snippet of GitHub PR showing 74 files changed with +13k and -1,2k line changes
071
Laurynas Keturakis @laulau.land · 20/05/2025
one kind of hilarious thing of trying to combine neverthrow with Cloudflare's Workflow primitives is having to write wrappers that throw..neverthrow-returned errors as Cloudflare Workflows uses caught errors to trigger retries there's probably a better way to do this...
this is the code in the image:

/**
 * Wraps a neverthrow Result-returning function in a WorkflowStep.do call.
 * Throws an Error to trigger a retry by default, or a NonRetryableError if classified as fatal.
 */
async function runStep<T extends Rpc.Serializable<T>>(
  step: WorkflowStep,
  name: string,
  config: WorkflowStepConfig,
  fn: () => Promise<Result<T, TugboatError>>,
  isFatal: (error: TugboatError) => boolean = () => false,
): Promise<T> {
  return await step.do<T>(name, config, async (): Promise<T> => {
    const result = await fn();
    if (result.isOk()) {
      return result.value;
    }
    const error = result.error;
    if (isFatal(error)) {
      throw new NonRetryableError(error.message);
    }
    throw new Error(error.message);
  });
}
010
Laurynas Keturakis @laulau.land · 26/03/2025
revisiting some of my favorite film shots from last year all shot on Olympus XA - one of those magical small items
glowing shot of Roxie cinema in San Franciscoshot of Greenland from an airplane windowshot of a Japanese shop in The Hague
120
Laurynas Keturakis @laulau.land · 19/02/2025
Your outie always installs the latest version of drizzle-orm. 👍 Your outie resolves lockfile merge conflicts by hand.
1110
Laurynas Keturakis @laulau.land · 04/02/2025
I raved about @cloudflare.social Workflows earlier and they're great. I just wish I could pass in a custom `onError` callback for some custom retry logic
A screenshot of a code editor displaying TypeScript code for a Cloudflare Workflow. The class TextGenerator extends WorkflowEntrypoint<Env> and defines an async run method. Inside, the code extracts a prompt from the event payload and executes step.do with retry logic. It handles errors using an onError callback, attempting to fall back to a faster model (gpt-3.5-turbo) if an AITimeoutError occurs. If this fallback also fails, it retries the original callback. The editor has a dark theme with syntax highlighting and an orange gradient border.
here's the code snippet:

export class TextGenerator extends WorkflowEntrypoint<Env> {
  async run(
    event: Readonly<WorkflowEvent<{ prompt: string }>>,
    step: WorkflowStep,
  ) {
    const { prompt } = event.payload;

    return await step.do(
      "generate-text",
      {
        retries: { limit: 3, delay: 1000, backoff: "exponential" },
        onError: async (error, retry) => {
          if (error instanceof AITimeoutError) {
            // Complex model timed out, try with a faster one first
            try {
              return await generateText({
                model: "gpt-3.5-turbo",
                prompt,
                timeout: 5000,
              });
            } catch {
              // If faster model fails, retry with original complex model (retry is the original callback in step.do)
              return retry();
            }
          }
          throw error;
        }
      },
040
Laurynas Keturakis @laulau.land · 20/01/2025
me: maybe *this* time I'll maintain a clean commit flow me this time:
a snippet of git commit log showing three sequential commits: "WIPUI", "WIPERONI", "WIP"
020
Laurynas Keturakis @laulau.land · 22/12/2024
Been playing with an idea: what if text editors had canvas Alt+drag interaction? Write some text, hit CTRL+. and the paragraph 'rotates' into its alternate version. Edit either version, flip between them, but always keep reading your text naturally. Like having parallel universes for each paragraph
140
Laurynas Keturakis @laulau.land · 29/11/2024
thank you SF, you’ve been good! See ya soon
Landscape shot of San Francisco
030
Laurynas Keturakis @laulau.land · 29/11/2024
also, quite useful for discovering profiles (although my query in this case should be a bit more specific)
a screenshot of Claude desktop that is using the MCP server plugin to search for Bluesky profiles
220
Laurynas Keturakis @laulau.land · 29/11/2024
also mayyybe useful for quick topic-specific searches?
110
Laurynas Keturakis @laulau.land · 29/11/2024
getting my hands dirty with @anthropic.com 's MCP by setting up a @bsky.app server. Will be very helpful for queries like "what was that post I liked that was like <THING>" (featuring an underrated post from @bootsboots.bsky.social)
3163
Laurynas Keturakis @laulau.land · 20/11/2024
you know you’re in for a good time when the presenter has a thousand tabs open thank you @greg.technology and @recursecenter.bsky.social for the good vibes in the internet discoland
030
Laurynas Keturakis @laulau.land · 11/11/2024
a machine for a better time
OS X Mavericks wallpaper depicting blue-green wave
100
Laurynas Keturakis @laulau.land · 07/11/2024
thursday is for the small and "obvious" changes
011
Laurynas Keturakis @laulau.land · 03/11/2024
oh my god the Internet Archive is the coolest and the most insane place in the city
interior of the Internet Archive, showing the golden glow of the building exterior of the Internet Archive, a classical building seat cushion showing old school ad for Alexa
030
Laurynas Keturakis @laulau.land · 01/11/2024
in the spirit of sharing scrappy fiddles - here's a little experiment and sneak peek of what i've been working on at Fiberplane: what if you could chain your HTTP calls in an API client?
051
Laurynas Keturakis @laulau.land · 30/10/2024
ending the day with good local(-first) vibes thanks @paulbutler.org and InstantDB for hosting
031
Laurynas Keturakis @laulau.land · 29/10/2024
hiya universe of GitHubs!
030
Laurynas Keturakis @laulau.land · 22/10/2024
claude losing focus during a "computer use" session and going on the internet to look at some pretty landscape shots is extremely relatable tbh
010
Laurynas Keturakis @laulau.land · 26/04/2024
you wouldn't last an hour in the asylum where they raised me
screenshot of Stronghold castlebuilder gameplay
010