gnosys 5.7.1 → 5.8.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.
Files changed (47) hide show
  1. package/README.md +14 -0
  2. package/dist/cli.js +61 -9
  3. package/dist/cli.js.map +1 -1
  4. package/dist/index.js +71 -21
  5. package/dist/index.js.map +1 -1
  6. package/dist/lib/ask.d.ts.map +1 -1
  7. package/dist/lib/ask.js +20 -4
  8. package/dist/lib/ask.js.map +1 -1
  9. package/dist/lib/chat/SlashPalette.d.ts +34 -0
  10. package/dist/lib/chat/SlashPalette.d.ts.map +1 -0
  11. package/dist/lib/chat/SlashPalette.js +49 -0
  12. package/dist/lib/chat/SlashPalette.js.map +1 -0
  13. package/dist/lib/chat/index.d.ts.map +1 -1
  14. package/dist/lib/chat/index.js +6 -4
  15. package/dist/lib/chat/index.js.map +1 -1
  16. package/dist/lib/chat/llmTurn.d.ts.map +1 -1
  17. package/dist/lib/chat/llmTurn.js +4 -1
  18. package/dist/lib/chat/llmTurn.js.map +1 -1
  19. package/dist/lib/chat/render.d.ts.map +1 -1
  20. package/dist/lib/chat/render.js +91 -10
  21. package/dist/lib/chat/render.js.map +1 -1
  22. package/dist/lib/config.d.ts +25 -1
  23. package/dist/lib/config.d.ts.map +1 -1
  24. package/dist/lib/config.js +30 -0
  25. package/dist/lib/config.js.map +1 -1
  26. package/dist/lib/db.d.ts +1 -0
  27. package/dist/lib/db.d.ts.map +1 -1
  28. package/dist/lib/db.js +8 -5
  29. package/dist/lib/db.js.map +1 -1
  30. package/dist/lib/import.d.ts.map +1 -1
  31. package/dist/lib/import.js +2 -1
  32. package/dist/lib/import.js.map +1 -1
  33. package/dist/lib/ingest.d.ts +7 -1
  34. package/dist/lib/ingest.d.ts.map +1 -1
  35. package/dist/lib/ingest.js +23 -4
  36. package/dist/lib/ingest.js.map +1 -1
  37. package/dist/lib/llm.d.ts +1 -1
  38. package/dist/lib/llm.d.ts.map +1 -1
  39. package/dist/lib/llm.js.map +1 -1
  40. package/dist/lib/setup/sections/routing.d.ts.map +1 -1
  41. package/dist/lib/setup/sections/routing.js +4 -2
  42. package/dist/lib/setup/sections/routing.js.map +1 -1
  43. package/dist/lib/setup.d.ts +5 -0
  44. package/dist/lib/setup.d.ts.map +1 -1
  45. package/dist/lib/setup.js +127 -0
  46. package/dist/lib/setup.js.map +1 -1
  47. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -65,7 +65,7 @@ import { GnosysDreamEngine, DreamScheduler, formatDreamReport } from "./lib/drea
65
65
  import { GnosysExporter, formatExportReport } from "./lib/export.js";
66
66
  import { createProjectIdentity, readProjectIdentity } from "./lib/projectIdentity.js";
67
67
  import { setPreference, getPreference, getAllPreferences, deletePreference } from "./lib/preferences.js";
68
- import { syncRules } from "./lib/rulesGen.js";
68
+ import { syncRules, generateRulesBlock } from "./lib/rulesGen.js";
69
69
  import { federatedSearch, detectAmbiguity, generateBriefing, generateAllBriefings, getWorkingSet, formatWorkingSet, detectCurrentProject } from "./lib/federated.js";
70
70
  import { generatePortfolio, formatPortfolioCompact, formatPortfolioMarkdown, generateStatusPrompt } from "./lib/portfolio.js";
71
71
  // Initialize resolver (discovers all layered stores)
@@ -513,7 +513,9 @@ server.tool("gnosys_add", "Add a new memory. Accepts raw text — an LLM structu
513
513
  };
514
514
  }
