{"id":47819169,"url":"https://github.com/noxcraftdev/soffit","last_synced_at":"2026-04-06T22:01:00.424Z","repository":{"id":349204346,"uuid":"1197637348","full_name":"noxcraftdev/soffit","owner":"noxcraftdev","description":"Customizable statusline manager for Claude Code with desktop editor and plugin system","archived":false,"fork":false,"pushed_at":"2026-04-04T16:42:13.000Z","size":2767,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-05T21:03:02.779Z","etag":null,"topics":["claude-code","cli","developer-tools","plugin-system","rust","statusline","terminal"],"latest_commit_sha":null,"homepage":"https://crates.io/crates/soffit","language":"Rust","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/noxcraftdev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-31T18:44:28.000Z","updated_at":"2026-04-05T20:27:29.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/noxcraftdev/soffit","commit_stats":null,"previous_names":["noxcraftdev/soffit"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/noxcraftdev/soffit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noxcraftdev%2Fsoffit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noxcraftdev%2Fsoffit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noxcraftdev%2Fsoffit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noxcraftdev%2Fsoffit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/noxcraftdev","download_url":"https://codeload.github.com/noxcraftdev/soffit/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/noxcraftdev%2Fsoffit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31491097,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-06T17:22:55.647Z","status":"ssl_error","status_checked_at":"2026-04-06T17:22:54.741Z","response_time":112,"last_error":"SSL_read: 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":["claude-code","cli","developer-tools","plugin-system","rust","statusline","terminal"],"created_at":"2026-04-03T19:01:43.202Z","updated_at":"2026-04-06T22:01:00.313Z","avatar_url":"https://github.com/noxcraftdev.png","language":"Rust","readme":"# soffit\n\n[![Crates.io](https://img.shields.io/crates/v/soffit)](https://crates.io/crates/soffit)\n[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n[![CI](https://github.com/noxcraftdev/soffit/actions/workflows/release.yml/badge.svg)](https://github.com/noxcraftdev/soffit/actions)\n\nCustomizable statusline manager for [Claude Code](https://docs.anthropic.com/en/docs/claude-code).\nDesktop editor with drag-and-drop, live preview, and a widget system for custom statusline extensions.\n\n![soffit in action](assets/soffit-live.png)\n\n![soffit statusline](assets/statusline.png)\n\n## Features\n\n- **9 built-in widgets**: context bar, cost, git, version, duration, vim mode, agent, quota, session\n- **Configurable theme**: custom colors, icons, and bar styles via config or the desktop editor\n- **Desktop editor**: drag-and-drop widget ordering, live preview, per-widget component configuration\n- **Custom widgets**: create your own widgets as shell scripts or compiled binaries\n- **Auto-detection**: widgets declare components via JSON output for full editor integration\n- **Terminal-width aware**: automatic wrapping and responsive bar widths\n\n## Install\n\n### Pre-built binary (recommended)\n```bash\ncurl -fsSL https://raw.githubusercontent.com/noxcraftdev/soffit/main/install.sh | sh\n```\n\n### Homebrew (macOS/Linux)\n```bash\nbrew tap noxcraftdev/soffit\nbrew install soffit\n```\n\n### From source\n```bash\ncargo install soffit\n```\n\n### System dependencies (Linux, build from source only)\n```bash\nsudo apt install libgtk-3-dev libwebkit2gtk-4.1-dev libxdo-dev libsoup-3.0-dev libjavascriptcoregtk-4.1-dev\n```\n\n### Supported platforms\n\n- Linux (x86_64)\n- macOS (Intel and Apple Silicon)\n\n## Setup\n\nRun the setup command to configure Claude Code automatically:\n\n```bash\nsoffit setup\n```\n\nOr add manually to `~/.claude/settings.json`:\n\n```json\n{\n  \"statusLine\": {\n    \"type\": \"command\",\n    \"command\": \"soffit render\",\n    \"padding\": 0\n  }\n}\n```\n\n## Usage\n\n```bash\nsoffit setup           # Configure Claude Code to use soffit (writes settings.json)\nsoffit render          # Render statusline (reads Claude Code JSON from stdin)\nsoffit edit            # Open the desktop config editor\nsoffit widgets         # List available widgets (built-in + custom)\nsoffit widget \u003cname\u003e   # Test a single widget\n```\n\n## Configuration\n\nConfig lives at `~/.config/soffit/config.toml` (falls back to `~/.config/claude-statusline/config.toml`):\n\n```toml\nstatusline_line1 = [\"vim\", \"agent\", \"version\", \"context_bar\", \"quota\", \"duration\", \"cost\"]\nstatusline_line2 = [\"git\", \"insights\"]\nstatusline_line3 = []\n\ncost_target_weekly = 300.0\nautocompact_pct = 100\n\n[statusline_widgets.cost]\ncompact = false\ncomponents = [\"session\", \"today\", \"week\"]\n```\n\n### Theme\n\nOverride semantic color roles using ANSI 256-color indices:\n\n```toml\n[palette]\nsuccess = 114     # green tones (context bar ok, git clean)\nwarning = 215     # orange tones (quota approaching, cost high)\ndanger  = 203     # red tones (quota critical, over budget)\nmuted   = 242     # dimmed text (secondary info)\nsubtle  = 250     # light gray (tertiary info)\nprimary = 111     # blue tones (main accent)\naccent  = 183     # purple tones (secondary accent)\n```\n\nAll 7 roles have built-in defaults.\nUnset roles use the defaults.\n\n### Icons\n\nOverride icons per widget under `[statusline_widgets.NAME.icons]`:\n\n```toml\n[statusline_widgets.cost.icons]\ncost = \"$ \"          # instead of 💸\n\n[statusline_widgets.duration.icons]\nduration = \"T \"      # instead of ⏱\n\n[statusline_widgets.git.icons]\ngit_branch = \" \"    # nerd font branch icon\n\n[statusline_widgets.agent.icons]\nagent = \"\u003e \"         # ASCII fallback\n```\n\nAvailable icon keys per widget are shown in `soffit edit` under the widget's appearance panel.\n\n### Bar style\n\nChoose a preset for the quota progress bar:\n\n```toml\nbar_style = \"block\"   # ◎◉● density (default)\nbar_style = \"dot\"     # ●○\nbar_style = \"ascii\"   # #-\n```\n\n### Unicode text\n\nSuperscript/subscript rendering in the version widget can be toggled:\n\n```toml\nuse_unicode_text = false   # plain text instead of ¹·²·³ / ₛₒₙₙₑₜ\n```\n\n## Custom Widgets\n\nDrop scripts in `~/.config/soffit/plugins/`:\n\n```bash\n#!/bin/bash\n# ~/.config/soffit/plugins/weather.sh\nINPUT=$(cat)\nCOMPACT=$(echo \"$INPUT\" | python3 -c \"import json,sys; print(json.load(sys.stdin).get('config',{}).get('compact',False))\" 2\u003e/dev/null)\n\nTEMP=\"22°C\"\nCOND=\"sunny\"\n\nif [ \"$COMPACT\" = \"True\" ]; then\n  echo \"{\\\"output\\\": \\\"$TEMP\\\", \\\"components\\\": [\\\"temp\\\", \\\"condition\\\"]}\"\nelse\n  echo \"{\\\"output\\\": \\\"☀ $TEMP $COND\\\", \\\"components\\\": [\\\"temp\\\", \\\"condition\\\"]}\"\nfi\n```\n\nMake it executable: `chmod +x ~/.config/soffit/plugins/weather.sh`\n\n### Widget input format\n\nWidgets receive JSON on stdin:\n\n```json\n{\n  \"data\": {\n    \"session_id\": \"abc123\",\n    \"version\": \"1.2.16\",\n    \"model\": {\"display_name\": \"claude-sonnet-4-6\"},\n    \"context_window\": {\"used_percentage\": 42.0},\n    \"cost\": {\"total_duration_ms\": 4830000, \"total_cost_usd\": 0.42},\n    \"vim\": {\"mode\": \"NORMAL\"},\n    \"agent\": {\"name\": \"worker-1\"}\n  },\n  \"config\": {\n    \"compact\": false,\n    \"components\": [\"temp\", \"condition\"]\n  },\n  \"palette\": {\n    \"primary\":  \"\\u001b[38;5;111m\",\n    \"accent\":   \"\\u001b[38;5;183m\",\n    \"success\":  \"\\u001b[38;5;114m\",\n    \"warning\":  \"\\u001b[38;5;215m\",\n    \"danger\":   \"\\u001b[38;5;203m\",\n    \"muted\":    \"\\u001b[38;5;242m\",\n    \"subtle\":   \"\\u001b[38;5;250m\",\n    \"reset\":    \"\\u001b[0m\"\n  }\n}\n```\n\n### Widget output format\n\nReturn JSON with `parts` so the framework reorders components per user config:\n```json\n{\"parts\": {\"temp\": \"22°C\", \"condition\": \"sunny\"}, \"components\": [\"temp\", \"condition\"]}\n```\n\nOr return a pre-composed string (component reordering won't apply):\n```json\n{\"output\": \"22°C sunny\", \"components\": [\"temp\", \"condition\"]}\n```\n\nOr return plain text:\n```\n22°C sunny\n```\n\n### Widget metadata (optional)\n\nCreate a `.toml` sidecar for richer editor integration:\n\n```toml\n# ~/.config/soffit/plugins/weather.toml\ndescription = \"Current weather conditions\"\ncomponents = [\"temp\", \"condition\"]\nhas_compact = true\n```\n\n## Marketplace\n\nThe marketplace subcommand manages a list of named widget sources (GitHub repos that publish a `registry.json`).\nBy default soffit ships with the official `noxcraftdev/soffit-marketplace` source.\n\n```bash\n# Add a community source\nsoffit marketplace add community alice/soffit-extras\n\n# List registered sources (no network)\nsoffit marketplace list\n\n# List sources with widget counts (fetches or uses cached registry)\nsoffit marketplace list --verbose\n\n# Remove a source\nsoffit marketplace remove community\n\n# Refresh the cached registry for all sources (or one with --source)\nsoffit marketplace update\nsoffit marketplace update --source community\n```\n\n### Installing from the marketplace\n\nOnce sources are configured, install by widget name — soffit searches all sources:\n\n```bash\nsoffit install \u003cname\u003e          # resolves from marketplace sources\nsoffit install owner/repo      # installs all widgets from a repo directly\nsoffit install owner/repo/name # installs a single widget from a specific repo\n```\n\n### Publishing a marketplace source\n\nCreate a `registry.json` at the root of any public GitHub repo:\n\n```json\n{\n  \"plugins\": [\n    {\n      \"name\": \"weather\",\n      \"description\": \"Current weather conditions\",\n      \"repo\": \"alice/soffit-extras\",\n      \"file\": \"weather.sh\"\n    }\n  ]\n}\n```\n\nThen share the source with: `soffit marketplace add your-source alice/soffit-extras`.\n\n## Community Widgets\n\nInstall widgets shared on GitHub:\n\n```bash\n# Install all widgets from the official collection\nsoffit install noxcraftdev/soffit-plugins\n\n# Install a specific widget\nsoffit install noxcraftdev/soffit-plugins/last-msg\n\n# Remove an installed widget\nsoffit uninstall last-msg\n\n# Overwrite an existing widget\nsoffit install noxcraftdev/soffit-plugins --force\n```\n\nInstalled widgets land in `~/.config/soffit/plugins/` and are immediately available.\n\n### Creating a widget repository\n\nLay out your repo as a flat directory of `{name}.sh` + `{name}.toml` pairs:\n\n```\nmy-soffit-plugins/\n  weather.sh\n  weather.toml\n  stocks.sh\n  stocks.toml\n```\n\nsoffit looks for this layout at the repo root first, then inside a `plugins/` subdirectory.\nMultiple widgets per repo is the norm — a single repo can host an entire collection.\n\nThe `.toml` sidecar is optional but recommended: it supplies the description and component list shown in `soffit edit`.\n\n## Editor\n\n`soffit edit` opens a desktop GUI:\n\n- **Lines tab**: drag-and-drop widgets across 3 statusline rows\n- **Widgets tab**: configure built-in widgets (reorder components, toggle compact mode)\n- **Widget management**: create, edit, preview, rename, delete custom widgets\n- **Live preview**: see your statusline update in real-time\n\n![Editor - Lines tab](assets/editor-lines.png)\n![Editor - Widgets tab](assets/editor-widgets.png)\n\n\u003cvideo src=\"assets/editor-demo.webm\" autoplay loop muted playsinline width=\"100%\"\u003e\u003c/video\u003e\n\n## License\n\nMIT\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnoxcraftdev%2Fsoffit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnoxcraftdev%2Fsoffit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnoxcraftdev%2Fsoffit/lists"}