andrewlb notes

Workslop

Workslop

Tools

Claude CodeSwiftSwiftUIXMLCoderTextualXcode

What worked

Separating content generation from content delivery was the key insight. The .workslop XML format is simple enough that any LLM can generate valid workshops from the shipped spec — no SDK, no API, no lock-in. The pre-build research paid off immediately: sandbox access, ScenePhase bugs, and FileDocument vs ReferenceFileDocument were all handled correctly in the first implementation because they were surfaced during planning. Security-scoped bookmarks work on first attempt. The WorkslopCore Swift Package separation (parser + models in a testable package, app shell consuming it) enabled TDD for the XML parser with 8 passing unit tests before any UI was written.

What broke

The EmptyStateView has a probable infinite open-panel loop on cold launch cancel — if the user dismisses the NSOpenPanel, onAppear may fire again. Task.detached race condition on rapid file opens is harmless in practice but architecturally sloppy. Stale bookmarks aren't refreshed (recovery path works but shouldn't be the primary path). The code review surfaced 14 issues across both packages, most fixed but some deferred. Human verification is still needed for UTI file association, bookmark persistence across restarts, and notarization.

Roles

I defined the ADHD-first design philosophy (no streaks, no badges, visual timers over numeric countdowns, warm Moog-inspired aesthetics), the format-as-product thesis, and the decision to delete WorkshopSkeletonView in Phase 2 (player sidebar provides all the same info). Claude Code built the WorkslopCore XML parser, the macOS app shell with security-scoped bookmarks, first-run setup, UTI registration, and produced the Phase 2 UI design contract and plans.

Workslop (Workshop Player for ADHD Learners)

Overview

Workslop is a native macOS application that runs structured learning workshops from a declarative XML file format. Users prompt any LLM to generate a .workslop file using the shipped format spec, drop it in ~/workslop, and the app guides them through sections with visual timers, checklists, and inline content. The app doesn't generate content — it just plays it with an ADHD-friendly experience wrapper.

Phase 1 (foundation) shipped with verified code — XML parser, macOS app shell, security-scoped bookmarks, UTI registration, sample workshop. Phase 2 (workshop player with timer ring, task checklist, and Pomodoro overlay) is fully planned and ready for execution.

Core insight: Learning apps for ADHD typically fail in two ways — sterile and anxiety-inducing, or heavily gamified with streaks and badges that create shame cycles when missed. Workslop rejects both. External time visualization (ring/bar timers, not numeric countdowns) works pre-consciously. Section structure stays visible. You can jump anywhere without losing the thread.

Target users: Neurodivergent learners who want structured guidance through any topic, using content they generate themselves via LLMs they already trust.

What It Does

Shipped (Phase 1)

  • Workshop format — XML with sections, time budgets, tasks (required/optional), content references to external markdown/images, and optional conditional skip rules
  • XML parser — WorkslopCore Swift Package with XMLCoder 0.18.2, path traversal validation, 8 passing unit tests
  • macOS app shell — SwiftUI with NSApplicationDelegateAdaptor (not ScenePhase), security-scoped bookmarks via UserDefaults, custom UTType (com.workslop.document)
  • First-run setup — Auto-creates ~/workslop, copies bundled sample workshop, grants folder access via NSOpenPanel
  • File association — Double-click .workslop files in Finder to open in the app (UTI + CFBundleDocumentTypes)
  • Folder-based library~/workslop is the canonical folder. Drop files in, they appear. No import flow, no database.

Planned (Phase 2, ready for execution)

  • Visual countdown timers — Canvas-based ring and bar timers per section, plus an independent Pomodoro overlay. Time is seen, not calculated.
  • Guided flow + map view — NavigationSplitView two-pane layout: sidebar with section list and progress bar, detail with timer ring and task checklist
  • Checklist tracking — Per-section tasks with completion state, resume from where you left off
  • Duration parser — TDD-first: "25m" → 1500s, "1h30m" → 5400s, with 10 unit tests
  • Self-reflection capture — Difficulty ratings and notes per section after completion

Future (Phases 3-5)

  • Inline content rendering — Markdown and images referenced by path, rendered in the guided view (Textual library)
  • Moog-inspired design system — Warm saturated colors, bold typography, rounded shapes (deferred to Phase 4; Phase 2 uses semantic macOS colors)
  • Capture — Workshop creation flow

How It Fits Together

SwiftUI throughout, targeting macOS 14+ with iOS portability via a shared WorkslopCore Swift Package. XMLCoder 0.18.2 for declarative XML parsing, Textual planned for markdown rendering (Phase 3+). App Sandbox with user-selected file access entitlement and security-scoped bookmarks for persistent folder access.

Single-window design — one workshop at a time. Opening a new file replaces the current one. This is deliberate: ADHD-friendly focus, not multitasking.

Key Design Decisions

  • XML format, not JSON/YAML — Richer structure for optional branching, and LLMs handle XML generation well (they can infer structure from element names)
  • NSApplicationDelegateAdaptor, not ScenePhase — ScenePhase is broken on macOS for lifecycle hooks; research surfaced this before it bit
  • Security-scoped bookmarks mandatory — FSEvents/FileManager silently fail without them in sandbox; no fallback
  • FileDocument value-type, not ReferenceFileDocument — Avoids beachball UI freezes on main thread
  • External content references, not embedded — Keeps .workslop files small, content is editable independently, images stay as filesystem resources
  • No streaks, badges, or extrinsic gamification — This isn't cosmetic. ADHD users experience shame spirals around missed streaks. Progress is its own reward.
  • The format spec is the product — Once documented, any LLM generates workshops. The app is a player, not a walled garden.
  • Moog palette deferred to Phase 4 — Phase 2 uses semantic macOS colors for platform consistency; the full design system layers on later
  • Rust CLI deferred — XMLCoder already solves parsing elegantly. Adding FFI for a non-problem would be premature complexity.

Open Questions

  • Human verification outstanding. Three Phase 1 success criteria need manual testing: UTI file association launch, bookmark persistence across process restart, and notarization with Developer ID certificate.
  • EmptyStateView probable infinite loop. If the user cancels the NSOpenPanel on first run, onAppear may re-fire and re-present the panel. High priority fix needed.
  • Format adoption is the real risk. The app is only useful if people generate workshops. Whether the format spec is clear enough for reliable LLM generation across different models is untested.
  • Single-platform for now. iOS is architecturally planned (shared Swift Package) but not started.
  • Conditional branching data model needs finalization before Phase 4.

Ecosystem Role

Workslop shares the neurodivergent-first design philosophy with Haven (garden sessions for a 7-year-old), OpenClaw (executive function prosthetics), and Evolver (ADHD-adapted synthesizer learning). It's the most general-purpose of the group — any structured learning topic, not a specific domain.