gnosys 4.1.3 → 4.2.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 +184 -1
- package/dist/cli.js.map +1 -1
- package/dist/lib/db.d.ts +2 -0
- package/dist/lib/db.d.ts.map +1 -1
- package/dist/lib/db.js +35 -0
- package/dist/lib/db.js.map +1 -1
- package/dist/lib/resolver.d.ts +3 -2
- package/dist/lib/resolver.d.ts.map +1 -1
- package/dist/lib/resolver.js +15 -13
- package/dist/lib/resolver.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
import { Command } from "commander";
|
|
7
7
|
import path from "path";
|
|
8
8
|
import fs from "fs/promises";
|
|
9
|
+
import os from "os";
|
|
9
10
|
import { fileURLToPath } from "url";
|
|
10
11
|
import dotenv from "dotenv";
|
|
11
12
|
import { readFileSync, existsSync, copyFileSync } from "fs";
|
|
@@ -91,7 +92,25 @@ function outputResult(json, data, humanFn) {
|
|
|
91
92
|
program
|
|
92
93
|
.name("gnosys")
|
|
93
94
|
.description("Gnosys — Persistent memory for AI agents. Sandbox-first runtime, central SQLite brain, federated search, reflection API, process tracing, preferences, Dream Mode, Obsidian export. Also runs as a full MCP server.")
|
|
94
|
-
.version(pkg.version)
|
|
95
|
+
.version(pkg.version)
|
|
96
|
+
.hook("preAction", async () => {
|
|
97
|
+
// Check if central DB was upgraded to a newer version on another machine
|
|
98
|
+
try {
|
|
99
|
+
const centralDb = GnosysDB.openCentral();
|
|
100
|
+
if (centralDb.isAvailable()) {
|
|
101
|
+
const dbVersion = centralDb.getMeta("app_version");
|
|
102
|
+
if (dbVersion && dbVersion !== pkg.version) {
|
|
103
|
+
const upgradedBy = centralDb.getMeta("upgraded_by") || "another machine";
|
|
104
|
+
console.error(`\n⚠ Gnosys DB was upgraded to v${dbVersion} by ${upgradedBy}.` +
|
|
105
|
+
`\n You are running v${pkg.version}. Run: npm install -g gnosys && gnosys upgrade\n`);
|
|
106
|
+
}
|
|
107
|
+
centralDb.close();
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
// non-critical — don't block the command
|
|
112
|
+
}
|
|
113
|
+
});
|
|
95
114
|
// ─── gnosys read <path> ──────────────────────────────────────────────────
|
|
96
115
|
program
|
|
97
116
|
.command("read <memoryPath>")
|
|
@@ -444,6 +463,9 @@ program
|
|
|
444
463
|
projectName: opts.name,
|
|
445
464
|
centralDb: centralDb || undefined,
|
|
446
465
|
});
|
|
466
|
+
// Register in file-based project registry so resolver can find it
|
|
467
|
+
const tempResolver = new GnosysResolver();
|
|
468
|
+
await tempResolver.registerProject(targetDir);
|
|
447
469
|
if (centralDb)
|
|
448
470
|
centralDb.close();
|
|
449
471
|
const action = isResync ? "re-synced" : "initialized";
|
|
@@ -1887,6 +1909,167 @@ program
|
|
|
1887
1909
|
}
|
|
1888
1910
|
});
|
|
1889
1911
|
// NOTE: gnosys migrate is defined below (near the end) with --to-central support
|
|
1912
|
+
// ─── gnosys upgrade ─────────────────────────────────────────────────────
|
|
1913
|
+
program
|
|
1914
|
+
.command("upgrade")
|
|
1915
|
+
.description("Re-initialize all registered projects after a Gnosys version upgrade. Updates agent rules, project registry, and stamps the central DB with the current version.")
|
|
1916
|
+
.action(async () => {
|
|
1917
|
+
const currentVersion = pkg.version;
|
|
1918
|
+
console.log(`Gnosys v${currentVersion} — upgrading registered projects...\n`);
|
|
1919
|
+
// 1. Read registered projects
|
|
1920
|
+
const home = process.env.HOME || process.env.USERPROFILE || "/tmp";
|
|
1921
|
+
const registryPath = path.join(home, ".config", "gnosys", "projects.json");
|
|
1922
|
+
let projects = [];
|
|
1923
|
+
try {
|
|
1924
|
+
projects = JSON.parse(await fs.readFile(registryPath, "utf-8"));
|
|
1925
|
+
}
|
|
1926
|
+
catch {
|
|
1927
|
+
console.log("No registered projects found. Run 'gnosys init' in each project first.");
|
|
1928
|
+
return;
|
|
1929
|
+
}
|
|
1930
|
+
// 2. Iterate and upgrade each project that exists on this machine
|
|
1931
|
+
const upgraded = [];
|
|
1932
|
+
const skipped = [];
|
|
1933
|
+
const failed = [];
|
|
1934
|
+
for (const projectDir of projects) {
|
|
1935
|
+
const storePath = path.join(projectDir, ".gnosys");
|
|
1936
|
+
try {
|
|
1937
|
+
await fs.stat(storePath);
|
|
1938
|
+
}
|
|
1939
|
+
catch {
|
|
1940
|
+
skipped.push(projectDir);
|
|
1941
|
+
continue;
|
|
1942
|
+
}
|
|
1943
|
+
try {
|
|
1944
|
+
// Re-create project identity (re-syncs with central DB)
|
|
1945
|
+
let centralDb = null;
|
|
1946
|
+
try {
|
|
1947
|
+
centralDb = GnosysDB.openCentral();
|
|
1948
|
+
if (!centralDb.isAvailable())
|
|
1949
|
+
centralDb = null;
|
|
1950
|
+
}
|
|
1951
|
+
catch {
|
|
1952
|
+
centralDb = null;
|
|
1953
|
+
}
|
|
1954
|
+
await createProjectIdentity(projectDir, { centralDb: centralDb || undefined });
|
|
1955
|
+
// Re-register in file-based registry (idempotent)
|
|
1956
|
+
const tempResolver = new GnosysResolver();
|
|
1957
|
+
await tempResolver.registerProject(projectDir);
|
|
1958
|
+
// Re-generate agent rules for all detected IDEs
|
|
1959
|
+
if (centralDb) {
|
|
1960
|
+
const { syncToTarget } = await import("./lib/rulesGen.js");
|
|
1961
|
+
const { readProjectIdentity } = await import("./lib/projectIdentity.js");
|
|
1962
|
+
const identity = await readProjectIdentity(projectDir);
|
|
1963
|
+
const projectId = identity?.projectId || null;
|
|
1964
|
+
try {
|
|
1965
|
+
await syncToTarget(centralDb, projectDir, "all", projectId);
|
|
1966
|
+
}
|
|
1967
|
+
catch {
|
|
1968
|
+
// Some projects may not have IDE configs — that's ok
|
|
1969
|
+
}
|
|
1970
|
+
centralDb.close();
|
|
1971
|
+
}
|
|
1972
|
+
upgraded.push(projectDir);
|
|
1973
|
+
}
|
|
1974
|
+
catch (err) {
|
|
1975
|
+
failed.push(`${projectDir} (${err.message})`);
|
|
1976
|
+
}
|
|
1977
|
+
}
|
|
1978
|
+
// 3. Update global agent rules
|
|
1979
|
+
try {
|
|
1980
|
+
let centralDb = null;
|
|
1981
|
+
try {
|
|
1982
|
+
centralDb = GnosysDB.openCentral();
|
|
1983
|
+
if (!centralDb.isAvailable())
|
|
1984
|
+
centralDb = null;
|
|
1985
|
+
}
|
|
1986
|
+
catch {
|
|
1987
|
+
centralDb = null;
|
|
1988
|
+
}
|
|
1989
|
+
if (centralDb) {
|
|
1990
|
+
const { syncToTarget } = await import("./lib/rulesGen.js");
|
|
1991
|
+
await syncToTarget(centralDb, process.cwd(), "global", null);
|
|
1992
|
+
centralDb.close();
|
|
1993
|
+
console.log(` ✓ Global agent rules updated (~/.claude/CLAUDE.md)`);
|
|
1994
|
+
}
|
|
1995
|
+
}
|
|
1996
|
+
catch {
|
|
1997
|
+
console.log(` ⚠ Could not update global agent rules`);
|
|
1998
|
+
}
|
|
1999
|
+
// 4. Stamp the central DB with current version and machine info
|
|
2000
|
+
try {
|
|
2001
|
+
const centralDb = GnosysDB.openCentral();
|
|
2002
|
+
if (centralDb.isAvailable()) {
|
|
2003
|
+
const hostname = os.hostname();
|
|
2004
|
+
centralDb.setMeta("app_version", currentVersion);
|
|
2005
|
+
centralDb.setMeta("last_upgrade", new Date().toISOString());
|
|
2006
|
+
centralDb.setMeta("upgraded_by", hostname);
|
|
2007
|
+
// Track all machines that have accessed this DB
|
|
2008
|
+
let machines = {};
|
|
2009
|
+
try {
|
|
2010
|
+
const raw = centralDb.getMeta("machines");
|
|
2011
|
+
if (raw)
|
|
2012
|
+
machines = JSON.parse(raw);
|
|
2013
|
+
}
|
|
2014
|
+
catch { /* fresh start */ }
|
|
2015
|
+
machines[hostname] = { version: currentVersion, lastSeen: new Date().toISOString() };
|
|
2016
|
+
centralDb.setMeta("machines", JSON.stringify(machines));
|
|
2017
|
+
centralDb.close();
|
|
2018
|
+
}
|
|
2019
|
+
}
|
|
2020
|
+
catch {
|
|
2021
|
+
// non-critical
|
|
2022
|
+
}
|
|
2023
|
+
// 5. Report
|
|
2024
|
+
console.log("");
|
|
2025
|
+
if (upgraded.length > 0) {
|
|
2026
|
+
console.log(`Upgraded (${upgraded.length}):`);
|
|
2027
|
+
for (const p of upgraded)
|
|
2028
|
+
console.log(` ✓ ${path.basename(p)} — ${p}`);
|
|
2029
|
+
}
|
|
2030
|
+
if (skipped.length > 0) {
|
|
2031
|
+
console.log(`\nSkipped — not on this machine (${skipped.length}):`);
|
|
2032
|
+
for (const p of skipped)
|
|
2033
|
+
console.log(` ○ ${path.basename(p)} — ${p}`);
|
|
2034
|
+
}
|
|
2035
|
+
if (failed.length > 0) {
|
|
2036
|
+
console.log(`\nFailed (${failed.length}):`);
|
|
2037
|
+
for (const f of failed)
|
|
2038
|
+
console.log(` ✗ ${f}`);
|
|
2039
|
+
}
|
|
2040
|
+
console.log(`\nDone. Central DB stamped with v${currentVersion}.`);
|
|
2041
|
+
// Show machine status from shared DB
|
|
2042
|
+
try {
|
|
2043
|
+
const centralDb = GnosysDB.openCentral();
|
|
2044
|
+
if (centralDb.isAvailable()) {
|
|
2045
|
+
const raw = centralDb.getMeta("machines");
|
|
2046
|
+
if (raw) {
|
|
2047
|
+
const machines = JSON.parse(raw);
|
|
2048
|
+
const entries = Object.entries(machines);
|
|
2049
|
+
if (entries.length > 1) {
|
|
2050
|
+
console.log(`\nConnected machines:`);
|
|
2051
|
+
for (const [host, info] of entries) {
|
|
2052
|
+
const isCurrent = host === os.hostname();
|
|
2053
|
+
const status = info.version === currentVersion ? "✓" : `⚠ v${info.version}`;
|
|
2054
|
+
console.log(` ${status} ${host}${isCurrent ? " (this machine)" : ""} — last seen ${info.lastSeen.split("T")[0]}`);
|
|
2055
|
+
}
|
|
2056
|
+
const behind = entries.filter(([, info]) => info.version !== currentVersion);
|
|
2057
|
+
if (behind.length > 0) {
|
|
2058
|
+
console.log(`\n ${behind.length} machine(s) need upgrading. Run 'npm install -g gnosys && gnosys upgrade' on each.`);
|
|
2059
|
+
}
|
|
2060
|
+
}
|
|
2061
|
+
}
|
|
2062
|
+
centralDb.close();
|
|
2063
|
+
}
|
|
2064
|
+
}
|
|
2065
|
+
catch {
|
|
2066
|
+
// non-critical
|
|
2067
|
+
}
|
|
2068
|
+
if (skipped.length > 0) {
|
|
2069
|
+
console.log(`\nNote: ${skipped.length} project(s) not found on this machine.`);
|
|
2070
|
+
console.log(`If they exist on another machine, run 'gnosys upgrade' there too.`);
|
|
2071
|
+
}
|
|
2072
|
+
});
|
|
1890
2073
|
// ─── gnosys doctor ──────────────────────────────────────────────────────
|
|
1891
2074
|
program
|
|
1892
2075
|
.command("doctor")
|