@tpsdev-ai/flair 0.40.0 → 0.41.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +64 -2
- package/docs/upgrade.md +1 -1
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -774,6 +774,14 @@ export function buildDirectSpawnEnv(opts) {
|
|
|
774
774
|
HTTP_PORT: String(opts.httpPort),
|
|
775
775
|
OPERATIONSAPI_NETWORK_PORT: opsNetworkPortValue(opts.opsBindHost, opts.opsPort),
|
|
776
776
|
LOCAL_STUDIO: "false",
|
|
777
|
+
// flair#905 / lrf5: Harper's forceDowngradePrompt reads CONFIRM_DOWNGRADE
|
|
778
|
+
// from the environment (via the `prompt` npm package's assignCmdEnvVariables
|
|
779
|
+
// override). Under launchd/systemd stdin is not a TTY, so the prompt gets
|
|
780
|
+
// EOF and Harper exits 0 without starting — leaving the instance DOWN with
|
|
781
|
+
// no error. Setting this to "yes" makes the prompt non-interactive: Harper
|
|
782
|
+
// proceeds without blocking, which is the correct default for a managed
|
|
783
|
+
// restart where the operator already chose to proceed.
|
|
784
|
+
CONFIRM_DOWNGRADE: "yes",
|
|
777
785
|
};
|
|
778
786
|
if (opts.adminPass)
|
|
779
787
|
env.HDB_ADMIN_PASSWORD = opts.adminPass;
|
|
@@ -9688,6 +9696,50 @@ program
|
|
|
9688
9696
|
console.error(` Recover by hand: npm install -g @tpsdev-ai/flair@${toVersion} && flair start`);
|
|
9689
9697
|
process.exit(1);
|
|
9690
9698
|
}
|
|
9699
|
+
// flair#1053: when the engine (Harper) version changed, the pre-upgrade
|
|
9700
|
+
// snapshot is the ONLY way back — the old Harper cannot read data written
|
|
9701
|
+
// by the new one (e.g. 5.2 LZ4-compressed storage is unreadable by 5.1).
|
|
9702
|
+
// Restore it before restarting, or refuse loudly when none exists.
|
|
9703
|
+
if (engineVersionChanging) {
|
|
9704
|
+
if (snapshotPath) {
|
|
9705
|
+
console.log(`\nEngine version changed — restoring pre-upgrade snapshot before rollback...`);
|
|
9706
|
+
console.log(` snapshot: ${snapshotPath}`);
|
|
9707
|
+
console.log(` target: ${upgradeDataDir}`);
|
|
9708
|
+
try {
|
|
9709
|
+
await validateSnapshotArchive({ file: snapshotPath, targetDir: upgradeDataDir });
|
|
9710
|
+
rmSync(upgradeDataDir, { recursive: true, force: true });
|
|
9711
|
+
mkdirSync(upgradeDataDir, { recursive: true, mode: 0o700 });
|
|
9712
|
+
await extractSnapshotSafely({ file: snapshotPath, targetDir: upgradeDataDir });
|
|
9713
|
+
console.log(` ✅ snapshot restored`);
|
|
9714
|
+
}
|
|
9715
|
+
catch (err) {
|
|
9716
|
+
console.error(`❌ snapshot restore failed: ${err.message}`);
|
|
9717
|
+
console.error(` @tpsdev-ai/flair@${toVersion} is installed but the data directory could not be restored.`);
|
|
9718
|
+
console.error(` The snapshot itself is intact at ${snapshotPath} — restore it by hand:`);
|
|
9719
|
+
console.error(` flair snapshot restore "${snapshotPath}"`);
|
|
9720
|
+
console.error(` Then: flair start`);
|
|
9721
|
+
process.exit(1);
|
|
9722
|
+
}
|
|
9723
|
+
}
|
|
9724
|
+
else {
|
|
9725
|
+
// No snapshot exists — the old Harper WILL NOT BOOT against the new
|
|
9726
|
+
// data. Refuse loudly rather than attempting a guaranteed failure.
|
|
9727
|
+
console.error(`\n❌ Cannot roll back: the Harper engine version changed (${currentEngineVersion ?? "?"} → ${targetEngineVersion ?? "?"}) and no pre-upgrade snapshot exists.`);
|
|
9728
|
+
console.error(` The old Harper cannot read data written by the new engine — restarting without a snapshot restore would fail.`);
|
|
9729
|
+
console.error(` @tpsdev-ai/flair@${toVersion} is installed but NOT running.`);
|
|
9730
|
+
if (snapshotDecision === "nudge") {
|
|
9731
|
+
console.error(` A snapshot was skipped because --no-engine-snapshot was passed.`);
|
|
9732
|
+
console.error(` Recovery options:`);
|
|
9733
|
+
console.error(` 1. Re-upgrade to the version that wrote this data: npm install -g @tpsdev-ai/flair@${expectedFlairVersion ?? "latest"} && flair start`);
|
|
9734
|
+
console.error(` 2. Restore from a ` + "`flair backup`" + ` JSON export on a fresh data directory.`);
|
|
9735
|
+
}
|
|
9736
|
+
else {
|
|
9737
|
+
console.error(` No snapshot was taken (data directory may not have existed, or the snapshot step was skipped).`);
|
|
9738
|
+
console.error(` Recovery: re-upgrade to the version that wrote this data, or restore from a ` + "`flair backup`" + ` JSON export.`);
|
|
9739
|
+
}
|
|
9740
|
+
process.exit(1);
|
|
9741
|
+
}
|
|
9742
|
+
}
|
|
9691
9743
|
// Same post-swap rule as the upgrade restart above: the rolled-back
|
|
9692
9744
|
// version's own CLI is the thing that knows how to start it.
|
|
9693
9745
|
const rolledBackCli = resolveInstalledFlairCli(flairPackageDir(), toVersion);
|
|
@@ -10321,8 +10373,18 @@ async function stopFlairProcess(port, dataDir) {
|
|
|
10321
10373
|
}
|
|
10322
10374
|
catch { }
|
|
10323
10375
|
}
|
|
10324
|
-
//
|
|
10325
|
-
|
|
10376
|
+
// flair#905 / lrf5: wait for every signalled process to actually exit.
|
|
10377
|
+
// A blind 2-second sleep is not a guarantee — Harper may be flushing
|
|
10378
|
+
// RocksDB WAL/MANIFEST, and the next start will fail with a locked data
|
|
10379
|
+
// directory if the old process hasn't released it yet. The launchd path
|
|
10380
|
+
// above already does this via waitForProcessExit; the port-based path
|
|
10381
|
+
// must match that guarantee.
|
|
10382
|
+
for (const target of targets) {
|
|
10383
|
+
try {
|
|
10384
|
+
await waitForProcessExit(target, STARTUP_TIMEOUT_MS);
|
|
10385
|
+
}
|
|
10386
|
+
catch { /* best-effort — the next start will surface the real problem */ }
|
|
10387
|
+
}
|
|
10326
10388
|
}
|
|
10327
10389
|
/**
|
|
10328
10390
|
* Start the local Flair (Harper) process — launchd `start` on darwin when a
|
package/docs/upgrade.md
CHANGED
|
@@ -357,7 +357,7 @@ if you want to see it scripted end-to-end.
|
|
|
357
357
|
upgraded via `flair upgrade`. Real snapshots for production datasets run hundreds of
|
|
358
358
|
megabytes — plan disk capacity accordingly. Cleanup of old engine snapshots is manual;
|
|
359
359
|
`flair snapshot list` shows available snapshots, and you can delete entries you no longer
|
|
360
|
-
need.
|
|
360
|
+
need (e.g. `rm ~/.flair/upgrade-snapshots/flair-data-<old>.tar.gz`).
|
|
361
361
|
|
|
362
362
|
## Rollback
|
|
363
363
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tpsdev-ai/flair",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.41.0",
|
|
4
4
|
"packageManager": "bun@1.3.10",
|
|
5
5
|
"description": "Identity, memory, and soul for AI agents. Cryptographic identity (Ed25519), semantic memory with local embeddings, and persistent personality — all in a single process.",
|
|
6
6
|
"type": "module",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"@harperfast/oauth": "2.4.0",
|
|
65
65
|
"@types/js-yaml": "4.0.9",
|
|
66
66
|
"commander": "14.0.3",
|
|
67
|
-
"harper": "5.
|
|
67
|
+
"harper": "5.2.0",
|
|
68
68
|
"harper-fabric-embeddings": "^0.5.0",
|
|
69
69
|
"jose": "6.2.2",
|
|
70
70
|
"js-yaml": "^4.3.1",
|