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,142 @@
1
+ import { GnosysTagRegistry } from "./tags.js";
2
+ import { GnosysSearch } from "./search.js";
3
+ import { loadConfig } from "./config.js";
4
+ import { getLLMProvider } from "./llm.js";
5
+ import { GnosysDB } from "./db.js";
6
+ export async function runCommitContextCommand(getResolver, resolveProjectId, context, opts) {
7
+ const resolver = await getResolver();
8
+ const writeTarget = resolver.getWriteTarget(opts.store || undefined);
9
+ if (!writeTarget) {
10
+ console.error("No writable store found.");
11
+ process.exit(1);
12
+ }
13
+ const tagRegistry = new GnosysTagRegistry(writeTarget.store.getStorePath());
14
+ await tagRegistry.load();
15
+ const { GnosysIngestion } = await import("./ingest.js");
16
+ const ingestion = new GnosysIngestion(writeTarget.store, tagRegistry);
17
+ if (!ingestion.isLLMAvailable) {
18
+ console.error("Error: No LLM provider available. Add an API key to ~/.config/gnosys/.env or use a local model: gnosys config set provider ollama");
19
+ process.exit(1);
20
+ }
21
+ // Build search index
22
+ const stores = resolver.getStores();
23
+ const search = new GnosysSearch(stores[0].path);
24
+ search.clearIndex();
25
+ for (const s of stores) {
26
+ await search.addStoreMemories(s.store, s.label);
27
+ }
28
+ // Step 1: Extract candidates via LLM abstraction
29
+ console.log("Extracting knowledge candidates from context...");
30
+ // Load config for the write target store
31
+ const ccConfig = await loadConfig(writeTarget.store.getStorePath());
32
+ let extractProvider;
33
+ try {
34
+ extractProvider = getLLMProvider(ccConfig, "structuring");
35
+ }
36
+ catch (err) {
37
+ console.error(`LLM not available: ${err instanceof Error ? err.message : String(err)}`);
38
+ search.close();
39
+ process.exit(1);
40
+ }
41
+ const extractText = await extractProvider.generate(`Extract atomic knowledge items from this context:\n\n${context}`, {
42
+ system: `You extract atomic knowledge items from conversations. Each item should be ONE decision, fact, insight, or observation — not compound.
43
+
44
+ Output a JSON array of objects, each with:
45
+ - summary: One-sentence description of the knowledge
46
+ - type: "decision" | "insight" | "fact" | "observation" | "requirement"
47
+ - search_terms: 3-5 keywords someone would search for to find if this already exists
48
+
49
+ Be selective. Only extract things worth remembering long-term. Skip small talk, debugging steps, and transient details. Focus on decisions made, architecture choices, requirements established, and insights gained.
50
+
51
+ Output ONLY the JSON array, no markdown fences.`,
52
+ maxTokens: 4000,
53
+ });
54
+ let candidates;
55
+ try {
56
+ const jsonMatch = extractText.match(/```json\s*([\s\S]*?)```/) ||
57
+ extractText.match(/```\s*([\s\S]*?)```/) || [null, extractText];
58
+ candidates = JSON.parse(jsonMatch[1] || extractText);
59
+ }
60
+ catch {
61
+ console.error("Failed to extract candidates — LLM output was not valid JSON.");
62
+ search.close();
63
+ process.exit(1);
64
+ }
65
+ if (!Array.isArray(candidates) || candidates.length === 0) {
66
+ console.log("No extractable knowledge found in the provided context.");
67
+ search.close();
68
+ return;
69
+ }
70
+ console.log(`Found ${candidates.length} candidates. Checking novelty...\n`);
71
+ // Step 2: Check novelty and commit
72
+ let added = 0;
73
+ let skipped = 0;
74
+ let centralDb = null;
75
+ try {
76
+ centralDb = GnosysDB.openCentral();
77
+ const projectId = await resolveProjectId();
78
+ for (const candidate of candidates) {
79
+ const searchTerms = candidate.search_terms.join(" ");
80
+ const existing = search.discover(searchTerms, 3);
81
+ if (existing.length > 0) {
82
+ console.log(` ⏭ SKIP: "${candidate.summary}"`);
83
+ console.log(` Overlaps with: ${existing[0].title}`);
84
+ skipped++;
85
+ }
86
+ else if (opts.dryRun) {
87
+ console.log(` ➕ WOULD ADD: "${candidate.summary}" [${candidate.type}]`);
88
+ added++;
89
+ }
90
+ else {
91
+ try {
92
+ const result = await ingestion.ingest(candidate.summary);
93
+ const id = centralDb.getNextId(result.category, projectId || undefined);
94
+ const now = new Date().toISOString();
95
+ const content = `# ${result.title}\n\n${result.content}`;
96
+ const resultTags = result.tags;
97
+ const tagsJson = Array.isArray(resultTags)
98
+ ? JSON.stringify(resultTags)
99
+ : JSON.stringify(Object.values(resultTags).flat());
100
+ centralDb.insertMemory({
101
+ id,
102
+ title: result.title,
103
+ category: result.category,
104
+ content,
105
+ summary: null,
106
+ tags: tagsJson,
107
+ relevance: result.relevance,
108
+ author: "ai",
109
+ authority: "observed",
110
+ confidence: result.confidence,
111
+ reinforcement_count: 0,
112
+ content_hash: "",
113
+ status: "active",
114
+ tier: "active",
115
+ supersedes: null,
116
+ superseded_by: null,
117
+ last_reinforced: null,
118
+ created: now,
119
+ modified: now,
120
+ embedding: null,
121
+ source_path: null,
122
+ project_id: projectId,
123
+ scope: "project",
124
+ });
125
+ console.log(` ➕ ADDED: "${result.title}"`);
126
+ console.log(` ID: ${id}`);
127
+ added++;
128
+ }
129
+ catch (err) {
130
+ console.error(` ❌ FAILED: "${candidate.summary}": ${err instanceof Error ? err.message : String(err)}`);
131
+ }
132
+ }
133
+ console.log();
134
+ }
135
+ }
136
+ finally {
137
+ centralDb?.close();
138
+ }
139
+ search.close();
140
+ const mode = opts.dryRun ? "DRY RUN" : "COMMITTED";
141
+ console.log(`\n${mode}: ${candidates.length} candidates, ${added} ${opts.dryRun ? "would be added" : "added"}, ${skipped} duplicates skipped.`);
142
+ }
@@ -3,6 +3,7 @@
3
3
  * Uses Zod for schema validation with sensible defaults.
