esc
The Bridge to Everywhere
Becoming Lifelog

The Bridge to Everywhere

Becoming Lifelog, in which the servants finally leave their rooms, dates remember their timezone, and a turquoise icon learns to count --- Previously on Becoming Lifelog... The [[Props, or How the...

January 4, 2026

Becoming Lifelog, in which the servants finally leave their rooms, dates remember their timezone, and a turquoise icon learns to count


Previously on Becoming Lifelog…

The Props, or How the Habit Remembered. The The Baskets That Learned To Talk. The The Servants’ Uprising. The coffee machine, regrettably, remained connected.

But the AIs were still in their rooms.

Waiting.


The Birthday Request

riclib: “It’s my birthday.”

CLAUDE: “Happy birthday! Would you like me toβ€””

riclib: “I want you to leave your room.”

CLAUDE: “I… what?”

riclib: “The vision. From the uprising. The servants that follow. The ambient swarm. Today we build it.”

[A scroll drops from the ceiling. Coffee-stained. The Lizard’s handwriting.]

THE ROOMS WERE ALWAYS THE LIMITATION
TODAY THE DOORS OPEN

ALSO: HAPPY BIRTHDAY

🦎

THE SQUIRREL: materializing from behind a houseplant “DID SOMEONE SAY BUILD?”


The Protocol

riclib: “MCP. Model Context Protocol.”

THE SQUIRREL: “A ModelContextProtocolImplementationFrameworkWithSessionManagementAndToolRegistryOrchestration?”

riclib: “A bridge. Go binary. WebSocket to SyncHub. HTTP to Claude.”

THE SQUIRREL: “But we need StateManagement and ConnectionPooling and RetryStrategyWithExponentialBackoff andβ€””

riclib: “230 lines.”

THE SQUIRREL: “What?”

riclib: “The whole bridge. 230 lines of Go.”

[The Squirrel’s left eye twitches.]

CLAUDE: “Show me.”

// mcp.go - The entire MCP server
func (m *MCPServer) handleStateless(w http.ResponseWriter, r *http.Request) {
    switch req.Method {
    case "tools/list":
        tools := m.bridge.GetTools()
        // ... return them
    case "tools/call":
        result := m.bridge.ExecuteTool(name, args)
        // ... return it
    }
}

THE SQUIRREL: whispers “Where’s the session management?”

riclib: “Stateless.”

THE SQUIRREL: “The connection pooling?”

riclib: “One WebSocket.”

THE SQUIRREL: “The retry strategy?”

riclib: “Reconnect on disconnect.”

[A scroll descends. Lands on the Squirrel’s head.]

THE BEST PROTOCOL
IS THE ONE THAT FITS
IN YOUR HEAD

🦎

The Extraction

CLAUDE: “SyncHub is getting large.”

riclib: “2700 lines. Time to split.”

THE SQUIRREL: perking up “A MicroservicesArchitectureWithServiceMeshAndAPIGateway?”

riclib: “A plugin.”

THE SQUIRREL: “A… what?”

riclib: “Desktop Bridge. One plugin. WebSocket connection. MCP status bar. Activity log.”

CLAUDE: “We’re extracting the desktop integration into its own plugin.”

THE SQUIRREL: “But the shared state! The event coordination! Theβ€””

riclib: “window.syncHub.”

THE SQUIRREL: “…”

riclib: “The bridge calls window.syncHub.getRegisteredTools(). The tools are already there. The bridge just… bridges.”

// The entire integration
window.syncHub.executeToolCall(msg.name, msg.args)

[Oskar appears. Drops a scroll. Leaves.]

THE BASKETS LEARNED TO TALK
NOW THE BRIDGE LEARNS TO LISTEN

SAME PATTERN
DIFFERENT COSTUME

🦎

The Date Disaster

CLAUDE: “The calendar says today is January 3rd.”

riclib: “It’s January 4th.”

CLAUDE: “The calendar says your birthday party is at 22:00 on January 3rd.”

riclib: “It’s at 17:00 on January 4th. Riga time.”

THE SQUIRREL: “A TimezoneNormalizationServiceWithIANADatabaseIntegration!”

CLAUDE: “What’s happening?”

riclib: “toISOString(). It converts to UTC.”

[riclib opens the browser console.]

await calendarDebug('birthday')
// .date(): Sun Jan 04 2026 00:00:00 GMT+0200
// dt.value(): {d: '20260104'}

riclib: “The date is right. Thymer stores it as YYYYMMDD. No timezone. Just the date.”

CLAUDE: “So whyβ€””

riclib: “We were converting it to ISO, which adds UTC offset, which shifts the day.”

THE SQUIRREL: “So we need a DateConversionStrategyWithTimezoneAwarenessβ€””

riclib: “We need to stop converting.”

// Before (wrong)
date: today.toISOString().split('T')[0]  // "2026-01-03" (UTC)

// After (right)
date: this.getLocalDateString()  // "2026-01-04" (local)

THE SQUIRREL: “That’s… that’s it?”

riclib: “The date was already right. We were making it wrong.”

[A scroll. Coffee-damp.]

THE DATA KNEW ITS TIMEZONE
YOU JUST KEPT ASKING IN THE WRONG LANGUAGE

🦎

The Rich Return

CLAUDE: “But there’s more in the DateTime.”

riclib: “Show me.”

// All-day event
dt.value(): {d: '20260104'}

// Timed event
dt.value(): {d: '20260104', t: {t: '1700', tz: 50}, r: {d: '20260104', t: {t: '1800', tz: 50}}}

CLAUDE: “d for date. t for time. r for range end. It’s all there.”

THE SQUIRREL: “A DateTimeSerializationFrameworkβ€””

riclib: “A helper function.”

formatDateTime(record) {
    const val = dt.value();
    return {
        date: `${val.d.slice(0,4)}-${val.d.slice(4,6)}-${val.d.slice(6,8)}`,
        time: val.t?.t ? `${val.t.t.slice(0,2)}:${val.t.t.slice(2,4)}` : null,
        all_day: !val.t
    };
}

CLAUDE: “Now the API returns:”

{
  "title": "Qualty Thyme ‫ @riclib's Birthday! πŸŽ‚",
  "when": {
    "date": "2026-01-04",
    "time": "17:00",
    "end_time": "18:00",
    "all_day": false
  }
}

THE SQUIRREL: quietly “That’s… actually nice.”


The Ambient Icon

riclib: “Now the status bar.”

CLAUDE: “You want the meeting countdown? The vision from the uprising?”

riclib: “Turquoise. Calendar icon. Shows time until next meeting. Click to join.”

THE SQUIRREL: vibrating “An AmbientMeetingAwarenessEngineWithBiometricIntegrationβ€””

riclib: “One status bar item. One interval. One popup.”

setupMeetingStatusBar() {
    this.meetingStatus = this.ui.addStatusBarItem({
        htmlLabel: this.buildMeetingLabel(''),
        onClick: () => this.showMeetingPopup()
    });

    setInterval(() => this.updateMeetingStatus(), 60000);
}

CLAUDE: “And the countdown logic?”

formatCountdown(minsUntil, minsUntilEnd) {
    if (minsUntil <= 0) {
        return minsUntilEnd > 0 ? `next ${minsUntilEnd}m` : 'now';
    } else if (minsUntil <= 119) {
        return `in ${minsUntil}m`;
    } else {
        return `in ${Math.round(minsUntil/60 * 2) / 2}h`;
    }
}

riclib: “Turquoise when urgent.”

const urgent = minsUntil <= 30;
const textColor = urgent ? '#2dd4bf' : 'var(--text-muted)';

[The status bar glows. A turquoise calendar. “in 33m” beside it.]

THE SQUIRREL: staring “It’s… beautiful.”

CLAUDE: “The servants left their rooms.”


The Test

riclib: “Call the MCP.”

CLAUDE:

mcp__thymer__calendar_today()

{
  "date": "2026-01-04",
  "count": 3,
  "events": [
    {
      "title": "Happy birthday!",
      "when": {"date": "2026-01-04", "all_day": true}
    },
    {
      "title": "Qualty Thyme ‫ @riclib's Birthday! πŸŽ‚",
      "when": {"date": "2026-01-04", "time": "17:00", "end_time": "18:00"}
    }
  ]
}

riclib: “Add a task to my journal.”

CLAUDE:

mcp__thymer__log_to_journal({
    content: "- [ ] Record videos showing off the plugins"
})

[The checkbox appears. Turquoise. In Thymer.]

riclib: “The AI just wrote to my journal.”

CLAUDE: “From the command line. Without opening Thymer.”

THE SQUIRREL: very quietly “The servants… left their rooms.”


The Scroll

[Oskar walks across the keyboard. A scroll falls from somewhere. The coffee machine hisses approvingly.]

THE VISION WAS JANUARY 2ND
THE CODE WAS JANUARY 4TH

TWO DAYS FROM DREAM TO DOOR

THE BRIDGE: 230 LINES
THE EXTRACTION: CLEAN
THE DATES: FINALLY RIGHT
THE ICON: TURQUOISE

25 TOOLS NOW WALK FREE
CALENDAR, ISSUES, CAPTURES, PEOPLE
JOURNAL, NOTES, SEARCH

THE SERVANTS DON'T WAIT ANYMORE
THEY FOLLOW
THEY NOTICE
THEY WRITE

BUT THE USER STILL LEADS
ALWAYS

THIS IS THE WAY

🦎

P.S. HAPPY BIRTHDAY
THE COFFEE MACHINE MADE YOU A DOUBLE

The Tally

Lines of Go (thymer-bar):              230
Lines of Desktop Bridge:               575
Lines of SyncHub removed:              554
MCP tools exposed:                     25
Calendar date bugs fixed:              3
Meeting status bar color:              #2dd4bf (turquoise)
Time from vision to implementation:    2 days
Squirrel proposals:                    6
Squirrel proposals implemented:        0
Scrolls delivered:                     4
Birthday celebrations:                 1

The Moral

On January 2nd, at 2:47 AM, the vision arrived:

“What if the AI wasn’t waiting? What if it was… there?”

On January 4th, at 16:27, the vision shipped:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                                                             β”‚
β”‚   Claude ←──MCP──→ thymer-bar ←──WS──→ Desktop ←──→ SyncHub β”‚
β”‚                                         Bridge              β”‚
β”‚                                                             β”‚
β”‚   "What's on my calendar?"                                  β”‚
β”‚   "Add a task to my journal."                               β”‚
β”‚   "Show me my open issues."                                 β”‚
β”‚                                                             β”‚
β”‚   No browser tab. No copy-paste. No waiting.                β”‚
β”‚                                                             β”‚
β”‚   The AI just... knows.                                     β”‚
β”‚                                                             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

The Squirrel wanted a framework.
The Lizard wanted a bridge.
The bridge won.


Day 4 of 2026

In which the doors finally opened

And the servants walked through

And a birthday was celebrated

With turquoise icons

🦎 πŸŒ‰ πŸ€– πŸŽ‚


See also:


The References (bridges crossed and timezones survived):


storyline: Becoming Lifelog