{"id":50512983,"url":"https://github.com/avidrucker/fulcro-solo-learn","last_synced_at":"2026-06-02T21:32:59.274Z","repository":{"id":355699044,"uuid":"1228193163","full_name":"avidrucker/fulcro-solo-learn","owner":"avidrucker","description":null,"archived":false,"fork":false,"pushed_at":"2026-05-24T22:39:44.000Z","size":2877,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-24T23:25:14.037Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://avidrucker.github.io/fulcro-solo-learn/","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/avidrucker.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-03T18:05:02.000Z","updated_at":"2026-05-24T22:39:47.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/avidrucker/fulcro-solo-learn","commit_stats":null,"previous_names":["avidrucker/fulcro-solo-learn"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/avidrucker/fulcro-solo-learn","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avidrucker%2Ffulcro-solo-learn","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avidrucker%2Ffulcro-solo-learn/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avidrucker%2Ffulcro-solo-learn/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avidrucker%2Ffulcro-solo-learn/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/avidrucker","download_url":"https://codeload.github.com/avidrucker/fulcro-solo-learn/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avidrucker%2Ffulcro-solo-learn/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33838216,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-02T02:00:07.132Z","response_time":109,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-02T21:32:58.505Z","updated_at":"2026-06-02T21:32:59.267Z","avatar_url":"https://github.com/avidrucker.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"# fulcro-solo-learn\n\nHands-on Fulcro / ClojureScript port of the AutoFocus productivity\nmodel — built TDD-first across many small phases, with a focus on\nunderstanding each layer of the stack as it lands.\n\n**Status:** v0.0.1 · 104 specs / 728 assertions · Phase 13 closed.\n\n## Live demo\n\nThe deployed Fulcro port: \u003chttps://avidrucker.github.io/fulcro-solo-learn/\u003e\n\nThe original JS port (source of truth for behaviour comparisons):\n\u003chttps://github.com/avidrucker/pwa-autofocus-app\u003e · \u003chttps://avidrucker.github.io/pwa-autofocus-app/\u003e\n\n## What this is (and isn't)\n\nA learning project, not a replacement for the OG. The goal is to\ninternalise Fulcro / Pathom / statecharts / shadow-cljs / Tachyons by\nporting a real app (Mark Forster's AutoFocus system) one feature at a\ntime, with red-green-refactor TDD as the development discipline.\n\nEach phase has its own retrospective entry in `docs/phases.md`; each\nintentional divergence from the JS port is logged in `docs/changes.md`;\neach defect we surfaced and fixed has a `B-N` entry in `docs/bugs.md`.\nDecision write-ups for the \"should we adopt X?\" calls live alongside as\n`benefits-of-X.md` / `when-to-X.md` docs.\n\n## Tech stack\n\n| Layer | Choice |\n|---|---|\n| UI / state | [Fulcro 3.9](https://github.com/fulcrologic/fulcro) |\n| Schemas / contracts | [Malli](https://github.com/metosin/malli) + [Guardrails](https://github.com/fulcrologic/guardrails) (`\u003edefn`) |\n| Server-side resolvers | [Pathom 2](https://github.com/wilkerlucio/pathom) (in-process, no real backend) |\n| State machines | [com.fulcrologic/statecharts](https://github.com/fulcrologic/statecharts) (review/prioritize flow) |\n| Attribute-driven UI | [Fulcro RAD](https://github.com/fulcrologic/fulcro-rad) (1.6.23 — `defattr` for the new-todo input) |\n| Browser build | [shadow-cljs](https://github.com/thheller/shadow-cljs) |\n| CSS | [Tachyons](https://tachyons.io/) + a small `app.css` |\n| Tests | [fulcro-spec](https://github.com/fulcrologic/fulcro-spec) (CLJC, JVM-headless) |\n| i18n | Hand-rolled lookup (`learn.i18n.core` — see `docs/benefits-of-i18n-in-this-project.md`) |\n| PWA | Manifest + service worker for offline shell |\n\n## Quick start\n\n```bash\n# 1. JS deps\nnpm install\n\n# 2. Start the dev build (shadow-cljs watch + static server on :8000)\nnpx shadow-cljs watch app\n\n# 3. Open the app\n#    http://localhost:8000\n```\n\nTo run the JVM spec suite, start a Clojure REPL with the test alias:\n\n```bash\nclojure -M:test:cljs:nrepl\n```\n\nThen evaluate the master test-runner snippet from `CLAUDE.md` (`do\n(require ...) (run-tests ...)`). Or invoke per-namespace tests directly\nfrom any nREPL client connected to the printed port.\n\nFor browser-side REPL access (poking live app state, firing mutations,\nflipping locale), see `docs/dev_scripts.md`.\n\n## Where to look next\n\nStart with `docs/README.md` — that's the docs index, lens-per-doc, no\nduplication. From there:\n\n- **First time?** `docs/SCHEMA.md` for the domain model; `docs/phases.md`\n  for the dev arc; `docs/user_stories.md` for what the app does today.\n- **Contributing?** `CLAUDE.md` at root has the hard rules (TDD-first,\n  stub-then-implement, master-test-runner-after-every-change). The\n  per-doc lenses in `docs/README.md` tell you which file gets updated\n  for which kind of change.\n- **Curious about a specific design decision?** The\n  `benefits-of-*.md` / `when-to-*.md` docs in `docs/` capture the\n  \"why we did / didn't reach for X\" for RAD, statecharts, i18n,\n  Pathom production patterns, and RAD forms/reports.\n- **Picking up where another Claude / agent session left off?** A\n  `handoffs` branch (sibling of `main`) holds cross-session handoff\n  docs in `handoffs/`. Read the latest one without switching\n  branches:\n  ```\n  git ls-tree origin/handoffs handoffs/         # list available docs\n  git show origin/handoffs:handoffs/\u003cdoc\u003e.md    # read one in place\n  ```\n  Handoffs carry the ephemeral context (recent decisions,\n  ruled-out approaches, in-flight branches, running background\n  processes) that the code + `docs/` don't capture.\n\n## Project layout\n\n```\nsrc/learn/\n  client.cljc                 # thin facade — re-exports + init + snapshot\n  client/                     # split sub-namespaces (Phase 12.7)\n    session.cljc              #   cross-ns constants\n    state.cljc                #   pure state-map helpers\n    mutations.cljc            #   Fulcro defmutations\n    lifecycle.cljc            #   SPA atom, chart bootstrap, body-theme sync\n    ui/\n      theme.cljc              #   Tachyons class strings + theme helpers\n      modals.cljc             #   modal-shell + body fns + header icon button\n      components.cljc         #   TodoItem / TodoList / Root\n  model/                      # pure domain (Malli + \u003edefn)\n    schema.cljc               #   :status/* enum, item/list shapes\n    list.cljc                 #   add / cancel / clone / benchmark logic\n    review.cljc               #   prioritization predicates + question template\n  rad/\n    attributes.cljc           #   defattr declarations (Phase 9)\n    input.cljc                #   attribute-driven text-input helper\n  review/\n    chart.cljc                #   statechart for the review flow\n  i18n/\n    core.cljc                 #   translation map + `tr` lookup\n  ui/\n    icons.cljc                #   Font Awesome SVG paths\n    strings.cljc              #   centralized English source\n  util/\n    normalized.cljc           #   denormalize / sync-items helpers\n    remote.cljc               #   CLJC sync-remote shim for the loopback parser\n    storage.cljc              #   localStorage adapter + persistence watch\n    tasks-io.cljc             #   JSON import parser (Phase 13)\n    url-encoding.cljc         #   ?list=\u003cbase64-JSON\u003e encoder + decoder\n    version-macros.clj        #   compile-time package.json version reader\n  resolvers.cljc              # Pathom resolvers + mutation handlers\n  parser.clj                  # Pathom parser construction\n  server.cljc                 # in-process SERVER-DB atom + seed\n  main.cljs                   # CLJS entrypoint (calls learn.client/init)\n\ntest/learn/                   # mirrors src layout; CLJC fulcro-spec\ndocs/                         # everything else — see docs/README.md\nresources/public/             # index.html, app.css, manifest, sw.js, icons\nscripts/                      # Playwright snapshot tools, paren-balance check\nshadow-cljs.edn               # CLJS build config\ndeps.edn                      # JVM deps + :test / :cljs / :nrepl aliases\npackage.json                  # JS deps + version (single source of truth)\nCLAUDE.md                     # agent-instructions / hard rules\n```\n\n## License\n\nNo license declared; this is a private learning project. Don't reuse\ncode from here in production without checking with the author first.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Favidrucker%2Ffulcro-solo-learn","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Favidrucker%2Ffulcro-solo-learn","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Favidrucker%2Ffulcro-solo-learn/lists"}