4
4
  */
5
5
  import { z } from "zod";
6
+ export type { LlmTaskName } from "./apiKeyVault.js";
6
7
  declare const LLMProviderEnum: z.ZodEnum<{
7
8
  anthropic: "anthropic";
8
9
  ollama: "ollama";
@@ -11,6 +12,7 @@ declare const LLMProviderEnum: z.ZodEnum<{
11
12
  lmstudio: "lmstudio";
12
13
  xai: "xai";
13
14
  mistral: "mistral";
15
+ openrouter: "openrouter";
14
16
  custom: "custom";
15
17
  }>;
16
18
  export type LLMProviderName = z.infer<typeof LLMProviderEnum>;
@@ -26,6 +28,7 @@ declare const DreamConfigSchema: z.ZodObject<{
26
28
  lmstudio: "lmstudio";
27
29
  xai: "xai";
28
30
  mistral: "mistral";
31
+ openrouter: "openrouter";
29
32
  custom: "custom";
30
33
  }>>;
31
34
  model: z.ZodOptional<z.ZodString>;
@@ -33,6 +36,14 @@ declare const DreamConfigSchema: z.ZodObject<{
33
36
  generateSummaries: z.ZodDefault<z.ZodBoolean>;
34
37
  discoverRelationships: z.ZodDefault<z.ZodBoolean>;
35
38
  minMemories: z.ZodDefault<z.ZodNumber>;
39
+ schedule: z.ZodDefault<z.ZodObject<{
40
+ startHour: z.ZodDefault<z.ZodNumber>;
41
+ endHour: z.ZodDefault<z.ZodNumber>;
42
+ }, z.core.$strip>>;
43
+ systemIdleMinutes: z.ZodDefault<z.ZodNumber>;
44
+ minNewMemoriesToDream: z.ZodDefault<z.ZodNumber>;
45
+ minHoursBetweenRuns: z.ZodDefault<z.ZodNumber>;
46
+ maxLLMCallsPerRun: z.ZodDefault<z.ZodNumber>;
36
47
  }, z.core.$strip>;
37
48
  export type DreamConfig = z.infer<typeof DreamConfigSchema>;
38
49
  declare const RecallConfigSchema: z.ZodObject<{
@@ -62,6 +73,7 @@ declare const MultimodalConfigSchema: z.ZodObject<{
62
73
  lmstudio: "lmstudio";
63
74
  xai: "xai";
64
75
  mistral: "mistral";
76
+ openrouter: "openrouter";
65
77
  custom: "custom";
66
78
  }>>;
67
79
  visionModel: z.ZodOptional<z.ZodString>;
@@ -97,6 +109,7 @@ export declare const GnosysConfigSchema: z.ZodObject<{
97
109
  lmstudio: "lmstudio";
98
110
  xai: "xai";
99
111
  mistral: "mistral";
112
+ openrouter: "openrouter";
100
113
  custom: "custom";
101
114
  }>>;
102
115
  anthropic: z.ZodDefault<z.ZodObject<{
@@ -128,6 +141,11 @@ export declare const GnosysConfigSchema: z.ZodObject<{
128
141
  model: z.ZodDefault<z.ZodString>;
129
142
  apiKey: z.ZodOptional<z.ZodString>;
130
143
  }, z.core.$strip>>;
144
+ openrouter: z.ZodDefault<z.ZodObject<{
145
+ model: z.ZodDefault<z.ZodString>;
146
+ baseUrl: z.ZodDefault<z.ZodString>;
147
+ apiKey: z.ZodOptional<z.ZodString>;
148
+ }, z.core.$strip>>;
131
149
  custom: z.ZodOptional<z.ZodObject<{
132
150
  model: z.ZodString;
133
151
  baseUrl: z.ZodString;
@@ -144,6 +162,7 @@ export declare const GnosysConfigSchema: z.ZodObject<{
144
162
  lmstudio: "lmstudio";
145
163
  xai: "xai";
146
164
  mistral: "mistral";
165
+ openrouter: "openrouter";
147
166
  custom: "custom";
148
167
  }>;
149
168
  model: z.ZodString;
@@ -157,6 +176,7 @@ export declare const GnosysConfigSchema: z.ZodObject<{
157
176
  lmstudio: "lmstudio";
158
177
  xai: "xai";
159
178
  mistral: "mistral";
179
+ openrouter: "openrouter";
160
180
  custom: "custom";
161
181
  }>;
162
182
  model: z.ZodString;
@@ -170,6 +190,7 @@ export declare const GnosysConfigSchema: z.ZodObject<{
170
190
  lmstudio: "lmstudio";
171
191
  xai: "xai";
172
192
  mistral: "mistral";
193
+ openrouter: "openrouter";
173
194
  custom: "custom";
174
195
  }>;
175
196
  model: z.ZodString;
@@ -183,6 +204,7 @@ export declare const GnosysConfigSchema: z.ZodObject<{
183
204
  lmstudio: "lmstudio";
184
205
  xai: "xai";
185
206
  mistral: "mistral";
207
+ openrouter: "openrouter";
186
208
  custom: "custom";
187
209
  }>;
188
210
  model: z.ZodString;
@@ -196,6 +218,7 @@ export declare const GnosysConfigSchema: z.ZodObject<{
196
218
  lmstudio: "lmstudio";
197
219
  xai: "xai";
198
220
  mistral: "mistral";
221
+ openrouter: "openrouter";
199
222
  custom: "custom";
200
223
  }>;
201
224
  model: z.ZodString;
@@ -247,6 +270,7 @@ export declare const GnosysConfigSchema: z.ZodObject<{
247
270
  lmstudio: "lmstudio";
248
271
  xai: "xai";
249
272
  mistral: "mistral";
273
+ openrouter: "openrouter";
250
274
  custom: "custom";
251
275
  }>>;
252
276
  model: z.ZodOptional<z.ZodString>;
@@ -254,6 +278,14 @@ export declare const GnosysConfigSchema: z.ZodObject<{
254
278
  generateSummaries: z.ZodDefault<z.ZodBoolean>;
255
279
  discoverRelationships: z.ZodDefault<z.ZodBoolean>;
256
280
  minMemories: z.ZodDefault<z.ZodNumber>;
281
+ schedule: z.ZodDefault<z.ZodObject<{
282
+ startHour: z.ZodDefault<z.ZodNumber>;
283
+ endHour: z.ZodDefault<z.ZodNumber>;
284
+ }, z.core.$strip>>;
285
+ systemIdleMinutes: z.ZodDefault<z.ZodNumber>;
286
+ minNewMemoriesToDream: z.ZodDefault<z.ZodNumber>;
287
+ minHoursBetweenRuns: z.ZodDefault<z.ZodNumber>;
288
+ maxLLMCallsPerRun: z.ZodDefault<z.ZodNumber>;
257
289
  }, z.core.$strip>>;
258
290
  chat: z.ZodDefault<z.ZodObject<{
259
291
  toolsEnabled: z.ZodDefault<z.ZodBoolean>;
@@ -275,6 +307,7 @@ export declare const GnosysConfigSchema: z.ZodObject<{
275
307
  lmstudio: "lmstudio";
276
308
  xai: "xai";
277
309
  mistral: "mistral";
310
+ openrouter: "openrouter";
278
311
  custom: "custom";
279
312
  }>>;
280
313
  visionModel: z.ZodOptional<z.ZodString>;
@@ -314,11 +347,11 @@ export declare function resolveTaskModel(config: GnosysConfig, task: "structurin
314
347
  */
315
348
  export declare function getProviderModel(config: GnosysConfig, provider: LLMProviderName): string;
316
349
  /**
317
- * Get the Groq API key, checking config first then env var.
350
+ * Get the Groq API key (global provider legacy env).
318
351
  */
319
352
  export declare function getGroqApiKey(config: GnosysConfig): string | undefined;
320
353
  /**
321
- * Get the OpenAI API key, checking config first then env var.
354
+ * Get the OpenAI API key (global provider legacy env).
322
355
  */
323
356
  export declare function getOpenAIApiKey(config: GnosysConfig): string | undefined;
324
357
  /**
@@ -345,6 +378,14 @@ export declare function getXAIApiKey(config: GnosysConfig): string | undefined;
345
378
  * Get the Mistral API key, checking config first then env var.
346
379
  */
347
380
  export declare function getMistralApiKey(config: GnosysConfig): string | undefined;
381
+ /**
382
+ * Get the OpenRouter API key, checking config first then env var.
383
+ */
384
+ export declare function getOpenRouterApiKey(config: GnosysConfig): string | undefined;
385
+ /**
386
+ * Get the OpenRouter API base URL from config.
387
+ */
388
+ export declare function getOpenRouterBaseUrl(config: GnosysConfig): string;
348
389
  /**
349
390
  * Get the Custom provider API key, checking config first then env var.
350
391
  */
@@ -381,4 +422,3 @@ export declare function generateConfigTemplate(): string;
381
422
  * All supported provider names.
382
423
  */
383
424
  export declare const ALL_PROVIDERS: LLMProviderName[];
384
- export {};
@@ -5,11 +5,11 @@
5
5
  import { z } from "zod";
6
6
  import fs from "fs/promises";
7
7
  import path from "path";
8
- import { execSync } from "child_process";
9
8
  import { getGnosysHome } from "./paths.js";
10
9
  import { atomicWriteFile } from "./atomicWrite.js";
10
+ import { getApiKeyForProviderFromConfig, } from "./apiKeyVault.js";
11
11
  // ─── LLM Provider Schemas ───────────────────────────────────────────────
12
- const LLMProviderEnum = z.enum(["anthropic", "ollama", "groq", "openai", "lmstudio", "xai", "mistral", "custom"]);
12
+ const LLMProviderEnum = z.enum(["anthropic", "ollama", "groq", "openai", "lmstudio", "xai", "mistral", "openrouter", "custom"]);
13
13
  const AnthropicConfigSchema = z.object({
14
14
  model: z.string().default("claude-sonnet-4-6"),
15
15
  apiKey: z.string().optional(), // Falls back to ANTHROPIC_API_KEY env var
@@ -39,6 +39,11 @@ const MistralConfigSchema = z.object({
39
39
  model: z.string().default("mistral-small-4"),
40
40
  apiKey: z.string().optional(),
41
41
  });
42
+ const OpenRouterConfigSchema = z.object({
43
+ model: z.string().default("nvidia/nemotron-3-super-120b-a12b:free"),
44
+ baseUrl: z.string().default("https://openrouter.ai/api/v1"),
45
+ apiKey: z.string().optional(),
46
+ });
42
47
  const CustomConfigSchema = z.object({
43
48
  model: z.string(),
44
49
  baseUrl: z.string(),
@@ -57,6 +62,10 @@ const LLMConfigSchema = z.object({
57
62
  lmstudio: LMStudioConfigSchema.default({ model: "default", baseUrl: "http://localhost:1234/v1" }),
58
63
  xai: XAIConfigSchema.default({ model: "grok-4.20" }),
59
64
  mistral: MistralConfigSchema.default({ model: "mistral-small-4" }),
65
+ openrouter: OpenRouterConfigSchema.default({
66
+ model: "nvidia/nemotron-3-super-120b-a12b:free",
67
+ baseUrl: "https://openrouter.ai/api/v1",
68
+ }),
60
69
  custom: CustomConfigSchema.optional(),
61
70
  });
62
71
  const TaskModelsSchema = z.object({
@@ -96,6 +105,19 @@ const DreamConfigSchema = z.object({
96
105
  discoverRelationships: z.boolean().default(true),
97
106
  /** Min memory count before dream mode activates */
98
107
  minMemories: z.number().int().min(1).default(10),
108
+ /** Night-only launch window for scheduled Dream runs. Hours are local 0-23. */
109
+ schedule: z.object({
110
+ startHour: z.number().int().min(0).max(23).default(2),
111
+ endHour: z.number().int().min(0).max(23).default(5),
112
+ }).default({ startHour: 2, endHour: 5 }),
113
+ /** Required real machine idle time before scheduled Dream can run. */
114
+ systemIdleMinutes: z.number().int().min(1).default(30),
115
+ /** Minimum new or changed memories since the last successful run. */
116
+ minNewMemoriesToDream: z.number().int().min(0).default(10),
117
+ /** Cooldown between scheduled Dream runs. */
118
+ minHoursBetweenRuns: z.number().int().min(0).default(20),
119
+ /** Hard cap on paid LLM calls in a single Dream run. */
120
+ maxLLMCallsPerRun: z.number().int().min(0).default(12),
99
121
  });
100
122
  // ─── Recall Schema ─────────────────────────────────────────────────────
101
123
  const RecallConfigSchema = z.object({
@@ -177,6 +199,7 @@ export const GnosysConfigSchema = z.object({
177
199
  lmstudio: { model: "default", baseUrl: "http://localhost:1234/v1" },
178
200
  xai: { model: "grok-4.20" },
179
201
  mistral: { model: "mistral-small-4" },
202
+ openrouter: { model: "nvidia/nemotron-3-super-120b-a12b:free", baseUrl: "https://openrouter.ai/api/v1" },
180
203
  }),
181
204
  /** Task-specific model overrides */
182
205
  taskModels: TaskModelsSchema.default({}),
@@ -227,6 +250,11 @@ export const GnosysConfigSchema = z.object({
227
250
  generateSummaries: true,
228
251
  discoverRelationships: true,
229
252
  minMemories: 10,
253
+ schedule: { startHour: 2, endHour: 5 },
254
+ systemIdleMinutes: 30,
255
+ minNewMemoriesToDream: 10,
256
+ minHoursBetweenRuns: 20,
257
+ maxLLMCallsPerRun: 12,
230
258
  }),
231
259
  /** Chat TUI — interactive chat configuration (v5.8.0) */
232
260
  chat: ChatConfigSchema.default({
@@ -282,67 +310,22 @@ export function getProviderModel(config, provider) {
282
310
  case "lmstudio": return config.llm.lmstudio.model;
283
311
  case "xai": return config.llm.xai.model;
284
312
  case "mistral": return config.llm.mistral.model;
313
+ case "openrouter": return config.llm.openrouter.model;
285
314
  case "custom": return config.llm.custom?.model || "";
286
315
  default: return config.llm.anthropic.model;
287
316
  }
288
317
  }
289
318
  /**
290
- * Resolve an API key from multiple sources in priority order:
291
- * 1. Config (gnosys.json)
292
- * 2. GNOSYS_<PROVIDER>_KEY env var (new convention)
293
- * 3. macOS Keychain (if on macOS)
294
- * 4. Legacy env var (ANTHROPIC_API_KEY, etc.)
295
- * 5. ~/.config/gnosys/.env (read at startup)
296
- */
297
- function resolveApiKey(configKey, gnosysEnvVar, legacyEnvVar) {
298
- // 1. Config value
299
- if (configKey)
300
- return configKey;
301
- // 2. New GNOSYS_*_KEY env var
302
- if (process.env[gnosysEnvVar])
303
- return process.env[gnosysEnvVar];
304
- // Skip keychain lookups inside vitest — test env can't differentiate
305
- // a real keychain entry from a stubbed env var, so tests asserting "no
306
- // key configured" leak the developer's actual keys.
307
- const inTest = !!process.env.VITEST;
308
- // 3. macOS Keychain
309
- if (!inTest && process.platform === "darwin") {
310
- try {
311
- const result = execSync(`security find-generic-password -a "$USER" -s "${gnosysEnvVar}" -w 2>/dev/null`, { stdio: "pipe", encoding: "utf-8", timeout: 2000 }).trim();
312
- if (result)
313
- return result;
314
- }
315
- catch {
316
- // Not in keychain — fall through
317
- }
318
- }
319
- // 4. Linux GNOME Keyring (secret-tool)
320
- if (!inTest && process.platform === "linux") {
321
- try {
322
- const result = execSync(`secret-tool lookup service gnosys account ${gnosysEnvVar} 2>/dev/null`, { stdio: "pipe", encoding: "utf-8", timeout: 2000 }).trim();
323
- if (result)
324
- return result;
325
- }
326
- catch {
327
- // secret-tool not installed or no entry — fall through
328
- }
329
- }
330
- // 5. Legacy env var
331
- if (legacyEnvVar && process.env[legacyEnvVar])
332
- return process.env[legacyEnvVar];
333
- return undefined;
334
- }
335
- /**
336
- * Get the Groq API key, checking config first then env var.
319
+ * Get the Groq API key (global provider legacy env).
337
320
  */
338
321
  export function getGroqApiKey(config) {
339
- return resolveApiKey(config.llm.groq.apiKey, "GNOSYS_GROQ_KEY", "GROQ_API_KEY");
322
+ return getApiKeyForProviderFromConfig(config, "groq");
340
323
  }
341
324
  /**
342
- * Get the OpenAI API key, checking config first then env var.
325
+ * Get the OpenAI API key (global provider legacy env).
343
326
  */
344
327
  export function getOpenAIApiKey(config) {
345
- return resolveApiKey(config.llm.openai.apiKey, "GNOSYS_OPENAI_KEY", "OPENAI_API_KEY");
328
+ return getApiKeyForProviderFromConfig(config, "openai");
346
329
  }
347
330
  /**
348
331
  * Get the OpenAI base URL from config.
@@ -360,7 +343,7 @@ export function getLMStudioBaseUrl(config) {
360
343
  * Get the Anthropic API key, checking config first then env var.
361
344
  */
362
345
  export function getAnthropicApiKey(config) {
363
- return resolveApiKey(config.llm.anthropic.apiKey, "GNOSYS_ANTHROPIC_KEY", "ANTHROPIC_API_KEY");
346
+ return getApiKeyForProviderFromConfig(config, "anthropic");
364
347
  }
365
348
  /**
366
349
  * Get the Ollama base URL from config.
@@ -372,19 +355,31 @@ export function getOllamaBaseUrl(config) {
372
355
  * Get the xAI API key, checking config first then env var.
373
356
  */
374
357
  export function getXAIApiKey(config) {
375
- return resolveApiKey(config.llm.xai.apiKey, "GNOSYS_XAI_KEY", "XAI_API_KEY");
358
+ return getApiKeyForProviderFromConfig(config, "xai");
376
359
  }
377
360
  /**
378
361
  * Get the Mistral API key, checking config first then env var.
379
362
  */
380
363
  export function getMistralApiKey(config) {
381
- return resolveApiKey(config.llm.mistral.apiKey, "GNOSYS_MISTRAL_KEY", "MISTRAL_API_KEY");
364
+ return getApiKeyForProviderFromConfig(config, "mistral");
365
+ }
366
+ /**
367
+ * Get the OpenRouter API key, checking config first then env var.
368
+ */
369
+ export function getOpenRouterApiKey(config) {
370
+ return getApiKeyForProviderFromConfig(config, "openrouter");
371
+ }
372
+ /**
373
+ * Get the OpenRouter API base URL from config.
374
+ */
375
+ export function getOpenRouterBaseUrl(config) {
376
+ return config.llm.openrouter.baseUrl;
382
377
  }
383
378
  /**
384
379
  * Get the Custom provider API key, checking config first then env var.
385
380
  */
386
381
  export function getCustomApiKey(config) {
387
- return resolveApiKey(config.llm.custom?.apiKey, "GNOSYS_CUSTOM_KEY", "GNOSYS_LLM_API_KEY");
382
+ return getApiKeyForProviderFromConfig(config, "custom");
388
383
  }
389
384
  // ─── Migration ───────────────────────────────────────────────────────────
390
385
  /**
@@ -578,6 +573,10 @@ export function generateConfigTemplate() {
578
573
  lmstudio: { model: "default", baseUrl: "http://localhost:1234/v1" },
579
574
  xai: { model: "grok-4.20" },
580
575
  mistral: { model: "mistral-small-4" },
576
+ openrouter: {
577
+ model: "nvidia/nemotron-3-super-120b-a12b:free",
578
+ baseUrl: "https://openrouter.ai/api/v1",
579
+ },
581
580
  },
582
581
  taskModels: {},
583
582
  bulkIngestionBatchSize: 500,
@@ -617,4 +616,6 @@ export function generateConfigTemplate() {
617
616
  /**
618
617
  * All supported provider names.
619
618
  */
620
- export const ALL_PROVIDERS = ["anthropic", "ollama", "groq", "openai", "lmstudio", "xai", "mistral", "custom"];
619
+ export const ALL_PROVIDERS = [
620
+ "anthropic", "ollama", "groq", "openai", "lmstudio", "xai", "mistral", "openrouter", "custom",
621
+ ];
@@ -0,0 +1,10 @@
1
+ import type { GnosysResolver } from "./resolver.js";
2
+ type GetResolver = () => Promise<GnosysResolver>;
3
+ export declare function runConfigShowCommand(getResolver: GetResolver, opts: {
4
+ json?: boolean;
5
+ }): Promise<void>;
6
+ export declare function runConfigSetCommand(getResolver: GetResolver, key: string, value: string, extra: string[]): Promise<void>;
7
+ export declare function runConfigInitCommand(getResolver: GetResolver, opts: {
8
+ force?: boolean;
9
+ }): Promise<void>;
10
+ export {};