gnosys 5.11.3 → 5.12.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.
Files changed (244) hide show
  1. package/dist/cli.js +332 -5151
  2. package/dist/index.js +364 -235
  3. package/dist/lib/addCommand.d.ts +9 -0
  4. package/dist/lib/addCommand.js +103 -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/askCommand.d.ts +13 -0
  12. package/dist/lib/askCommand.js +145 -0
  13. package/dist/lib/audioExtract.js +4 -1
  14. package/dist/lib/auditCommand.d.ts +7 -0
  15. package/dist/lib/auditCommand.js +27 -0
  16. package/dist/lib/backupCommand.d.ts +6 -0
  17. package/dist/lib/backupCommand.js +54 -0
  18. package/dist/lib/bootstrapCommand.d.ts +15 -0
  19. package/dist/lib/bootstrapCommand.js +51 -0
  20. package/dist/lib/briefingCommand.d.ts +7 -0
  21. package/dist/lib/briefingCommand.js +92 -0
  22. package/dist/lib/centralizeCommand.d.ts +5 -0
  23. package/dist/lib/centralizeCommand.js +16 -0
  24. package/dist/lib/chatCommand.d.ts +12 -0
  25. package/dist/lib/chatCommand.js +46 -0
  26. package/dist/lib/checkCommand.d.ts +4 -0
  27. package/dist/lib/checkCommand.js +133 -0
  28. package/dist/lib/clientReadOverlay.d.ts +27 -0
  29. package/dist/lib/clientReadOverlay.js +73 -0
  30. package/dist/lib/clientReadResolve.d.ts +32 -0
  31. package/dist/lib/clientReadResolve.js +84 -0
  32. package/dist/lib/commitContextCommand.d.ts +9 -0
  33. package/dist/lib/commitContextCommand.js +142 -0
  34. package/dist/lib/config.d.ts +43 -3
  35. package/dist/lib/config.js +58 -57
  36. package/dist/lib/configCommand.d.ts +10 -0
  37. package/dist/lib/configCommand.js +321 -0
  38. package/dist/lib/connectCommand.d.ts +8 -0
  39. package/dist/lib/connectCommand.js +19 -0
  40. package/dist/lib/db.d.ts +52 -0
  41. package/dist/lib/db.js +169 -1
  42. package/dist/lib/dearchiveCommand.d.ts +7 -0
  43. package/dist/lib/dearchiveCommand.js +41 -0
  44. package/dist/lib/discoverCommand.d.ts +9 -0
  45. package/dist/lib/discoverCommand.js +87 -0
  46. package/dist/lib/doctorCommand.d.ts +6 -0
  47. package/dist/lib/doctorCommand.js +256 -0
  48. package/dist/lib/dream.d.ts +42 -2
  49. package/dist/lib/dream.js +290 -30
  50. package/dist/lib/dreamCommand.d.ts +10 -0
  51. package/dist/lib/dreamCommand.js +195 -0
  52. package/dist/lib/dreamLaunchd.d.ts +2 -0
  53. package/dist/lib/dreamLaunchd.js +72 -0
  54. package/dist/lib/dreamLogCommand.d.ts +10 -0
  55. package/dist/lib/dreamLogCommand.js +58 -0
  56. package/dist/lib/dreamReport.d.ts +7 -0
  57. package/dist/lib/dreamReport.js +114 -0
  58. package/dist/lib/dreamRunLog.d.ts +121 -0
  59. package/dist/lib/dreamRunLog.js +212 -0
  60. package/dist/lib/embeddings.js +3 -0
  61. package/dist/lib/exportCommand.d.ts +18 -0
  62. package/dist/lib/exportCommand.js +101 -0
  63. package/dist/lib/fsearchCommand.d.ts +8 -0
  64. package/dist/lib/fsearchCommand.js +44 -0
  65. package/dist/lib/graphCommand.d.ts +4 -0
  66. package/dist/lib/graphCommand.js +68 -0
  67. package/dist/lib/helperGenerateCommand.d.ts +5 -0
  68. package/dist/lib/helperGenerateCommand.js +27 -0
  69. package/dist/lib/historyCommand.d.ts +5 -0
  70. package/dist/lib/historyCommand.js +51 -0
  71. package/dist/lib/hybridSearchCommand.d.ts +12 -0
  72. package/dist/lib/hybridSearchCommand.js +95 -0
  73. package/dist/lib/ideMcpInstall.d.ts +30 -0
  74. package/dist/lib/ideMcpInstall.js +102 -0
  75. package/dist/lib/importCommand.d.ts +16 -0
  76. package/dist/lib/importCommand.js +89 -0
  77. package/dist/lib/importProjectCommand.d.ts +6 -0
  78. package/dist/lib/importProjectCommand.js +43 -0
  79. package/dist/lib/ingestCommand.d.ts +13 -0
  80. package/dist/lib/ingestCommand.js +95 -0
  81. package/dist/lib/installOutput.d.ts +36 -0
  82. package/dist/lib/installOutput.js +55 -0
  83. package/dist/lib/lensCommand.d.ts +20 -0
  84. package/dist/lib/lensCommand.js +61 -0
  85. package/dist/lib/lensing.d.ts +1 -0
  86. package/dist/lib/lensing.js +50 -9
  87. package/dist/lib/linksCommand.d.ts +7 -0
  88. package/dist/lib/linksCommand.js +48 -0
  89. package/dist/lib/listCommand.d.ts +8 -0
  90. package/dist/lib/listCommand.js +74 -0
  91. package/dist/lib/llm.d.ts +1 -1
  92. package/dist/lib/llm.js +26 -8
  93. package/dist/lib/localDiskCheck.d.ts +17 -0
  94. package/dist/lib/localDiskCheck.js +54 -0
  95. package/dist/lib/machineConfig.d.ts +11 -1
  96. package/dist/lib/machineConfig.js +16 -0
  97. package/dist/lib/machineRegistry.d.ts +61 -0
  98. package/dist/lib/machineRegistry.js +80 -0
  99. package/dist/lib/maintainCommand.d.ts +8 -0
  100. package/dist/lib/maintainCommand.js +34 -0
  101. package/dist/lib/masterLease.d.ts +20 -0
  102. package/dist/lib/masterLease.js +68 -0
  103. package/dist/lib/migrateCommand.d.ts +7 -0
  104. package/dist/lib/migrateCommand.js +158 -0
  105. package/dist/lib/migrateDbCommand.d.ts +9 -0
  106. package/dist/lib/migrateDbCommand.js +94 -0
  107. package/dist/lib/modelValidation.d.ts +5 -0
  108. package/dist/lib/modelValidation.js +27 -0
  109. package/dist/lib/openrouterTiers.d.ts +29 -0
  110. package/dist/lib/openrouterTiers.js +113 -0
  111. package/dist/lib/prefCommand.d.ts +10 -0
  112. package/dist/lib/prefCommand.js +118 -0
  113. package/dist/lib/projectsCommand.d.ts +8 -0
  114. package/dist/lib/projectsCommand.js +131 -0
  115. package/dist/lib/readCommand.d.ts +7 -0
  116. package/dist/lib/readCommand.js +62 -0
  117. package/dist/lib/recall.d.ts +3 -0
  118. package/dist/lib/recall.js +19 -4
  119. package/dist/lib/recallCommand.d.ts +11 -0
  120. package/dist/lib/recallCommand.js +112 -0
  121. package/dist/lib/reflectCommand.d.ts +8 -0
  122. package/dist/lib/reflectCommand.js +61 -0
  123. package/dist/lib/reindexCommand.d.ts +4 -0
  124. package/dist/lib/reindexCommand.js +34 -0
  125. package/dist/lib/reindexGraphCommand.d.ts +4 -0
  126. package/dist/lib/reindexGraphCommand.js +12 -0
  127. package/dist/lib/reinforceCommand.d.ts +8 -0
  128. package/dist/lib/reinforceCommand.js +40 -0
  129. package/dist/lib/remote.d.ts +5 -1
  130. package/dist/lib/remote.js +5 -1
  131. package/dist/lib/remoteWizard.d.ts +24 -5
  132. package/dist/lib/remoteWizard.js +308 -319
  133. package/dist/lib/restoreCommand.d.ts +5 -0
  134. package/dist/lib/restoreCommand.js +35 -0
  135. package/dist/lib/sandboxStartCommand.d.ts +6 -0
  136. package/dist/lib/sandboxStartCommand.js +25 -0
  137. package/dist/lib/sandboxStatusCommand.d.ts +4 -0
  138. package/dist/lib/sandboxStatusCommand.js +24 -0
  139. package/dist/lib/sandboxStopCommand.d.ts +4 -0
  140. package/dist/lib/sandboxStopCommand.js +21 -0
  141. package/dist/lib/searchCommand.d.ts +9 -0
  142. package/dist/lib/searchCommand.js +90 -0
  143. package/dist/lib/semanticSearchCommand.d.ts +8 -0
  144. package/dist/lib/semanticSearchCommand.js +52 -0
  145. package/dist/lib/setup/configSetRender.js +2 -0
  146. package/dist/lib/setup/providerGlyphs.d.ts +19 -0
  147. package/dist/lib/setup/providerGlyphs.js +42 -0
  148. package/dist/lib/setup/remoteRender.d.ts +31 -1
  149. package/dist/lib/setup/remoteRender.js +95 -4
  150. package/dist/lib/setup/sections/ides.d.ts +7 -0
  151. package/dist/lib/setup/sections/ides.js +24 -2
  152. package/dist/lib/setup/sections/providers.d.ts +17 -0
  153. package/dist/lib/setup/sections/providers.js +255 -0
  154. package/dist/lib/setup/sections/routing.d.ts +2 -6
  155. package/dist/lib/setup/sections/routing.js +33 -85
  156. package/dist/lib/setup/sections/taskRoutingEditor.d.ts +17 -0
  157. package/dist/lib/setup/sections/taskRoutingEditor.js +149 -0
  158. package/dist/lib/setup/summary.d.ts +9 -0
  159. package/dist/lib/setup/summary.js +51 -37
  160. package/dist/lib/setup/ui/status.d.ts +1 -0
  161. package/dist/lib/setup/ui/status.js +2 -0
  162. package/dist/lib/setup.d.ts +108 -3
  163. package/dist/lib/setup.js +813 -303
  164. package/dist/lib/setupKeys.d.ts +42 -0
  165. package/dist/lib/setupKeys.js +564 -0
  166. package/dist/lib/setupRemoteCommand.d.ts +4 -0
  167. package/dist/lib/setupRemoteCommand.js +28 -0
  168. package/dist/lib/setupRemotePullCommand.d.ts +5 -0
  169. package/dist/lib/setupRemotePullCommand.js +52 -0
  170. package/dist/lib/setupRemotePushCommand.d.ts +5 -0
  171. package/dist/lib/setupRemotePushCommand.js +57 -0
  172. package/dist/lib/setupRemoteResolveCommand.d.ts +4 -0
  173. package/dist/lib/setupRemoteResolveCommand.js +48 -0
  174. package/dist/lib/setupRemoteStatusCommand.d.ts +4 -0
  175. package/dist/lib/setupRemoteStatusCommand.js +73 -0
  176. package/dist/lib/setupRemoteSyncCommand.d.ts +6 -0
  177. package/dist/lib/setupRemoteSyncCommand.js +65 -0
  178. package/dist/lib/setupSyncProjectsCommand.d.ts +4 -0
  179. package/dist/lib/setupSyncProjectsCommand.js +292 -0
  180. package/dist/lib/staleCommand.d.ts +8 -0
  181. package/dist/lib/staleCommand.js +34 -0
  182. package/dist/lib/statsCommand.d.ts +6 -0
  183. package/dist/lib/statsCommand.js +142 -0
  184. package/dist/lib/statusCommand.d.ts +18 -0
  185. package/dist/lib/statusCommand.js +250 -0
  186. package/dist/lib/storesCommand.d.ts +2 -0
  187. package/dist/lib/storesCommand.js +4 -0
  188. package/dist/lib/syncClient.d.ts +47 -0
  189. package/dist/lib/syncClient.js +212 -0
  190. package/dist/lib/syncCommand.d.ts +6 -0
  191. package/dist/lib/syncCommand.js +57 -0
  192. package/dist/lib/syncDoctorCommand.d.ts +5 -0
  193. package/dist/lib/syncDoctorCommand.js +100 -0
  194. package/dist/lib/syncIngest.d.ts +19 -0
  195. package/dist/lib/syncIngest.js +152 -0
  196. package/dist/lib/syncIngestLaunchd.d.ts +8 -0
  197. package/dist/lib/syncIngestLaunchd.js +93 -0
  198. package/dist/lib/syncIngestStartup.d.ts +5 -0
  199. package/dist/lib/syncIngestStartup.js +29 -0
  200. package/dist/lib/syncIngestSystemd.d.ts +10 -0
  201. package/dist/lib/syncIngestSystemd.js +97 -0
  202. package/dist/lib/syncIngestTimer.d.ts +8 -0
  203. package/dist/lib/syncIngestTimer.js +27 -0
  204. package/dist/lib/syncIngestTimerCommand.d.ts +7 -0
  205. package/dist/lib/syncIngestTimerCommand.js +83 -0
  206. package/dist/lib/syncLock.d.ts +6 -0
  207. package/dist/lib/syncLock.js +74 -0
  208. package/dist/lib/syncSnapshot.d.ts +30 -0
  209. package/dist/lib/syncSnapshot.js +184 -0
  210. package/dist/lib/syncStaging.d.ts +81 -0
  211. package/dist/lib/syncStaging.js +239 -0
  212. package/dist/lib/tagsAddCommand.d.ts +8 -0
  213. package/dist/lib/tagsAddCommand.js +18 -0
  214. package/dist/lib/tagsCommand.d.ts +4 -0
  215. package/dist/lib/tagsCommand.js +16 -0
  216. package/dist/lib/timelineCommand.d.ts +7 -0
  217. package/dist/lib/timelineCommand.js +49 -0
  218. package/dist/lib/traceCommand.d.ts +6 -0
  219. package/dist/lib/traceCommand.js +39 -0
  220. package/dist/lib/traverseCommand.d.ts +6 -0
  221. package/dist/lib/traverseCommand.js +58 -0
  222. package/dist/lib/updateCommand.d.ts +13 -0
  223. package/dist/lib/updateCommand.js +67 -0
  224. package/dist/lib/updateStatusCommand.d.ts +5 -0
  225. package/dist/lib/updateStatusCommand.js +38 -0
  226. package/dist/lib/webAddCommand.d.ts +8 -0
  227. package/dist/lib/webAddCommand.js +55 -0
  228. package/dist/lib/webBuildCommand.d.ts +10 -0
  229. package/dist/lib/webBuildCommand.js +65 -0
  230. package/dist/lib/webBuildIndexCommand.d.ts +8 -0
  231. package/dist/lib/webBuildIndexCommand.js +37 -0
  232. package/dist/lib/webIngestCommand.d.ts +11 -0
  233. package/dist/lib/webIngestCommand.js +51 -0
  234. package/dist/lib/webInitCommand.d.ts +9 -0
  235. package/dist/lib/webInitCommand.js +167 -0
  236. package/dist/lib/webRemoveCommand.d.ts +5 -0
  237. package/dist/lib/webRemoveCommand.js +41 -0
  238. package/dist/lib/webStatusCommand.d.ts +5 -0
  239. package/dist/lib/webStatusCommand.js +94 -0
  240. package/dist/lib/webUpdateCommand.d.ts +7 -0
  241. package/dist/lib/webUpdateCommand.js +72 -0
  242. package/dist/lib/workingSetCommand.d.ts +6 -0
  243. package/dist/lib/workingSetCommand.js +37 -0
  244. package/package.json +2 -1