515
515
  try {
516
- const result = await ingestion.ingest(input);
516
+ // v5.8.0 (#8): pass per-call config so the LLM provider resolves against
517
+ // the merged project+global config, not the MCP's boot-time config.
518
+ const result = await ingestion.ingest(input, ctx.config);
517
519
  if (!ctx.centralDb?.isAvailable()) {
518
520
  return {
519
521
  content: [{ type: "text", text: "Database not available. Cannot write memory." }],
@@ -1049,15 +1051,15 @@ server.tool("gnosys_commit_context", "Pre-compaction memory sweep. Call this bef
1049
1051
  projectRoot: projectRootParam,
1050
1052
  }, async ({ context, dry_run, projectRoot }) => {
1051
1053
  const ctx = await resolveToolContext(projectRoot);
1052
- // Note: ingestion is module-level since it's heavy
1053
- if (!ingestion || !ingestion.isLLMAvailable) {
1054
+ // v5.8.0 (#8): no early-gate on the module-level `ingestion` here.
1055
+ // It's bound to the MCP's boot-time config — which may not have an LLM
1056
+ // block on the directory we launched in. The real LLM resolution
1057
+ // happens against `ctx.config` (merged project+global) below; if that
1058
+ // can't find a provider, getLLMProvider() surfaces a provider-specific
1059
+ // error message.
1060
+ if (!ingestion) {
1054
1061
  return {
1055
- content: [
1056
- {
1057
- type: "text",
1058
- text: "Commit context requires an LLM. Configure a provider in gnosys.json or set ANTHROPIC_API_KEY.",
1059
- },
1060
- ],
1062
+ content: [{ type: "text", text: "Ingestion module not initialized." }],
1061
1063
  isError: true,
1062
1064
  };
1063
1065
  }
@@ -1147,7 +1149,7 @@ Output ONLY the JSON array, no markdown fences.`,
1147
1149
  results.push(`❌ FAILED: "${candidate.summary}": Database not available`);
1148
1150
  continue;
1149
1151
  }
1150
- const result = await ingestion.ingest(candidate.summary);
1152
+ const result = await ingestion.ingest(candidate.summary, ctx.config);
1151
1153
  const id = ctx.centralDb.getNextId(result.category, ctx.projectId ?? undefined);
1152
1154
  const today = new Date().toISOString().split("T")[0];
1153
1155
  const frontmatter = {
@@ -2138,7 +2140,11 @@ server.tool("gnosys_preference_set", "Set a user preference. Preferences are sto
2138
2140
  return {
2139
2141
  content: [{
2140
2142
  type: "text",
2141
- text: `Preference set: **${pref.title}**\n Key: ${pref.key}\n Value: ${pref.value}\n\nRun \`gnosys_sync\` to regenerate agent rules files with this preference.`,
2143
+ // v5.8.0 (#9): no longer suggest running gnosys_sync. The
2144
+ // SessionStart hook (gnosys recall) already injects preferences
2145
+ // into the next session's context — no need to rewrite tracked
2146
+ // files like CLAUDE.md.
2147
+ text: `Preference set: **${pref.title}**\n Key: ${pref.key}\n Value: ${pref.value}`,
2142
2148
  }],
2143
2149
  };
2144
2150
  }
@@ -2211,14 +2217,31 @@ server.tool("gnosys_preference_delete", "Delete a user preference by key.", {
2211
2217
  return {
2212
2218
  content: [{
2213
2219
  type: "text",
2214
- text: `Preference "${key}" deleted. Run \`gnosys_sync\` to update agent rules files.`,
2220
+ // v5.8.0 (#9): drop the gnosys_sync suggestion SessionStart
2221
+ // hook picks up the change next time without rewriting tracked files.
2222
+ text: `Preference "${key}" deleted.`,
2215
2223
  }],
2216
2224
  };
2217
2225
  });
2218
2226
  // ─── Tool: gnosys_sync ──────────────────────────────────────────────────
2219
- server.tool("gnosys_sync", "Regenerate agent rules file from current user preferences and project conventions. Injects a GNOSYS:START/GNOSYS:END block into the detected agent rules file (CLAUDE.md, .cursor/rules/gnosys.mdc). User content outside the block is preserved.", {
2227
+ //
2228
+ // v5.8.0 (#9): inert-by-default. Previously this tool always wrote a
2229
+ // GNOSYS:START/GNOSYS:END block into the project's CLAUDE.md (a tracked
2230
+ // file in most repos), producing phantom git diffs every time an agent
2231
+ // helpfully called it after a preference change. Now the default is
2232
+ // "return the rules block as text" — the agent can use that as in-context
2233
+ // guidance without touching disk. To actually rewrite the rules file
2234
+ // (the v5.7.0 behaviour), pass `commit_to_disk: true` explicitly.
2235
+ //
2236
+ // Routine in-session context flows through the SessionStart hook
2237
+ // (`gnosys recall`), not through this tool.
2238
+ server.tool("gnosys_sync", "Get the current user preferences + project conventions formatted as a GNOSYS:START/GNOSYS:END block. By default returns the block as text only (no disk write). Pass commit_to_disk=true to write it into the detected agent rules file (CLAUDE.md, .cursor/rules/gnosys.mdc) — only do this if the user has explicitly asked to refresh the rules file. Routine session context is already injected via the SessionStart hook (`gnosys recall`); do NOT call this tool after every preference change.", {
2220
2239
  projectRoot: projectRootParam,
2221
- }, async ({ projectRoot }) => {
2240
+ commit_to_disk: z
2241
+ .boolean()
2242
+ .optional()
2243
+ .describe("If true, write the block into the detected agent rules file on disk. Default: false (text only). Note: rules files like CLAUDE.md and .cursor/rules/*.mdc are typically tracked in git, so writing creates a diff."),
2244
+ }, async ({ projectRoot, commit_to_disk }) => {
2222
2245
  if (!centralDb?.isAvailable()) {
2223
2246
  return {
2224
2247
  content: [{ type: "text", text: "Central DB not available. Cannot sync rules." }],
@@ -2243,12 +2266,36 @@ server.tool("gnosys_sync", "Regenerate agent rules file from current user prefer
2243
2266
  isError: true,
2244
2267
  };
2245
2268
  }
2269
+ const preferences = getAllPreferences(centralDb);
2270
+ let projectConventions = [];
2271
+ if (identity.projectId) {
2272
+ const projectMems = centralDb.getMemoriesByProject(identity.projectId);
2273
+ projectConventions = projectMems.filter((m) => (m.category === "decisions" || m.category === "conventions") && m.status === "active");
2274
+ }
2275
+ const block = generateRulesBlock(preferences, projectConventions);
2276
+ // Default path: return the block as text, no disk write.
2277
+ if (!commit_to_disk) {
2278
+ return {
2279
+ content: [
2280
+ {
2281
+ type: "text",
2282
+ text: `Rules block (preview, not written to disk):\n\n${block}\n\n` +
2283
+ `Summary: ${preferences.length} preference(s), ${projectConventions.length} project convention(s).\n` +
2284
+ `To write this into ${identity.agentRulesTarget || "the agent rules file"}, call gnosys_sync again with commit_to_disk=true.\n` +
2285
+ `(SessionStart hook 'gnosys recall' already provides routine session context — usually no disk write is needed.)`,
2286
+ },
2287
+ ],
2288
+ };
2289
+ }
2290
+ // Opt-in disk write path.
2246
2291
  if (!identity.agentRulesTarget) {
2247
2292
  return {
2248
- content: [{
2293
+ content: [
2294
+ {
2249
2295
  type: "text",
2250
- text: "No agent rules target detected (no .cursor/ or CLAUDE.md found). Create one of these first, then re-run gnosys_init to detect it.",
2251
- }],
2296
+ text: "commit_to_disk=true requested, but no agent rules target detected (no .cursor/ or CLAUDE.md found). Create one first, then re-run gnosys_init to detect it.",
2297
+ },
2298
+ ],
2252
2299
  };
2253
2300
  }
2254
2301
  const result = await syncRules(centralDb, projectDir, identity.agentRulesTarget, identity.projectId);
@@ -2260,10 +2307,13 @@ server.tool("gnosys_sync", "Regenerate agent rules file from current user prefer
2260
2307
  }
2261
2308
  const action = result.created ? "Created" : "Updated";
2262
2309
  return {
2263
- content: [{
2310
+ content: [
2311
+ {
2264
2312
  type: "text",
2265
- text: `${action} rules file: ${result.filePath}\n\n Preferences injected: ${result.prefCount}\n Project conventions: ${result.conventionCount}\n\nContent is inside <!-- GNOSYS:START --> / <!-- GNOSYS:END --> markers.\nUser content outside these markers is preserved.`,
2266
- }],
2313
+ text: `${action} rules file: ${result.filePath}\n\n Preferences injected: ${result.prefCount}\n Project conventions: ${result.conventionCount}\n\n` +
2314
+ `⚠ This wrote to a file that may be tracked in git — expect a diff. Routine session context flows through the SessionStart hook; only call gnosys_sync with commit_to_disk=true when the user explicitly asks to refresh the rules file.`,
2315
+ },
2316
+ ],
2267
2317
  };
2268
2318
  });
2269
2319
  // ─── Tool: gnosys_federated_search ───────────────────────────────────────