gnosys 5.11.4 → 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 (240) hide show
  1. package/dist/cli.js +324 -5150
  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/importCommand.d.ts +16 -0
  74. package/dist/lib/importCommand.js +89 -0
  75. package/dist/lib/importProjectCommand.d.ts +6 -0
  76. package/dist/lib/importProjectCommand.js +43 -0
  77. package/dist/lib/ingestCommand.d.ts +13 -0
  78. package/dist/lib/ingestCommand.js +95 -0
  79. package/dist/lib/installOutput.d.ts +36 -0
  80. package/dist/lib/installOutput.js +55 -0
  81. package/dist/lib/lensCommand.d.ts +20 -0
  82. package/dist/lib/lensCommand.js +61 -0
  83. package/dist/lib/lensing.d.ts +1 -0
  84. package/dist/lib/lensing.js +50 -9
  85. package/dist/lib/linksCommand.d.ts +7 -0
  86. package/dist/lib/linksCommand.js +48 -0
  87. package/dist/lib/listCommand.d.ts +8 -0
  88. package/dist/lib/listCommand.js +74 -0
  89. package/dist/lib/llm.d.ts +1 -1
  90. package/dist/lib/llm.js +26 -8
  91. package/dist/lib/localDiskCheck.d.ts +17 -0
  92. package/dist/lib/localDiskCheck.js +54 -0
  93. package/dist/lib/machineConfig.d.ts +11 -1
  94. package/dist/lib/machineConfig.js +16 -0
  95. package/dist/lib/machineRegistry.d.ts +61 -0
  96. package/dist/lib/machineRegistry.js +80 -0
  97. package/dist/lib/maintainCommand.d.ts +8 -0
  98. package/dist/lib/maintainCommand.js +34 -0
  99. package/dist/lib/masterLease.d.ts +20 -0
  100. package/dist/lib/masterLease.js +68 -0
  101. package/dist/lib/migrateCommand.d.ts +7 -0
  102. package/dist/lib/migrateCommand.js +158 -0
  103. package/dist/lib/migrateDbCommand.d.ts +9 -0
  104. package/dist/lib/migrateDbCommand.js +94 -0
  105. package/dist/lib/modelValidation.d.ts +5 -0
  106. package/dist/lib/modelValidation.js +27 -0
  107. package/dist/lib/openrouterTiers.d.ts +29 -0
  108. package/dist/lib/openrouterTiers.js +113 -0
  109. package/dist/lib/prefCommand.d.ts +10 -0
  110. package/dist/lib/prefCommand.js +118 -0
  111. package/dist/lib/projectsCommand.d.ts +8 -0
  112. package/dist/lib/projectsCommand.js +131 -0
  113. package/dist/lib/readCommand.d.ts +7 -0
  114. package/dist/lib/readCommand.js +62 -0
  115. package/dist/lib/recall.d.ts +3 -0
  116. package/dist/lib/recall.js +19 -4
  117. package/dist/lib/recallCommand.d.ts +11 -0
  118. package/dist/lib/recallCommand.js +112 -0
  119. package/dist/lib/reflectCommand.d.ts +8 -0
  120. package/dist/lib/reflectCommand.js +61 -0
  121. package/dist/lib/reindexCommand.d.ts +4 -0
  122. package/dist/lib/reindexCommand.js +34 -0
  123. package/dist/lib/reindexGraphCommand.d.ts +4 -0
  124. package/dist/lib/reindexGraphCommand.js +12 -0
  125. package/dist/lib/reinforceCommand.d.ts +8 -0
  126. package/dist/lib/reinforceCommand.js +40 -0
  127. package/dist/lib/remote.d.ts +5 -1
  128. package/dist/lib/remote.js +5 -1
  129. package/dist/lib/remoteWizard.d.ts +24 -5
  130. package/dist/lib/remoteWizard.js +308 -319
  131. package/dist/lib/restoreCommand.d.ts +5 -0
  132. package/dist/lib/restoreCommand.js +35 -0
  133. package/dist/lib/sandboxStartCommand.d.ts +6 -0
  134. package/dist/lib/sandboxStartCommand.js +25 -0
  135. package/dist/lib/sandboxStatusCommand.d.ts +4 -0
  136. package/dist/lib/sandboxStatusCommand.js +24 -0
  137. package/dist/lib/sandboxStopCommand.d.ts +4 -0
  138. package/dist/lib/sandboxStopCommand.js +21 -0
  139. package/dist/lib/searchCommand.d.ts +9 -0
  140. package/dist/lib/searchCommand.js +90 -0
  141. package/dist/lib/semanticSearchCommand.d.ts +8 -0
  142. package/dist/lib/semanticSearchCommand.js +52 -0
  143. package/dist/lib/setup/configSetRender.js +2 -0
  144. package/dist/lib/setup/providerGlyphs.d.ts +19 -0
  145. package/dist/lib/setup/providerGlyphs.js +42 -0
  146. package/dist/lib/setup/remoteRender.d.ts +31 -1
  147. package/dist/lib/setup/remoteRender.js +95 -4
  148. package/dist/lib/setup/sections/providers.d.ts +17 -0
  149. package/dist/lib/setup/sections/providers.js +255 -0
  150. package/dist/lib/setup/sections/routing.d.ts +2 -6
  151. package/dist/lib/setup/sections/routing.js +33 -85
  152. package/dist/lib/setup/sections/taskRoutingEditor.d.ts +17 -0
  153. package/dist/lib/setup/sections/taskRoutingEditor.js +149 -0
  154. package/dist/lib/setup/summary.d.ts +9 -0
  155. package/dist/lib/setup/summary.js +51 -37
  156. package/dist/lib/setup/ui/status.d.ts +1 -0
  157. package/dist/lib/setup/ui/status.js +2 -0
  158. package/dist/lib/setup.d.ts +108 -3
  159. package/dist/lib/setup.js +762 -157
  160. package/dist/lib/setupKeys.d.ts +42 -0
  161. package/dist/lib/setupKeys.js +564 -0
  162. package/dist/lib/setupRemoteCommand.d.ts +4 -0
  163. package/dist/lib/setupRemoteCommand.js +28 -0
  164. package/dist/lib/setupRemotePullCommand.d.ts +5 -0
  165. package/dist/lib/setupRemotePullCommand.js +52 -0
  166. package/dist/lib/setupRemotePushCommand.d.ts +5 -0
  167. package/dist/lib/setupRemotePushCommand.js +57 -0
  168. package/dist/lib/setupRemoteResolveCommand.d.ts +4 -0
  169. package/dist/lib/setupRemoteResolveCommand.js +48 -0
  170. package/dist/lib/setupRemoteStatusCommand.d.ts +4 -0
  171. package/dist/lib/setupRemoteStatusCommand.js +73 -0
  172. package/dist/lib/setupRemoteSyncCommand.d.ts +6 -0
  173. package/dist/lib/setupRemoteSyncCommand.js +65 -0
  174. package/dist/lib/setupSyncProjectsCommand.d.ts +4 -0
  175. package/dist/lib/setupSyncProjectsCommand.js +292 -0
  176. package/dist/lib/staleCommand.d.ts +8 -0
  177. package/dist/lib/staleCommand.js +34 -0
  178. package/dist/lib/statsCommand.d.ts +6 -0
  179. package/dist/lib/statsCommand.js +142 -0
  180. package/dist/lib/statusCommand.d.ts +18 -0
  181. package/dist/lib/statusCommand.js +250 -0
  182. package/dist/lib/storesCommand.d.ts +2 -0
  183. package/dist/lib/storesCommand.js +4 -0
  184. package/dist/lib/syncClient.d.ts +47 -0
  185. package/dist/lib/syncClient.js +212 -0
  186. package/dist/lib/syncCommand.d.ts +6 -0
  187. package/dist/lib/syncCommand.js +57 -0
  188. package/dist/lib/syncDoctorCommand.d.ts +5 -0
  189. package/dist/lib/syncDoctorCommand.js +100 -0
  190. package/dist/lib/syncIngest.d.ts +19 -0
  191. package/dist/lib/syncIngest.js +152 -0
  192. package/dist/lib/syncIngestLaunchd.d.ts +8 -0
  193. package/dist/lib/syncIngestLaunchd.js +93 -0
  194. package/dist/lib/syncIngestStartup.d.ts +5 -0
  195. package/dist/lib/syncIngestStartup.js +29 -0
  196. package/dist/lib/syncIngestSystemd.d.ts +10 -0
  197. package/dist/lib/syncIngestSystemd.js +97 -0
  198. package/dist/lib/syncIngestTimer.d.ts +8 -0
  199. package/dist/lib/syncIngestTimer.js +27 -0
  200. package/dist/lib/syncIngestTimerCommand.d.ts +7 -0
  201. package/dist/lib/syncIngestTimerCommand.js +83 -0
  202. package/dist/lib/syncLock.d.ts +6 -0
  203. package/dist/lib/syncLock.js +74 -0
  204. package/dist/lib/syncSnapshot.d.ts +30 -0
  205. package/dist/lib/syncSnapshot.js +184 -0
  206. package/dist/lib/syncStaging.d.ts +81 -0
  207. package/dist/lib/syncStaging.js +239 -0
  208. package/dist/lib/tagsAddCommand.d.ts +8 -0
  209. package/dist/lib/tagsAddCommand.js +18 -0
  210. package/dist/lib/tagsCommand.d.ts +4 -0
  211. package/dist/lib/tagsCommand.js +16 -0
  212. package/dist/lib/timelineCommand.d.ts +7 -0
  213. package/dist/lib/timelineCommand.js +49 -0
  214. package/dist/lib/traceCommand.d.ts +6 -0
  215. package/dist/lib/traceCommand.js +39 -0
  216. package/dist/lib/traverseCommand.d.ts +6 -0
  217. package/dist/lib/traverseCommand.js +58 -0
  218. package/dist/lib/updateCommand.d.ts +13 -0
  219. package/dist/lib/updateCommand.js +67 -0
  220. package/dist/lib/updateStatusCommand.d.ts +5 -0
  221. package/dist/lib/updateStatusCommand.js +38 -0
  222. package/dist/lib/webAddCommand.d.ts +8 -0
  223. package/dist/lib/webAddCommand.js +55 -0
  224. package/dist/lib/webBuildCommand.d.ts +10 -0
  225. package/dist/lib/webBuildCommand.js +65 -0
  226. package/dist/lib/webBuildIndexCommand.d.ts +8 -0
  227. package/dist/lib/webBuildIndexCommand.js +37 -0
  228. package/dist/lib/webIngestCommand.d.ts +11 -0
  229. package/dist/lib/webIngestCommand.js +51 -0
  230. package/dist/lib/webInitCommand.d.ts +9 -0
  231. package/dist/lib/webInitCommand.js +167 -0
  232. package/dist/lib/webRemoveCommand.d.ts +5 -0
  233. package/dist/lib/webRemoveCommand.js +41 -0
  234. package/dist/lib/webStatusCommand.d.ts +5 -0
  235. package/dist/lib/webStatusCommand.js +94 -0
  236. package/dist/lib/webUpdateCommand.d.ts +7 -0
  237. package/dist/lib/webUpdateCommand.js +72 -0
  238. package/dist/lib/workingSetCommand.d.ts +6 -0
  239. package/dist/lib/workingSetCommand.js +37 -0
  240. package/package.json +2 -1
