gnosys 5.7.0 → 5.7.1
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/README.md +15 -2
- package/dist/cli.js +188 -108
- package/dist/cli.js.map +1 -1
- package/dist/index.js +96 -4
- package/dist/index.js.map +1 -1
- package/dist/lib/db.d.ts +20 -0
- package/dist/lib/db.d.ts.map +1 -1
- package/dist/lib/db.js +36 -12
- package/dist/lib/db.js.map +1 -1
- package/dist/lib/heartbeat.d.ts +31 -0
- package/dist/lib/heartbeat.d.ts.map +1 -0
- package/dist/lib/heartbeat.js +91 -0
- package/dist/lib/heartbeat.js.map +1 -0
- package/dist/lib/idFormat.d.ts +41 -0
- package/dist/lib/idFormat.d.ts.map +1 -0
- package/dist/lib/idFormat.js +66 -0
- package/dist/lib/idFormat.js.map +1 -0
- package/dist/lib/progress.d.ts +54 -0
- package/dist/lib/progress.d.ts.map +1 -0
- package/dist/lib/progress.js +92 -0
- package/dist/lib/progress.js.map +1 -0
- package/dist/lib/remote.d.ts +14 -1
- package/dist/lib/remote.d.ts.map +1 -1
- package/dist/lib/remote.js +75 -28
- package/dist/lib/remote.js.map +1 -1
- package/dist/lib/upgrade.d.ts +38 -0
- package/dist/lib/upgrade.d.ts.map +1 -0
- package/dist/lib/upgrade.js +61 -0
- package/dist/lib/upgrade.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -80,7 +80,7 @@ gnosys recall "database selection"
|
|
|
80
80
|
|
|
81
81
|
> **Postinstall hook:** After `npm install -g gnosys`, a postinstall script automatically runs `gnosys setup` if no configuration is detected, so first-time users are guided through provider and IDE setup immediately.
|
|
82
82
|
|
|
83
|
-
> **Multi-machine?** Set `GNOSYS_GLOBAL` to a cloud-synced folder (iCloud Drive, Dropbox, OneDrive) and both machines share the same brain.
|
|
83
|
+
> **Multi-machine?** Set `GNOSYS_GLOBAL` to a cloud-synced folder (iCloud Drive, Dropbox, OneDrive) and both machines share the same brain. To update: run `gnosys upgrade` — it installs the latest gnosys, signals any running MCP servers to restart cleanly, and prompts to run `gnosys setup sync-projects` afterwards (re-syncs all projects, regenerates agent rules, warns other machines to upgrade). See the [User Guide — Installation & Setup](https://gnosys.ai/guide.html#guide-installation) for the full walkthrough, memory scopes, and multi-machine setup.
|
|
84
84
|
|
|
85
85
|
### Agent / Helper Library
|
|
86
86
|
|
|
@@ -331,7 +331,7 @@ Dream Mode is the idle-time consolidation engine — confidence decay, summary g
|
|
|
331
331
|
- Run `gnosys setup dream` on the machine you want to host dream cycles.
|
|
332
332
|
- The wizard validates your provider/model with a live API probe before saving.
|
|
333
333
|
- Other machines stay quiet — they see the designation in the central DB and skip the scheduler.
|
|
334
|
-
- `gnosys dream log` shows recent runs; `gnosys
|
|
334
|
+
- `gnosys dream log` shows recent runs; `gnosys status --system` has a `DREAM HEALTH` section with last-run timestamp, designated machine, and consecutive-failure counter.
|
|
335
335
|
- If the designated machine's LLM provider becomes unreachable, you'll see warnings at three layers: in audit log entries (`dream_provider_unreachable`), as stderr at MCP startup, and as a desktop notification after 3 consecutive failures.
|
|
336
336
|
|
|
337
337
|
### Removed in v5.4.2
|
|
@@ -345,6 +345,19 @@ The following commands were removed in favor of the canonical `gnosys setup <thi
|
|
|
345
345
|
|
|
346
346
|
`gnosys remote push|pull|sync|status` remain unchanged — only `configure` moved.
|
|
347
347
|
|
|
348
|
+
### Removed / renamed in v5.7.1
|
|
349
|
+
|
|
350
|
+
| Removed / renamed | Use instead |
|
|
351
|
+
|---|---|
|
|
352
|
+
| `gnosys dashboard` | `gnosys status --system` |
|
|
353
|
+
| `gnosys portfolio` | `gnosys status --projects` (or `--web` for HTML) |
|
|
354
|
+
| `gnosys upgrade` (old behaviour) | `gnosys setup sync-projects` |
|
|
355
|
+
| `gnosys status --global` | `gnosys status --projects` (alias kept) |
|
|
356
|
+
|
|
357
|
+
`gnosys upgrade` is now `npm install -g gnosys@latest` + a marker that
|
|
358
|
+
tells running MCP servers to exit-and-respawn against the new global
|
|
359
|
+
binary. Run it on each machine.
|
|
360
|
+
|
|
348
361
|
---
|
|
349
362
|
|
|
350
363
|
### Manual config (if you prefer)
|
package/dist/cli.js
CHANGED
|
@@ -225,6 +225,7 @@ program
|
|
|
225
225
|
.option("--federated", "Use federated discovery with tier boosting (project > user > global)")
|
|
226
226
|
.option("--scope <scope>", "Filter by scope: project, user, global (comma-separated for multiple)")
|
|
227
227
|
.option("-d, --directory <dir>", "Project directory for context")
|
|
228
|
+
.option("--id-format <format>", "ID display format: short | long | raw (default: short)", "short")
|
|
228
229
|
.action(async (query, opts) => {
|
|
229
230
|
// Federated discover path
|
|
230
231
|
if (opts.federated || opts.scope) {
|
|
@@ -279,11 +280,16 @@ program
|
|
|
279
280
|
});
|
|
280
281
|
return;
|
|
281
282
|
}
|
|
283
|
+
const { formatMemoryId, buildProjectNameLookup, parseIdFormat } = await import("./lib/idFormat.js");
|
|
284
|
+
const idFormat = parseIdFormat(opts.idFormat);
|
|
285
|
+
const projectNames = buildProjectNameLookup(centralDb);
|
|
282
286
|
outputResult(!!opts.json, { query, count: results.length, results }, () => {
|
|
283
287
|
console.log(`Found ${results.length} relevant memories for "${query}":\n`);
|
|
284
288
|
for (const r of results) {
|
|
289
|
+
const projectName = r.project_id ? projectNames.get(r.project_id) || null : null;
|
|
290
|
+
const displayId = formatMemoryId(r.id, projectName, idFormat);
|
|
285
291
|
console.log(` ${r.title}`);
|
|
286
|
-
console.log(` id: ${
|
|
292
|
+
console.log(` id: ${displayId}`);
|
|
287
293
|
if (r.relevance)
|
|
288
294
|
console.log(` Relevance: ${r.relevance}`);
|
|
289
295
|
console.log();
|
|
@@ -391,6 +397,7 @@ program
|
|
|
391
397
|
.option("-t, --tag <tag>", "Filter by tag")
|
|
392
398
|
.option("-s, --store <store>", "Filter by store layer (project|user|global)")
|
|
393
399
|
.option("--json", "Output as JSON")
|
|
400
|
+
.option("--id-format <format>", "ID display format: short | long | raw (default: short)", "short")
|
|
394
401
|
.action(async (opts) => {
|
|
395
402
|
let centralDb = null;
|
|
396
403
|
try {
|
|
@@ -424,6 +431,9 @@ program
|
|
|
424
431
|
}
|
|
425
432
|
});
|
|
426
433
|
}
|
|
434
|
+
const { formatMemoryId, buildProjectNameLookup, parseIdFormat } = await import("./lib/idFormat.js");
|
|
435
|
+
const idFormat = parseIdFormat(opts.idFormat);
|
|
436
|
+
const projectNames = buildProjectNameLookup(centralDb);
|
|
427
437
|
outputResult(!!opts.json, {
|
|
428
438
|
count: memories.length,
|
|
429
439
|
memories: memories.map((m) => ({
|
|
@@ -433,12 +443,15 @@ program
|
|
|
433
443
|
status: m.status,
|
|
434
444
|
scope: m.scope,
|
|
435
445
|
confidence: m.confidence,
|
|
446
|
+
project: m.project_id ? projectNames.get(m.project_id) || null : null,
|
|
436
447
|
})),
|
|
437
448
|
}, () => {
|
|
438
449
|
console.log(`${memories.length} memories:\n`);
|
|
439
450
|
for (const m of memories) {
|
|
451
|
+
const projectName = m.project_id ? projectNames.get(m.project_id) || null : null;
|
|
452
|
+
const displayId = formatMemoryId(m.id, projectName, idFormat);
|
|
440
453
|
console.log(` [${m.scope}] [${m.status}] ${m.title}`);
|
|
441
|
-
console.log(` id: ${
|
|
454
|
+
console.log(` id: ${displayId} | category: ${m.category} | confidence: ${m.confidence}`);
|
|
442
455
|
console.log();
|
|
443
456
|
}
|
|
444
457
|
});
|
|
@@ -654,8 +667,9 @@ setupRemoteCmd
|
|
|
654
667
|
return;
|
|
655
668
|
}
|
|
656
669
|
const { RemoteSync, formatStatus } = await import("./lib/remote.js");
|
|
670
|
+
const { withHeartbeat } = await import("./lib/heartbeat.js");
|
|
657
671
|
const sync = new RemoteSync(centralDb, remotePath);
|
|
658
|
-
const status = await sync.getStatus();
|
|
672
|
+
const status = await withHeartbeat("Checking remote sync status", () => sync.getStatus());
|
|
659
673
|
sync.closeRemote();
|
|
660
674
|
if (opts.json) {
|
|
661
675
|
console.log(JSON.stringify(status, null, 2));
|
|
@@ -685,6 +699,7 @@ setupRemoteCmd
|
|
|
685
699
|
.command("push")
|
|
686
700
|
.description("Push local changes to remote")
|
|
687
701
|
.option("--newer-wins", "Auto-resolve conflicts by taking the newer version")
|
|
702
|
+
.option("--verbose", "Stream per-memory progress to stderr")
|
|
688
703
|
.action(async (opts) => {
|
|
689
704
|
let centralDb = null;
|
|
690
705
|
try {
|
|
@@ -699,8 +714,18 @@ setupRemoteCmd
|
|
|
699
714
|
process.exit(1);
|
|
700
715
|
}
|
|
701
716
|
const { RemoteSync } = await import("./lib/remote.js");
|
|
717
|
+
const { withHeartbeat } = await import("./lib/heartbeat.js");
|
|
718
|
+
const { createProgress } = await import("./lib/progress.js");
|
|
719
|
+
const progress = createProgress(!!opts.verbose);
|
|
702
720
|
const sync = new RemoteSync(centralDb, remotePath);
|
|
703
|
-
|
|
721
|
+
// Suppress heartbeat when verbose is on (progress already streams).
|
|
722
|
+
const runPush = () => sync.push({
|
|
723
|
+
strategy: opts.newerWins ? "newer-wins" : "skip-and-flag",
|
|
724
|
+
onProgress: progress.noop ? undefined : progress.emit.bind(progress),
|
|
725
|
+
});
|
|
726
|
+
const result = opts.verbose
|
|
727
|
+
? await runPush()
|
|
728
|
+
: await withHeartbeat("Pushing to remote", runPush);
|
|
704
729
|
sync.closeRemote();
|
|
705
730
|
const projParts = (result.projectsPushed || 0) > 0 ? ` | Projects pushed: ${result.projectsPushed}` : "";
|
|
706
731
|
const auditParts = (result.auditPushed || 0) > 0 ? ` | Audit pushed: ${result.auditPushed}` : "";
|
|
@@ -728,6 +753,7 @@ setupRemoteCmd
|
|
|
728
753
|
.command("pull")
|
|
729
754
|
.description("Pull remote changes to local")
|
|
730
755
|
.option("--newer-wins", "Auto-resolve conflicts by taking the newer version")
|
|
756
|
+
.option("--verbose", "Stream per-memory progress to stderr")
|
|
731
757
|
.action(async (opts) => {
|
|
732
758
|
let centralDb = null;
|
|
733
759
|
try {
|
|
@@ -742,8 +768,17 @@ setupRemoteCmd
|
|
|
742
768
|
process.exit(1);
|
|
743
769
|
}
|
|
744
770
|
const { RemoteSync } = await import("./lib/remote.js");
|
|
771
|
+
const { withHeartbeat } = await import("./lib/heartbeat.js");
|
|
772
|
+
const { createProgress } = await import("./lib/progress.js");
|
|
773
|
+
const progress = createProgress(!!opts.verbose);
|
|
745
774
|
const sync = new RemoteSync(centralDb, remotePath);
|
|
746
|
-
const
|
|
775
|
+
const runPull = () => sync.pull({
|
|
776
|
+
strategy: opts.newerWins ? "newer-wins" : "skip-and-flag",
|
|
777
|
+
onProgress: progress.noop ? undefined : progress.emit.bind(progress),
|
|
778
|
+
});
|
|
779
|
+
const result = opts.verbose
|
|
780
|
+
? await runPull()
|
|
781
|
+
: await withHeartbeat("Pulling from remote", runPull);
|
|
747
782
|
sync.closeRemote();
|
|
748
783
|
const projParts = (result.projectsPulled || 0) > 0 ? ` | Projects pulled: ${result.projectsPulled}` : "";
|
|
749
784
|
const auditParts = (result.auditPulled || 0) > 0 ? ` | Audit pulled: ${result.auditPulled}` : "";
|
|
@@ -767,6 +802,7 @@ setupRemoteCmd
|
|
|
767
802
|
.description("Two-way sync: push local changes then pull remote changes")
|
|
768
803
|
.option("--auto", "Run silently for cron/LaunchAgent (skip-and-flag for conflicts)")
|
|
769
804
|
.option("--newer-wins", "Auto-resolve conflicts by taking the newer version")
|
|
805
|
+
.option("--verbose", "Stream per-memory progress to stderr")
|
|
770
806
|
.action(async (opts) => {
|
|
771
807
|
let centralDb = null;
|
|
772
808
|
try {
|
|
@@ -783,11 +819,20 @@ setupRemoteCmd
|
|
|
783
819
|
process.exit(opts.auto ? 0 : 1);
|
|
784
820
|
}
|
|
785
821
|
const { RemoteSync } = await import("./lib/remote.js");
|
|
822
|
+
const { withHeartbeat } = await import("./lib/heartbeat.js");
|
|
823
|
+
const { createProgress } = await import("./lib/progress.js");
|
|
824
|
+
const progress = createProgress(!!opts.verbose);
|
|
786
825
|
const sync = new RemoteSync(centralDb, remotePath);
|
|
787
|
-
const
|
|
826
|
+
const runSync = () => sync.sync({
|
|
788
827
|
auto: opts.auto,
|
|
789
828
|
strategy: opts.newerWins ? "newer-wins" : "skip-and-flag",
|
|
829
|
+
onProgress: progress.noop ? undefined : progress.emit.bind(progress),
|
|
790
830
|
});
|
|
831
|
+
// Auto mode + verbose mode both bypass the heartbeat. Auto mode is
|
|
832
|
+
// for non-interactive runs (no spinner). Verbose streams its own output.
|
|
833
|
+
const result = opts.auto || opts.verbose
|
|
834
|
+
? await runSync()
|
|
835
|
+
: await withHeartbeat("Syncing with remote", runSync);
|
|
791
836
|
sync.closeRemote();
|
|
792
837
|
if (!opts.auto || result.conflicts.length > 0 || result.errors.length > 0) {
|
|
793
838
|
const pp = result.projectsPushed || 0;
|
|
@@ -3007,41 +3052,9 @@ program
|
|
|
3007
3052
|
console.log("");
|
|
3008
3053
|
console.log(formatGraphStats(stats));
|
|
3009
3054
|
});
|
|
3010
|
-
//
|
|
3011
|
-
//
|
|
3012
|
-
//
|
|
3013
|
-
program
|
|
3014
|
-
.command("dashboard")
|
|
3015
|
-
.description("(alias) Show system health — equivalent to 'gnosys status --system'")
|
|
3016
|
-
.option("--json", "Output as JSON instead of pretty table")
|
|
3017
|
-
.action(async (opts) => {
|
|
3018
|
-
const { collectDashboardData, formatDashboard, formatDashboardJSON } = await import("./lib/dashboard.js");
|
|
3019
|
-
const resolver = await getResolver();
|
|
3020
|
-
const stores = resolver.getStores();
|
|
3021
|
-
if (stores.length === 0) {
|
|
3022
|
-
console.error("No Gnosys stores found. Run gnosys init first.");
|
|
3023
|
-
process.exit(1);
|
|
3024
|
-
}
|
|
3025
|
-
const cfg = await loadConfig(stores[0].path);
|
|
3026
|
-
// v5.1: Use central DB for dashboard stats
|
|
3027
|
-
let dashDb;
|
|
3028
|
-
try {
|
|
3029
|
-
const db = GnosysDB.openCentral();
|
|
3030
|
-
if (db.isAvailable() && db.isMigrated()) {
|
|
3031
|
-
dashDb = db;
|
|
3032
|
-
}
|
|
3033
|
-
}
|
|
3034
|
-
catch {
|
|
3035
|
-
// Central DB not available — legacy dashboard only
|
|
3036
|
-
}
|
|
3037
|
-
const data = await collectDashboardData(resolver, cfg, pkg.version, dashDb);
|
|
3038
|
-
if (opts.json) {
|
|
3039
|
-
console.log(formatDashboardJSON(data));
|
|
3040
|
-
}
|
|
3041
|
-
else {
|
|
3042
|
-
console.log(formatDashboard(data));
|
|
3043
|
-
}
|
|
3044
|
-
});
|
|
3055
|
+
// `gnosys dashboard` was removed in v5.7.1.
|
|
3056
|
+
// Use `gnosys status --system` instead. Hard removal — commander will emit
|
|
3057
|
+
// the standard "unknown command" error.
|
|
3045
3058
|
// ─── gnosys maintain ─────────────────────────────────────────────────────
|
|
3046
3059
|
program
|
|
3047
3060
|
.command("maintain")
|
|
@@ -3125,12 +3138,19 @@ program
|
|
|
3125
3138
|
}
|
|
3126
3139
|
});
|
|
3127
3140
|
// NOTE: gnosys migrate is defined below (near the end) with --to-central support
|
|
3128
|
-
// ─── gnosys upgrade
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3141
|
+
// ─── gnosys upgrade + gnosys setup sync-projects ──────────────────────
|
|
3142
|
+
//
|
|
3143
|
+
// v5.7.1 (#15) split this command:
|
|
3144
|
+
//
|
|
3145
|
+
// gnosys upgrade — upgrade the gnosys CLI/MCP itself
|
|
3146
|
+
// (npm install + restart signal to MCPs)
|
|
3147
|
+
// gnosys setup sync-projects — what the old `gnosys upgrade` used to do
|
|
3148
|
+
// (re-init project identities, agent rules,
|
|
3149
|
+
// central DB stamp, portfolio dashboard)
|
|
3150
|
+
//
|
|
3151
|
+
// The body of the legacy command is preserved verbatim below as
|
|
3152
|
+
// `syncProjectsAction`, called from the new `setup sync-projects` command.
|
|
3153
|
+
async function syncProjectsAction(opts) {
|
|
3134
3154
|
const currentVersion = pkg.version;
|
|
3135
3155
|
console.log(`Gnosys v${currentVersion} — upgrading registered projects...\n`);
|
|
3136
3156
|
// 1. Read registered projects from file registry AND central DB
|
|
@@ -3349,6 +3369,76 @@ program
|
|
|
3349
3369
|
console.log(`\n Could not regenerate portfolio dashboard`);
|
|
3350
3370
|
}
|
|
3351
3371
|
}
|
|
3372
|
+
}
|
|
3373
|
+
// `gnosys setup sync-projects` — re-init project identities + agent rules.
|
|
3374
|
+
// (This is what `gnosys upgrade` used to do; renamed in v5.7.1.)
|
|
3375
|
+
setupCmd
|
|
3376
|
+
.command("sync-projects")
|
|
3377
|
+
.description("Re-initialize all registered projects after upgrading gnosys: refresh agent rules, project registry, central DB stamp, and portfolio dashboard.")
|
|
3378
|
+
.option("--skip-dashboard", "Skip regenerating the portfolio dashboard")
|
|
3379
|
+
.action(syncProjectsAction);
|
|
3380
|
+
// `gnosys upgrade` — upgrade the gnosys CLI/MCP itself, then prompt the
|
|
3381
|
+
// user to run sync-projects. Writes ~/.gnosys/last-upgrade-at so running
|
|
3382
|
+
// MCP servers exit cleanly and the host respawns them against the new
|
|
3383
|
+
// global binary (see src/lib/upgrade.ts).
|
|
3384
|
+
program
|
|
3385
|
+
.command("upgrade")
|
|
3386
|
+
.description("Upgrade gnosys itself (npm install -g gnosys@latest) and signal running MCP servers to restart. After upgrading, suggests running 'gnosys setup sync-projects'.")
|
|
3387
|
+
.option("--yes", "Skip the post-upgrade sync-projects prompt and exit")
|
|
3388
|
+
.option("--no-sync", "Don't suggest running sync-projects afterward")
|
|
3389
|
+
.action(async (opts) => {
|
|
3390
|
+
const currentVersion = pkg.version;
|
|
3391
|
+
console.log(`Gnosys CLI: currently v${currentVersion}`);
|
|
3392
|
+
console.log(`Running: npm install -g gnosys@latest ...`);
|
|
3393
|
+
const { execSync } = await import("child_process");
|
|
3394
|
+
try {
|
|
3395
|
+
execSync("npm install -g gnosys@latest", { stdio: "inherit" });
|
|
3396
|
+
}
|
|
3397
|
+
catch (err) {
|
|
3398
|
+
console.error(`\nUpgrade failed: ${err instanceof Error ? err.message : err}`);
|
|
3399
|
+
console.error(`Try running 'npm install -g gnosys@latest' manually.`);
|
|
3400
|
+
process.exit(1);
|
|
3401
|
+
}
|
|
3402
|
+
// Read the newly-installed version (best-effort — we may still be the
|
|
3403
|
+
// old binary in-process; this is purely informational).
|
|
3404
|
+
let newVersion = "(see npm output)";
|
|
3405
|
+
try {
|
|
3406
|
+
const out = execSync("npm ls -g gnosys --depth=0 --json", { encoding: "utf8" });
|
|
3407
|
+
const parsed = JSON.parse(out);
|
|
3408
|
+
newVersion = parsed?.dependencies?.gnosys?.version || newVersion;
|
|
3409
|
+
}
|
|
3410
|
+
catch {
|
|
3411
|
+
// Best-effort lookup only.
|
|
3412
|
+
}
|
|
3413
|
+
// Write the marker so any running MCP servers exit and respawn.
|
|
3414
|
+
const { writeUpgradeMarker } = await import("./lib/upgrade.js");
|
|
3415
|
+
try {
|
|
3416
|
+
writeUpgradeMarker(typeof newVersion === "string" && newVersion !== "(see npm output)"
|
|
3417
|
+
? newVersion
|
|
3418
|
+
: currentVersion);
|
|
3419
|
+
console.log(`\n✓ Upgrade marker written: ~/.gnosys/last-upgrade-at`);
|
|
3420
|
+
console.log(` Any running MCP servers will detect this within 10s and restart cleanly.`);
|
|
3421
|
+
console.log(` (Your MCP client — Claude Code, Cursor, VS Code — will auto-respawn.)`);
|
|
3422
|
+
}
|
|
3423
|
+
catch (err) {
|
|
3424
|
+
console.error(`\nCould not write upgrade marker: ${err instanceof Error ? err.message : err}`);
|
|
3425
|
+
console.error(`Running MCP servers will need to be restarted manually.`);
|
|
3426
|
+
}
|
|
3427
|
+
if (opts.sync === false || opts.yes) {
|
|
3428
|
+
console.log(`\nDone. Run 'gnosys setup sync-projects' when you're ready to refresh registered projects.`);
|
|
3429
|
+
return;
|
|
3430
|
+
}
|
|
3431
|
+
// Prompt for sync-projects.
|
|
3432
|
+
const readline = await import("readline");
|
|
3433
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
3434
|
+
const answer = await new Promise((resolve) => rl.question(`\nRun 'gnosys setup sync-projects' now to refresh registered projects? [Y/n] `, resolve));
|
|
3435
|
+
rl.close();
|
|
3436
|
+
if (answer.trim().toLowerCase() === "n" || answer.trim().toLowerCase() === "no") {
|
|
3437
|
+
console.log(`Done. You can run 'gnosys setup sync-projects' later.`);
|
|
3438
|
+
return;
|
|
3439
|
+
}
|
|
3440
|
+
console.log(``);
|
|
3441
|
+
await syncProjectsAction({});
|
|
3352
3442
|
});
|
|
3353
3443
|
// ─── gnosys doctor ──────────────────────────────────────────────────────
|
|
3354
3444
|
program
|
|
@@ -4858,80 +4948,70 @@ program
|
|
|
4858
4948
|
centralDb?.close();
|
|
4859
4949
|
}
|
|
4860
4950
|
});
|
|
4861
|
-
//
|
|
4951
|
+
// `gnosys portfolio` was removed in v5.7.1.
|
|
4952
|
+
// Use `gnosys status --projects` (formerly --global) for the projects
|
|
4953
|
+
// overview, or `gnosys status --web` for the HTML dashboard, or
|
|
4954
|
+
// `gnosys status --projects --output file.html` to write to disk.
|
|
4955
|
+
// ─── gnosys status ──────────────────────────────────────────────────────
|
|
4956
|
+
// v5.7.1 (#11): the catch-all status command. Section flags select what to
|
|
4957
|
+
// show; output flags control format. Default (no flag) is the current
|
|
4958
|
+
// project. `dashboard` and `portfolio` were removed in v5.7.1 — their
|
|
4959
|
+
// content lives under `--system` and `--projects` respectively.
|
|
4862
4960
|
program
|
|
4863
|
-
.command("
|
|
4864
|
-
.description("
|
|
4865
|
-
.option("-
|
|
4866
|
-
.option("--
|
|
4961
|
+
.command("status")
|
|
4962
|
+
.description("Show status. Sections: --projects (all projects) · --remote (sync) · --system (memory/LLM health) · default: current project. Output: --web · --json. Note: 'gnosys dashboard' and 'gnosys portfolio' were removed in v5.7.1 — use 'gnosys status --system' and 'gnosys status --projects' instead.")
|
|
4963
|
+
.option("-d, --directory <dir>", "Project directory (auto-detects if omitted)")
|
|
4964
|
+
.option("-p, --project <id>", "Project ID")
|
|
4965
|
+
.option("-g, --global", "(deprecated alias for --projects)")
|
|
4966
|
+
.option("--projects", "Show all projects portfolio (replaces the old 'gnosys portfolio')")
|
|
4967
|
+
.option("-r, --remote", "Show remote sync status (alias for 'gnosys setup remote status')")
|
|
4968
|
+
.option("-w, --web", "Open the HTML dashboard in the browser")
|
|
4969
|
+
.option("-s, --system", "Show system health (memory count, LLM connectivity, embeddings, archive)")
|
|
4867
4970
|
.option("--json", "Output as JSON")
|
|
4868
4971
|
.action(async (opts) => {
|
|
4869
|
-
|
|
4870
|
-
|
|
4871
|
-
|
|
4872
|
-
|
|
4873
|
-
|
|
4874
|
-
|
|
4875
|
-
|
|
4876
|
-
|
|
4877
|
-
|
|
4878
|
-
|
|
4879
|
-
|
|
4880
|
-
const useJson = opts.json || (opts.output?.endsWith(".json") ?? false);
|
|
4881
|
-
if (useJson) {
|
|
4882
|
-
const json = JSON.stringify(report, null, 2);
|
|
4883
|
-
if (opts.output) {
|
|
4884
|
-
const { writeFileSync } = await import("fs");
|
|
4885
|
-
writeFileSync(opts.output, json, "utf-8");
|
|
4886
|
-
console.log(`Portfolio written to ${opts.output}`);
|
|
4972
|
+
// v5.7.1: --projects supersedes --global (kept as alias).
|
|
4973
|
+
if (opts.projects)
|
|
4974
|
+
opts.global = true;
|
|
4975
|
+
// v5.7.1: --remote — dispatch to RemoteSync.getStatus()
|
|
4976
|
+
if (opts.remote) {
|
|
4977
|
+
let remoteCentralDb = null;
|
|
4978
|
+
try {
|
|
4979
|
+
remoteCentralDb = GnosysDB.openLocal();
|
|
4980
|
+
if (!remoteCentralDb.isAvailable()) {
|
|
4981
|
+
console.error("Central DB not available.");
|
|
4982
|
+
process.exit(1);
|
|
4887
4983
|
}
|
|
4888
|
-
|
|
4889
|
-
|
|
4984
|
+
const remotePath = remoteCentralDb.getMeta("remote_path");
|
|
4985
|
+
if (!remotePath) {
|
|
4986
|
+
if (opts.json) {
|
|
4987
|
+
console.log(JSON.stringify({ configured: false, message: "Remote not configured. Run 'gnosys setup remote'." }, null, 2));
|
|
4988
|
+
}
|
|
4989
|
+
else {
|
|
4990
|
+
console.log("Remote sync: not configured. Run 'gnosys setup remote' to set up multi-machine sync.");
|
|
4991
|
+
}
|
|
4992
|
+
return;
|
|
4890
4993
|
}
|
|
4891
|
-
|
|
4892
|
-
|
|
4893
|
-
|
|
4894
|
-
const
|
|
4895
|
-
|
|
4896
|
-
if (opts.
|
|
4897
|
-
|
|
4898
|
-
writeFileSync(opts.output, html, "utf-8");
|
|
4899
|
-
console.log(`Portfolio dashboard written to ${opts.output}`);
|
|
4994
|
+
const { RemoteSync, formatStatus } = await import("./lib/remote.js");
|
|
4995
|
+
const { withHeartbeat } = await import("./lib/heartbeat.js");
|
|
4996
|
+
const sync = new RemoteSync(remoteCentralDb, remotePath);
|
|
4997
|
+
const status = await withHeartbeat("Checking remote sync status", () => sync.getStatus());
|
|
4998
|
+
sync.closeRemote();
|
|
4999
|
+
if (opts.json) {
|
|
5000
|
+
console.log(JSON.stringify(status, null, 2));
|
|
4900
5001
|
}
|
|
4901
5002
|
else {
|
|
4902
|
-
console.log(
|
|
5003
|
+
console.log(formatStatus(status));
|
|
4903
5004
|
}
|
|
4904
5005
|
return;
|
|
4905
5006
|
}
|
|
4906
|
-
|
|
4907
|
-
|
|
4908
|
-
|
|
4909
|
-
writeFileSync(opts.output, markdown, "utf-8");
|
|
4910
|
-
console.log(`Portfolio dashboard written to ${opts.output}`);
|
|
5007
|
+
catch (err) {
|
|
5008
|
+
console.error(`Error: ${err instanceof Error ? err.message : err}`);
|
|
5009
|
+
process.exit(1);
|
|
4911
5010
|
}
|
|
4912
|
-
|
|
4913
|
-
|
|
5011
|
+
finally {
|
|
5012
|
+
remoteCentralDb?.close();
|
|
4914
5013
|
}
|
|
4915
5014
|
}
|
|
4916
|
-
catch (err) {
|
|
4917
|
-
console.error(`Error: ${err instanceof Error ? err.message : err}`);
|
|
4918
|
-
process.exit(1);
|
|
4919
|
-
}
|
|
4920
|
-
finally {
|
|
4921
|
-
centralDb?.close();
|
|
4922
|
-
}
|
|
4923
|
-
});
|
|
4924
|
-
// ─── gnosys status ──────────────────────────────────────────────────────
|
|
4925
|
-
program
|
|
4926
|
-
.command("status")
|
|
4927
|
-
.description("Show project status (--global: all projects, --web: HTML dashboard, --system: memory/LLM health)")
|
|
4928
|
-
.option("-d, --directory <dir>", "Project directory (auto-detects if omitted)")
|
|
4929
|
-
.option("-p, --project <id>", "Project ID")
|
|
4930
|
-
.option("-g, --global", "Show all projects")
|
|
4931
|
-
.option("-w, --web", "Open the HTML dashboard in the browser")
|
|
4932
|
-
.option("-s, --system", "Show system health (memory count, LLM connectivity, embeddings, archive)")
|
|
4933
|
-
.option("--json", "Output as JSON")
|
|
4934
|
-
.action(async (opts) => {
|
|
4935
5015
|
// --system delegates to the dashboard formatter (formerly `gnosys dashboard`).
|
|
4936
5016
|
if (opts.system) {
|
|
4937
5017
|
const { collectDashboardData, formatDashboard, formatDashboardJSON } = await import("./lib/dashboard.js");
|