{"id":31285708,"url":"https://github.com/drringo/bb-form","last_synced_at":"2026-05-17T00:36:05.947Z","repository":{"id":304301312,"uuid":"1018393251","full_name":"DrRingo/bb-form","owner":"DrRingo","description":"Typeform, but for terminal. Script using clojure babashka and charm-gum to collect data from beautiful form","archived":false,"fork":false,"pushed_at":"2025-08-26T06:26:52.000Z","size":1031,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-08-26T07:25:22.876Z","etag":null,"topics":["clojure","shell","typeform"],"latest_commit_sha":null,"homepage":"","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DrRingo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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}},"created_at":"2025-07-12T06:55:38.000Z","updated_at":"2025-08-26T06:24:43.000Z","dependencies_parsed_at":"2025-07-12T08:36:26.354Z","dependency_job_id":"8904f1c6-1c78-445d-98d9-deb551fbb3a2","html_url":"https://github.com/DrRingo/bb-form","commit_stats":null,"previous_names":["drringo/bb-form"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/DrRingo/bb-form","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DrRingo%2Fbb-form","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DrRingo%2Fbb-form/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DrRingo%2Fbb-form/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DrRingo%2Fbb-form/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DrRingo","download_url":"https://codeload.github.com/DrRingo/bb-form/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DrRingo%2Fbb-form/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":276714453,"owners_count":25691398,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-24T02:00:09.776Z","response_time":97,"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":["clojure","shell","typeform"],"created_at":"2025-09-24T08:13:17.990Z","updated_at":"2026-05-17T00:36:05.940Z","avatar_url":"https://github.com/DrRingo.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"# bb-form\n\n**Hướng dẫn bằng tiếng Việt: [README.vi.md](./README.vi.md)**\n\nA Babashka + Charm Gum CLI tool to collect data through beautiful terminal forms, powered by a full-featured **EDN Logic Engine** with formula imports, dynamic labels, and Bayesian inference support.\n\n---\n\n## ✨ Features\n\n| Feature | Description |\n|---|---|\n| 🧠 **EDN Logic Engine** | Flat-list fields with `eval-expr` interpreter (`and/or/not/=/\u003e/\u003c`) |\n| 🔀 **Dynamic `:show-if`** | Conditionally show/hide fields based on runtime state |\n| 🗄️ **Hidden Variables** | Declare `:variables` to track background state |\n| ⚡ **Side Effects** | `:actions` to mutate state on each answer |\n| 📦 **Formula Imports** | Import `.edn` or `.clj` formula libraries with namespace aliases |\n| 🔣 **`[:call]` Operator** | Call any imported function using `[:call :alias/fn-name arg …]` |\n| 🔍 **`[:get]` Operator** | Extract properties from complex map results |\n| 🎲 **Stochastic Support** | Integrate Bayesian Stan models via Clojure bridge scripts |\n| 🏷️ **Dynamic Labels** | Interpolate computed values into labels with `{{expr}}` |\n| 📋 **`:info` Field** | Read-only display field that saves its resolved label to output |\n| 📁 **Multi-Stage Forms** | Organize complex forms into `:stages` with `on-begin`/`on-end` hooks |\n\n---\n\n## 📦 Installation\n\n### Option 1 — bbin (recommended, all platforms)\n\n```bash\n# Requires babashka + bbin\nbbin install io.github.drringo/bb-form\n```\n\n### Option 2 — Scoop (Windows)\n\n```powershell\nscoop bucket add drringo https://github.com/drringo/bb-form\nscoop install bb-form\n```\n\n### Option 3 — Homebrew (macOS / Linux)\n\n```bash\nbrew tap drringo/bb-form https://github.com/drringo/bb-form\nbrew install bb-form\n```\n\n### Option 4 — Manual (any platform)\n\n```bash\ngit clone https://github.com/drringo/bb-form\ncd bb-form\nbb src/com/drbinhthanh/bb_form.clj \u003cform.edn\u003e\n```\n\n### Prerequisites\n\n| Tool | Purpose | Install |\n|---|---|---|\n| [Babashka](https://babashka.org/) | Clojure runtime | `scoop install babashka` / `brew install borkdude/brew/babashka` |\n| [Charm Gum](https://github.com/charmbracelet/gum) | Terminal UI | `winget install charmbracelet.gum` / `brew install charmbracelet/tap/gum` |\n\n---\n\n## 🚀 Usage\n\n```bash\nbb-form \u003cform.edn\u003e [OPTIONS]\n```\n\n| Option | Description |\n|---|---|\n| `--values \u003cfile.edn\u003e` | Pre-fill answers from an EDN file (non-interactive / batch mode) |\n| `--out \u003cfile.edn\u003e` | Output result path (default: `result.edn`) |\n\n**Examples:**\n\n```bash\n# Basic interactive form\nbb-form forms/job_application.edn\n\n# Non-interactive batch run\nbb-form forms/job_application.edn --values forms/values.edn --out result.edn\n\n# Bayesian scoring example\nbb-form forms/bayesian_recruitment.edn\n```\n\n---\n\n## 📝 Form Structure\n\nA form is an EDN map. Minimal example:\n\n```clojure\n{:title       \"My Form\"\n :description \"Fill in the details below.\"\n\n ;; Hidden state variables (not shown to user)\n :variables {:score 0}\n\n :fields\n [{:id       :name\n   :label    \"Your name?\"\n   :type     :text\n   :required true}\n\n  {:id      :age\n   :label   \"Your age?\"\n   :type    :number\n   :show-if [:\u003e= [:var :score] 0]}\n\n  {:id      :result\n   :type    :info\n   :label   \"Your score is {{[:var :score]}} points.\"}]}\n```\n\n### Supported field types\n\n| Type | Description |\n|---|---|\n| `:text` | Text input with optional `:regex` validation |\n| `:number` | Integer input |\n| `:date` | Date input (DD-MM-YYYY) with shortcuts |\n| `:select` | Single-choice dropdown |\n| `:multiselect` | Multiple-choice selection |\n| `:hidden` | Computed value, not displayed |\n| `:info` | Read-only computed label, saved to output |\n\n### EDN Logic Operators (`eval-expr`)\n\n```clojure\n[:var :field_id]               ; get variable value\n[:= expr expr]                 ; equality\n[:!= expr expr]                ; inequality\n[:\u003e :\u003c :\u003e= :\u003c=]                ; numeric comparison\n[:and e1 e2 ...]               ; logical AND\n[:or  e1 e2 ...]               ; logical OR\n[:not e]                       ; logical NOT\n[:+ :- :* :/]                  ; arithmetic\n[:if cond then else]           ; conditional expression\n[:get map-expr :key]           ; get map property\n[:contains? [:var :list] val]  ; list membership\n[:call :alias/fn arg ...]      ; call imported formula function\n[:str/includes? s sub]         ; string contains\n```\n\n---\n\n## 📦 Importing Formula Libraries\n\nImport `.edn` formula files or full Clojure `.clj` scripts:\n\n```clojure\n:import [\"../formulas/cardio_risk.edn\"\n         [\"../formulas/candidate_score.clj\" :as :score]]\n```\n\nUse `:as :alias` to shorten long Clojure namespaces. Then call functions:\n\n```clojure\n:actions [[:set :result [:call :score/analyze-candidate [:var :x] [:var :y]]]]\n```\n\n---\n\n## 🎲 Bayesian / Stan Integration\n\nBridge a Stan model through a `.clj` wrapper script:\n\n```clojure\n;; formulas/bayesian_hiring.clj\n(ns formulas.bayesian-hiring)\n(defn run-stan-model [experience test-score]\n  ;; calls cmdstan via shell, returns posterior map\n  {:prob 78 :variance 0.02 :lower_bound 50 :upper_bound 100 :confidence \"95%\"})\n```\n\nImport and call it in a form:\n\n```clojure\n:import [[\"../formulas/bayesian_hiring.clj\" :as :stan]]\n:actions [[:set :result [:call :stan/run-stan-model [:var :exp] [:var :score]]]]\n:label   \"Hire probability: {{[:get [:var :result] :prob]}}%\"\n```\n\n---\n\n## 📂 Project Structure\n\n```\nbb-form/\n├── src/com/drbinhthanh/bb_form.clj   # Core engine\n├── forms/                             # Sample forms\n│   ├── job_application.edn            # Matrix scoring example\n│   ├── bayesian_recruitment.edn       # Bayesian hiring example\n│   └── health_check.edn\n├── formulas/                          # Formula libraries\n│   ├── candidate_score.clj\n│   ├── bayesian_hiring.clj\n│   ├── cardio_risk.edn\n│   └── stan_models/hiring_model.stan\n├── bucket/bb-form.json                # Scoop manifest\n├── Formula/bb-form.rb                 # Homebrew formula\n└── guide.md                           # Full Vietnamese user guide\n```\n\n---\n\n## 🗓️ Changelog\n\n### v2.0.0\n- ✅ **Phase 5**: `:import` formula libraries (`.edn` \u0026 `.clj`) with `:as` namespace alias\n- ✅ **Phase 6**: Stochastic variable support via Bayesian Stan model bridge\n- ✅ `[:call]` operator with alias resolution (priority: Clojure ns → EDN registry)\n- ✅ `[:get]` operator to extract map properties\n- ✅ `:info` field type — computed read-only display saved to output\n- ✅ Dynamic label interpolation `{{expr}}`\n- ✅ Bug fix: actions now execute correctly in batch `--values` mode\n\n### v1.0.0 (Phases 1–4)\n- ✅ Migration from `.json` to `.edn`\n- ✅ Flat-list fields + `:show-if` EDN expressions\n- ✅ `eval-expr` Logic Engine + Restarting Loop algorithm\n- ✅ `:variables` hidden state + `:actions` side effects\n- ✅ Multi-stage forms with `on-begin`/`on-end` hooks\n\n---\n\n## 📖 Documentation\n\n- **Vietnamese user guide**: [`guide.md`](./guide.md)\n- **Concept \u0026 design**: [`jsonlogic_concept.md`](./jsonlogic_concept.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdrringo%2Fbb-form","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdrringo%2Fbb-form","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdrringo%2Fbb-form/lists"}