@@ -0,0 +1,212 @@
1
+ import { execFileSync } from "child_process";
2
+ import crypto from "crypto";
3
+ import fs from "fs";
4
+ import os from "os";
5
+ import path from "path";
6
+ import { getGnosysHome } from "./paths.js";
7
+ const DEFAULT_STATE = {
8
+ analyzedFingerprints: {},
9
+ };
10
+ const MODEL_PRICES_USD_PER_MILLION = {
11
+ "grok-4.3": { input: 3, output: 15 },
12
+ "grok-4.20": { input: 3, output: 15 },
13
+ "grok-4": { input: 3, output: 15 },
14
+ "claude-sonnet-4-6": { input: 3, output: 15 },
15
+ "claude-haiku-4-5": { input: 1, output: 5 },
16
+ "gpt-5.4-mini": { input: 0.25, output: 2 },
17
+ "gpt-5.4-nano": { input: 0.05, output: 0.4 },
18
+ "mistral-small-4": { input: 0.2, output: 0.6 },
19
+ };
20
+ export function getDreamRunsPath() {
21
+ return path.join(getGnosysHome(), "dream-runs.jsonl");
22
+ }
23
+ export function getDreamStatePath() {
24
+ return path.join(getGnosysHome(), "dream-state.json");
25
+ }
26
+ export function getDreamLockPath() {
27
+ return path.join(getGnosysHome(), "dream.lock");
28
+ }
29
+ export function acquireDreamLock() {
30
+ const lockPath = getDreamLockPath();
31
+ fs.mkdirSync(path.dirname(lockPath), { recursive: true });
32
+ try {
33
+ const fd = fs.openSync(lockPath, "wx");
34
+ fs.writeFileSync(fd, JSON.stringify({ pid: process.pid, startedAt: new Date().toISOString() }));
35
+ fs.closeSync(fd);
36
+ return {
37
+ acquired: true,
38
+ release: () => {
39
+ try {
40
+ fs.unlinkSync(lockPath);
41
+ }
42
+ catch {
43
+ // Best effort: stale lock cleanup happens on the next acquire.
44
+ }
45
+ },
46
+ };
47
+ }
48
+ catch {
49
+ try {
50
+ const raw = fs.readFileSync(lockPath, "utf8");
51
+ const parsed = JSON.parse(raw);
52
+ if (parsed.pid && !isProcessRunning(parsed.pid)) {
53
+ fs.unlinkSync(lockPath);
54
+ return acquireDreamLock();
55
+ }
56
+ return { acquired: false, reason: `dream already running (pid ${parsed.pid || "unknown"})` };
57
+ }
58
+ catch {
59
+ return { acquired: false, reason: "dream already running (lock exists)" };
60
+ }
61
+ }
62
+ }
63
+ function isProcessRunning(pid) {
64
+ try {
65
+ process.kill(pid, 0);
66
+ return true;
67
+ }
68
+ catch {
69
+ return false;
70
+ }
71
+ }
72
+ export function estimateTokens(text) {
73
+ return Math.max(1, Math.ceil(text.length / 4));
74
+ }
75
+ export function estimateCost(model, inputTokens, outputTokens) {
76
+ const key = (model || "").toLowerCase();
77
+ const exact = MODEL_PRICES_USD_PER_MILLION[key];
78
+ const fuzzy = exact ?? Object.entries(MODEL_PRICES_USD_PER_MILLION).find(([m]) => key.includes(m))?.[1];
79
+ if (!fuzzy)
80
+ return 0;
81
+ const cost = (inputTokens / 1_000_000) * fuzzy.input + (outputTokens / 1_000_000) * fuzzy.output;
82
+ return Math.round(cost * 1_000_000) / 1_000_000;
83
+ }
84
+ export function readDreamState() {
85
+ try {
86
+ const raw = fs.readFileSync(getDreamStatePath(), "utf8");
87
+ const parsed = JSON.parse(raw);
88
+ return {
89
+ ...DEFAULT_STATE,
90
+ ...parsed,
91
+ analyzedFingerprints: parsed.analyzedFingerprints ?? {},
92
+ };
93
+ }
94
+ catch {
95
+ return { ...DEFAULT_STATE };
96
+ }
97
+ }
98
+ export function writeDreamState(state) {
99
+ const file = getDreamStatePath();
100
+ fs.mkdirSync(path.dirname(file), { recursive: true });
101
+ fs.writeFileSync(file, `${JSON.stringify(state, null, 2)}\n`, "utf8");
102
+ }
103
+ export function appendDreamRun(record) {
104
+ const file = getDreamRunsPath();
105
+ fs.mkdirSync(path.dirname(file), { recursive: true });
106
+ fs.appendFileSync(file, `${JSON.stringify(record)}\n`, "utf8");
107
+ }
108
+ export function readDreamRuns(opts = {}) {
109
+ const file = getDreamRunsPath();
110
+ if (!fs.existsSync(file))
111
+ return [];
112
+ const sinceMs = opts.sinceIso ? Date.parse(opts.sinceIso) : null;
113
+ const rows = fs.readFileSync(file, "utf8")
114
+ .split(/\r?\n/)
115
+ .filter(Boolean)
116
+ .map((line) => {
117
+ try {
118
+ return JSON.parse(line);
119
+ }
120
+ catch {
121
+ return null;
122
+ }
123
+ })
124
+ .filter((row) => !!row)
125
+ .filter((row) => !opts.status || row.status === opts.status)
126
+ .filter((row) => sinceMs == null || Date.parse(row.startedAt) >= sinceMs)
127
+ .sort((a, b) => Date.parse(b.startedAt) - Date.parse(a.startedAt));
128
+ return typeof opts.limit === "number" ? rows.slice(0, opts.limit) : rows;
129
+ }
130
+ export function fingerprintMemories(kind, memories) {
131
+ const material = memories
132
+ .map((m) => `${m.id}:${m.modified}:${m.content_hash || ""}`)
133
+ .sort()
134
+ .join("|");
135
+ return `${kind}:${crypto.createHash("sha256").update(material).digest("hex").slice(0, 24)}`;
136
+ }
137
+ export function memoryWatermark(memories) {
138
+ const maxModified = memories
139
+ .map((m) => m.modified || m.created)
140
+ .filter(Boolean)
141
+ .sort()
142
+ .at(-1);
143
+ return { count: memories.length, maxModified };
144
+ }
145
+ export function countChangedMemoriesSince(memories, sinceIso) {
146
+ if (!sinceIso)
147
+ return memories.length;
148
+ const sinceMs = Date.parse(sinceIso);
149
+ if (!Number.isFinite(sinceMs))
150
+ return memories.length;
151
+ return memories.filter((m) => Date.parse(m.modified || m.created) > sinceMs).length;
152
+ }
153
+ export function isInsideNightWindow(now, schedule) {
154
+ const start = schedule.startHour;
155
+ const end = schedule.endHour;
156
+ const hour = now.getHours();
157
+ if (start === end)
158
+ return true;
159
+ if (start < end)
160
+ return hour >= start && hour < end;
161
+ return hour >= start || hour < end;
162
+ }
163
+ export function getSystemIdleMinutes() {
164
+ if (process.platform !== "darwin")
165
+ return null;
166
+ try {
167
+ const output = execFileSync("ioreg", ["-c", "IOHIDSystem"], { encoding: "utf8", timeout: 2000 });
168
+ const match = output.match(/HIDIdleTime"\s*=\s*(\d+)/);
169
+ if (!match)
170
+ return null;
171
+ const nanoseconds = Number(match[1]);
172
+ return nanoseconds / 1_000_000_000 / 60;
173
+ }
174
+ catch {
175
+ return null;
176
+ }
177
+ }
178
+ export function createSkipRunRecord(input) {
179
+ const finishedAt = input.finishedAt ?? new Date().toISOString();
180
+ return {
181
+ id: `dream-${Date.parse(input.startedAt)}-${Math.random().toString(36).slice(2, 8)}`,
182
+ trigger: input.trigger,
183
+ status: "skipped",
184
+ startedAt: input.startedAt,
185
+ finishedAt,
186
+ durationMs: Math.max(0, Date.parse(finishedAt) - Date.parse(input.startedAt)),
187
+ machine: { hostname: os.hostname(), machineId: input.machineId },
188
+ provider: input.provider,
189
+ model: input.model,
190
+ gates: input.gates,
191
+ phases: [],
192
+ llmCalls: [],
193
+ totals: {
194
+ llmCallsMade: 0,
195
+ llmCallsSkipped: 0,
196
+ estimatedInputTokens: 0,
197
+ estimatedOutputTokens: 0,
198
+ estimatedCostUsd: 0,
199
+ },
200
+ effectiveness: {
201
+ usefulOutputScore: 0,
202
+ costPerUsefulOutput: null,
203
+ decaysApplied: 0,
204
+ summariesGenerated: 0,
205
+ summariesUpdated: 0,
206
+ reviewSuggestions: 0,
207
+ relationshipsDiscovered: 0,
208
+ },
209
+ errors: [],
210
+ skipReason: input.reason,
211
+ };
212
+ }
@@ -45,6 +45,9 @@ export class GnosysEmbeddings {
45
45
  // Dynamic import — keeps @huggingface/transformers out of the main bundle.
46
46
  // dtype 'q8' replaces the v2-era `quantized: true` option (8-bit quantized,
47
47
  // ~80 MB vs ~280 MB for fp32). Smaller is fine for sentence embeddings.
48
+ // Use `any` here so `tsc` succeeds even when the optional dep is not installed
49
+ // (CI network-share-simulation job, fresh checkouts, etc.). The real type
50
+ // is only needed at runtime when the package is present.
48
51
  let pipeline;
49
52
  try {
50
53
  ({ pipeline } = await import("@huggingface/transformers"));
@@ -0,0 +1,18 @@
1
+ export type VaultExportOptions = {
2
+ to: string;
3
+ all?: boolean;
4
+ overwrite?: boolean;
5
+ summaries?: boolean;
6
+ reviews?: boolean;
7
+ graph?: boolean;
8
+ json?: boolean;
9
+ };
10
+ export type ProjectExportOptions = {
11
+ to: string;
12
+ includeArchived?: boolean;
13
+ audit?: boolean;
14
+ json?: boolean;
15
+ };
16
+ export declare function runExportUsageCommand(): void;
17
+ export declare function runVaultExportCommand(opts: VaultExportOptions): Promise<void>;
18
+ export declare function runProjectExportCommand(projectIdArg: string | undefined, opts: ProjectExportOptions): Promise<void>;
@@ -0,0 +1,101 @@
1
+ import path from "path";
2
+ import { GnosysResolver } from "./resolver.js";
3
+ export function runExportUsageCommand() {
4
+ console.error("Usage: gnosys export vault --to <dir> # Obsidian vault export");
5
+ console.error(" gnosys export project [id] --to <bundle> # portable .json.gz bundle");
6
+ process.exit(1);
7
+ }
8
+ export async function runVaultExportCommand(opts) {
9
+ const resolver = new GnosysResolver();
10
+ await resolver.resolve();
11
+ const stores = resolver.getStores();
12
+ if (stores.length === 0) {
13
+ console.error("No Gnosys stores found. Run 'gnosys init' first.");
14
+ process.exit(1);
15
+ }
16
+ const { GnosysDB: DbClass } = await import("./db.js");
17
+ const { GnosysExporter, formatExportReport } = await import("./export.js");
18
+ const storePath = stores[0].path;
19
+ let db = null;
20
+ try {
21
+ db = new DbClass(storePath);
22
+ if (!db.isAvailable() || !db.isMigrated()) {
23
+ console.error("Export requires gnosys.db (v2.0). Run 'gnosys migrate' first.");
24
+ process.exitCode = 1;
25
+ return;
26
+ }
27
+ const targetDir = path.resolve(opts.to);
28
+ console.error(`Exporting to: ${targetDir}`);
29
+ const exporter = new GnosysExporter(db);
30
+ const report = await exporter.export({
31
+ targetDir,
32
+ activeOnly: !opts.all,
33
+ includeSummaries: opts.summaries !== false,
34
+ includeReviews: opts.reviews !== false,
35
+ includeGraph: opts.graph !== false,
36
+ overwrite: opts.overwrite || false,
37
+ onProgress: (current, total, file) => {
38
+ if (current % 10 === 0 || current === total) {
39
+ console.error(` [${current}/${total}] ${file}`);
40
+ }
41
+ },
42
+ });
43
+ if (opts.json) {
44
+ console.log(JSON.stringify(report, null, 2));
45
+ }
46
+ else {
47
+ console.log(formatExportReport(report));
48
+ }
49
+ }
50
+ finally {
51
+ db?.close();
52
+ }
53
+ }
54
+ export async function runProjectExportCommand(projectIdArg, opts) {
55
+ const { GnosysDB: DbClass } = await import("./db.js");
56
+ const { exportProject } = await import("./exportProject.js");
57
+ let centralDb = null;
58
+ try {
59
+ centralDb = DbClass.openCentral();
60
+ if (!centralDb.isAvailable()) {
61
+ console.error("Central DB unavailable.");
62
+ process.exitCode = 1;
63
+ return;
64
+ }
65
+ let projectId = projectIdArg;
66
+ if (!projectId) {
67
+ const proj = centralDb.getProjectByDirectory(process.cwd());
68
+ if (!proj) {
69
+ console.error("No project ID given and current directory is not a registered project.");
70
+ console.error("Usage: gnosys export project <projectId> --to <file>");
71
+ process.exitCode = 1;
72
+ return;
73
+ }
74
+ projectId = proj.id;
75
+ }
76
+ const result = exportProject(centralDb, {
77
+ projectId,
78
+ outputPath: path.resolve(opts.to),
79
+ includeArchived: !!opts.includeArchived,
80
+ includeAudit: opts.audit !== false,
81
+ });
82
+ if (opts.json) {
83
+ console.log(JSON.stringify(result, null, 2));
84
+ }
85
+ else {
86
+ const ratio = (result.compressedBytes / result.uncompressedBytes * 100).toFixed(1);
87
+ console.log(`Exported project ${projectId}`);
88
+ console.log(` Memories: ${result.memoryCount}`);
89
+ if (result.archivedExcluded > 0) {
90
+ console.log(` Archived: ${result.archivedExcluded} excluded — re-run with --include-archived for a full backup`);
91
+ }
92
+ console.log(` Relationships: ${result.relationshipCount}`);
93
+ console.log(` Audit entries: ${result.auditEntryCount}`);
94
+ console.log(` Bundle: ${result.outputPath}`);
95
+ console.log(` Size: ${(result.compressedBytes / 1024).toFixed(1)} KB compressed (${ratio}% of ${(result.uncompressedBytes / 1024).toFixed(1)} KB)`);
96
+ }
97
+ }
98
+ finally {
99
+ centralDb?.close();
100
+ }
101
+ }
@@ -0,0 +1,8 @@
1
+ export type FsearchCommandOptions = {
2
+ limit: string;
3
+ directory?: string;
4
+ global: boolean;
5
+ scope?: string;
6
+ json: boolean;
7
+ };
8
+ export declare function runFsearchCommand(query: string, opts: FsearchCommandOptions): Promise<void>;
@@ -0,0 +1,44 @@
1
+ export async function runFsearchCommand(query, opts) {
2
+ const { resolveClientRead } = await import("./clientReadResolve.js");
3
+ const resolved = resolveClientRead();
4
+ if (!resolved) {
5
+ console.error("Central DB not available.");
6
+ process.exit(1);
7
+ }
8
+ try {
9
+ const { federatedSearch, detectCurrentProject } = await import("./federated.js");
10
+ const projectId = await detectCurrentProject(resolved.db, opts.directory || undefined);
11
+ const scopeFilter = opts.scope ? opts.scope.split(",").map(s => s.trim()) : undefined;
12
+ const results = federatedSearch(resolved.db, query, {
13
+ limit: parseInt(opts.limit, 10),
14
+ projectId,
15
+ includeGlobal: opts.global,
16
+ scopeFilter,
17
+ });
18
+ if (opts.json) {
19
+ console.log(JSON.stringify({ query, projectId, count: results.length, results }, null, 2));
20
+ }
21
+ else {
22
+ if (results.length === 0) {
23
+ console.log(`No results for "${query}".`);
24
+ return;
25
+ }
26
+ const ctx = projectId ? `Context: project ${projectId}` : "No project detected";
27
+ console.log(ctx);
28
+ for (const [i, r] of results.entries()) {
29
+ const proj = r.projectName ? ` [${r.projectName}]` : "";
30
+ console.log(`\n${i + 1}. ${r.title} (${r.category})${proj}`);
31
+ console.log(` scope: ${r.scope} | score: ${r.score.toFixed(4)} | boosts: ${r.boosts.join(", ")}`);
32
+ if (r.snippet)
33
+ console.log(` ${r.snippet.substring(0, 120)}`);
34
+ }
35
+ }
36
+ }
37
+ catch (err) {
38
+ console.error(`Error: ${err instanceof Error ? err.message : err}`);
39
+ process.exit(1);
40
+ }
41
+ finally {
42
+ resolved.release();
43
+ }
44
+ }
@@ -0,0 +1,4 @@
1
+ export type GraphCommandOptions = {
2
+ json?: boolean;
3
+ };
4
+ export declare function runGraphCommand(opts: GraphCommandOptions): Promise<void>;
@@ -0,0 +1,68 @@
1
+ import { buildLinkGraph, formatGraphSummary } from "./wikilinks.js";
2
+ import { GnosysDB } from "./db.js";
3
+ function outputResult(json, data, humanFn) {
4
+ if (json) {
5
+ console.log(JSON.stringify(data, null, 2));
6
+ }
7
+ else {
8
+ humanFn();
9
+ }
10
+ }
11
+ export async function runGraphCommand(opts) {
12
+ let centralDb = null;
13
+ try {
14
+ centralDb = GnosysDB.openCentral();
15
+ if (!centralDb.isAvailable()) {
16
+ console.error("Central DB not available.");
17
+ process.exit(1);
18
+ }
19
+ const dbMemories = centralDb.getAllMemories();
20
+ if (dbMemories.length === 0) {
21
+ outputResult(!!opts.json, { totalLinks: 0, orphanedLinks: [], nodes: [] }, () => {
22
+ console.log("No memories found.");
23
+ });
24
+ return;
25
+ }
26
+ const adapted = dbMemories.map((m) => {
27
+ let parsedTags = [];
28
+ try {
29
+ parsedTags = JSON.parse(m.tags);
30
+ }
31
+ catch {
32
+ parsedTags = [];
33
+ }
34
+ const relativePath = `${m.category}/${m.id}.md`;
35
+ return {
36
+ frontmatter: {
37
+ id: m.id,
38
+ title: m.title,
39
+ category: m.category,
40
+ tags: parsedTags,
41
+ relevance: m.relevance,
42
+ author: m.author,
43
+ authority: m.authority,
44
+ confidence: m.confidence,
45
+ created: m.created,
46
+ modified: m.modified,
47
+ last_reviewed: m.modified,
48
+ status: m.status,
49
+ supersedes: m.supersedes,
50
+ },
51
+ content: m.content,
52
+ filePath: relativePath,
53
+ relativePath,
54
+ };
55
+ });
56
+ const graph = buildLinkGraph(adapted);
57
+ outputResult(!!opts.json, {
58
+ totalLinks: graph.totalLinks,
59
+ orphanedLinks: graph.orphanedLinks,
60
+ nodes: Array.from(graph.nodes.values()),
61
+ }, () => {
62
+ console.log(formatGraphSummary(graph));
63
+ });
64
+ }
65
+ finally {
66
+ centralDb?.close();
67
+ }
68
+ }
@@ -0,0 +1,5 @@
1
+ export type HelperGenerateCommandOptions = {
2
+ directory?: string;
3
+ json?: boolean;
4
+ };
5
+ export declare function runHelperGenerateCommand(opts: HelperGenerateCommandOptions): Promise<void>;
@@ -0,0 +1,27 @@
1
+ export async function runHelperGenerateCommand(opts) {
2
+ try {
3
+ const { generateHelper } = await import("../sandbox/helper-template.js");
4
+ const targetDir = opts.directory || process.cwd();
5
+ const outputPath = await generateHelper(targetDir);
6
+ if (opts.json) {
7
+ console.log(JSON.stringify({ ok: true, path: outputPath }));
8
+ }
9
+ else {
10
+ console.log(`Generated: ${outputPath}`);
11
+ console.log();
12
+ console.log("Usage in your agent/script:");
13
+ console.log(' import { gnosys } from "./gnosys-helper";');
14
+ console.log(' await gnosys.add("We use conventional commits");');
15
+ console.log(' const ctx = await gnosys.recall("auth decisions");');
16
+ }
17
+ }
18
+ catch (err) {
19
+ if (opts.json) {
20
+ console.log(JSON.stringify({ ok: false, error: err instanceof Error ? err.message : String(err) }));
21
+ }
22
+ else {
23
+ console.error(`Failed to generate helper: ${err instanceof Error ? err.message : err}`);
24
+ }
25
+ process.exit(1);
26
+ }
27
+ }
@@ -0,0 +1,5 @@
1
+ export type HistoryCommandOptions = {
2
+ limit: string;
3
+ json?: boolean;
4
+ };
5
+ export declare function runHistoryCommand(memoryPath: string, opts: HistoryCommandOptions): Promise<void>;
@@ -0,0 +1,51 @@
1
+ import { GnosysDB } from "./db.js";
2
+ function outputResult(json, data, humanFn) {
3
+ if (json) {
4
+ console.log(JSON.stringify(data, null, 2));
5
+ }
6
+ else {
7
+ humanFn();
8
+ }
9
+ }
10
+ export async function runHistoryCommand(memoryPath, opts) {
11
+ const centralDb = GnosysDB.openCentral();
12
+ if (!centralDb.isAvailable()) {
13
+ console.error("Central DB not available.");
14
+ process.exit(1);
15
+ }
16
+ try {
17
+ const dbMem = centralDb.getMemory(memoryPath);
18
+ if (!dbMem) {
19
+ console.error(`Memory not found: ${memoryPath}`);
20
+ process.exit(1);
21
+ }
22
+ const limit = parseInt(opts.limit, 10) || 20;
23
+ const audits = centralDb.getAuditLog(dbMem.id, limit);
24
+ outputResult(!!opts.json, {
25
+ memoryId: dbMem.id,
26
+ title: dbMem.title,
27
+ created: dbMem.created,
28
+ modified: dbMem.modified,
29
+ entries: audits,
30
+ }, () => {
31
+ if (audits.length === 0) {
32
+ console.log(`Memory: ${dbMem.title} (${dbMem.id})`);
33
+ console.log(`Created: ${dbMem.created}`);
34
+ console.log(`Modified: ${dbMem.modified}`);
35
+ console.log("No audit history recorded.");
36
+ return;
37
+ }
38
+ console.log(`History for ${dbMem.title} (${dbMem.id}, ${audits.length} entries):\n`);
39
+ console.log(`Created: ${dbMem.created}`);
40
+ console.log(`Modified: ${dbMem.modified}\n`);
41
+ for (const entry of audits) {
42
+ const date = entry.timestamp.split("T")[0];
43
+ const detail = entry.details ? ` (${entry.details})` : "";
44
+ console.log(` ${date} ${entry.operation}${detail}`);
45
+ }
46
+ });
47
+ }
48
+ finally {
49
+ centralDb.close();
50
+ }
51
+ }
@@ -0,0 +1,12 @@
1
+ import type { GnosysResolver } from "./resolver.js";
2
+ export type HybridSearchCommandOptions = {
3
+ limit: string;
4
+ mode: string;
5
+ json?: boolean;
6
+ federated?: boolean;
7
+ scope?: string;
8
+ directory?: string;
9
+ };
10
+ type GetResolver = () => Promise<GnosysResolver>;
11
+ export declare function runHybridSearchCommand(getResolver: GetResolver, query: string, opts: HybridSearchCommandOptions): Promise<void>;
12
+ export {};
@@ -0,0 +1,95 @@
1
+ import { GnosysSearch } from "./search.js";
2
+ function outputResult(json, data, humanFn) {
3
+ if (json) {
4
+ console.log(JSON.stringify(data, null, 2));
5
+ }
6
+ else {
7
+ humanFn();
8
+ }
9
+ }
10
+ export async function runHybridSearchCommand(getResolver, query, opts) {
11
+ // Federated path — uses central DB
12
+ if (opts.federated || opts.scope) {
13
+ const { resolveClientRead } = await import("./clientReadResolve.js");
14
+ const resolved = resolveClientRead();
15
+ if (!resolved) {
16
+ console.error("Central DB not available.");
17
+ process.exit(1);
18
+ }
19
+ try {
20
+ const { federatedSearch, detectCurrentProject } = await import("./federated.js");
21
+ const projectId = await detectCurrentProject(resolved.db, opts.directory || undefined);
22
+ const scopeFilter = opts.scope ? opts.scope.split(",").map(s => s.trim()) : undefined;
23
+ const results = federatedSearch(resolved.db, query, {
24
+ limit: parseInt(opts.limit, 10),
25
+ projectId,
26
+ scopeFilter,
27
+ });
28
+ outputResult(!!opts.json, { query, projectId, mode: "federated", count: results.length, results }, () => {
29
+ if (results.length === 0) {
30
+ console.log(`No results for "${query}".`);
31
+ return;
32
+ }
33
+ console.log(`Found ${results.length} results for "${query}" (mode: federated):\n`);
34
+ for (const [i, r] of results.entries()) {
35
+ const proj = r.projectName ? ` [${r.projectName}]` : "";
36
+ console.log(`${i + 1}. ${r.title} (${r.category})${proj}`);
37
+ console.log(` scope: ${r.scope} | score: ${r.score.toFixed(4)} | boosts: ${r.boosts.join(", ")}`);
38
+ if (r.snippet)
39
+ console.log(` ${r.snippet.substring(0, 120)}`);
40
+ }
41
+ });
42
+ }
43
+ catch (err) {
44
+ console.error(`Error: ${err instanceof Error ? err.message : err}`);
45
+ process.exit(1);
46
+ }
47
+ finally {
48
+ resolved.release();
49
+ }
50
+ return;
51
+ }
52
+ // Legacy file-based hybrid search
53
+ const resolver = await getResolver();
54
+ const stores = resolver.getStores();
55
+ if (stores.length === 0) {
56
+ console.error("No stores found.");
57
+ process.exit(1);
58
+ }
59
+ const storePath = stores[0].path;
60
+ const search = new GnosysSearch(storePath);
61
+ search.clearIndex();
62
+ for (const s of stores) {
63
+ await search.addStoreMemories(s.store, s.label);
64
+ }
65
+ const { GnosysEmbeddings } = await import("./embeddings.js");
66
+ const { GnosysHybridSearch } = await import("./hybridSearch.js");
67
+ const embeddings = new GnosysEmbeddings(storePath);
68
+ const hybridSearch = new GnosysHybridSearch(search, embeddings, resolver, storePath);
69
+ const mode = opts.mode;
70
+ const results = await hybridSearch.hybridSearch(query, parseInt(opts.limit), mode);
71
+ if (results.length === 0) {
72
+ outputResult(!!opts.json, { query, mode, results: [] }, () => {
73
+ console.log(`No results for "${query}". Try gnosys reindex to build embeddings.`);
74
+ });
75
+ }
76
+ else {
77
+ outputResult(!!opts.json, { query, mode, count: results.length, results }, () => {
78
+ console.log(`Found ${results.length} results for "${query}" (mode: ${mode}):\n`);
79
+ for (const r of results) {
80
+ console.log(` ${r.title}`);
81
+ console.log(` Path: ${r.relativePath}`);
82
+ console.log(` Score: ${r.score.toFixed(4)} (via: ${r.sources.join("+")})`);
83
+ console.log(` ${r.snippet.substring(0, 120)}...\n`);
84
+ }
85
+ });
86
+ // Reinforce used memories (best-effort)
87
+ const writeTarget = resolver.getWriteTarget();
88
+ if (writeTarget) {
89
+ const { GnosysMaintenanceEngine } = await import("./maintenance.js");
90
+ await GnosysMaintenanceEngine.reinforceBatch(writeTarget.store, results.map((r) => r.relativePath)).catch(() => { });
91
+ }
92
+ }
93
+ search.close();
94
+ embeddings.close();
95
+ }