Repository navigation
Releases
v0.1.8
Changed
- IPs that scan for secret files (the
cubby-probejail) are now banned for good instead of for 10 minutes: scanners
rarely come back from the same address, so the doubling ban never grew. Bans are kept in anipset(installed with
fail2ban, and bycubby-server upgradewhere fail2ban is already on), and the Security tab keeps listing a permanent
ban past 90 days until you lift it. Login floods (cubby-ratelimit) are still banned for 10 minutes, doubling.
v0.1.7
Fixed
cubby-server upgrade,cubby-server versionand the installer now ask the server inside its container whether it's
up. On servers with a domain they asked port 80, which only redirects to HTTPS, so every upgrade ended with "Cubby
didn't come back up" although it had worked,versionsaid the server wasn't answering, and the newcubby-server
was never installed. Servers with a domain: the upgrade to this release still runs your oldcubby-server, so
after it, install the new one once with
sudo install -m 755 /opt/cubby/src/docker/cubby-server /usr/local/bin/cubby-server.
v0.1.6
Added
- Scanner and brute-force bans with fail2ban. The installer sets it up on the host (
--no-fail2banskips it) with two
jails:cubby-probebans IPs that ask for scanner paths (/.env,/.git/config,*.php,/wp-login.php…) 5
times in 10 minutes, andcubby-ratelimitbans IPs that hit the login limit 30 times; bans start at 10 minutes and
double for repeat offenders. They block Cubby's web ports only (in Docker'sDOCKER-USERchain); SSH keeps
fail2ban's own jail. Caddy writes the access log fail2ban reads only while it's on, without headers or?token=,
and keeps it 7 days. Existing servers turn it on once withsudo cubby-server fail2ban enableafter upgrading (later upgrades
remind you until it's on);
fail2ban status,unban <ip>anddisablemanage it. - Admin → Security lists current bans (why, when, until, the hosts and paths each IP swept) with Unban, and 90
days of ban history. Agents get the same withcubby admin bansandcubby admin bans unban <ip> --yes; every unban
shows in the activity log.
Fixed
- Paths with a part starting with a dot (
/.env,/.aws/credentials,/admin/.env) are a 404 instead of the app's
page, so vulnerability scans no longer show up as page views or tell scanners a file exists./.well-known/is
still served. - Admin → Apps no longer shows a stray "null" when an admin opens the data panel of an app they own.
v0.1.5
Added
- Dashboard Home is now your agents' activity timeline: one line per change, grouped by day, with the agent's badge
and the app. The live deploy has Roll back (with a confirm), and a failed job gets Copy fix-it prompt.
"What should your agent do next?" offers prompts to copy, and a summary column (above the timeline on phones)
shows who's on your apps now, views over 7 days and your agents. Failed jobs and apps with many API errors are
flagged at the top. A new user with no agent and no app gets three connect steps instead. - The dashboard's Agents page lists your agents with their machine, the apps they touched and when they were last
seen; rename one inline or revoke it (its key stops working at once). Connect a new agent copies the setup
prompt, and the token for scripts and CI moved here from Home./agents/<id>shows what one agent did. - Each app has a page in the dashboard,
/apps/<app>[/<tab>], with tabs that keep their place on reload (and scroll
sideways on phones). Overview has a KPI strip (active now, views, visitors, API error rate, accounts) and
hand-drawn charts of views, unique visitors, active visitors and API errors over 24 hours, 7 or 30 days, sharing one
time axis with every deploy drawn through them; each has a text summary and a table fallback, and top paths show
when the server reports them. Activity, Deploys (roll back to any kept deploy), Jobs, Env (secrets
by name; values are never shown) and Settings (gallery visibility, delete after typing the app's name) follow.
Empty tabs suggest what to ask your agent. The Apps list became a table with active visitors, a 7-day views
sparkline and who deployed each app last. - The dashboard's Admin page has tabs with their own links (
/admin/<tab>, kept on reload): Overview
(server-wide users, views, visitors, active now, API error rate and free disk; every app's views charted over 7
days; the top apps by views; the most active agents across all users; the disk at a glance; updates), Users,
Apps (each app's older deploys, listed and deleted one by one or all at once; the live one never), Agents
(every agent that changed something in the last 30 days, with its owner), Jobs, Settings (name, invites,
limits, and how many nightly backups to keep with what that would delete and free, or add, before saving) and
Storage (a disk bar by category, apps by size, backups with Back up now, Delete with the newest and only-backup
guards and a copyablesudo cubby-server restore <date>, and data-clear snapshots with Purge).
/api/admin/metricsnow also returns every app's hours and days summed, for the Overview chart. - Each app has a Data tab (
/apps/<app>/data): its collections with record counts and uploaded file sizes (the
app's user accounts unticked, with the new-passwords warning when ticked); Empty, Drop, or delete records of one
collection by a filter (with examples and a "created before" date); a mandatory preview (matches N of M, up to five
records to tick and delete only those, cascades, what blocks it, an extra tick above 10,000 records) that goes
stale when the form changes; the app's name typed to confirm; then the snapshot it saved. Snapshots are listed with
Restore (dry run first, with schema drift and Overwrite) and Purge (not for an admin's snapshot, unless you're an
admin; one whose uploads were over the cap says they weren't kept). - Admins clear any app's data from Admin → Apps → Clear data (
/admin/apps/<app>), with a required reason. The
owner sees a banner on the app's page and an item at the top of Home, linking to the snapshots, until they dismiss it. - Scheduled jobs. An app can run code on a cron schedule (UTC): one file per job in
cubby/jobs/, bundled with its
npm dependencies bycubby deployand rolled back with the deploy. Each run is a sandboxed Node.js process (no
access to the server's files, environment, processes or local network) whose database client reaches only that
app's records, as admin.cubby jobslists jobs;cubby jobs run <job>runs one now and prints its log;
cubby jobs logsandcubby jobs pause|resumedo what they say. A job never overlaps itself, and missed runs are
skipped. - App secrets for jobs:
cubby env set NAME=value(or--from-stdin),cubby env list,cubby env unset NAME --yes.
Values are encrypted with a server key inDATA_DIR/secrets, which nightly backups now include. - The dashboard lists an app's jobs on its card, with Run now, Pause and the last log. The Admin tab lists every
app's jobs and has a switch to stop them all and a time limit per run (60 seconds by default). /api/infolists optional server features (features: ["jobs"]).- Admin storage and backups from the CLI, the first
cubby admincommands.cubby admin storageshows where the disk
goes (database, uploaded files, current deploys, older deploys kept for rollback, backups, free disk) and per app,
measured on demand and reused for 5 minutes.cubby admin backupslists backups by date with their database and
sites sizes;createbacks up now (one at a time, shared with the nightly run);delete <date> --yesremoves both
files of the pair, warns when it was the newest, and refuses the only backup without--leave-none. Restore stays
sudo cubby-server restore <date>. Non-admins get a clear error. API:GET /api/admin/storage,
GET|POST /api/admin/backups,DELETE /api/admin/backups/<date>[?leave_none=1]. - How many nightly backups to keep is now a server setting (1 to 90), seeded from
BACKUP_KEEPon first boot only;
existing servers keep usingBACKUP_KEEP(7 if unset) until it's changed.cubby admin backups keep <n>sets it
and says what the next nightly prune deletes and frees (or roughly how much more disk it takes); lowering it needs
--yes. API:backup_keepinPATCH /api/admin/settings;GET /api/admin/backups[?keep=N]returns anestimate. - Admins can delete older deploys of any app, never the one it serves:
cubby admin deploys <app>lists them,
prune [--keep <n>] --yesdeletes them oldest first (sparing the newest n),delete <id> --yesdeletes one. Their
jobs folders go too and they leave the app's rollback list. API:GET /api/admin/apps/<app>/deploys,
POST /api/admin/apps/<app>/deploys/prune,DELETE /api/admin/apps/<app>/deploys/<id>. - Every approved
cubby loginbecomes its own named agent with its own key, instead of handing out your one token.
The CLI tells the server which agent tool it runs under (Claude Code, Codex, Cursor, otherwise "Terminal";
--clientoverrides it) and the machine's name, so agents are named like "Claude Code · chaitanya-mbp". Logins
from older CLIs still work and get a dated name ("Agent · 2026-10-17"). Once you sign in, the approval page says which agent is
asking.cubby agents(andGET /api/agents) lists your agents and marks the current one; the dashboard's token,
and tokens from before this release, show up as "Manual token" and keep working. API keys gain an emptyscopes
field, reserved for limiting keys later. - Rename and revoke agents one at a time:
cubby agents rename <id> <name>andcubby agents revoke <id> --yes
(PATCH/DELETE /api/agents/:id). A revoked key gets 401 on its next request while your other agents keep
working; an agent may revoke itself, which logs it out likecubby logout. You can only see and change your own
agents.cubby agentsshows each agent's ID and when it was last seen. - An activity log of who changed what: app create, update and delete, deploys (deploy id and file count),
rollbacks, schema pushes (created, updated and kept) and drops, secrets set and removed (key names only, never
values), jobs run now, paused and resumed, agent logins, and admin actions on users, apps and backups
(cubby admin backups create|delete). Each entry names the agent that made it, or "dashboard" for the dashboard
and the manual token. Reads aren't logged.cubby activity [app] [--agent <id>|dashboard] [--limit n](and
GET /api/activity) shows your own entries; admins see everyone's with--all(GET /api/admin/activity).
Entries older than 30 days are pruned before every backup (nightly,cubby admin backups createand
cubby-server backup). An app's entries outlive the app until they age out; deleting a user deletes theirs.
Stored in a new platform collection,cubby_activity, closed to apps like the others. Entries also carry a small
structuredmetawhere it helps (deploys{ deploy, files }, rollbacks{ deploy }, job runs{ job, status },
job pause and resume{ job }; otherwisenull, and never a secret value), so the dashboard doesn't have to parse
the summary text. - Page views and unique visitors per app, counted by the server as it serves an app's pages: no script in the app,
no cookies. Assets,/pbcalls, HEAD requests, prefetches and obvious bots don't count. A visitor is a hash of IP
address and browser with a salt that lives only in memory and changes every UTC day; IPs are never stored. Counts
are flushed to the database every minute (and on shutdown): views per hour, views and visitors per UTC day.
cubby metrics <app>shows one app,cubby metricsall of yours,--rangeup to 1y (default 24h). Owners see
their apps; admins see any./api/infolistsmetricsinfeatures. - Live and backend metrics in
cubby metrics: active now (visitors seen on a page or a/pbcall in the last 5
minutes, in memory only, no heartbeat) and its peak per hour;/pbAPI requests and 5xx errors per hour with the
error rate; and the app's accounts with signups per day, read from PocketBase when asked.cubby metricswithout
an app also shows each app's active now and API errors. - Top paths, deploy markers, a year of history and admin tot...
v0.1.4
Added
- The server's root URL answers agents and curl (anything without a browser user agent) with the setup steps as plain
text, so "set up Cubby from https://your-server" works without the dashboard. Browsers still get the dashboard.
Changed
- The dashboard's connect card is redesigned around one "Copy prompt for agent" button: a prompt to paste into your
agent instead of a barecurl … | shcommand, which agents rightly flagged as suspicious. The prompt names the
server, installs the skill withnpx skills add chaitanyadukkipaty/cubby --skill cubby -g(or the server's
/skill.shwithout npm) and has the agent connect, so the server becomes your default./skill.shkeeps working
as before. - The skill takes the server URL from the user's message when the CLI isn't installed yet.
v0.1.3
Fixed
- The dashboard's Log in tab (and Sign up, when signup is open) no longer shows a stray "null" under the password
field.
v0.1.2
Added
- IP-only installs work when port 80 is taken. The installer names what holds the port and offers a free one (or
take one with--http-port); it becomes part of the URL, likehttp://203-0-113-5.sslip.io:8080.--pb-portdoes
the same for the PocketBase admin port (8090), and IP mode no longer publishes 443.
Changed
- The installer,
cubby-server rebuild/upgradeandset-domaincheck the ports they need first and refuse, naming
the process or container holding one, instead of failing indocker run. A domain needs 80 and 443.
v0.1.1
Added
- Each server has a display name, like "Priya's Cubby". The installer asks for it (or set
CUBBY_SERVER_NAMEon
first boot), admins can rename it in the Admin tab, and it's shown on the dashboard, the sign-in and agent-approval
pages,/api/info,/docs.mdand in CLI output, with a "runs on Cubby" credit. - One CLI and one agent skill for several servers.
~/.cubby/config.jsonkeeps a named list of servers;
cubby servers,cubby use <name>,cubby logout --server <name>/--allandcubby versionare new, and
--serveraccepts a server's name. Running a server's/skill.shadds it to the list. - Servers on different Cubby versions work side by side: the
cubbycommand is now a small launcher that runs, for
each server, a CLI matching that server's version (downloaded once into~/.cubby/cli/<version>/), and falls back
to the last known version when a server is unreachable. CUBBY_VERSION_OVERRIDEserver setting, for testing version skew locally.- Choose what to install:
install.shinstalls the latest release by default;--version X.Y.Zpicks a release and
--ref <branch|tag|commit>installs any ref.--domain/--no-domain,--admin-email,--admin-password-file
and--nameanswer the questions up front, for installs without prompts. cubby-server upgrademoves to the latest release (or keeps following the branch you installed from), takes a
backup first, and replaces itself with the new version's script.--version X.Y.Zpins or rolls back,--ref
switches to any ref,--no-backupskips the backup.cubby-server versionshows what's running, what it follows
and the latest release.- "Update available" notice in the Admin tab, with the release notes and the upgrade command. The server asks GitHub
for the latest release once a day (its only outbound request); admins can turn it off, andCUBBY_UPDATE_CHECK=0
disables it entirely. - Releases are tagged and published automatically when a release PR is merged (see CONTRIBUTING.md "Releases").
cubby help [<command>] [--json]: every command and flag the targeted server supports. Each server's/docs.md
includes the same list.- CI fails when test coverage drops: unit-only and unit + integration thresholds (
.c8rc.unit.json,.c8rc.json),
withnpm run coverage:ratchetto raise them.
Changed
-
The CLI always matches the server it's talking to; in an app folder, the server in
cubby.json. This now covers
every command that talks to a server, includinglogin,signup,whoamiandhelp, not just app commands. -
The agent skill only names a fixed core of commands every server supports and tells agents to run
cubby help --jsonfor the rest. The launcher refreshes the installed skill from newer CLIs and never downgrades it. -
cubby versionreports the CLI version that runs for the current server, the launcher's version and the server's. -
Servers older than Cubby 0.1.1 aren't supported: the CLI refuses them with one line asking the admin to upgrade.
-
A server's
/skill.shkeeps an installed skill that's newer than its own, instead of downgrading it. -
Servers report exactly what they run:
X.Y.Zfor a release build,X.Y.Z-dev+<commit>for anything else, in
/api/info(which also gainscommit), thex-cubby-versionheader, the Admin tab,/docs.mdand the CLI they
serve.
Upgrading from 0.1.0
0.1.0's cubby-server upgrade pulls main and doesn't update itself. Run these once:
sudo cubby-server upgrade
sudo install -m 755 /opt/cubby/src/docker/cubby-server /usr/local/bin/cubby-server
sudo cubby-server upgrade --version <latest release> # switch from following main to releases~/.cubby/config.jsonmoves to a multi-server format ("format": 1). Existing single-server configs are migrated
automatically on first use.- An app's
cubby.jsonnow pins it to its server and gets a"format"field. It's no longer rewritten to follow
whichever server you logged in to last; move an app withcubby link <app> --server <url>. cubby logoutforgets the current server instead of every server; use--allfor the old behavior.- The agent skill no longer embeds a server URL. It finds servers with
cubby serversand picks one by name.
v0.1.0
First public version.
Added
- Self-hosted server: one Docker container with Caddy, the Cubby server and a shared PocketBase.
install.shone-line installer and thecubby-servercommand (status, logs, upgrade, backups, restore, set-domain).- Domain mode with automatic HTTPS, and IP mode on
sslip.io(HTTP only). - Dashboard: signup with an invite code, My apps, Everyone's apps gallery, and an Admin tab (invites, limits, users, apps, disk).
- Per-app isolation in one PocketBase: collection prefixes, a tenant-guarding proxy, and per-app login tokens.
cubbyCLI served by each server: browser-approved login,init,deploy(schema + build + upload), rollback, schema push/pull/drop.- Non-destructive schema pushes; deleting needs an explicit
cubby schema drop. - Agent skill for Claude Code, Codex, Cursor and OpenCode, installed with
curl <server>/skill.sh | sh. - App template: Vite, React, Tailwind and the PocketBase SDK, with
AGENTS.mdfor coding agents. - Nightly backups with 7 kept.
- Unit, integration and browser test suites, with CI.