{"id":49650791,"url":"https://github.com/detain/sugarcraft","last_synced_at":"2026-05-06T04:31:05.548Z","repository":{"id":355121013,"uuid":"1226846729","full_name":"detain/sugarcraft","owner":"detain","description":"🍬🍭 Monorepo: 16 PHP TUI libraries — ports of 🫧 BubbleTea, 🎨 Lipgloss, 🍬 Gum, 💎 Glamour, ✨ Glow + more. PHP 8.1+, ReactPHP async, composer-installable.","archived":false,"fork":false,"pushed_at":"2026-05-02T22:20:08.000Z","size":11535,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-05-02T23:12:58.175Z","etag":null,"topics":["ansi","bubbletea","bubbletea-port","charmbracelet","composer","console-app","elm-architecture","framework","gum-port","hacktoberfest","lipgloss-port","monorepo","php-library","php81","phptui","reactphp","terminal-ui","tui","tui-framework"],"latest_commit_sha":null,"homepage":"https://detain.github.io/sugarcraft/","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/detain.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","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-01T22:31:32.000Z","updated_at":"2026-05-02T22:20:12.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/detain/sugarcraft","commit_stats":null,"previous_names":["detain/candycore","detain/sugarcraft"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/detain/sugarcraft","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/detain%2Fsugarcraft","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/detain%2Fsugarcraft/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/detain%2Fsugarcraft/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/detain%2Fsugarcraft/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/detain","download_url":"https://codeload.github.com/detain/sugarcraft/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/detain%2Fsugarcraft/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32678565,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-06T02:33:58.958Z","status":"ssl_error","status_checked_at":"2026-05-06T02:33:39.611Z","response_time":117,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["ansi","bubbletea","bubbletea-port","charmbracelet","composer","console-app","elm-architecture","framework","gum-port","hacktoberfest","lipgloss-port","monorepo","php-library","php81","phptui","reactphp","terminal-ui","tui","tui-framework"],"created_at":"2026-05-06T04:31:02.352Z","updated_at":"2026-05-06T04:31:05.542Z","avatar_url":"https://github.com/detain.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SugarCraft\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"media/social-preview.png\" alt=\"SugarCraft — sweet to build, fun to use\" width=\"720\"\u003e\n\u003c/p\u003e\n\n\u003c!-- BADGES:BEGIN --\u003e\n[![CI](https://github.com/detain/sugarcraft/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/detain/sugarcraft/actions/workflows/ci.yml)\n[![codecov](https://codecov.io/gh/detain/sugarcraft/branch/master/graph/badge.svg)](https://app.codecov.io/gh/detain/sugarcraft)\n[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n[![PHP](https://img.shields.io/badge/php-%E2%89%A58.1-8892bf.svg)](https://www.php.net/)\n[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-ff5f87.svg)](CONTRIBUTING.md)\n\u003c!-- BADGES:END --\u003e\n\nPHP ports of the [Charmbracelet](https://charm.sh) TUI ecosystem (plus\n[bubblezone](https://github.com/lrstanley/bubblezone),\n[ntcharts](https://github.com/NimbleMarkets/ntcharts), and a small\nSugarCraft-flavoured sweetshop of original libraries) — composer-installable,\nPHP 8.1+, async on ReactPHP.\n\n🌐 **Website:** [sugarcraft.github.io](https://sugarcraft.github.io/) — library matrix, quickstart, comparison page.\n\n```sh\ncomposer require candycore/candycore\n```\n\n## What's in the box\n\nSixteen libraries grouped by layer:\n\n| | Library | Role |\n|---|---|---|\n| \u003cimg src=\"media/icons/candy-core.png\" width=\"48\" alt=\"\"\u003e | **[CandyCore](candy-core/)** | Elm-architecture TUI runtime — `Model` / `Msg` / `Cmd` / `Program` (incl. cursed cell-diff renderer). Port of [bubbletea](https://github.com/charmbracelet/bubbletea). |\n| \u003cimg src=\"media/icons/candy-sprinkles.png\" width=\"48\" alt=\"\"\u003e | **[CandySprinkles](candy-sprinkles/)** | Declarative styling + layout — `Style`, `Border`, `Table`, `List`, `Tree`, `Layout::join`, `Place`, `Canvas` (multi-layer compositor). Port of [lipgloss](https://github.com/charmbracelet/lipgloss). |\n| \u003cimg src=\"media/icons/honey-bounce.png\" width=\"48\" alt=\"\"\u003e | **[HoneyBounce](honey-bounce/)** | Damped spring physics + Newtonian projectile sim. Port of [harmonica](https://github.com/charmbracelet/harmonica). |\n| \u003cimg src=\"media/icons/candy-zone.png\" width=\"48\" alt=\"\"\u003e | **[CandyZone](candy-zone/)** | Mouse-zone tracker — wrap rendered chunks, get back bounding boxes. Port of [bubblezone](https://github.com/lrstanley/bubblezone). |\n| \u003cimg src=\"media/icons/sugar-bits.png\" width=\"48\" alt=\"\"\u003e | **[SugarBits](sugar-bits/)** | 14 components: TextInput, TextArea, ItemList, Table, Viewport, FilePicker, Progress, Spinner, Cursor, Help, Key, Paginator, Stopwatch, Timer. Port of [bubbles](https://github.com/charmbracelet/bubbles). |\n| \u003cimg src=\"media/icons/sugar-charts.png\" width=\"48\" alt=\"\"\u003e | **[SugarCharts](sugar-charts/)** | Canvas + Sparkline, Bar, Line, Heatmap, Scatter, TimeSeries, Streamline, Waveline, OHLC, Picture (Sixel/Kitty/iTerm2). Port of [ntcharts](https://github.com/NimbleMarkets/ntcharts). |\n| \u003cimg src=\"media/icons/sugar-prompt.png\" width=\"48\" alt=\"\"\u003e | **[SugarPrompt](sugar-prompt/)** | Form library — Note, Input, Confirm, Select, MultiSelect, Text, FilePicker; multi-page Groups; 6 themes. Port of [huh](https://github.com/charmbracelet/huh). |\n| \u003cimg src=\"media/icons/candy-shell.png\" width=\"48\" alt=\"\"\u003e | **[CandyShell](candy-shell/)** | Composer-installable CLI of all 13 subcommands (choose, confirm, file, filter, format, input, join, log, pager, spin, style, table, write). Port of [gum](https://github.com/charmbracelet/gum). |\n| \u003cimg src=\"media/icons/candy-shine.png\" width=\"48\" alt=\"\"\u003e | **[CandyShine](candy-shine/)** | Markdown → ANSI renderer with word-wrap, OSC 8 hyperlinks, 8 themes. Port of [glamour](https://github.com/charmbracelet/glamour). |\n| \u003cimg src=\"media/icons/candy-kit.png\" width=\"48\" alt=\"\"\u003e | **[CandyKit](candy-kit/)** | CLI presentation helpers — StatusLine, Banner, Section, Stage, HelpText. Port of [fang](https://github.com/charmbracelet/fang). |\n| \u003cimg src=\"media/icons/candy-freeze.png\" width=\"48\" alt=\"\"\u003e | **[CandyFreeze](candy-freeze/)** | Code → SVG screenshot generator (no `ext-gd` required). Port of [freeze](https://github.com/charmbracelet/freeze). |\n| \u003cimg src=\"media/icons/sugar-glow.png\" width=\"48\" alt=\"\"\u003e | **[SugarGlow](sugar-glow/)** | Markdown CLI viewer / pager. Port of [glow](https://github.com/charmbracelet/glow). |\n| \u003cimg src=\"media/icons/sugar-spark.png\" width=\"48\" alt=\"\"\u003e | **[SugarSpark](sugar-spark/)** | ANSI escape-sequence inspector. Port of [sequin](https://github.com/charmbracelet/sequin). |\n| \u003cimg src=\"media/icons/candy-wish.png\" width=\"48\" alt=\"\"\u003e | **[CandyWish](candy-wish/)** | SSH server middleware — Logger, Auth, RateLimit, BubbleTea (mount a CandyCore Program over `ForceCommand`). Port of [wish](https://github.com/charmbracelet/wish). |\n| \u003cimg src=\"media/icons/sugar-wishlist.png\" width=\"48\" alt=\"\"\u003e | **[SugarWishlist](sugar-wishlist/)** | TUI directory of SSH endpoints — YAML/JSON config + `pcntl_exec` into the chosen `ssh`. Port of [wishlist](https://github.com/charmbracelet/wishlist). |\n| \u003cimg src=\"media/icons/candy-metrics.png\" width=\"48\" alt=\"\"\u003e | **[CandyMetrics](candy-metrics/)** | Telemetry primitives — counters, gauges, histograms with InMemory / JSON / StatsD / Prometheus textfile / Multi backends, plus a CandyWish session middleware. Port of [promwish](https://github.com/charmbracelet/promwish). |\n\n## Apps built on the stack\n\n| | App | Role |\n|---|---|---|\n| \u003cimg src=\"media/icons/candy-mold.png\" width=\"48\" alt=\"\"\u003e | **[CandyMold](candy-mold/)** | `composer create-project candycore/candy-mold my-app` — bootstrap skeleton with a working counter Model. Port of [bubbletea-app-template](https://github.com/charmbracelet/bubbletea-app-template). |\n| \u003cimg src=\"media/icons/candy-tetris.png\" width=\"48\" alt=\"\"\u003e | **[CandyTetris](candy-tetris/)** | Tetris clone — SRS rules, 7-bag, ghost piece, NES scoring, level-driven gravity. Port of [tetrigo](https://github.com/Broderick-Westrope/tetrigo). |\n| \u003cimg src=\"media/icons/super-candy.png\" width=\"48\" alt=\"\"\u003e | **[SuperCandy](super-candy/)** | Dual-pane file manager — Midnight Commander style, multi-select, sort, delete-with-confirm. Port of [superfile](https://github.com/yorukot/superfile). |\n| \u003cimg src=\"media/icons/sugar-crush.png\" width=\"48\" alt=\"\"\u003e | **[SugarCrush](sugar-crush/)** | AI coding-assistant chat shell — pluggable backend (EchoBackend offline; CommandBackend for Anthropic / OpenAI / Ollama via a wrapper script). Port of [crush](https://github.com/charmbracelet/crush). |\n| \u003cimg src=\"media/icons/sugar-stash.png\" width=\"48\" alt=\"\"\u003e | **[SugarStash](sugar-stash/)** | Three-pane git TUI — status / branches / log, single-key stage / unstage; shells out to `git` for every mutation. Port of [lazygit](https://github.com/jesseduffield/lazygit). |\n| \u003cimg src=\"media/icons/candy-query.png\" width=\"48\" alt=\"\"\u003e | **[CandyQuery](candy-query/)** | Terminal SQLite browser — list tables, browse rows, run ad-hoc queries (PDO + `:memory:` test fixtures). Port of [lazysql](https://github.com/jorgerojas26/lazysql). |\n| \u003cimg src=\"media/icons/sugar-tick.png\" width=\"48\" alt=\"\"\u003e | **[SugarTick](sugar-tick/)** | Privacy-first coding-time tracker — JSONL on disk, SugarCharts-driven dashboard, no cloud / no MongoDB. Port of [TakaTime](https://github.com/Rtarun3606k/TakaTime). |\n| \u003cimg src=\"media/icons/candy-mines.png\" width=\"48\" alt=\"\"\u003e | **[CandyMines](candy-mines/)** | Minesweeper — first-click safety, recursive flood-fill, flag toggle, win/lose detection, deterministic-RNG injectable. Port of [go-sweep](https://github.com/maxpaulus43/go-sweep). |\n| \u003cimg src=\"media/icons/candy-flip.png\" width=\"48\" alt=\"\"\u003e | **[CandyFlip](candy-flip/)** | ASCII GIF viewer — ext-gd decode, downsample to a cell grid, render as ANSI 24-bit blocks or a luminance-ramp. Port of [gifterm](https://github.com/namzug16/gifterm). |\n| \u003cimg src=\"media/icons/honey-flap.png\" width=\"48\" alt=\"\"\u003e | **[HoneyFlap](honey-flap/)** | Flappy-Bird-style game — bird motion is a HoneyBounce projectile, pipes scroll left at a fixed cell rate. Port of [flapioca](https://github.com/kbrgl/flapioca). |\n\nEach library has its own `README.md` with usage examples and a deep dive into\nits public API.\n\n## Quickstart — a counter app\n\n```php\nuse CandyCore\\Core\\{Cmd, KeyType, Model, Msg, Program};\nuse CandyCore\\Core\\Msg\\KeyMsg;\n\nfinal class Counter implements Model\n{\n    public function __construct(public readonly int $n = 0) {}\n    public function init(): ?\\Closure { return null; }\n\n    public function update(Msg $msg): array\n    {\n        if ($msg instanceof KeyMsg \u0026\u0026 $msg-\u003etype === KeyType::Char \u0026\u0026 $msg-\u003erune === 'q') {\n            return [$this, Cmd::quit()];\n        }\n        return [\n            $msg instanceof KeyMsg \u0026\u0026 $msg-\u003etype === KeyType::Up\n                ? new self($this-\u003en + 1)\n                : ($msg instanceof KeyMsg \u0026\u0026 $msg-\u003etype === KeyType::Down\n                    ? new self($this-\u003en - 1)\n                    : $this),\n            null,\n        ];\n    }\n\n    public function view(): string { return \"n = {$this-\u003en}\\n↑ ↓ to count, q to quit\\n\"; }\n}\n\n(new Program(new Counter()))-\u003erun();\n```\n\n## Architecture\n\n- **PHP 8.1+** — fibers, readonly props, enums, `match`, intersection types.\n- **Runtime**: ReactPHP event loop. Mirrors goroutine semantics for input,\n  signals, render tick, command execution.\n- **Style**: PSR-12 + readonly DTOs. Every `Style`, `Model`, etc. is\n  immutable — `with*()` returns a new instance.\n- **Testing**: PHPUnit 10. Snapshot ANSI tests for renderers; scripted-input\n  event tests for the runtime.\n- **Layout**: monorepo during the porting phase. Each library will split\n  into its own repo at v1.0.\n\n## Status\n\nEvery library in the table above is **at v1**. The full surface of every Go\ncounterpart that PHP can reasonably express (modulo the niche items called\nout in `CONVERSION.md` § Phase audit) has been ported. See\n[CONVERSION.md](./CONVERSION.md) for the full roadmap, per-library status,\nand the v2-parity sweep against Bubble Tea v2 / Lipgloss v2 / Bubbles v2.\n\n## Running the test suites\n\nThe umbrella package is a metapackage; each library has its own\n`composer.json` + `vendor/`. To test everything:\n\n```sh\nfor d in candy-core candy-sprinkles honey-bounce candy-zone sugar-bits \\\n         sugar-charts sugar-prompt candy-shell candy-shine candy-kit \\\n         candy-freeze sugar-glow sugar-spark \\\n         candy-wish sugar-wishlist candy-metrics \\\n         candy-mold candy-tetris super-candy sugar-crush \\\n         sugar-stash candy-query sugar-tick candy-mines candy-flip honey-flap; do\n    (cd \"$d\" \u0026\u0026 composer install --quiet \u0026\u0026 vendor/bin/phpunit) || exit 1\ndone\n```\n\n## Contributing\n\nSee [CONTRIBUTING.md](./CONTRIBUTING.md). Bugs, feature requests, and\nports of additional Charmbracelet (or compatible) libraries welcome.\nFor security issues, see [SECURITY.md](./SECURITY.md).\n\n## License\n\n[MIT](./LICENSE).\n\n---\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://sugarcraft.github.io/\"\u003e\u003cimg src=\"media/profile.png\" alt=\"SugarCraft\" width=\"120\"\u003e\u003c/a\u003e\u003cbr\u003e\n  \u003cem\u003emade with sugar · sweet to build · fun to use\u003c/em\u003e\n\u003c/p\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdetain%2Fsugarcraft","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdetain%2Fsugarcraft","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdetain%2Fsugarcraft/lists"}