feat: append-only version history + bliss CLI ergonomics
Snapshot the code-bearing fields of routes (verb/path/handler), templates (name/content/test_object), and db libraries (name/library) on every content-changing save, so nothing edited is ever lost. Recorded in a new `versions` table via recordVersion() hooked into the create/update functions in db.js (the single write choke point), deduped against the latest snapshot so no-op saves, error-flag-only route writes, and server-restart WS re-bootstraps don't pile up. The live row stays current; old snapshots are the undo trail. Read-only, no revert UI yet. - migrations/004_add_versions.sql: versions table + indexes - db.js: recordVersion/getVersions/getVersion + create/update hooks - plumbing.js: /versions/:id and per-entity .../versions list endpoints - bliss: `versions <type> <sid> <id>` and `version <id>` reads; `update-settings` (edit route_prefix/head_injection, preserving the untouched field); `use <url>` sticky target persisted to ~/.bliss/target so BLISS_URL needn't be re-exported each call - client.js: target-file precedence (BLISS_URL > ~/.bliss/target > localhost) - SKILL.md: document the above Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
03a9d2143d
commit
42f4aacf7c
6 changed files with 211 additions and 7 deletions
|
|
@ -10,16 +10,37 @@ const fs = require("fs");
|
|||
const os = require("os");
|
||||
const path = require("path");
|
||||
|
||||
const BASE = (process.env.BLISS_URL || "http://localhost:3000").replace(
|
||||
/\/$/,
|
||||
"",
|
||||
);
|
||||
const JAR_DIR = path.join(os.homedir(), ".bliss");
|
||||
// Sticky target so callers don't have to re-set BLISS_URL on every invocation
|
||||
// (shell env doesn't persist between separate CLI runs). Precedence:
|
||||
// BLISS_URL env > ~/.bliss/target > localhost default
|
||||
const TARGET_FILE = path.join(JAR_DIR, "target");
|
||||
|
||||
function readTarget() {
|
||||
try {
|
||||
return fs.readFileSync(TARGET_FILE, "utf8").trim() || null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function setTarget(url) {
|
||||
const clean = url.replace(/\/$/, "");
|
||||
fs.mkdirSync(JAR_DIR, { recursive: true });
|
||||
fs.writeFileSync(TARGET_FILE, clean + "\n");
|
||||
return clean;
|
||||
}
|
||||
|
||||
const BASE = (
|
||||
process.env.BLISS_URL ||
|
||||
readTarget() ||
|
||||
"http://localhost:3000"
|
||||
).replace(/\/$/, "");
|
||||
const USER = process.env.BLISS_USER;
|
||||
const PASS = process.env.BLISS_PASS;
|
||||
|
||||
// Persist the session cookie so we don't log in on every CLI invocation. Keyed
|
||||
// by base URL so pointing at a different instance uses a different jar.
|
||||
const JAR_DIR = path.join(os.homedir(), ".bliss");
|
||||
const JAR_FILE = path.join(
|
||||
JAR_DIR,
|
||||
"session-" + Buffer.from(BASE).toString("hex").slice(0, 24) + ".txt",
|
||||
|
|
@ -146,6 +167,7 @@ async function getText(urlPath) {
|
|||
|
||||
module.exports = {
|
||||
BASE,
|
||||
setTarget,
|
||||
request,
|
||||
getJSON,
|
||||
getText,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue