gnosys 5.2.8 → 5.2.11

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/index.js CHANGED
@@ -816,27 +816,37 @@ server.tool("gnosys_update", "Update an existing memory's frontmatter and/or con
816
816
  projectRoot: projectRootParam,
817
817
  }, async ({ path: memPath, title, tags, status, confidence, relevance, supersedes, superseded_by, content: newContent, projectRoot, }) => {
818
818
  const ctx = await resolveToolContext(projectRoot);
819
- const memory = await ctx.resolver.readMemory(memPath);
820
- if (!memory) {
819
+ if (!ctx.centralDb?.isAvailable()) {
821
820
  return {
822
- content: [{ type: "text", text: `Memory not found: ${memPath}` }],
821
+ content: [{ type: "text", text: "Database not available. Cannot update memory." }],
823
822
  isError: true,
824
823
  };
825
824
  }
826
- // Find the source store and check if writable
827
- const sourceStore = ctx.resolver
828
- .getStores()
829
- .find((s) => s.label === memory.sourceLabel);
830
- if (!sourceStore?.writable) {
831
- return {
832
- content: [
833
- {
834
- type: "text",
835
- text: `Cannot update: store [${memory.sourceLabel}] is read-only.`,
836
- },
837
- ],
838
- isError: true,
839
- };
825
+ // DB-first lookup: resolve memory ID from central DB (mirrors gnosys_read pattern)
826
+ let memoryId;
827
+ let currentTitle;
828
+ const dbMem = ctx.centralDb.getMemory(memPath);
829
+ if (dbMem) {
830
+ memoryId = dbMem.id;
831
+ currentTitle = dbMem.title;
832
+ }
833
+ else {
834
+ // Fallback to legacy file resolver
835
+ const memory = await ctx.resolver.readMemory(memPath);
836
+ if (!memory) {
837
+ return {
838
+ content: [{ type: "text", text: `Memory not found: ${memPath}` }],
839
+ isError: true,
840
+ };
841
+ }
842
+ if (!memory.frontmatter.id) {
843
+ return {
844
+ content: [{ type: "text", text: `Memory has no ID: ${memPath}` }],
845
+ isError: true,
846
+ };
847
+ }
848
+ memoryId = memory.frontmatter.id;
849
+ currentTitle = memory.frontmatter.title || memPath;
840
850
  }
841
851
  // Build updates object — only include defined fields
842
852
  const updates = {};
@@ -854,20 +864,7 @@ server.tool("gnosys_update", "Update an existing memory's frontmatter and/or con
854
864
  updates.supersedes = supersedes;
855
865
  if (superseded_by !== undefined)
856
866
  updates.superseded_by = superseded_by;
857
- const fullContent = newContent ? `# ${title || memory.frontmatter.title}\n\n${newContent}` : undefined;
858
- const memoryId = memory.frontmatter.id;
859
- if (!memoryId) {
860
- return {
861
- content: [{ type: "text", text: `Memory has no ID: ${memPath}` }],
862
- isError: true,
863
- };
864
- }
865
- if (!ctx.centralDb?.isAvailable()) {
866
- return {
867
- content: [{ type: "text", text: "Database not available. Cannot update memory." }],
868
- isError: true,
869
- };
870
- }
867
+ const fullContent = newContent ? `# ${title || currentTitle}\n\n${newContent}` : undefined;
871
868
  // Write update to DB only (SQLite is sole source of truth)
872
869
  syncUpdateToDb(ctx.centralDb, memoryId, updates, fullContent);
873
870
  auditToDb(ctx.centralDb, "write", memoryId, { tool: "gnosys_update", changed: Object.keys(updates) });
@@ -881,7 +878,7 @@ server.tool("gnosys_update", "Update an existing memory's frontmatter and/or con
881
878
  const changedFields = Object.keys(updates);
882
879
  if (newContent)
883
880
  changedFields.push("content");
884
- const updatedTitle = title || memory.frontmatter.title;
881
+ const updatedTitle = title || currentTitle;
885
882
  return {
886
883
  content: [
887
884
  {
@@ -1102,6 +1099,30 @@ server.tool("gnosys_history", "View version history for a memory. Shows what cha
1102
1099
  projectRoot: projectRootParam,
1103
1100
  }, async ({ path: memPath, limit, projectRoot }) => {
1104
1101
  const ctx = await resolveToolContext(projectRoot);
1102
+ // DB-first: resolve memory ID and show timestamps
1103
+ if (ctx.centralDb?.isAvailable()) {
1104
+ const dbMem = ctx.centralDb.getMemory(memPath);
1105
+ if (dbMem) {
1106
+ // Query audit_log for this memory
1107
+ const audits = ctx.centralDb.getAuditLog(dbMem.id, limit || 20);
1108
+ if (audits.length > 0) {
1109
+ const lines = audits.map((e) => `- ${e.timestamp.split("T")[0]} — ${e.operation}${e.details ? ` (${e.details})` : ""}`);
1110
+ return {
1111
+ content: [{
1112
+ type: "text",
1113
+ text: `History for **${dbMem.title}** (${dbMem.id}, ${audits.length} entries):\n\nCreated: ${dbMem.created}\nModified: ${dbMem.modified}\n\n${lines.join("\n")}`,
1114
+ }],
1115
+ };
1116
+ }
1117
+ return {
1118
+ content: [{
1119
+ type: "text",
1120
+ text: `Memory found: **${dbMem.title}** (${dbMem.id})\nCreated: ${dbMem.created}\nModified: ${dbMem.modified}\nNo audit history recorded.`,
1121
+ }],
1122
+ };
1123
+ }
1124
+ }
1125
+ // Legacy file-based fallback
1105
1126
  const memory = await ctx.resolver.readMemory(memPath);
1106
1127
  if (!memory) {
1107
1128
  return { content: [{ type: "text", text: `Memory not found: ${memPath}` }], isError: true };
@@ -1261,6 +1282,34 @@ server.tool("gnosys_links", "Show wikilinks for a specific memory — outgoing [
1261
1282
  projectRoot: projectRootParam,
1262
1283
  }, async ({ path: memPath, projectRoot }) => {
1263
1284
  const ctx = await resolveToolContext(projectRoot);
1285
+ // DB-first: resolve memory ID and check relationships table
1286
+ if (ctx.centralDb?.isAvailable()) {
1287
+ const dbMem = ctx.centralDb.getMemory(memPath);
1288
+ if (dbMem) {
1289
+ const outRels = ctx.centralDb.getRelationshipsFrom(dbMem.id);
1290
+ const inRels = ctx.centralDb.getRelationshipsTo(dbMem.id);
1291
+ if (outRels.length > 0 || inRels.length > 0) {
1292
+ const parts = [`Links for **${dbMem.title}** (${dbMem.id}):\n`];
1293
+ if (outRels.length > 0) {
1294
+ parts.push(`Outgoing (${outRels.length}):`);
1295
+ for (const r of outRels) {
1296
+ const target = ctx.centralDb.getMemory(r.target_id);
1297
+ parts.push(` → ${r.rel_type} → ${target ? target.title : r.target_id}`);
1298
+ }
1299
+ }
1300
+ if (inRels.length > 0) {
1301
+ parts.push(`\nIncoming (${inRels.length}):`);
1302
+ for (const r of inRels) {
1303
+ const source = ctx.centralDb.getMemory(r.source_id);
1304
+ parts.push(` ← ${r.rel_type} ← ${source ? source.title : r.source_id}`);
1305
+ }
1306
+ }
1307
+ return { content: [{ type: "text", text: parts.join("\n") }] };
1308
+ }
1309
+ return { content: [{ type: "text", text: `Memory found: **${dbMem.title}** (${dbMem.id})\nNo links or relationships recorded.` }] };
1310
+ }
1311
+ }
1312
+ // Legacy file-based fallback
1264
1313
  const memory = await ctx.resolver.readMemory(memPath);
1265
1314
  if (!memory) {
1266
1315
  return { content: [{ type: "text", text: `Memory not found: ${memPath}` }], isError: true };