gnosys 5.3.3 → 5.4.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 +156 -30
- package/dist/cli.js.map +1 -1
- package/dist/lib/db.d.ts +6 -3
- package/dist/lib/db.d.ts.map +1 -1
- package/dist/lib/db.js +13 -8
- package/dist/lib/db.js.map +1 -1
- package/dist/lib/modelValidation.d.ts +22 -0
- package/dist/lib/modelValidation.d.ts.map +1 -0
- package/dist/lib/modelValidation.js +157 -0
- package/dist/lib/modelValidation.js.map +1 -0
- package/dist/lib/paths.d.ts +32 -0
- package/dist/lib/paths.d.ts.map +1 -0
- package/dist/lib/paths.js +44 -0
- package/dist/lib/paths.js.map +1 -0
- package/dist/lib/remoteWizard.d.ts +2 -1
- package/dist/lib/remoteWizard.d.ts.map +1 -1
- package/dist/lib/remoteWizard.js +6 -3
- package/dist/lib/remoteWizard.js.map +1 -1
- package/dist/lib/setup.d.ts +25 -0
- package/dist/lib/setup.d.ts.map +1 -1
- package/dist/lib/setup.js +459 -25
- package/dist/lib/setup.js.map +1 -1
- package/dist/postinstall.js +2 -2
- package/dist/postinstall.js.map +1 -1
- package/dist/sandbox/helper-template.d.ts.map +1 -1
- package/dist/sandbox/helper-template.js +8 -2
- package/dist/sandbox/helper-template.js.map +1 -1
- package/dist/sandbox/server.d.ts.map +1 -1
- package/dist/sandbox/server.js +2 -2
- package/dist/sandbox/server.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -11,6 +11,7 @@ import { fileURLToPath } from "url";
|
|
|
11
11
|
import dotenv from "dotenv";
|
|
12
12
|
import { readFileSync, existsSync, copyFileSync } from "fs";
|
|
13
13
|
import { GnosysResolver } from "./lib/resolver.js";
|
|
14
|
+
import { getGnosysHome } from "./lib/paths.js";
|
|
14
15
|
import { GnosysSearch } from "./lib/search.js";
|
|
15
16
|
import { GnosysTagRegistry } from "./lib/tags.js";
|
|
16
17
|
import { GnosysIngestion } from "./lib/ingest.js";
|
|
@@ -469,10 +470,12 @@ program
|
|
|
469
470
|
}
|
|
470
471
|
}
|
|
471
472
|
});
|
|
472
|
-
// ─── gnosys setup
|
|
473
|
-
program
|
|
473
|
+
// ─── gnosys setup (parent command) ──────────────────────────────────────
|
|
474
|
+
const setupCmd = program
|
|
474
475
|
.command("setup")
|
|
475
|
-
.description("
|
|
476
|
+
.description("Configure Gnosys — LLM provider, models, remote sync, and IDE integration");
|
|
477
|
+
// Bare `gnosys setup` runs the full interactive wizard
|
|
478
|
+
setupCmd
|
|
476
479
|
.option("--non-interactive", "Skip prompts, use defaults (for CI/scripting)")
|
|
477
480
|
.action(async (opts) => {
|
|
478
481
|
const { runSetup } = await import("./lib/setup.js");
|
|
@@ -481,10 +484,64 @@ program
|
|
|
481
484
|
nonInteractive: opts.nonInteractive,
|
|
482
485
|
});
|
|
483
486
|
});
|
|
487
|
+
// `gnosys setup models` — just configure LLM provider/model/key
|
|
488
|
+
setupCmd
|
|
489
|
+
.command("models")
|
|
490
|
+
.description("Update LLM provider and model configuration")
|
|
491
|
+
.option("-p, --provider <name>", "Set provider directly (anthropic, openai, xai, groq, mistral, ollama, lmstudio, custom)")
|
|
492
|
+
.option("-m, --model <name>", "Set model name directly")
|
|
493
|
+
.option("--no-validate", "Skip the test API call")
|
|
494
|
+
.action(async (opts) => {
|
|
495
|
+
const { runModelsSetup } = await import("./lib/setup.js");
|
|
496
|
+
await runModelsSetup({
|
|
497
|
+
directory: process.cwd(),
|
|
498
|
+
provider: opts.provider,
|
|
499
|
+
model: opts.model,
|
|
500
|
+
validate: opts.validate,
|
|
501
|
+
});
|
|
502
|
+
});
|
|
503
|
+
// `gnosys setup remote` — configure remote sync (alias for `gnosys remote configure`)
|
|
504
|
+
setupCmd
|
|
505
|
+
.command("remote")
|
|
506
|
+
.description("Configure multi-machine sync (alias for 'gnosys remote configure')")
|
|
507
|
+
.option("--path <path>", "Set remote path directly (non-interactive)")
|
|
508
|
+
.action(async (opts) => {
|
|
509
|
+
const { GnosysDB } = await import("./lib/db.js");
|
|
510
|
+
const db = GnosysDB.openCentral();
|
|
511
|
+
if (!db.isAvailable()) {
|
|
512
|
+
console.error("Central DB not available.");
|
|
513
|
+
db.close();
|
|
514
|
+
process.exit(1);
|
|
515
|
+
}
|
|
516
|
+
try {
|
|
517
|
+
if (opts.path) {
|
|
518
|
+
const { configureFromPath } = await import("./lib/remoteWizard.js");
|
|
519
|
+
await configureFromPath(db, opts.path);
|
|
520
|
+
}
|
|
521
|
+
else {
|
|
522
|
+
const { runConfigureWizard } = await import("./lib/remoteWizard.js");
|
|
523
|
+
await runConfigureWizard(db);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
finally {
|
|
527
|
+
db.close();
|
|
528
|
+
}
|
|
529
|
+
});
|
|
530
|
+
// ─── gnosys models (top-level shortcut) ─────────────────────────────────
|
|
531
|
+
program
|
|
532
|
+
.command("models")
|
|
533
|
+
.description("Quick model operations — list available, refresh cache, or set the default")
|
|
534
|
+
.option("--list", "List available models for the current provider")
|
|
535
|
+
.option("--refresh", "Refresh model list from OpenRouter (clears the cache)")
|
|
536
|
+
.option("--set <model>", "Set the default model for the current provider")
|
|
537
|
+
.action(async (opts) => {
|
|
538
|
+
const { runModelsCommand } = await import("./lib/setup.js");
|
|
539
|
+
await runModelsCommand(opts);
|
|
540
|
+
});
|
|
484
541
|
// ─── gnosys init ─────────────────────────────────────────────────────────
|
|
485
542
|
program
|
|
486
543
|
.command("init [ide]")
|
|
487
|
-
.description("Initialize Gnosys in the current directory. Optionally specify IDE: cursor, claude,
|
|
544
|
+
.description("Initialize Gnosys in the current directory. Optionally specify IDE: cursor, claude, claude-desktop, codex, gemini-cli, or antigravity to force IDE setup.")
|
|
488
545
|
.option("-d, --directory <dir>", "Target directory (default: cwd)")
|
|
489
546
|
.option("-n, --name <name>", "Project name (default: directory basename)")
|
|
490
547
|
.action(async (ide, opts) => {
|
|
@@ -591,13 +648,15 @@ program
|
|
|
591
648
|
}
|
|
592
649
|
// If a specific IDE was requested, force-create its config
|
|
593
650
|
if (ide) {
|
|
594
|
-
const validIdes = ["cursor", "claude", "codex"];
|
|
651
|
+
const validIdes = ["cursor", "claude", "claude-desktop", "codex", "gemini-cli", "antigravity"];
|
|
595
652
|
const normalizedIde = ide.toLowerCase();
|
|
596
653
|
if (!validIdes.includes(normalizedIde)) {
|
|
597
654
|
console.log(`\nUnknown IDE: "${ide}". Valid options: ${validIdes.join(", ")}`);
|
|
598
655
|
}
|
|
599
656
|
else {
|
|
600
657
|
const { configureCursor, configureClaudeCode, configureCodex } = await import("./lib/projectIdentity.js");
|
|
658
|
+
// Cursor/Claude/Codex have IDE-specific session hooks. Gemini CLI and
|
|
659
|
+
// Antigravity don't yet, so we skip the hook step for them.
|
|
601
660
|
let result;
|
|
602
661
|
switch (normalizedIde) {
|
|
603
662
|
case "cursor":
|
|
@@ -615,28 +674,30 @@ program
|
|
|
615
674
|
console.log(` ${result.details}`);
|
|
616
675
|
console.log(` File: ${result.filePath}`);
|
|
617
676
|
}
|
|
618
|
-
//
|
|
677
|
+
// Set up MCP config for the IDE
|
|
619
678
|
const { setupIDE } = await import("./lib/setup.js");
|
|
620
679
|
const mcp = await setupIDE(normalizedIde, targetDir);
|
|
621
680
|
if (mcp.success) {
|
|
622
681
|
console.log(` MCP: ${mcp.message}`);
|
|
623
682
|
}
|
|
624
|
-
// Update agentRulesTarget in gnosys.json
|
|
625
|
-
const
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
683
|
+
// Update agentRulesTarget in gnosys.json (only for IDEs with rules files)
|
|
684
|
+
const targetMap = {
|
|
685
|
+
cursor: ".cursor/rules/gnosys.mdc",
|
|
686
|
+
claude: "CLAUDE.md",
|
|
687
|
+
codex: "CODEX.md",
|
|
688
|
+
};
|
|
689
|
+
if (targetMap[normalizedIde]) {
|
|
690
|
+
const identityPath = path.join(storePath, "gnosys.json");
|
|
691
|
+
try {
|
|
692
|
+
const identityContent = await fs.readFile(identityPath, "utf-8");
|
|
693
|
+
const identity = JSON.parse(identityContent);
|
|
694
|
+
identity.agentRulesTarget = targetMap[normalizedIde];
|
|
695
|
+
await fs.writeFile(identityPath, JSON.stringify(identity, null, 2) + "\n", "utf-8");
|
|
696
|
+
console.log(` Config: agentRulesTarget → ${identity.agentRulesTarget}`);
|
|
697
|
+
}
|
|
698
|
+
catch {
|
|
699
|
+
// Non-critical
|
|
700
|
+
}
|
|
640
701
|
}
|
|
641
702
|
}
|
|
642
703
|
}
|
|
@@ -3103,7 +3164,7 @@ program
|
|
|
3103
3164
|
.action(async (opts) => {
|
|
3104
3165
|
const projectDir = opts.directory ? path.resolve(opts.directory) : process.cwd();
|
|
3105
3166
|
const storePath = path.join(projectDir, ".gnosys");
|
|
3106
|
-
const globalStorePath =
|
|
3167
|
+
const globalStorePath = getGnosysHome();
|
|
3107
3168
|
// Load config: try project-level first, fall back to global ~/.gnosys/
|
|
3108
3169
|
let cfg;
|
|
3109
3170
|
let configSource;
|
|
@@ -3685,10 +3746,22 @@ program
|
|
|
3685
3746
|
console.log(` Central DB: ${GnosysDB.getCentralDbPath()}`);
|
|
3686
3747
|
});
|
|
3687
3748
|
// ─── gnosys projects ────────────────────────────────────────────────────
|
|
3749
|
+
/**
|
|
3750
|
+
* Returns true if a project's working directory no longer exists on disk.
|
|
3751
|
+
* Used by `gnosys projects` to filter dead entries by default and by
|
|
3752
|
+
* `gnosys projects --prune` to delete them. We deliberately do NOT pattern-
|
|
3753
|
+
* match on tmp paths — active test fixtures live in /var/folders/ and
|
|
3754
|
+
* /tmp/ and we want them visible while they're in use.
|
|
3755
|
+
*/
|
|
3756
|
+
function isDeadProjectDir(dir) {
|
|
3757
|
+
return !existsSync(dir);
|
|
3758
|
+
}
|
|
3688
3759
|
program
|
|
3689
3760
|
.command("projects")
|
|
3690
|
-
.description("List
|
|
3761
|
+
.description("List registered projects from the central DB")
|
|
3691
3762
|
.option("--json", "Output as JSON")
|
|
3763
|
+
.option("--all", "Include dead projects (deleted directories, /tmp/ paths)")
|
|
3764
|
+
.option("--prune", "Delete registry entries whose directory no longer exists or is a tmp path")
|
|
3692
3765
|
.action(async (opts) => {
|
|
3693
3766
|
let centralDb = null;
|
|
3694
3767
|
try {
|
|
@@ -3697,18 +3770,71 @@ program
|
|
|
3697
3770
|
console.error("Central DB not available (better-sqlite3 missing).");
|
|
3698
3771
|
process.exit(1);
|
|
3699
3772
|
}
|
|
3700
|
-
const
|
|
3701
|
-
if (
|
|
3702
|
-
|
|
3773
|
+
const allProjects = centralDb.getAllProjects();
|
|
3774
|
+
if (opts.prune) {
|
|
3775
|
+
// Find and delete dead projects
|
|
3776
|
+
const deadProjects = allProjects.filter((p) => isDeadProjectDir(p.working_directory));
|
|
3777
|
+
for (const p of deadProjects) {
|
|
3778
|
+
centralDb.deleteProject(p.id);
|
|
3779
|
+
}
|
|
3780
|
+
outputResult(!!opts.json, {
|
|
3781
|
+
deleted: deadProjects.length,
|
|
3782
|
+
remaining: allProjects.length - deadProjects.length,
|
|
3783
|
+
deletedProjects: deadProjects.map((p) => ({ id: p.id, name: p.name, directory: p.working_directory })),
|
|
3784
|
+
}, () => {
|
|
3785
|
+
if (deadProjects.length === 0) {
|
|
3786
|
+
console.log("No dead projects to prune.");
|
|
3787
|
+
}
|
|
3788
|
+
else {
|
|
3789
|
+
const DIM = "\x1b[2m";
|
|
3790
|
+
const RESET = "\x1b[0m";
|
|
3791
|
+
console.log(`Pruned ${deadProjects.length} dead project(s):\n`);
|
|
3792
|
+
for (const p of deadProjects) {
|
|
3793
|
+
console.log(` ${p.name} ${DIM}${p.working_directory}${RESET}`);
|
|
3794
|
+
}
|
|
3795
|
+
console.log();
|
|
3796
|
+
console.log(`${allProjects.length - deadProjects.length} project(s) remain.`);
|
|
3797
|
+
}
|
|
3798
|
+
});
|
|
3799
|
+
return;
|
|
3800
|
+
}
|
|
3801
|
+
// Normal listing — filter dead projects by default
|
|
3802
|
+
const visibleProjects = opts.all
|
|
3803
|
+
? allProjects
|
|
3804
|
+
: allProjects.filter((p) => !isDeadProjectDir(p.working_directory));
|
|
3805
|
+
if (visibleProjects.length === 0) {
|
|
3806
|
+
const deadCount = allProjects.length;
|
|
3807
|
+
outputResult(!!opts.json, {
|
|
3808
|
+
count: 0,
|
|
3809
|
+
totalRegistered: deadCount,
|
|
3810
|
+
deadCount,
|
|
3811
|
+
projects: [],
|
|
3812
|
+
}, () => {
|
|
3813
|
+
if (deadCount === 0) {
|
|
3814
|
+
console.log("No projects registered. Run 'gnosys init' in a project directory.");
|
|
3815
|
+
}
|
|
3816
|
+
else {
|
|
3817
|
+
console.log(`No live projects (${deadCount} dead — run 'gnosys projects --all' to see them or 'gnosys projects --prune' to remove them).`);
|
|
3818
|
+
}
|
|
3819
|
+
});
|
|
3703
3820
|
centralDb.close();
|
|
3704
3821
|
return;
|
|
3705
3822
|
}
|
|
3706
|
-
const projectData =
|
|
3823
|
+
const projectData = visibleProjects.map((p) => ({
|
|
3707
3824
|
...p,
|
|
3708
3825
|
memoryCount: centralDb.getMemoriesByProject(p.id).length,
|
|
3709
3826
|
}));
|
|
3710
|
-
|
|
3711
|
-
|
|
3827
|
+
const deadCount = allProjects.length - visibleProjects.length;
|
|
3828
|
+
outputResult(!!opts.json, {
|
|
3829
|
+
count: visibleProjects.length,
|
|
3830
|
+
totalRegistered: allProjects.length,
|
|
3831
|
+
deadCount,
|
|
3832
|
+
projects: projectData,
|
|
3833
|
+
}, () => {
|
|
3834
|
+
const header = deadCount > 0 && !opts.all
|
|
3835
|
+
? `${visibleProjects.length} live project(s) (${deadCount} dead hidden — use --all or --prune):\n`
|
|
3836
|
+
: `${visibleProjects.length} registered project(s):\n`;
|
|
3837
|
+
console.log(header);
|
|
3712
3838
|
for (const p of projectData) {
|
|
3713
3839
|
console.log(` ${p.name}`);
|
|
3714
3840
|
console.log(` ID: ${p.id}`);
|