gnosys 5.11.4 → 5.12.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.
Files changed (265) hide show
  1. package/dist/cli.js +377 -5162
  2. package/dist/index.js +542 -244
  3. package/dist/lib/addCommand.d.ts +9 -0
  4. package/dist/lib/addCommand.js +102 -0
  5. package/dist/lib/addStructuredCommand.d.ts +16 -0
  6. package/dist/lib/addStructuredCommand.js +103 -0
  7. package/dist/lib/ambiguityCommand.d.ts +4 -0
  8. package/dist/lib/ambiguityCommand.js +36 -0
  9. package/dist/lib/apiKeyVault.d.ts +78 -0
  10. package/dist/lib/apiKeyVault.js +447 -0
  11. package/dist/lib/archive.js +0 -2
  12. package/dist/lib/askCommand.d.ts +13 -0
  13. package/dist/lib/askCommand.js +145 -0
  14. package/dist/lib/attachCommand.d.ts +17 -0
  15. package/dist/lib/attachCommand.js +66 -0
  16. package/dist/lib/attachments.d.ts +43 -2
  17. package/dist/lib/attachments.js +81 -2
  18. package/dist/lib/audioExtract.js +4 -1
  19. package/dist/lib/auditCommand.d.ts +7 -0
  20. package/dist/lib/auditCommand.js +27 -0
  21. package/dist/lib/backupCommand.d.ts +6 -0
  22. package/dist/lib/backupCommand.js +54 -0
  23. package/dist/lib/bootstrapCommand.d.ts +15 -0
  24. package/dist/lib/bootstrapCommand.js +51 -0
  25. package/dist/lib/briefingCommand.d.ts +7 -0
  26. package/dist/lib/briefingCommand.js +92 -0
  27. package/dist/lib/centralizeCommand.d.ts +5 -0
  28. package/dist/lib/centralizeCommand.js +16 -0
  29. package/dist/lib/chat/choose.js +2 -2
  30. package/dist/lib/chatCommand.d.ts +12 -0
  31. package/dist/lib/chatCommand.js +46 -0
  32. package/dist/lib/checkCommand.d.ts +4 -0
  33. package/dist/lib/checkCommand.js +133 -0
  34. package/dist/lib/clientReadOverlay.d.ts +27 -0
  35. package/dist/lib/clientReadOverlay.js +76 -0
  36. package/dist/lib/clientReadResolve.d.ts +32 -0
  37. package/dist/lib/clientReadResolve.js +84 -0
  38. package/dist/lib/commitContextCommand.d.ts +9 -0
  39. package/dist/lib/commitContextCommand.js +142 -0
  40. package/dist/lib/config.d.ts +41 -48
  41. package/dist/lib/config.js +58 -57
  42. package/dist/lib/configCommand.d.ts +10 -0
  43. package/dist/lib/configCommand.js +321 -0
  44. package/dist/lib/connectCommand.d.ts +8 -0
  45. package/dist/lib/connectCommand.js +19 -0
  46. package/dist/lib/db.d.ts +68 -1
  47. package/dist/lib/db.js +385 -120
  48. package/dist/lib/dbWrite.d.ts +1 -1
  49. package/dist/lib/dearchiveCommand.d.ts +7 -0
  50. package/dist/lib/dearchiveCommand.js +41 -0
  51. package/dist/lib/discoverCommand.d.ts +9 -0
  52. package/dist/lib/discoverCommand.js +87 -0
  53. package/dist/lib/doctorCommand.d.ts +6 -0
  54. package/dist/lib/doctorCommand.js +256 -0
  55. package/dist/lib/docxExtract.js +1 -1
  56. package/dist/lib/dream.d.ts +50 -2
  57. package/dist/lib/dream.js +324 -30
  58. package/dist/lib/dreamCommand.d.ts +10 -0
  59. package/dist/lib/dreamCommand.js +195 -0
  60. package/dist/lib/dreamLaunchd.d.ts +2 -0
  61. package/dist/lib/dreamLaunchd.js +72 -0
  62. package/dist/lib/dreamLogCommand.d.ts +10 -0
  63. package/dist/lib/dreamLogCommand.js +58 -0
  64. package/dist/lib/dreamReport.d.ts +7 -0
  65. package/dist/lib/dreamReport.js +114 -0
  66. package/dist/lib/dreamRunLog.d.ts +121 -0
  67. package/dist/lib/dreamRunLog.js +234 -0
  68. package/dist/lib/embeddings.js +3 -3
  69. package/dist/lib/exportCommand.d.ts +18 -0
  70. package/dist/lib/exportCommand.js +101 -0
  71. package/dist/lib/exportProject.d.ts +3 -2
  72. package/dist/lib/exportProject.js +2 -1
  73. package/dist/lib/federated.js +1 -1
  74. package/dist/lib/fsearchCommand.d.ts +8 -0
  75. package/dist/lib/fsearchCommand.js +44 -0
  76. package/dist/lib/graphCommand.d.ts +4 -0
  77. package/dist/lib/graphCommand.js +68 -0
  78. package/dist/lib/helperGenerateCommand.d.ts +5 -0
  79. package/dist/lib/helperGenerateCommand.js +27 -0
  80. package/dist/lib/historyCommand.d.ts +5 -0
  81. package/dist/lib/historyCommand.js +51 -0
  82. package/dist/lib/hybridSearchCommand.d.ts +12 -0
  83. package/dist/lib/hybridSearchCommand.js +95 -0
  84. package/dist/lib/importCommand.d.ts +16 -0
  85. package/dist/lib/importCommand.js +89 -0
  86. package/dist/lib/importProject.js +2 -1
  87. package/dist/lib/importProjectCommand.d.ts +6 -0
  88. package/dist/lib/importProjectCommand.js +43 -0
  89. package/dist/lib/ingestCommand.d.ts +13 -0
  90. package/dist/lib/ingestCommand.js +95 -0
  91. package/dist/lib/installOutput.d.ts +36 -0
  92. package/dist/lib/installOutput.js +55 -0
  93. package/dist/lib/lensCommand.d.ts +20 -0
  94. package/dist/lib/lensCommand.js +61 -0
  95. package/dist/lib/lensing.d.ts +1 -0
  96. package/dist/lib/lensing.js +50 -9
  97. package/dist/lib/linksCommand.d.ts +7 -0
  98. package/dist/lib/linksCommand.js +48 -0
  99. package/dist/lib/listCommand.d.ts +8 -0
  100. package/dist/lib/listCommand.js +74 -0
  101. package/dist/lib/llm.d.ts +1 -1
  102. package/dist/lib/llm.js +27 -9
  103. package/dist/lib/localDiskCheck.d.ts +17 -0
  104. package/dist/lib/localDiskCheck.js +54 -0
  105. package/dist/lib/lock.d.ts +1 -1
  106. package/dist/lib/lock.js +5 -3
  107. package/dist/lib/machineConfig.d.ts +11 -1
  108. package/dist/lib/machineConfig.js +16 -0
  109. package/dist/lib/machineRegistry.d.ts +61 -0
  110. package/dist/lib/machineRegistry.js +80 -0
  111. package/dist/lib/maintainCommand.d.ts +8 -0
  112. package/dist/lib/maintainCommand.js +34 -0
  113. package/dist/lib/masterLease.d.ts +20 -0
  114. package/dist/lib/masterLease.js +68 -0
  115. package/dist/lib/migrate.js +0 -1
  116. package/dist/lib/migrateCommand.d.ts +7 -0
  117. package/dist/lib/migrateCommand.js +158 -0
  118. package/dist/lib/migrateDbCommand.d.ts +9 -0
  119. package/dist/lib/migrateDbCommand.js +94 -0
  120. package/dist/lib/modelValidation.d.ts +5 -0
  121. package/dist/lib/modelValidation.js +27 -0
  122. package/dist/lib/multimodalIngest.js +1 -1
  123. package/dist/lib/openrouterTiers.d.ts +29 -0
  124. package/dist/lib/openrouterTiers.js +113 -0
  125. package/dist/lib/platform.d.ts +0 -6
  126. package/dist/lib/platform.js +0 -28
  127. package/dist/lib/prefCommand.d.ts +10 -0
  128. package/dist/lib/prefCommand.js +118 -0
  129. package/dist/lib/projectsCommand.d.ts +8 -0
  130. package/dist/lib/projectsCommand.js +131 -0
  131. package/dist/lib/readCommand.d.ts +7 -0
  132. package/dist/lib/readCommand.js +63 -0
  133. package/dist/lib/recall.d.ts +3 -0
  134. package/dist/lib/recall.js +19 -4
  135. package/dist/lib/recallCommand.d.ts +11 -0
  136. package/dist/lib/recallCommand.js +112 -0
  137. package/dist/lib/reflectCommand.d.ts +8 -0
  138. package/dist/lib/reflectCommand.js +61 -0
  139. package/dist/lib/reindexCommand.d.ts +4 -0
  140. package/dist/lib/reindexCommand.js +34 -0
  141. package/dist/lib/reindexGraphCommand.d.ts +4 -0
  142. package/dist/lib/reindexGraphCommand.js +12 -0
  143. package/dist/lib/reinforceCommand.d.ts +8 -0
  144. package/dist/lib/reinforceCommand.js +40 -0
  145. package/dist/lib/remote.d.ts +5 -1
  146. package/dist/lib/remote.js +5 -1
  147. package/dist/lib/remoteWizard.d.ts +24 -5
  148. package/dist/lib/remoteWizard.js +308 -319
  149. package/dist/lib/restoreCommand.d.ts +5 -0
  150. package/dist/lib/restoreCommand.js +35 -0
  151. package/dist/lib/rulesGen.d.ts +8 -0
  152. package/dist/lib/rulesGen.js +16 -0
  153. package/dist/lib/sandboxStartCommand.d.ts +6 -0
  154. package/dist/lib/sandboxStartCommand.js +25 -0
  155. package/dist/lib/sandboxStatusCommand.d.ts +4 -0
  156. package/dist/lib/sandboxStatusCommand.js +24 -0
  157. package/dist/lib/sandboxStopCommand.d.ts +4 -0
  158. package/dist/lib/sandboxStopCommand.js +21 -0
  159. package/dist/lib/search.d.ts +0 -2
  160. package/dist/lib/search.js +0 -7
  161. package/dist/lib/searchCommand.d.ts +9 -0
  162. package/dist/lib/searchCommand.js +90 -0
  163. package/dist/lib/semanticSearchCommand.d.ts +8 -0
  164. package/dist/lib/semanticSearchCommand.js +52 -0
  165. package/dist/lib/setup/configSetRender.js +2 -0
  166. package/dist/lib/setup/providerGlyphs.d.ts +19 -0
  167. package/dist/lib/setup/providerGlyphs.js +42 -0
  168. package/dist/lib/setup/remoteRender.d.ts +31 -1
  169. package/dist/lib/setup/remoteRender.js +95 -4
  170. package/dist/lib/setup/sections/providers.d.ts +17 -0
  171. package/dist/lib/setup/sections/providers.js +307 -0
  172. package/dist/lib/setup/sections/routing.d.ts +2 -6
  173. package/dist/lib/setup/sections/routing.js +67 -82
  174. package/dist/lib/setup/sections/taskRoutingEditor.d.ts +13 -0
  175. package/dist/lib/setup/sections/taskRoutingEditor.js +139 -0
  176. package/dist/lib/setup/summary.d.ts +9 -0
  177. package/dist/lib/setup/summary.js +51 -37
  178. package/dist/lib/setup/ui/header.js +0 -1
  179. package/dist/lib/setup.d.ts +105 -15
  180. package/dist/lib/setup.js +747 -287
  181. package/dist/lib/setupKeys.d.ts +42 -0
  182. package/dist/lib/setupKeys.js +564 -0
  183. package/dist/lib/setupRemoteCommand.d.ts +4 -0
  184. package/dist/lib/setupRemoteCommand.js +28 -0
  185. package/dist/lib/setupRemotePullCommand.d.ts +5 -0
  186. package/dist/lib/setupRemotePullCommand.js +52 -0
  187. package/dist/lib/setupRemotePushCommand.d.ts +5 -0
  188. package/dist/lib/setupRemotePushCommand.js +57 -0
  189. package/dist/lib/setupRemoteResolveCommand.d.ts +4 -0
  190. package/dist/lib/setupRemoteResolveCommand.js +48 -0
  191. package/dist/lib/setupRemoteStatusCommand.d.ts +4 -0
  192. package/dist/lib/setupRemoteStatusCommand.js +73 -0
  193. package/dist/lib/setupRemoteSyncCommand.d.ts +6 -0
  194. package/dist/lib/setupRemoteSyncCommand.js +65 -0
  195. package/dist/lib/setupSyncProjectsCommand.d.ts +4 -0
  196. package/dist/lib/setupSyncProjectsCommand.js +292 -0
  197. package/dist/lib/staleCommand.d.ts +8 -0
  198. package/dist/lib/staleCommand.js +34 -0
  199. package/dist/lib/statsCommand.d.ts +6 -0
  200. package/dist/lib/statsCommand.js +142 -0
  201. package/dist/lib/statusCommand.d.ts +18 -0
  202. package/dist/lib/statusCommand.js +250 -0
  203. package/dist/lib/storesCommand.d.ts +2 -0
  204. package/dist/lib/storesCommand.js +4 -0
  205. package/dist/lib/syncClient.d.ts +41 -0
  206. package/dist/lib/syncClient.js +234 -0
  207. package/dist/lib/syncCommand.d.ts +6 -0
  208. package/dist/lib/syncCommand.js +57 -0
  209. package/dist/lib/syncDoctorCommand.d.ts +5 -0
  210. package/dist/lib/syncDoctorCommand.js +100 -0
  211. package/dist/lib/syncIngest.d.ts +30 -0
  212. package/dist/lib/syncIngest.js +175 -0
  213. package/dist/lib/syncIngestLaunchd.d.ts +8 -0
  214. package/dist/lib/syncIngestLaunchd.js +93 -0
  215. package/dist/lib/syncIngestStartup.d.ts +5 -0
  216. package/dist/lib/syncIngestStartup.js +29 -0
  217. package/dist/lib/syncIngestSystemd.d.ts +10 -0
  218. package/dist/lib/syncIngestSystemd.js +97 -0
  219. package/dist/lib/syncIngestTimer.d.ts +8 -0
  220. package/dist/lib/syncIngestTimer.js +27 -0
  221. package/dist/lib/syncIngestTimerCommand.d.ts +7 -0
  222. package/dist/lib/syncIngestTimerCommand.js +83 -0
  223. package/dist/lib/syncLock.d.ts +6 -0
  224. package/dist/lib/syncLock.js +74 -0
  225. package/dist/lib/syncSnapshot.d.ts +32 -0
  226. package/dist/lib/syncSnapshot.js +188 -0
  227. package/dist/lib/syncStaging.d.ts +79 -0
  228. package/dist/lib/syncStaging.js +237 -0
  229. package/dist/lib/tagsAddCommand.d.ts +8 -0
  230. package/dist/lib/tagsAddCommand.js +18 -0
  231. package/dist/lib/tagsCommand.d.ts +4 -0
  232. package/dist/lib/tagsCommand.js +16 -0
  233. package/dist/lib/timelineCommand.d.ts +7 -0
  234. package/dist/lib/timelineCommand.js +49 -0
  235. package/dist/lib/traceCommand.d.ts +6 -0
  236. package/dist/lib/traceCommand.js +39 -0
  237. package/dist/lib/traverseCommand.d.ts +6 -0
  238. package/dist/lib/traverseCommand.js +58 -0
  239. package/dist/lib/updateCommand.d.ts +13 -0
  240. package/dist/lib/updateCommand.js +67 -0
  241. package/dist/lib/updateStatusCommand.d.ts +5 -0
  242. package/dist/lib/updateStatusCommand.js +38 -0
  243. package/dist/lib/webAddCommand.d.ts +8 -0
  244. package/dist/lib/webAddCommand.js +55 -0
  245. package/dist/lib/webBuildCommand.d.ts +10 -0
  246. package/dist/lib/webBuildCommand.js +65 -0
  247. package/dist/lib/webBuildIndexCommand.d.ts +8 -0
  248. package/dist/lib/webBuildIndexCommand.js +37 -0
  249. package/dist/lib/webIndex.js +0 -1
  250. package/dist/lib/webIngestCommand.d.ts +11 -0
  251. package/dist/lib/webIngestCommand.js +51 -0
  252. package/dist/lib/webInitCommand.d.ts +9 -0
  253. package/dist/lib/webInitCommand.js +167 -0
  254. package/dist/lib/webRemoveCommand.d.ts +5 -0
  255. package/dist/lib/webRemoveCommand.js +41 -0
  256. package/dist/lib/webStatusCommand.d.ts +5 -0
  257. package/dist/lib/webStatusCommand.js +94 -0
  258. package/dist/lib/webUpdateCommand.d.ts +7 -0
  259. package/dist/lib/webUpdateCommand.js +72 -0
  260. package/dist/lib/workingSetCommand.d.ts +6 -0
  261. package/dist/lib/workingSetCommand.js +37 -0
  262. package/dist/sandbox/client.js +1 -1
  263. package/dist/sandbox/manager.js +1 -14
  264. package/dist/sandbox/server.js +3 -5
  265. package/package.json +6 -2