@@ -0,0 +1,195 @@
1
+ import { GnosysResolver } from "./resolver.js";
2
+ import { GnosysDB } from "./db.js";
3
+ import { loadConfig } from "./config.js";
4
+ import { acquireDreamLock, appendDreamRun, countChangedMemoriesSince, createSkipRunRecord, getSystemIdleMinutes, isInsideNightWindow, readDreamState, } from "./dreamRunLog.js";
5
+ export async function runDreamCommand(opts) {
6
+ const resolver = new GnosysResolver();
7
+ await resolver.resolve();
8
+ const stores = resolver.getStores();
9
+ if (stores.length === 0) {
10
+ console.error("No Gnosys stores found. Run 'gnosys init' first.");
11
+ process.exit(1);
12
+ }
13
+ const { GnosysDB: DbClass } = await import("./db.js");
14
+ const { GnosysDreamEngine, formatDreamReport } = await import("./dream.js");
15
+ const { getMachineId } = await import("./remote.js");
16
+ const storePath = stores[0].path;
17
+ const cfg = await loadConfig(storePath);
18
+ const db = new DbClass(storePath);
19
+ if (!db.isAvailable() || !db.isMigrated()) {
20
+ console.error("Dream Mode requires gnosys.db (v2.0). Run 'gnosys migrate' first.");
21
+ process.exit(1);
22
+ }
23
+ const trigger = opts.scheduled ? "scheduled" : "manual";
24
+ const gates = [];
25
+ // Machine-level lock — only one dream may run per machine at a time.
26
+ const lock = acquireDreamLock();
27
+ if (!lock.acquired) {
28
+ appendDreamRun(createSkipRunRecord({
29
+ trigger,
30
+ startedAt: new Date().toISOString(),
31
+ provider: cfg.dream?.provider || "ollama",
32
+ model: cfg.dream?.model,
33
+ gates: [{ name: "lock", passed: false, reason: lock.reason }],
34
+ reason: lock.reason,
35
+ }));
36
+ if (!opts.scheduled)
37
+ console.error(lock.reason);
38
+ db.close();
39
+ if (!opts.scheduled)
40
+ process.exit(1);
41
+ return;
42
+ }
43
+ try {
44
+ // Designation gate — warn (and exit unless --force) if this isn't the
45
+ // designated dream machine. Manual runs from non-designated machines are
46
+ // useful for testing but shouldn't happen by accident on shared brains.
47
+ const centralDb = GnosysDB.openCentral();
48
+ let localId;
49
+ if (centralDb.isAvailable()) {
50
+ const designated = centralDb.getDreamMachineId();
51
+ localId = getMachineId(centralDb);
52
+ if (designated) {
53
+ if (designated !== localId && !opts.force) {
54
+ const reason = `Dream is designated to machine ${designated}, but this is ${localId}.`;
55
+ gates.push({ name: "designation", passed: false, reason, details: { designated, localId } });
56
+ appendDreamRun(createSkipRunRecord({
57
+ trigger,
58
+ startedAt: new Date().toISOString(),
59
+ provider: cfg.dream?.provider || "ollama",
60
+ model: cfg.dream?.model,
61
+ gates,
62
+ reason,
63
+ machineId: localId,
64
+ }));
65
+ if (!opts.scheduled) {
66
+ console.error(`${reason}\nPass --force to run anyway, or run 'gnosys setup dream' to redesignate.`);
67
+ }
68
+ centralDb.close();
69
+ db.close();
70
+ if (!opts.scheduled)
71
+ process.exit(1);
72
+ return;
73
+ }
74
+ gates.push({ name: "designation", passed: true, details: { designated, localId } });
75
+ }
76
+ else if (opts.scheduled) {
77
+ const reason = "No designated dream machine.";
78
+ gates.push({ name: "designation", passed: false, reason });
79
+ appendDreamRun(createSkipRunRecord({
80
+ trigger,
81
+ startedAt: new Date().toISOString(),
82
+ provider: cfg.dream?.provider || "ollama",
83
+ model: cfg.dream?.model,
84
+ gates,
85
+ reason,
86
+ machineId: localId,
87
+ }));
88
+ centralDb.close();
89
+ db.close();
90
+ return;
91
+ }
92
+ centralDb.close();
93
+ }
94
+ // Scheduled runs apply the cheap night/idle/dreamworthiness gates before
95
+ // touching the LLM. Manual runs skip these (explicit user intent).
96
+ if (opts.scheduled) {
97
+ const now = new Date();
98
+ if (!isInsideNightWindow(now, cfg.dream.schedule)) {
99
+ const reason = `Outside dream schedule (${cfg.dream.schedule.startHour}:00-${cfg.dream.schedule.endHour}:00).`;
100
+ gates.push({ name: "night-window", passed: false, reason, details: { hour: now.getHours() } });
101
+ appendDreamRun(createSkipRunRecord({ trigger, startedAt: now.toISOString(), provider: cfg.dream.provider, model: cfg.dream.model, gates, reason, machineId: localId }));
102
+ db.close();
103
+ return;
104
+ }
105
+ gates.push({ name: "night-window", passed: true, details: { hour: now.getHours() } });
106
+ const idleMinutes = getSystemIdleMinutes();
107
+ if (idleMinutes != null && idleMinutes < cfg.dream.systemIdleMinutes) {
108
+ const reason = `Machine idle ${idleMinutes.toFixed(1)}min < required ${cfg.dream.systemIdleMinutes}min.`;
109
+ gates.push({ name: "system-idle", passed: false, reason, details: { idleMinutes } });
110
+ appendDreamRun(createSkipRunRecord({ trigger, startedAt: now.toISOString(), provider: cfg.dream.provider, model: cfg.dream.model, gates, reason, machineId: localId }));
111
+ db.close();
112
+ return;
113
+ }
114
+ gates.push({ name: "system-idle", passed: true, details: { idleMinutes } });
115
+ const state = readDreamState();
116
+ const memories = db.getActiveMemories();
117
+ const changed = countChangedMemoriesSince(memories, state.lastMemoryMaxModified);
118
+ const lastRunMs = state.lastSuccessfulRunAt ? Date.parse(state.lastSuccessfulRunAt) : 0;
119
+ const hoursSince = lastRunMs ? (Date.now() - lastRunMs) / 3_600_000 : Infinity;
120
+ const enoughMemories = changed >= cfg.dream.minNewMemoriesToDream;
121
+ const enoughTime = hoursSince >= cfg.dream.minHoursBetweenRuns;
122
+ if (!enoughMemories || !enoughTime) {
123
+ const reason = `Not dreamworthy yet (${changed} changed memories, ${hoursSince === Infinity ? "never" : hoursSince.toFixed(1)}h since last run).`;
124
+ gates.push({
125
+ name: "dreamworthiness",
126
+ passed: false,
127
+ reason,
128
+ details: { changed, minChanged: cfg.dream.minNewMemoriesToDream, hoursSince, minHours: cfg.dream.minHoursBetweenRuns },
129
+ });
130
+ appendDreamRun(createSkipRunRecord({ trigger, startedAt: now.toISOString(), provider: cfg.dream.provider, model: cfg.dream.model, gates, reason, machineId: localId }));
131
+ db.close();
132
+ return;
133
+ }
134
+ gates.push({ name: "dreamworthiness", passed: true, details: { changed, hoursSince } });
135
+ }
136
+ const dreamConfig = {
137
+ enabled: true,
138
+ idleMinutes: 0,
139
+ maxRuntimeMinutes: opts.maxRuntime ? parseInt(opts.maxRuntime, 10) : 30,
140
+ selfCritique: opts.critique !== false,
141
+ generateSummaries: opts.summaries !== false,
142
+ discoverRelationships: opts.relationships !== false,
143
+ minMemories: 1,
144
+ provider: cfg.dream?.provider || "ollama",
145
+ model: cfg.dream?.model,
146
+ schedule: cfg.dream?.schedule,
147
+ systemIdleMinutes: cfg.dream?.systemIdleMinutes,
148
+ minNewMemoriesToDream: cfg.dream?.minNewMemoriesToDream,
149
+ minHoursBetweenRuns: cfg.dream?.minHoursBetweenRuns,
150
+ maxLLMCallsPerRun: cfg.dream?.maxLLMCallsPerRun,
151
+ };
152
+ console.error("Starting Dream Mode cycle...");
153
+ const engine = new GnosysDreamEngine(db, cfg, dreamConfig, { trigger, machineId: localId });
154
+ const report = await engine.dream((phase, detail) => {
155
+ console.error(` [${phase}] ${detail}`);
156
+ });
157
+ appendDreamRun({
158
+ ...report,
159
+ id: report.id || `dream-${Date.now()}`,
160
+ trigger,
161
+ status: report.aborted ? "aborted" : report.errors.length > 0 ? "failed" : "completed",
162
+ machine: report.machine || { hostname: "unknown", machineId: localId },
163
+ provider: report.provider || dreamConfig.provider,
164
+ phases: report.phases || [],
165
+ llmCalls: report.llmCalls || [],
166
+ totals: report.totals || {
167
+ llmCallsMade: 0,
168
+ llmCallsSkipped: 0,
169
+ estimatedInputTokens: 0,
170
+ estimatedOutputTokens: 0,
171
+ estimatedCostUsd: 0,
172
+ },
173
+ effectiveness: report.effectiveness || {
174
+ usefulOutputScore: 0,
175
+ costPerUsefulOutput: null,
176
+ decaysApplied: report.decayUpdated,
177
+ summariesGenerated: report.summariesGenerated,
178
+ summariesUpdated: report.summariesUpdated,
179
+ reviewSuggestions: report.reviewSuggestions.length,
180
+ relationshipsDiscovered: report.relationshipsDiscovered,
181
+ },
182
+ gates,
183
+ });
184
+ if (opts.json) {
185
+ console.log(JSON.stringify(report, null, 2));
186
+ }
187
+ else {
188
+ console.log(formatDreamReport(report));
189
+ }
190
+ db.close();
191
+ }
192
+ finally {
193
+ lock.release();
194
+ }
195
+ }
@@ -0,0 +1,2 @@
1
+ export declare function installDreamLaunchAgent(): string | null;
2
+ export declare function uninstallDreamLaunchAgent(): string | null;
@@ -0,0 +1,72 @@
1
+ import fs from "fs";
2
+ import os from "os";
3
+ import path from "path";
4
+ const LABEL = "com.gnosys.dream";
5
+ function plistPath() {
6
+ return path.join(os.homedir(), "Library", "LaunchAgents", `${LABEL}.plist`);
7
+ }
8
+ function xmlEscape(value) {
9
+ return value
10
+ .replace(/&/g, "&amp;")
11
+ .replace(/</g, "&lt;")
12
+ .replace(/>/g, "&gt;")
13
+ .replace(/"/g, "&quot;");
14
+ }
15
+ export function installDreamLaunchAgent() {
16
+ if (process.platform !== "darwin")
17
+ return null;
18
+ const file = plistPath();
19
+ const nodePath = process.execPath;
20
+ const cliPath = process.argv[1] || "gnosys";
21
+ const logPath = path.join(os.tmpdir(), "gnosys-dream.log");
22
+ const pathEnv = `${path.dirname(nodePath)}:/usr/local/bin:/usr/bin:/bin`;
23
+ const body = `<?xml version="1.0" encoding="UTF-8"?>
24
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
25
+ <plist version="1.0">
26
+ <dict>
27
+ <key>Label</key>
28
+ <string>${LABEL}</string>
29
+ <key>ProgramArguments</key>
30
+ <array>
31
+ <string>${xmlEscape(nodePath)}</string>
32
+ <string>${xmlEscape(cliPath)}</string>
33
+ <string>dream</string>
34
+ <string>run</string>
35
+ <string>--scheduled</string>
36
+ </array>
37
+ <key>StartCalendarInterval</key>
38
+ <array>
39
+ <dict><key>Hour</key><integer>2</integer><key>Minute</key><integer>0</integer></dict>
40
+ <dict><key>Hour</key><integer>3</integer><key>Minute</key><integer>0</integer></dict>
41
+ <dict><key>Hour</key><integer>4</integer><key>Minute</key><integer>0</integer></dict>
42
+ </array>
43
+ <key>StandardOutPath</key>
44
+ <string>${xmlEscape(logPath)}</string>
45
+ <key>StandardErrorPath</key>
46
+ <string>${xmlEscape(logPath)}</string>
47
+ <key>EnvironmentVariables</key>
48
+ <dict>
49
+ <key>HOME</key>
50
+ <string>${xmlEscape(os.homedir())}</string>
51
+ <key>PATH</key>
52
+ <string>${xmlEscape(pathEnv)}</string>
53
+ </dict>
54
+ </dict>
55
+ </plist>
56
+ `;
57
+ fs.mkdirSync(path.dirname(file), { recursive: true });
58
+ fs.writeFileSync(file, body, "utf8");
59
+ return file;
60
+ }
61
+ export function uninstallDreamLaunchAgent() {
62
+ if (process.platform !== "darwin")
63
+ return null;
64
+ const file = plistPath();
65
+ try {
66
+ fs.unlinkSync(file);
67
+ }
68
+ catch {
69
+ // Missing is already uninstalled.
70
+ }
71
+ return file;
72
+ }
@@ -0,0 +1,10 @@
1
+ export type DreamLogOptions = {
2
+ last: string;
3
+ since?: string;
4
+ failuresOnly?: boolean;
5
+ json?: boolean;
6
+ };
7
+ export type DreamLogContext = {
8
+ parentJson?: boolean;
9
+ };
10
+ export declare function runDreamLogCommand(opts: DreamLogOptions, context?: DreamLogContext): Promise<void>;
@@ -0,0 +1,58 @@
1
+ import { GnosysDB } from "./db.js";
2
+ export async function runDreamLogCommand(opts, context = {}) {
3
+ let centralDb = null;
4
+ try {
5
+ centralDb = GnosysDB.openCentral();
6
+ if (!centralDb.isAvailable()) {
7
+ console.error("Central DB not available.");
8
+ process.exitCode = 1;
9
+ return;
10
+ }
11
+ const limit = Math.max(1, parseInt(opts.last) || 20);
12
+ const sinceIso = opts.since ? `${opts.since}T00:00:00Z` : undefined;
13
+ const runs = centralDb.getRecentDreamRuns(limit, {
14
+ failuresOnly: !!opts.failuresOnly,
15
+ sinceIso,
16
+ });
17
+ const wantJson = !!opts.json || !!context.parentJson;
18
+ // JSON path always emits a structured response — including empty runs.
19
+ if (wantJson) {
20
+ console.log(JSON.stringify({ count: runs.length, runs }, null, 2));
21
+ return;
22
+ }
23
+ if (runs.length === 0) {
24
+ console.log("No dream runs recorded.");
25
+ return;
26
+ }
27
+ const DIM = "\x1b[2m";
28
+ const RESET = "\x1b[0m";
29
+ const RED = "\x1b[31m";
30
+ const GREEN = "\x1b[32m";
31
+ console.log(`${runs.length} dream run(s):\n`);
32
+ for (const r of runs) {
33
+ const d = r.details;
34
+ const dur = r.durationMs != null ? `${(r.durationMs / 1000).toFixed(1)}s` : "—";
35
+ const summaries = Number(d.summariesGenerated || 0);
36
+ const decays = Number(d.decayUpdated || 0);
37
+ const reviews = Number(d.reviewSuggestions || 0);
38
+ const rels = Number(d.relationshipsDiscovered || 0);
39
+ const errors = Number(d.errors || 0);
40
+ const unreachable = Boolean(d.providerUnreachable);
41
+ const status = unreachable
42
+ ? `${RED}provider unreachable${RESET}`
43
+ : errors > 0
44
+ ? `${RED}${errors} error(s)${RESET}`
45
+ : summaries + decays + rels > 0
46
+ ? `${GREEN}did work${RESET}`
47
+ : `${DIM}no LLM work${RESET}`;
48
+ console.log(` ${r.completed} ${DIM}(${dur})${RESET} ${status}`);
49
+ console.log(` decays=${decays} summaries=${summaries} reviews=${reviews} relations=${rels}`);
50
+ if (d.provider) {
51
+ console.log(` ${DIM}provider=${d.provider}${d.model ? "/" + d.model : ""}${RESET}`);
52
+ }
53
+ }
54
+ }
55
+ finally {
56
+ centralDb?.close();
57
+ }
58
+ }
@@ -0,0 +1,7 @@
1
+ import { type DreamRunRecord } from "./dreamRunLog.js";
2
+ export interface DreamReportOptions {
3
+ output?: string;
4
+ last?: string;
5
+ }
6
+ export declare function generateDreamDashboardHtml(runs: DreamRunRecord[]): string;
7
+ export declare function runDreamReportCommand(opts: DreamReportOptions): Promise<void>;
@@ -0,0 +1,114 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import { readDreamRuns } from "./dreamRunLog.js";
4
+ function escapeHtml(value) {
5
+ return String(value ?? "")
6
+ .replace(/&/g, "&amp;")
7
+ .replace(/</g, "&lt;")
8
+ .replace(/>/g, "&gt;")
9
+ .replace(/"/g, "&quot;");
10
+ }
11
+ function fmtMoney(value) {
12
+ return `$${value.toFixed(value < 0.01 ? 4 : 2)}`;
13
+ }
14
+ function sum(runs, fn) {
15
+ return runs.reduce((total, run) => total + fn(run), 0);
16
+ }
17
+ function bar(value, max) {
18
+ const width = max <= 0 ? 0 : Math.max(2, Math.round((value / max) * 100));
19
+ return `<div class="bar"><span style="width:${width}%"></span></div>`;
20
+ }
21
+ export function generateDreamDashboardHtml(runs) {
22
+ const sorted = [...runs].sort((a, b) => Date.parse(b.startedAt) - Date.parse(a.startedAt));
23
+ const completed = sorted.filter((r) => r.status === "completed");
24
+ const totalCost = sum(sorted, (r) => r.totals.estimatedCostUsd);
25
+ const totalCalls = sum(sorted, (r) => r.totals.llmCallsMade);
26
+ const totalSkippedCalls = sum(sorted, (r) => r.totals.llmCallsSkipped);
27
+ const totalUseful = sum(sorted, (r) => r.effectiveness.usefulOutputScore);
28
+ const maxUseful = Math.max(1, ...sorted.map((r) => r.effectiveness.usefulOutputScore));
29
+ const maxCost = Math.max(0.000001, ...sorted.map((r) => r.totals.estimatedCostUsd));
30
+ const rows = sorted.map((run) => {
31
+ const phaseSummary = run.phases
32
+ .map((p) => `${p.name}: ${p.status}, ${p.memoryIdsTouched.length} memories, ${p.llmCallsMade}/${p.llmCallsSkipped} calls`)
33
+ .join("; ");
34
+ const gateSummary = run.gates
35
+ .map((g) => `${g.name}: ${g.passed ? "pass" : "skip"}${g.reason ? ` (${g.reason})` : ""}`)
36
+ .join("; ");
37
+ return `<tr>
38
+ <td>${escapeHtml(run.startedAt)}</td>
39
+ <td><span class="pill ${escapeHtml(run.status)}">${escapeHtml(run.status)}</span></td>
40
+ <td>${escapeHtml(run.trigger)}</td>
41
+ <td>${escapeHtml(run.provider)}${run.model ? `/${escapeHtml(run.model)}` : ""}</td>
42
+ <td>${(run.durationMs / 1000).toFixed(1)}s</td>
43
+ <td>${run.totals.llmCallsMade}</td>
44
+ <td>${run.totals.llmCallsSkipped}</td>
45
+ <td>${fmtMoney(run.totals.estimatedCostUsd)}</td>
46
+ <td>${run.effectiveness.usefulOutputScore}</td>
47
+ <td title="${escapeHtml(gateSummary)}">${escapeHtml(run.skipReason || phaseSummary || gateSummary || "—")}</td>
48
+ </tr>`;
49
+ }).join("\n");
50
+ const chartRows = sorted.slice(0, 30).map((run) => `<div class="runChart">
51
+ <div class="date">${escapeHtml(run.startedAt.slice(0, 16).replace("T", " "))}</div>
52
+ <div>${bar(run.effectiveness.usefulOutputScore, maxUseful)}</div>
53
+ <div>${bar(run.totals.estimatedCostUsd, maxCost)}</div>
54
+ </div>`).join("\n");
55
+ return `<!doctype html>
56
+ <html lang="en">
57
+ <head>
58
+ <meta charset="utf-8">
59
+ <meta name="viewport" content="width=device-width, initial-scale=1">
60
+ <title>Gnosys Dream Dashboard</title>
61
+ <style>
62
+ :root { color-scheme: light dark; --border: #8b949e55; --muted: #8b949e; --bg2: #8b949e18; }
63
+ body { font: 14px/1.45 -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; margin: 32px; }
64
+ h1, h2 { margin: 0 0 12px; }
65
+ .grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 12px; margin: 20px 0; }
66
+ .card { border: 1px solid var(--border); border-radius: 12px; padding: 16px; background: var(--bg2); }
67
+ .metric { font-size: 28px; font-weight: 700; }
68
+ .label { color: var(--muted); font-size: 12px; text-transform: uppercase; letter-spacing: .06em; }
69
+ table { width: 100%; border-collapse: collapse; margin-top: 16px; }
70
+ th, td { border-bottom: 1px solid var(--border); padding: 8px; text-align: left; vertical-align: top; }
71
+ th { color: var(--muted); font-size: 12px; text-transform: uppercase; letter-spacing: .04em; }
72
+ .pill { border: 1px solid var(--border); border-radius: 999px; padding: 2px 8px; }
73
+ .completed { color: #2da44e; }
74
+ .skipped { color: #bf8700; }
75
+ .failed, .aborted { color: #cf222e; }
76
+ .runChart { display: grid; grid-template-columns: 160px 1fr 1fr; gap: 10px; align-items: center; margin: 7px 0; }
77
+ .date { color: var(--muted); font-size: 12px; }
78
+ .bar { height: 10px; border-radius: 999px; background: var(--bg2); overflow: hidden; }
79
+ .bar span { display: block; height: 100%; background: currentColor; opacity: .65; }
80
+ .hint { color: var(--muted); }
81
+ </style>
82
+ </head>
83
+ <body>
84
+ <h1>Gnosys Dream Dashboard</h1>
85
+ <p class="hint">Generated from <code>~/.gnosys/dream-runs.jsonl</code>. Useful output is a weighted score: decay=1, summary generated=5, summary updated=3, relationship=2.</p>
86
+ <section class="grid">
87
+ <div class="card"><div class="label">Runs</div><div class="metric">${sorted.length}</div></div>
88
+ <div class="card"><div class="label">Completed</div><div class="metric">${completed.length}</div></div>
89
+ <div class="card"><div class="label">LLM Calls</div><div class="metric">${totalCalls}</div><div class="hint">${totalSkippedCalls} skipped</div></div>
90
+ <div class="card"><div class="label">Estimated Cost</div><div class="metric">${fmtMoney(totalCost)}</div></div>
91
+ <div class="card"><div class="label">Useful Output</div><div class="metric">${totalUseful}</div></div>
92
+ </section>
93
+
94
+ <h2>Recent Runs</h2>
95
+ <div class="runChart"><div></div><div class="label">Useful output</div><div class="label">Cost</div></div>
96
+ ${chartRows || "<p>No dream runs logged yet.</p>"}
97
+
98
+ <h2>Run Details</h2>
99
+ <table>
100
+ <thead>
101
+ <tr><th>Started</th><th>Status</th><th>Trigger</th><th>Model</th><th>Duration</th><th>Calls</th><th>Skipped</th><th>Cost</th><th>Useful</th><th>Notes</th></tr>
102
+ </thead>
103
+ <tbody>${rows}</tbody>
104
+ </table>
105
+ </body>
106
+ </html>`;
107
+ }
108
+ export async function runDreamReportCommand(opts) {
109
+ const limit = opts.last ? Math.max(1, parseInt(opts.last, 10) || 100) : undefined;
110
+ const runs = readDreamRuns({ limit });
111
+ const output = path.resolve(opts.output || "dream-dashboard.html");
112
+ fs.writeFileSync(output, generateDreamDashboardHtml(runs), "utf8");
113
+ console.log(`Wrote ${output}`);
114
+ }
@@ -0,0 +1,121 @@
1
+ import type { DbMemory } from "./db.js";
2
+ import type { DreamConfig } from "./config.js";
3
+ export type DreamTrigger = "manual" | "scheduled";
4
+ export type DreamRunStatus = "completed" | "skipped" | "aborted" | "failed";
5
+ export interface DreamRunGateResult {
6
+ name: "designation" | "night-window" | "system-idle" | "dreamworthiness" | "lock";
7
+ passed: boolean;
8
+ reason?: string;
9
+ details?: Record<string, unknown>;
10
+ }
11
+ export interface DreamRunPhaseRecord {
12
+ name: "decay" | "critique" | "summaries" | "relationships";
13
+ status: "ran" | "skipped";
14
+ reason?: string;
15
+ durationMs: number;
16
+ memoryIdsTouched: string[];
17
+ llmCallsMade: number;
18
+ llmCallsSkipped: number;
19
+ estimatedInputTokens: number;
20
+ estimatedOutputTokens: number;
21
+ estimatedCostUsd: number;
22
+ }
23
+ export interface DreamLLMCallRecord {
24
+ phase: DreamRunPhaseRecord["name"];
25
+ label: string;
26
+ status: "made" | "skipped" | "failed";
27
+ reason?: string;
28
+ model: string;
29
+ provider: string;
30
+ memoryIds: string[];
31
+ fingerprint?: string;
32
+ estimatedInputTokens: number;
33
+ estimatedOutputTokens: number;
34
+ estimatedCostUsd: number;
35
+ }
36
+ export interface DreamEffectivenessRecord {
37
+ usefulOutputScore: number;
38
+ costPerUsefulOutput: number | null;
39
+ decaysApplied: number;
40
+ summariesGenerated: number;
41
+ summariesUpdated: number;
42
+ reviewSuggestions: number;
43
+ relationshipsDiscovered: number;
44
+ }
45
+ export interface DreamRunRecord {
46
+ id: string;
47
+ trigger: DreamTrigger;
48
+ status: DreamRunStatus;
49
+ startedAt: string;
50
+ finishedAt: string;
51
+ durationMs: number;
52
+ machine: {
53
+ hostname: string;
54
+ machineId?: string;
55
+ };
56
+ provider: string;
57
+ model?: string;
58
+ gates: DreamRunGateResult[];
59
+ phases: DreamRunPhaseRecord[];
60
+ llmCalls: DreamLLMCallRecord[];
61
+ totals: {
62
+ llmCallsMade: number;
63
+ llmCallsSkipped: number;
64
+ estimatedInputTokens: number;
65
+ estimatedOutputTokens: number;
66
+ estimatedCostUsd: number;
67
+ };
68
+ effectiveness: DreamEffectivenessRecord;
69
+ errors: string[];
70
+ skipReason?: string;
71
+ }
72
+ export interface DreamState {
73
+ lastRunAt?: string;
74
+ lastSuccessfulRunAt?: string;
75
+ lastMemoryMaxModified?: string;
76
+ lastMemoryCount?: number;
77
+ analyzedFingerprints: Record<string, {
78
+ kind: "summary" | "critique" | "relationship";
79
+ lastAnalyzedAt: string;
80
+ memoryIds: string[];
81
+ }>;
82
+ }
83
+ export interface DreamReadOptions {
84
+ limit?: number;
85
+ sinceIso?: string;
86
+ status?: DreamRunStatus;
87
+ }
88
+ export declare function getDreamRunsPath(): string;
89
+ export declare function getDreamStatePath(): string;
90
+ export declare function getDreamLockPath(): string;
91
+ export declare function acquireDreamLock(): {
92
+ acquired: true;
93
+ release: () => void;
94
+ } | {
95
+ acquired: false;
96
+ reason: string;
97
+ };
98
+ export declare function estimateTokens(text: string): number;
99
+ export declare function estimateCost(model: string | undefined, inputTokens: number, outputTokens: number): number;
100
+ export declare function readDreamState(): DreamState;
101
+ export declare function writeDreamState(state: DreamState): void;
102
+ export declare function appendDreamRun(record: DreamRunRecord): void;
103
+ export declare function readDreamRuns(opts?: DreamReadOptions): DreamRunRecord[];
104
+ export declare function fingerprintMemories(kind: "summary" | "critique" | "relationship", memories: DbMemory[]): string;
105
+ export declare function memoryWatermark(memories: DbMemory[]): {
106
+ count: number;
107
+ maxModified: string | undefined;
108
+ };
109
+ export declare function countChangedMemoriesSince(memories: DbMemory[], sinceIso?: string): number;
110
+ export declare function isInsideNightWindow(now: Date, schedule: DreamConfig["schedule"]): boolean;
111
+ export declare function getSystemIdleMinutes(): number | null;
112
+ export declare function createSkipRunRecord(input: {
113
+ trigger: DreamTrigger;
114
+ startedAt: string;
115
+ finishedAt?: string;
116
+ provider: string;
117
+ model?: string;
118
+ gates: DreamRunGateResult[];
119
+ reason: string;
120
+ machineId?: string;
121
+ }): DreamRunRecord;