gnosys 5.4.1 → 5.4.2

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 CHANGED
@@ -269,6 +269,40 @@ cd /path/to/project-b && gnosys init
269
269
 
270
270
  ---
271
271
 
272
+ ## Setup Wizards
273
+
274
+ `gnosys setup` runs the full interactive wizard. To configure just one piece without walking the whole thing, use one of these subcommands:
275
+
276
+ ```bash
277
+ gnosys setup # full wizard (provider, models, IDE, remote sync, dream)
278
+ gnosys setup models # LLM provider + model only
279
+ gnosys setup remote # multi-machine sync (NAS/shared drive)
280
+ gnosys setup dream # Dream Mode designation, schedule, sub-tasks
281
+ ```
282
+
283
+ ### Dream Mode setup (v5.4.2+)
284
+
285
+ Dream Mode is the idle-time consolidation engine — confidence decay, summary generation, self-critique, relationship discovery. With multi-machine sync (v5.3.0+), running dream cycles from every machine wastes work and fights for SQLite write locks. v5.4.2 introduces a **single designated machine** model:
286
+
287
+ - Run `gnosys setup dream` on the machine you want to host dream cycles.
288
+ - The wizard validates your provider/model with a live API probe before saving.
289
+ - Other machines stay quiet — they see the designation in the central DB and skip the scheduler.
290
+ - `gnosys dream log` shows recent runs; `gnosys dashboard` has a `DREAM HEALTH` section with last-run timestamp, designated machine, and consecutive-failure counter.
291
+ - 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.
292
+
293
+ ### Removed in v5.4.2
294
+
295
+ The following commands were removed in favor of the canonical `gnosys setup <thing>` form:
296
+
297
+ | Removed | Use instead |
298
+ |---|---|
299
+ | `gnosys models` | `gnosys setup models` |
300
+ | `gnosys remote configure` | `gnosys setup remote` |
301
+
302
+ `gnosys remote push|pull|sync|status` remain unchanged — only `configure` moved.
303
+
304
+ ---
305
+
272
306
  ### Manual config (if you prefer)
273
307
 
274
308
  If you'd rather edit configs by hand, here's where each client looks for MCP servers.
package/dist/cli.js CHANGED
@@ -503,7 +503,7 @@ setupCmd
503
503
  // `gnosys setup remote` — configure remote sync (alias for `gnosys remote configure`)
504
504
  setupCmd
505
505
  .command("remote")
506
- .description("Configure multi-machine sync (alias for 'gnosys remote configure')")
506
+ .description("Configure multi-machine sync (NAS/shared drive)")
507
507
  .option("--path <path>", "Set remote path directly (non-interactive)")
508
508
  .action(async (opts) => {
509
509
  const { GnosysDB } = await import("./lib/db.js");
@@ -528,17 +528,18 @@ setupCmd
528
528
  db.close();
529
529
  }
530
530
  });
531
- // ─── gnosys models (top-level shortcut) ─────────────────────────────────
532
- program
533
- .command("models")
534
- .description("Quick model operationslist available, refresh cache, or set the default")
535
- .option("--list", "List available models for the current provider")
536
- .option("--refresh", "Refresh model list from OpenRouter (clears the cache)")
537
- .option("--set <model>", "Set the default model for the current provider")
538
- .action(async (opts) => {
539
- const { runModelsCommand } = await import("./lib/setup.js");
540
- await runModelsCommand(opts);
531
+ // `gnosys setup dream` — configure dream mode (designation, provider, schedule)
532
+ setupCmd
533
+ .command("dream")
534
+ .description("Configure Dream Modedesignate this machine, pick provider/model, set schedule")
535
+ .action(async () => {
536
+ const { runDreamSetup } = await import("./lib/setup.js");
537
+ await runDreamSetup({ directory: process.cwd() });
541
538
  });
539
+ // v5.4.2 removal: `gnosys models` (top-level shortcut) was removed in favor
540
+ // of the canonical `gnosys setup models` form. The implementation function
541
+ // runModelsCommand() in setup.ts is no longer wired but kept for now in case
542
+ // we need to revive a top-level shortcut later.
542
543
  // ─── gnosys init ─────────────────────────────────────────────────────────
543
544
  program
544
545
  .command("init [ide]")
@@ -2804,39 +2805,10 @@ remoteCmd
2804
2805
  centralDb?.close();
2805
2806
  }
2806
2807
  });
2807
- remoteCmd
2808
- .command("configure")
2809
- .description("Configure or change the remote sync location (interactive wizard)")
2810
- .option("--path <path>", "Set remote path non-interactively (skips wizard)")
2811
- .option("--migrate", "Copy current local DB to remote on first setup (with --path)")
2812
- .action(async (opts) => {
2813
- let centralDb = null;
2814
- try {
2815
- centralDb = GnosysDB.openLocal();
2816
- if (!centralDb.isAvailable()) {
2817
- console.error("Central DB not available.");
2818
- process.exit(1);
2819
- }
2820
- const { runConfigureWizard, configureFromPath } = await import("./lib/remoteWizard.js");
2821
- if (opts.path) {
2822
- // Non-interactive mode
2823
- const ok = await configureFromPath(centralDb, opts.path, { migrate: opts.migrate });
2824
- process.exit(ok ? 0 : 1);
2825
- }
2826
- else {
2827
- // Interactive wizard
2828
- const ok = await runConfigureWizard(centralDb);
2829
- process.exit(ok ? 0 : 1);
2830
- }
2831
- }
2832
- catch (err) {
2833
- console.error(`Error: ${err instanceof Error ? err.message : err}`);
2834
- process.exit(1);
2835
- }
2836
- finally {
2837
- centralDb?.close();
2838
- }
2839
- });
2808
+ // v5.4.2 removal: `gnosys remote configure` was removed in favor of the
2809
+ // canonical `gnosys setup remote` form (which calls the same wizard
2810
+ // helpers from lib/remoteWizard.ts). Sync operations like push/pull/sync
2811
+ // remain under the `remote` parent.
2840
2812
  // ─── gnosys upgrade ─────────────────────────────────────────────────────