@@ -0,0 +1,133 @@
1
+ import path from "path";
2
+ import { loadConfig, DEFAULT_CONFIG, resolveTaskModel, } from "./config.js";
3
+ import { getGnosysHome } from "./paths.js";
4
+ import { getLLMProvider, isProviderAvailable } from "./llm.js";
5
+ export async function runCheckCommand(opts) {
6
+ const projectDir = process.cwd();
7
+ const storePath = path.join(projectDir, ".gnosys");
8
+ const globalStorePath = getGnosysHome();
9
+ // Load config: try project-level first, fall back to global ~/.gnosys/
10
+ let cfg;
11
+ let configSource;
12
+ try {
13
+ const projectCfg = await loadConfig(storePath);
14
+ // Check if it's just defaults (no actual config file) by seeing if dream has been configured
15
+ const hasProjectConfig = projectCfg.dream?.provider !== DEFAULT_CONFIG.dream?.provider ||
16
+ projectCfg.llm?.defaultProvider !== DEFAULT_CONFIG.llm?.defaultProvider;
17
+ if (hasProjectConfig) {
18
+ cfg = projectCfg;
19
+ configSource = storePath;
20
+ }
21
+ else {
22
+ cfg = await loadConfig(globalStorePath);
23
+ configSource = globalStorePath;
24
+ }
25
+ }
26
+ catch {
27
+ cfg = await loadConfig(globalStorePath);
28
+ configSource = globalStorePath;
29
+ }
30
+ const GREEN = "\x1b[32m";
31
+ const RED = "\x1b[31m";
32
+ const YELLOW = "\x1b[33m";
33
+ const DIM = "\x1b[2m";
34
+ const BOLD = "\x1b[1m";
35
+ const RESET = "\x1b[0m";
36
+ const CHECK = `${GREEN}✓${RESET}`;
37
+ const CROSS = `${RED}✗${RESET}`;
38
+ const WARN = `${YELLOW}⚠${RESET}`;
39
+ console.log(`\n${BOLD}Gnosys LLM Check${RESET} ${DIM}(config: ${configSource})${RESET}\n`);
40
+ const tasks = [
41
+ {
42
+ name: "structuring",
43
+ description: "adding memories, tagging",
44
+ resolve: () => resolveTaskModel(cfg, "structuring"),
45
+ },
46
+ {
47
+ name: "synthesis",
48
+ description: "Q&A answers (gnosys ask)",
49
+ resolve: () => resolveTaskModel(cfg, "synthesis"),
50
+ },
51
+ {
52
+ name: "chat",
53
+ description: "interactive chat (gnosys chat)",
54
+ // Chat reuses the synthesis task's model — surface it under its own name
55
+ // so users can see exactly what their TUI will use.
56
+ resolve: () => resolveTaskModel(cfg, "synthesis"),
57
+ },
58
+ {
59
+ name: "vision",
60
+ description: "images, PDFs",
61
+ resolve: () => resolveTaskModel(cfg, "vision"),
62
+ },
63
+ {
64
+ name: "transcription",
65
+ description: "audio files",
66
+ resolve: () => resolveTaskModel(cfg, "transcription"),
67
+ },
68
+ {
69
+ name: "dream",
70
+ description: "overnight consolidation",
71
+ resolve: () => ({
72
+ provider: cfg.dream?.provider || "ollama",
73
+ model: cfg.dream?.model || "llama3.2",
74
+ }),
75
+ },
76
+ ];
77
+ let passed = 0;
78
+ let failed = 0;
79
+ let skipped = 0;
80
+ // Filter to a single task if --task was given.
81
+ const filteredTasks = opts.task
82
+ ? tasks.filter((t) => t.name === opts.task)
83
+ : tasks;
84
+ if (opts.task && filteredTasks.length === 0) {
85
+ console.error(`Unknown task: ${opts.task}. Pick one of: ${tasks.map((t) => t.name).join(", ")}`);
86
+ process.exit(1);
87
+ }
88
+ for (const task of filteredTasks) {
89
+ const { provider, model } = task.resolve();
90
+ const label = `${task.name.padEnd(16)} ${DIM}${provider} / ${model}${RESET}`;
91
+ const desc = `${DIM}(${task.description})${RESET}`;
92
+ // Special handling for dream — check if enabled
93
+ if (task.name === "dream" && !cfg.dream?.enabled) {
94
+ console.log(` ${WARN} ${label} disabled ${desc}`);
95
+ skipped++;
96
+ continue;
97
+ }
98
+ // Check provider availability (API key, etc.)
99
+ const availability = isProviderAvailable(cfg, provider);
100
+ if (!availability.available) {
101
+ console.log(` ${CROSS} ${label} ${RED}${availability.error}${RESET} ${desc}`);
102
+ failed++;
103
+ continue;
104
+ }
105
+ // Test actual connection with timing
106
+ const start = Date.now();
107
+ try {
108
+ const llmProvider = getLLMProvider({ ...cfg, llm: { ...cfg.llm, defaultProvider: provider } });
109
+ await llmProvider.testConnection();
110
+ const ms = Date.now() - start;
111
+ console.log(` ${CHECK} ${label} ${GREEN}${ms}ms${RESET} ${desc}`);
112
+ passed++;
113
+ }
114
+ catch (err) {
115
+ const ms = Date.now() - start;
116
+ const errMsg = err instanceof Error ? err.message : String(err);
117
+ // Truncate long error messages
118
+ const shortErr = errMsg.length > 60 ? errMsg.slice(0, 57) + "..." : errMsg;
119
+ console.log(` ${CROSS} ${label} ${RED}${shortErr}${RESET} (${ms}ms) ${desc}`);
120
+ failed++;
121
+ }
122
+ }
123
+ console.log();
124
+ const total = passed + failed + skipped;
125
+ if (failed === 0) {
126
+ console.log(`${CHECK} All ${passed}/${total} tasks connected.`);
127
+ }
128
+ else {
129
+ console.log(`${passed}/${total} connected, ${failed} failed${skipped > 0 ? `, ${skipped} skipped` : ""}.`);
130
+ console.log(`\n${DIM}Fix: Run 'gnosys setup' to configure providers and API keys.${RESET}`);
131
+ }
132
+ console.log();
133
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * v13 client read overlay — merge pending-adds into read results.
3
+ */
4
+ import type { DbMemory } from "./db.js";
5
+ export type PendingAddRow = {
6
+ id: string;
7
+ title: string;
8
+ category: string;
9
+ content: string;
10
+ tags: string;
11
+ project_id: string | null;
12
+ scope: string;
13
+ created: string;
14
+ };
15
+ export interface OverlayReadResult {
16
+ memories: DbMemory[];
17
+ overlayCount: number;
18
+ source: string;
19
+ }
20
+ export declare function pendingAddToDbMemory(p: PendingAddRow): DbMemory;
21
+ export declare function applyPendingOverlay(baseMemories: DbMemory[], pendingAdds: PendingAddRow[], ingestedUlids: Set<string>): OverlayReadResult;
22
+ export declare function mergeOverlayDiscoverResults<T extends {
23
+ id: string;
24
+ }>(base: T[], pendingAdds: PendingAddRow[], query: string, limit: number, toRow: (p: PendingAddRow) => T): T[];
25
+ export declare function mergeOverlaySearchResults<T extends {
26
+ id: string;
27
+ }>(base: T[], pendingAdds: PendingAddRow[], query: string, limit: number, toRow: (p: PendingAddRow) => T): T[];
@@ -0,0 +1,76 @@
1
+ /**
2
+ * v13 client read overlay — merge pending-adds into read results.
3
+ */
4
+ export function pendingAddToDbMemory(p) {
5
+ return {
6
+ id: p.id,
7
+ title: p.title,
8
+ category: p.category,
9
+ content: p.content,
10
+ summary: null,
11
+ tags: p.tags,
12
+ relevance: "",
13
+ author: "user",
14
+ authority: "user",
15
+ confidence: 0.8,
16
+ reinforcement_count: 0,
17
+ content_hash: "",
18
+ status: "active",
19
+ tier: "active",
20
+ supersedes: null,
21
+ superseded_by: null,
22
+ last_reinforced: null,
23
+ created: p.created,
24
+ modified: p.created,
25
+ embedding: null,
26
+ source_path: null,
27
+ source_file: null,
28
+ source_page: null,
29
+ source_timerange: null,
30
+ attachment_data: null,
31
+ attachment_mime: null,
32
+ attachment_name: null,
33
+ project_id: p.project_id,
34
+ scope: p.scope,
35
+ };
36
+ }
37
+ export function applyPendingOverlay(baseMemories, pendingAdds, ingestedUlids) {
38
+ const stillPending = pendingAdds.filter((p) => !ingestedUlids.has(p.id));
39
+ const overlayMemories = stillPending.map(pendingAddToDbMemory);
40
+ const seen = new Set(baseMemories.map((m) => m.id));
41
+ const merged = [...baseMemories];
42
+ for (const m of overlayMemories) {
43
+ if (!seen.has(m.id)) {
44
+ merged.push(m);
45
+ seen.add(m.id);
46
+ }
47
+ }
48
+ return {
49
+ memories: merged,
50
+ overlayCount: overlayMemories.length,
51
+ source: "merged",
52
+ };
53
+ }
54
+ function pendingMatchesQuery(p, query) {
55
+ const q = query.replace(/['"]/g, "").trim().toLowerCase();
56
+ if (!q)
57
+ return true;
58
+ const hay = `${p.title} ${p.content} ${p.tags} ${p.category}`.toLowerCase();
59
+ return q.split(/\s+/).every((term) => hay.includes(term));
60
+ }
61
+ export function mergeOverlayDiscoverResults(base, pendingAdds, query, limit, toRow) {
62
+ const seen = new Set(base.map((r) => r.id));
63
+ const merged = [...base];
64
+ for (const p of pendingAdds) {
65
+ if (merged.length >= limit)
66
+ break;
67
+ if (seen.has(p.id) || !pendingMatchesQuery(p, query))
68
+ continue;
69
+ merged.push(toRow(p));
70
+ seen.add(p.id);
71
+ }
72
+ return merged;
73
+ }
74
+ export function mergeOverlaySearchResults(base, pendingAdds, query, limit, toRow) {
75
+ return mergeOverlayDiscoverResults(base, pendingAdds, query, limit, toRow);
76
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Shared client read-path resolution for MCP tools and CLI commands.
3
+ */
4
+ import { GnosysDB } from "./db.js";
5
+ import { type ClientReadContext } from "./syncClient.js";
6
+ import type { PendingAddRow } from "./clientReadOverlay.js";
7
+ import type { DbMemory } from "./db.js";
8
+ export interface ResolvedClientRead {
9
+ db: GnosysDB;
10
+ localDb: GnosysDB;
11
+ pendingOverlay: PendingAddRow[];
12
+ clientRead: ClientReadContext | null;
13
+ release: () => void;
14
+ }
15
+ /** Open central DB and apply v13 client read context when role is client. */
16
+ export declare function resolveClientRead(): ResolvedClientRead | null;
17
+ export declare function listMemoriesWithOverlay(resolved: ResolvedClientRead, fetch: (db: GnosysDB) => DbMemory[]): DbMemory[];
18
+ export declare function getMemoryWithOverlay(resolved: ResolvedClientRead, id: string): DbMemory | null;
19
+ export declare function discoverWithOverlay(resolved: ResolvedClientRead, query: string, limit: number): Array<{
20
+ id: string;
21
+ title: string;
22
+ relevance: string;
23
+ rank: number;
24
+ project_id: string | null;
25
+ }>;
26
+ export declare function searchWithOverlay(resolved: ResolvedClientRead, query: string, limit: number): Array<{
27
+ id: string;
28
+ title: string;
29
+ snippet: string;
30
+ rank: number;
31
+ project_id: string | null;
32
+ }>;
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Shared client read-path resolution for MCP tools and CLI commands.
3
+ */
4
+ import { GnosysDB } from "./db.js";
5
+ import { readMachineConfig } from "./machineConfig.js";
6
+ import { getConfiguredRemotePath } from "./remote.js";
7
+ import { closeClientReadContext, openClientReadContext, } from "./syncClient.js";
8
+ import { applyPendingOverlay, mergeOverlayDiscoverResults, mergeOverlaySearchResults, pendingAddToDbMemory, } from "./clientReadOverlay.js";
9
+ /** Open central DB and apply v13 client read context when role is client. */
10
+ export function resolveClientRead() {
11
+ const localDb = GnosysDB.openCentral();
12
+ if (!localDb.isAvailable()) {
13
+ localDb.close();
14
+ return null;
15
+ }
16
+ const mc = readMachineConfig();
17
+ if (!mc?.remote.enabled || mc.remote.role !== "client") {
18
+ return {
19
+ db: localDb,
20
+ localDb,
21
+ pendingOverlay: [],
22
+ clientRead: null,
23
+ release: () => localDb.close(),
24
+ };
25
+ }
26
+ const masterPath = getConfiguredRemotePath(localDb);
27
+ if (!masterPath) {
28
+ return {
29
+ db: localDb,
30
+ localDb,
31
+ pendingOverlay: [],
32
+ clientRead: null,
33
+ release: () => localDb.close(),
34
+ };
35
+ }
36
+ const clientRead = openClientReadContext(localDb, masterPath, mc.machineId);
37
+ return {
38
+ db: clientRead.db,
39
+ localDb,
40
+ pendingOverlay: clientRead.pendingOverlay,
41
+ clientRead,
42
+ release: () => {
43
+ closeClientReadContext(clientRead);
44
+ localDb.close();
45
+ },
46
+ };
47
+ }
48
+ export function listMemoriesWithOverlay(resolved, fetch) {
49
+ const base = fetch(resolved.db);
50
+ if (resolved.pendingOverlay.length === 0)
51
+ return base;
52
+ return applyPendingOverlay(base, resolved.pendingOverlay, new Set()).memories;
53
+ }
54
+ export function getMemoryWithOverlay(resolved, id) {
55
+ const fromDb = resolved.db.getMemory(id);
56
+ if (fromDb)
57
+ return fromDb;
58
+ const pending = resolved.pendingOverlay.find((p) => p.id === id);
59
+ return pending ? pendingAddToDbMemory(pending) : null;
60
+ }
61
+ export function discoverWithOverlay(resolved, query, limit) {
62
+ const base = resolved.db.discoverFts(query, limit);
63
+ if (resolved.pendingOverlay.length === 0)
64
+ return base;
65
+ return mergeOverlayDiscoverResults(base, resolved.pendingOverlay, query, limit, (p) => ({
66
+ id: p.id,
67
+ title: p.title,
68
+ relevance: "",
69
+ rank: 0,
70
+ project_id: p.project_id,
71
+ }));
72
+ }
73
+ export function searchWithOverlay(resolved, query, limit) {
74
+ const base = resolved.db.searchFts(query, limit);
75
+ if (resolved.pendingOverlay.length === 0)
76
+ return base;
77
+ return mergeOverlaySearchResults(base, resolved.pendingOverlay, query, limit, (p) => ({
78
+ id: p.id,
79
+ title: p.title,
80
+ snippet: p.content.substring(0, 200),
81
+ rank: 0,
82
+ project_id: p.project_id,
83
+ }));
84
+ }
@@ -0,0 +1,9 @@
1
+ import type { GnosysResolver } from "./resolver.js";
2
+ export type CommitContextOptions = {
3
+ dryRun?: boolean;
4
+ store?: string;
5
+ };
6
+ type GetResolver = () => Promise<GnosysResolver>;
7
+ type ResolveProjectId = (dir?: string) => Promise<string | null>;
8
+ export declare function runCommitContextCommand(getResolver: GetResolver, resolveProjectId: ResolveProjectId, context: string, opts: CommitContextOptions): Promise<void>;
9
+ export {};
@@ -0,0 +1,142 @@
1
+ import { GnosysTagRegistry } from "./tags.js";
2
+ import { GnosysSearch } from "./search.js";
3
+ import { loadConfig } from "./config.js";
4
+ import { getLLMProvider } from "./llm.js";
5
+ import { GnosysDB } from "./db.js";
6
+ export async function runCommitContextCommand(getResolver, resolveProjectId, context, opts) {
7
+ const resolver = await getResolver();
8
+ const writeTarget = resolver.getWriteTarget(opts.store || undefined);
9
+ if (!writeTarget) {
10
+ console.error("No writable store found.");
11
+ process.exit(1);
12
+ }
13
+ const tagRegistry = new GnosysTagRegistry(writeTarget.store.getStorePath());
14
+ await tagRegistry.load();
15
+ const { GnosysIngestion } = await import("./ingest.js");
16
+ const ingestion = new GnosysIngestion(writeTarget.store, tagRegistry);
17
+ if (!ingestion.isLLMAvailable) {
18
+ console.error("Error: No LLM provider available. Add an API key to ~/.config/gnosys/.env or use a local model: gnosys config set provider ollama");
19
+ process.exit(1);
20
+ }
21
+ // Build search index
22
+ const stores = resolver.getStores();
23
+ const search = new GnosysSearch(stores[0].path);
24
+ search.clearIndex();
25
+ for (const s of stores) {
26
+ await search.addStoreMemories(s.store, s.label);
27
+ }
28
+ // Step 1: Extract candidates via LLM abstraction
29
+ console.log("Extracting knowledge candidates from context...");
30
+ // Load config for the write target store
31
+ const ccConfig = await loadConfig(writeTarget.store.getStorePath());
32
+ let extractProvider;
33
+ try {
34
+ extractProvider = getLLMProvider(ccConfig, "structuring");
35
+ }
36
+ catch (err) {
37
+ console.error(`LLM not available: ${err instanceof Error ? err.message : String(err)}`);
38
+ search.close();
39
+ process.exit(1);
40
+ }
41
+ const extractText = await extractProvider.generate(`Extract atomic knowledge items from this context:\n\n${context}`, {
42
+ system: `You extract atomic knowledge items from conversations. Each item should be ONE decision, fact, insight, or observation — not compound.
43
+
44
+ Output a JSON array of objects, each with:
45
+ - summary: One-sentence description of the knowledge
46
+ - type: "decision" | "insight" | "fact" | "observation" | "requirement"
47
+ - search_terms: 3-5 keywords someone would search for to find if this already exists
48
+
49
+ Be selective. Only extract things worth remembering long-term. Skip small talk, debugging steps, and transient details. Focus on decisions made, architecture choices, requirements established, and insights gained.
50
+
51
+ Output ONLY the JSON array, no markdown fences.`,
52
+ maxTokens: 4000,
53
+ });
54
+ let candidates;
55
+ try {
56
+ const jsonMatch = extractText.match(/```json\s*([\s\S]*?)```/) ||
57
+ extractText.match(/```\s*([\s\S]*?)```/) || [null, extractText];
58
+ candidates = JSON.parse(jsonMatch[1] || extractText);
59
+ }
60
+ catch {
61
+ console.error("Failed to extract candidates — LLM output was not valid JSON.");
62
+ search.close();
63
+ process.exit(1);
64
+ }
65
+ if (!Array.isArray(candidates) || candidates.length === 0) {
66
+ console.log("No extractable knowledge found in the provided context.");
67
+ search.close();
68
+ return;
69
+ }
70
+ console.log(`Found ${candidates.length} candidates. Checking novelty...\n`);
71
+ // Step 2: Check novelty and commit
72
+ let added = 0;
73
+ let skipped = 0;
74
+ let centralDb = null;
75
+ try {
76
+ centralDb = GnosysDB.openCentral();
77
+ const projectId = await resolveProjectId();
78
+ for (const candidate of candidates) {
79
+ const searchTerms = candidate.search_terms.join(" ");
80
+ const existing = search.discover(searchTerms, 3);
81
+ if (existing.length > 0) {
82
+ console.log(` ⏭ SKIP: "${candidate.summary}"`);
83
+ console.log(` Overlaps with: ${existing[0].title}`);
84
+ skipped++;
85
+ }
86
+ else if (opts.dryRun) {
87
+ console.log(` ➕ WOULD ADD: "${candidate.summary}" [${candidate.type}]`);
88
+ added++;
89
+ }
90
+ else {
91
+ try {
92
+ const result = await ingestion.ingest(candidate.summary);
93
+ const id = centralDb.getNextId(result.category, projectId || undefined);
94
+ const now = new Date().toISOString();
95
+ const content = `# ${result.title}\n\n${result.content}`;
96
+ const resultTags = result.tags;
97
+ const tagsJson = Array.isArray(resultTags)
98
+ ? JSON.stringify(resultTags)
99
+ : JSON.stringify(Object.values(resultTags).flat());
100
+ centralDb.insertMemory({
101
+ id,
102
+ title: result.title,
103
+ category: result.category,
104
+ content,
105
+ summary: null,
106
+ tags: tagsJson,
107
+ relevance: result.relevance,
108
+ author: "ai",
109
+ authority: "observed",
110
+ confidence: result.confidence,
111
+ reinforcement_count: 0,
112
+ content_hash: "",
113
+ status: "active",
114
+ tier: "active",
115
+ supersedes: null,
116
+ superseded_by: null,
117
+ last_reinforced: null,
118
+ created: now,
119
+ modified: now,
120
+ embedding: null,
121
+ source_path: null,
122
+ project_id: projectId,
123
+ scope: "project",
124
+ });
125
+ console.log(` ➕ ADDED: "${result.title}"`);
126
+ console.log(` ID: ${id}`);
127
+ added++;
128
+ }
129
+ catch (err) {
130
+ console.error(` ❌ FAILED: "${candidate.summary}": ${err instanceof Error ? err.message : String(err)}`);
131
+ }
132
+ }
133
+ console.log();
134
+ }
135
+ }
136
+ finally {
137
+ centralDb?.close();
138
+ }
139
+ search.close();
140
+ const mode = opts.dryRun ? "DRY RUN" : "COMMITTED";
141
+ console.log(`\n${mode}: ${candidates.length} candidates, ${added} ${opts.dryRun ? "would be added" : "added"}, ${skipped} duplicates skipped.`);
142
+ }