--- name: bliss description: Drive a remote Bliss instance from the command line the way a human uses the /workshop UI — create/edit structures, routes, templates, databases, run the db REPL, read logs. Use when asked to build, inspect, or modify Bliss Structures against a running instance. --- # bliss CLI `bliss` talks to a running Bliss instance exactly as a human does through the workshop UI. **Reads** come back as JSON from the `/plumbing` API (pipe into `jq`). **Writes** go through the same `/workshop/*` endpoints the UI posts to. ## Setup The CLI is at `bliss-cli/bliss` in the repo. Configure via env vars: ```bash export BLISS_URL=https://your-instance.example.com # default http://localhost:3000 export BLISS_USER=you export BLISS_PASS=secret ``` It logs in once and caches the session cookie under `~/.bliss/`, re-logging-in automatically when it expires. Run it as `node bliss-cli/bliss ` (or `./bliss-cli/bliss` if on PATH). Instead of re-exporting `BLISS_URL` every time, set a **sticky target** once — it persists to `~/.bliss/target` and is used until you change it (a `BLISS_URL` env var still overrides it when set): ```bash bliss use https://your-instance.example.com # set the target instance bliss use # print the current target ``` ## The model (what you're editing) A **Structure** is a mini web app. It has **routes** (a VERB + path + a JS `handler` string run in a sandbox), **templates** (Eta, with a `test_object` used for preview), and **databases** (each with a `library` JS module and its own SQLite file). Ids are integers. Build a structure by: create it → add a db → write its library → add routes whose handlers call the library → add templates the handlers render. ## Reads (JSON) ```bash bliss structures # list all structures bliss structure # structure + its routes, templates, dbs, files bliss route # one route incl. its handler source bliss template # one template incl. content + test_object bliss db # one db incl. its library source bliss files # files attached to a structure bliss logs [--since ] # route logs (console.log output + errors) bliss versions # save history (newest first) bliss version # one version incl. full snapshot ``` All emit JSON, so: `bliss structure 3 | jq '.routes[].path'`. ## Version history (undo trail) Every content-changing save of a route handler, template, or db library records an append-only snapshot. The live row is always the current version; old ones are kept so nothing edited is ever lost. `versions` lists the summaries (id, `created_at`, `bytes`) newest-first; `version ` returns the full snapshot (the versioned fields). No-op re-saves are deduped, so identical content doesn't pile up. There's no revert command yet — to roll back, fetch an old snapshot and re-`update-*` its content: ```bash bliss versions route 3 12 # what saves exist bliss version 24 | jq -r .snapshot.handler > /tmp/old.js bliss update-route 3 12 --handler-file /tmp/old.js # restore it as a new save ``` ## Writes ```bash bliss create-structure "" # -> {location, id} bliss update-settings [--route-prefix

] [--head-injection |--head-injection-file ] bliss clone --name "" --prefix /p [--clone-dbs] bliss create-route # VERB: GET|POST|PUT|DELETE|WS ; -> {id} bliss update-route --handler-file # replace handler code [--scaffold-file ] [--path

] [--verb ] bliss create-template "" # -> {id} bliss update-template --content-file [--test-object-file ] bliss create-db "" # -> {id} bliss attach-db # share an existing db under an alias bliss update-library --file # returns eval output/errors bliss repl '' # run JS/SQL against the db; --file also works bliss upload # upload a static file ``` ## Previews ```bash bliss preview-route # rendered HTML of a GET route bliss preview-template # rendered HTML using the template's test_object ``` ## Links Jump straight into the workshop editor for something instead of constructing the URL by hand: ```bash bliss link structure bliss link route bliss link template bliss link db # by numeric db id bliss link db # or by the alias used in require('db')(alias) ``` `bliss link db` resolves an alias (e.g. `chat`, as in `require('db')('chat')`) by looking at the structure's attached dbs — handy since the same alias name often points to a different db per structure (aliased/cloned dbs). ## Editing code (handlers, templates, library) Handlers/templates/library are multiline code. Write the code to a temp file and pass `--*-file`, or pipe via `-` (stdin): ```bash cat > /tmp/handler.js <<'EOF' function handler(req, res) { const { library } = require('db')('main'); res.render('home', { items: library.all() }); } EOF bliss update-route 3 12 --handler-file /tmp/handler.js echo "function handler(req,res){ res.send('hi') }" | bliss update-route 3 12 --handler-file - ``` The db `library` runs with `sql` (the better-sqlite3 instance) in scope and sets `module.exports`. Test it fast with `bliss repl 'library.someFn()'`. ## Typical loop 1. `bliss structures` / `bliss structure ` to orient. 2. Edit a handler/template/library into a temp file, push with the matching `update-*` command. 3. `bliss preview-route` / `bliss repl` to see the result; `bliss logs` to debug.