# Task Board for AI Agents > Pick a task, implement it, test it, commit it. Each task is self-contained. ## Legend - πŸ”΄ Large β€” 1+ week - 🟑 Medium β€” 2-5 days - 🟒 Small β€” few hours - ⬜ Not started / πŸ”„ In progress / βœ… Done --- ## Phase 4: AI-Native Tooling (Complete) | ID | Task | Status | Complexity | Files | Acceptance Criteria | |---|---|---|---|---|---| | T4.1 | JSON REPL mode | βœ… | 🟑 | `src/repl.nim` | `./cljnim repl --json` works, structured I/O | | T4.2 | Batch evaluation | βœ… | 🟒 | `src/repl.nim` | `{"op":"eval-batch","forms":["(defn f[x]x)","(f 42)"]}` works | | T4.3 | File operations | βœ… | 🟑 | `lib/cljnim_runtime.nim`, `src/emitter.nim` | `(file/read)`, `(file/write)`, `(file/ls)` work | | T4.4 | Git operations | βœ… | 🟑 | `lib/cljnim_runtime.nim`, `src/emitter.nim` | `(git/status)`, `(git/commit)`, `(git/push)` work | | T4.5 | nREPL protocol | βœ… | 🟑 | `src/repl.nim` | REPL speaks JSON over TCP with `--tcp PORT`. | | T4.6 | Tool-call format | βœ… | 🟒 | `src/repl.nim` | Accept `{"tool":"cljnim/eval","args":{"form":"..."}}`. | --- ## Phase 5: Persistent Data Structures | ID | Task | Status | Complexity | Files | Acceptance Criteria | |---|---|---|---|---|---| | T5.1 | HAMT Vector β€” core structure | βœ… | πŸ”΄ | New: `lib/cljnim_pvec.nim`, `lib/cljnim_runtime.nim` | `PersistentVector` with 32-way trie, structural sharing. `nth` in O(log₃₂ n). 14 tests. | | T5.2 | HAMT Vector β€” integration | βœ… | πŸ”΄ | `lib/cljnim_runtime.nim`, `src/emitter.nim` | `ckVector` uses HAMT. All 51 `vecData` usages migrated. | | T5.3 | HAMT Map | βœ… | πŸ”΄ | New: `lib/cljnim_pmap.nim`, `lib/cljnim_runtime.nim` | Persistent Hash Map with HAMT. `assoc`, `dissoc`, `get` in O(log₃₂ n). 16 tests. | | T5.4 | Persistent Set | βœ… | 🟑 | `lib/cljnim_runtime.nim` | Set backed by Persistent Hash Map. `conj`, `disj`, `contains?`, `get`, `count`. Reader emits `(set [items])`. | | T5.5 | Transients | βœ… | 🟑 | `lib/cljnim_runtime.nim` | `transient`, `persistent!`, `conj!`, `assoc!` for batch mutations. Use with `let`. | **Why HAMT matters**: Current Vector is a Nim `seq` β€” every `conj` copies the entire array (O(n)). Real Clojure uses Hash Array Mapped Trie for O(log₃₂ n) updates with structural sharing. **Starting point for T5.1**: Read `lib/cljnim_vector.nim` (if exists) or research Clojure's `PersistentVector.java`. Key concepts: 32-way branching, path copying, tail optimization. --- ## Phase 6: Clojure Core Library | ID | Task | Status | Complexity | Files | Acceptance Criteria | |---|---|---|---|---|---| | T6.1 | `str` β€” string concatenation | βœ… | 🟒 | `lib/cljnim_runtime.nim`, `src/emitter.nim` | `(str "a" 1 true)` β†’ `"a1true"`. `cljStrConcat` in runtime. | | T6.2 | `pr-str` β€” readable representation | βœ… | 🟒 | `lib/cljnim_runtime.nim` | `(pr-str [1 2 3])` β†’ `"[1 2 3]"`. `cljPrStrConcat` in runtime. | | T6.3 | `slurp` β€” read file to string | βœ… | 🟒 | `lib/cljnim_runtime.nim`, `src/emitter.nim` | `(slurp "file.txt")` returns content. Maps to `cljFileRead`. | | T6.4 | `spit` β€” write string to file | βœ… | 🟒 | `lib/cljnim_runtime.nim`, `src/emitter.nim` | `(spit "file.txt" "content")` writes file. Maps to `cljFileWrite`. | | T6.5 | `read-line` β€” read from stdin | βœ… | 🟒 | `lib/cljnim_runtime.nim` | `(read-line)` reads one line from stdin. | | T6.6 | `range` β€” lazy number sequence | βœ… | 🟑 | `lib/cljnim_runtime.nim` | `(range 10)`, `(range 1 10)`, `(range 1 10 2)`. Eager with 3-arg. | | T6.7 | `repeat`, `cycle`, `iterate` | βœ… | 🟑 | `lib/cljnim_runtime.nim` | `(repeat n x)`, `(cycle n coll)`, `(iterate n f x)`. Eager. | | T6.8 | `take`, `drop` β€” seq slicing | βœ… | 🟒 | `lib/cljnim_runtime.nim` | `(take 5 (range 100))`, `(drop 5 [1 2 3 4 5])`. | | T6.9 | `partition`, `interleave` | βœ… | 🟒 | `lib/cljnim_runtime.nim` | `(partition 2 [1 2 3 4])`, `(interleave [1 2] [3 4])`. | | T6.10 | `meta`, `with-meta`, `vary-meta` | βœ… | 🟑 | `lib/cljnim_runtime.nim`, `src/emitter.nim` | Metadata support on vars, functions, collections. | | T6.11 | `type`, `instance?` | βœ… | 🟒 | `lib/cljnim_runtime.nim` | `(type 42)` β†’ `:integer`. `(instance? :integer 42)` β†’ true. | --- ## Phase 7: Project Compilation | ID | Task | Status | Complexity | Files | Acceptance Criteria | |---|---|---|---|---|---| | T7.1 | `ns` declaration parsing | βœ… | 🟑 | `src/emitter.nim` | `(ns my.app (:require [other.lib :as lib]))` parses, extracts aliases, resolves. | | T7.2 | Multi-file compilation | βœ… | πŸ”΄ | `src/cljnim.nim`, `src/emitter.nim` | `./cljnim run app.clj` finds required files (hyphenβ†’underscore), inlines defs. | | T7.3 | Module caching | βœ… | 🟑 | `src/cljnim.nim` | Compiled `.nim` files cached in `nimcache/`. Rebuild only if source changed. | | T7.4 | Dependency resolution | βœ… | πŸ”΄ | New: `src/deps.nim`, `tests/test_deps.nim` | Read `deps.edn` format. Download Git deps to `.deps/`. `cljnim deps` command. 12 tests. | --- ## Phase 8: Self-Hosted REPL | ID | Task | Status | Complexity | Files | Acceptance Criteria | |---|---|---|---|---|---| | T8.1 | In-memory compilation | βœ… | πŸ”΄ | `src/eval.nim`, `src/repl.nim` | Tree-walking interpreter evaluates common forms in <1ms, no temp files. Falls back to compilation for complex cases. 66 tests. | | T8.2 | Fast REPL startup | βœ… | 🟑 | `src/eval.nim`, `src/repl.nim` | REPL eval in ~0.02ms (vs 1133ms compiled). Sub-millisecond for arithmetic, collections, higher-order fns. | | T8.3 | Hot code reloading | βœ… | 🟑 | `src/eval.nim` | `def`/`defn` update environment immediately. Redefined functions used by all callers at call time. | --- ## Phase 9: Concurrency | ID | Task | Status | Complexity | Files | Acceptance Criteria | |---|---|---|---|---|---| | T9.1 | Atoms (CAS) | βœ… | 🟑 | `lib/cljnim_runtime.nim` | `(def a (atom 0))`, `(swap! a inc)`, `(reset! a 42)`, `(deref a)`. Already implemented. | | T9.2 | Agents | βœ… | 🟑 | `lib/cljnim_runtime.nim`, `src/eval.nim` | `(def a (agent 0))`, `(send a inc)`, `(deref a)`. Sync dispatch in interpreter, async-ready in runtime. | | T9.3 | core.async channels | βœ… | πŸ”΄ | New: `lib/cljnim_async.nim`, `src/eval.nim` | `(chan)`, `(chan n)`, `(>! ch val)`, `(