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,234 @@
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(depth = 0) {
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
+ // Bounded retries so stale-lock cleanup can't recurse forever under
50
+ // genuine contention (two processes racing to re-acquire).
51
+ if (depth >= 3) {
52
+ return { acquired: false, reason: "dream lock contention" };
53
+ }
54
+ let raw;
55
+ try {
56
+ raw = fs.readFileSync(lockPath, "utf8");
57
+ }
58
+ catch {
59
+ // Lock vanished between our create attempt and this read — retry.
60
+ return acquireDreamLock(depth + 1);
61
+ }
62
+ try {
63
+ const parsed = JSON.parse(raw);
64
+ if (parsed.pid && !isProcessRunning(parsed.pid)) {
65
+ fs.unlinkSync(lockPath);
66
+ return acquireDreamLock(depth + 1);
67
+ }
68
+ return { acquired: false, reason: `dream already running (pid ${parsed.pid || "unknown"})` };
69
+ }
70
+ catch {
71
+ // v5.12.1: unreadable/corrupt lock (crash mid-write) previously blocked
72
+ // dreaming forever until manual deletion. Treat it as stale: the lock
73
+ // payload is a single tiny write, so a live owner with a corrupt lock
74
+ // is implausible.
75
+ try {
76
+ fs.unlinkSync(lockPath);
77
+ }
78
+ catch {
79
+ // ignore — next acquire retries
80
+ }
81
+ return acquireDreamLock(depth + 1);
82
+ }
83
+ }
84
+ }
85
+ function isProcessRunning(pid) {
86
+ try {
87
+ process.kill(pid, 0);
88
+ return true;
89
+ }
90
+ catch {
91
+ return false;
92
+ }
93
+ }
94
+ export function estimateTokens(text) {
95
+ return Math.max(1, Math.ceil(text.length / 4));
96
+ }
97
+ export function estimateCost(model, inputTokens, outputTokens) {
98
+ const key = (model || "").toLowerCase();
99
+ const exact = MODEL_PRICES_USD_PER_MILLION[key];
100
+ const fuzzy = exact ?? Object.entries(MODEL_PRICES_USD_PER_MILLION).find(([m]) => key.includes(m))?.[1];
101
+ if (!fuzzy)
102
+ return 0;
103
+ const cost = (inputTokens / 1_000_000) * fuzzy.input + (outputTokens / 1_000_000) * fuzzy.output;
104
+ return Math.round(cost * 1_000_000) / 1_000_000;
105
+ }
106
+ export function readDreamState() {
107
+ try {
108
+ const raw = fs.readFileSync(getDreamStatePath(), "utf8");
109
+ const parsed = JSON.parse(raw);
110
+ return {
111
+ ...DEFAULT_STATE,
112
+ ...parsed,
113
+ analyzedFingerprints: parsed.analyzedFingerprints ?? {},
114
+ };
115
+ }
116
+ catch {
117
+ return { ...DEFAULT_STATE };
118
+ }
119
+ }
120
+ export function writeDreamState(state) {
121
+ const file = getDreamStatePath();
122
+ fs.mkdirSync(path.dirname(file), { recursive: true });
123
+ fs.writeFileSync(file, `${JSON.stringify(state, null, 2)}\n`, "utf8");
124
+ }
125
+ export function appendDreamRun(record) {
126
+ const file = getDreamRunsPath();
127
+ fs.mkdirSync(path.dirname(file), { recursive: true });
128
+ fs.appendFileSync(file, `${JSON.stringify(record)}\n`, "utf8");
129
+ }
130
+ export function readDreamRuns(opts = {}) {
131
+ const file = getDreamRunsPath();
132
+ if (!fs.existsSync(file))
133
+ return [];
134
+ const sinceMs = opts.sinceIso ? Date.parse(opts.sinceIso) : null;
135
+ const rows = fs.readFileSync(file, "utf8")
136
+ .split(/\r?\n/)
137
+ .filter(Boolean)
138
+ .map((line) => {
139
+ try {
140
+ return JSON.parse(line);
141
+ }
142
+ catch {
143
+ return null;
144
+ }
145
+ })
146
+ .filter((row) => !!row)
147
+ .filter((row) => !opts.status || row.status === opts.status)
148
+ .filter((row) => sinceMs == null || Date.parse(row.startedAt) >= sinceMs)
149
+ .sort((a, b) => Date.parse(b.startedAt) - Date.parse(a.startedAt));
150
+ return typeof opts.limit === "number" ? rows.slice(0, opts.limit) : rows;
151
+ }
152
+ export function fingerprintMemories(kind, memories) {
153
+ const material = memories
154
+ .map((m) => `${m.id}:${m.modified}:${m.content_hash || ""}`)
155
+ .sort()
156
+ .join("|");
157
+ return `${kind}:${crypto.createHash("sha256").update(material).digest("hex").slice(0, 24)}`;
158
+ }
159
+ export function memoryWatermark(memories) {
160
+ const maxModified = memories
161
+ .map((m) => m.modified || m.created)
162
+ .filter(Boolean)
163
+ .sort()
164
+ .at(-1);
165
+ return { count: memories.length, maxModified };
166
+ }
167
+ export function countChangedMemoriesSince(memories, sinceIso) {
168
+ if (!sinceIso)
169
+ return memories.length;
170
+ const sinceMs = Date.parse(sinceIso);
171
+ if (!Number.isFinite(sinceMs))
172
+ return memories.length;
173
+ return memories.filter((m) => Date.parse(m.modified || m.created) > sinceMs).length;
174
+ }
175
+ export function isInsideNightWindow(now, schedule) {
176
+ const start = schedule.startHour;
177
+ const end = schedule.endHour;
178
+ const hour = now.getHours();
179
+ if (start === end)
180
+ return true;
181
+ if (start < end)
182
+ return hour >= start && hour < end;
183
+ return hour >= start || hour < end;
184
+ }
185
+ export function getSystemIdleMinutes() {
186
+ if (process.platform !== "darwin")
187
+ return null;
188
+ try {
189
+ const output = execFileSync("ioreg", ["-c", "IOHIDSystem"], { encoding: "utf8", timeout: 2000 });
190
+ const match = output.match(/HIDIdleTime"\s*=\s*(\d+)/);
191
+ if (!match)
192
+ return null;
193
+ const nanoseconds = Number(match[1]);
194
+ return nanoseconds / 1_000_000_000 / 60;
195
+ }
196
+ catch {
197
+ return null;
198
+ }
199
+ }
200
+ export function createSkipRunRecord(input) {
201
+ const finishedAt = input.finishedAt ?? new Date().toISOString();
202
+ return {
203
+ id: `dream-${Date.parse(input.startedAt)}-${Math.random().toString(36).slice(2, 8)}`,
204
+ trigger: input.trigger,
205
+ status: "skipped",
206
+ startedAt: input.startedAt,
207
+ finishedAt,
208
+ durationMs: Math.max(0, Date.parse(finishedAt) - Date.parse(input.startedAt)),
209
+ machine: { hostname: os.hostname(), machineId: input.machineId },
210
+ provider: input.provider,
211
+ model: input.model,
212
+ gates: input.gates,
213
+ phases: [],
214
+ llmCalls: [],
215
+ totals: {
216
+ llmCallsMade: 0,
217
+ llmCallsSkipped: 0,
218
+ estimatedInputTokens: 0,
219
+ estimatedOutputTokens: 0,
220
+ estimatedCostUsd: 0,
221
+ },
222
+ effectiveness: {
223
+ usefulOutputScore: 0,
224
+ costPerUsefulOutput: null,
225
+ decaysApplied: 0,
226
+ summariesGenerated: 0,
227
+ summariesUpdated: 0,
228
+ reviewSuggestions: 0,
229
+ relationshipsDiscovered: 0,
230
+ },
231
+ errors: [],
232
+ skipReason: input.reason,
233
+ };
234
+ }
@@ -5,7 +5,6 @@
5
5
  * Embeddings are stored in SQLite as regeneratable sidecar data.
6
6
  */
7
7
  // Dynamic import — gracefully handles missing native module (dlopen failures)
8
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
9
8
  let Database = null;
10
9
  try {
11
10
  Database = (await import("better-sqlite3")).default;
@@ -17,10 +16,8 @@ import path from "path";
17
16
  import fs from "fs/promises";
18
17
  import { enableWAL } from "./lock.js";
19
18
  const MODEL_NAME = "Xenova/all-MiniLM-L6-v2";
20
- const EMBEDDING_DIM = 384;
21
19
  export class GnosysEmbeddings {
22
20
  pipeline = null;
23
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
24
21
  db = null;
25
22
  storePath;
26
23
  modelReady = false;
@@ -45,6 +42,9 @@ export class GnosysEmbeddings {
45
42
  // Dynamic import — keeps @huggingface/transformers out of the main bundle.
46
43
  // dtype 'q8' replaces the v2-era `quantized: true` option (8-bit quantized,
47
44
  // ~80 MB vs ~280 MB for fp32). Smaller is fine for sentence embeddings.
45
+ // Use `any` here so `tsc` succeeds even when the optional dep is not installed
46
+ // (CI network-share-simulation job, fresh checkouts, etc.). The real type
47
+ // is only needed at runtime when the package is present.
48
48
  let pipeline;
49
49
  try {
50
50
  ({ 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
+ }
@@ -14,9 +14,10 @@ interface BundleManifest {
14
14
  source_user: string;
15
15
  gnosys_version: string;
16
16
  }
17
- /** A memory row with its embedding base64-encoded for JSON transport. */
18
- export interface PortableMemory extends Omit<DbMemory, "embedding"> {
17
+ /** A memory row with its binary columns base64-encoded for JSON transport. */
18
+ export interface PortableMemory extends Omit<DbMemory, "embedding" | "attachment_data"> {
19
19
  embedding_b64: string | null;
20
+ attachment_data_b64: string | null;
20
21
  }
21
22
  export interface ProjectBundle {
22
23
  manifest: BundleManifest;
@@ -34,10 +34,11 @@ export function exportProject(db, opts) {
34
34
  const totalIncludingArchived = db.getMemoriesByProject(opts.projectId, true).length;
35
35
  const archivedExcluded = opts.includeArchived ? 0 : totalIncludingArchived - rawMemories.length;
36
36
  const memories = rawMemories.map((m) => {
37
- const { embedding: _embedding, ...rest } = m;
37
+ const { embedding: _embedding, attachment_data: _attachment, ...rest } = m;
38
38
  return {
39
39
  ...rest,
40
40
  embedding_b64: m.embedding ? Buffer.from(m.embedding).toString("base64") : null,
41
+ attachment_data_b64: m.attachment_data ? Buffer.from(m.attachment_data).toString("base64") : null,
41
42
  };
42
43
  });
43
44
  const memoryIds = rawMemories.map((m) => m.id);
@@ -132,7 +132,7 @@ export function detectAmbiguity(db, query, opts) {
132
132
  const projectHits = new Map();
133
133
  for (const r of results) {
134
134
  const mem = db.getMemory(r.id);
135
- if (!mem || !mem.project_id)
135
+ if (!mem?.project_id)
136
136
  continue;
137
137
  projectHits.set(mem.project_id, (projectHits.get(mem.project_id) || 0) + 1);
138
138
  }
@@ -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 {};