2841
2813
  program
2842
2814
  .command("upgrade")
@@ -3328,10 +3300,12 @@ program
3328
3300
  }
3329
3301
  console.log();
3330
3302
  });
3331
- // ─── gnosys dream ────────────────────────────────────────────────────────
3332
- program
3303
+ // ─── gnosys dream (parent command) ───────────────────────────────────────
3304
+ const dreamCmd = program
3333
3305
  .command("dream")
3334
- .description("Run a Dream Mode cycle — idle-time consolidation (decay, summaries, self-critique, relationships)")
3306
+ .description("Dream Mode — idle-time consolidation (run a cycle, view log)");
3307
+ // Bare `gnosys dream` runs a cycle now (preserves v5.4.1 behavior).
3308
+ dreamCmd
3335
3309
  .option("--max-runtime <minutes>", "Max runtime in minutes (default: 30)")
3336
3310
  .option("--no-critique", "Skip self-critique phase")
3337
3311
  .option("--no-summaries", "Skip summary generation")
@@ -3378,6 +3352,73 @@ program
3378
3352
  }
3379
3353
  db.close();
3380
3354
  });
3355
+ // `gnosys dream log` — view recent dream runs from audit_log
3356
+ dreamCmd
3357
+ .command("log")
3358
+ .description("Show recent dream runs from the audit log (default: last 20)")
3359
+ .option("--last <N>", "Number of most recent runs to show", "20")
3360
+ .option("--since <YYYY-MM-DD>", "Only runs since this date")
3361
+ .option("--failures-only", "Only runs with errors or unreachable provider")
3362
+ .option("--json", "Output raw audit rows as JSON")
3363
+ .action(async function (opts) {
3364
+ let centralDb = null;
3365
+ try {
3366
+ centralDb = GnosysDB.openCentral();
3367
+ if (!centralDb.isAvailable()) {
3368
+ console.error("Central DB not available.");
3369
+ process.exit(1);
3370
+ }
3371
+ const limit = Math.max(1, parseInt(opts.last) || 20);
3372
+ const sinceIso = opts.since ? `${opts.since}T00:00:00Z` : undefined;
3373
+ const runs = centralDb.getRecentDreamRuns(limit, {
3374
+ failuresOnly: !!opts.failuresOnly,
3375
+ sinceIso,
3376
+ });
3377
+ // Commander v13 hoists `--json` to the parent when both parent and
3378
+ // subcommand define it. Check the parent (dreamCmd) too so users can
3379
+ // type `gnosys dream log --json` and get JSON output.
3380
+ const wantJson = !!opts.json || !!(this.parent?.opts().json);
3381
+ // JSON path always emits a structured response — including empty runs.
3382
+ if (wantJson) {
3383
+ console.log(JSON.stringify({ count: runs.length, runs }, null, 2));
3384
+ return;
3385
+ }
3386
+ if (runs.length === 0) {
3387
+ console.log("No dream runs recorded.");
3388
+ return;
3389
+ }
3390
+ const DIM = "\x1b[2m";
3391
+ const RESET = "\x1b[0m";
3392
+ const RED = "\x1b[31m";
3393
+ const GREEN = "\x1b[32m";
3394
+ console.log(`${runs.length} dream run(s):\n`);
3395
+ for (const r of runs) {
3396
+ const d = r.details;
3397
+ const dur = r.durationMs != null ? `${(r.durationMs / 1000).toFixed(1)}s` : "—";
3398
+ const summaries = Number(d.summariesGenerated || 0);
3399
+ const decays = Number(d.decayUpdated || 0);
3400
+ const reviews = Number(d.reviewSuggestions || 0);
3401
+ const rels = Number(d.relationshipsDiscovered || 0);
3402
+ const errors = Number(d.errors || 0);
3403
+ const unreachable = Boolean(d.providerUnreachable);
3404
+ const status = unreachable
3405
+ ? `${RED}provider unreachable${RESET}`
3406
+ : errors > 0
3407
+ ? `${RED}${errors} error(s)${RESET}`
3408
+ : summaries + decays + rels > 0
3409
+ ? `${GREEN}did work${RESET}`
3410
+ : `${DIM}no LLM work${RESET}`;
3411
+ console.log(` ${r.completed} ${DIM}(${dur})${RESET} ${status}`);
3412
+ console.log(` decays=${decays} summaries=${summaries} reviews=${reviews} relations=${rels}`);
3413
+ if (d.provider) {
3414
+ console.log(` ${DIM}provider=${d.provider}${d.model ? "/" + d.model : ""}${RESET}`);
3415
+ }
3416
+ }
3417
+ }
3418
+ finally {
3419
+ centralDb?.close();
3420
+ }
3421
+ });
3381
3422
  // ─── gnosys export ───────────────────────────────────────────────────────
3382
3423
  program
3383
3424
  .command("export")