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,5 @@
1
+ export type RestoreCommandOptions = {
2
+ from?: string;
3
+ json?: boolean;
4
+ };
5
+ export declare function runRestoreCommand(backupFile: string, opts: RestoreCommandOptions): Promise<void>;
@@ -0,0 +1,35 @@
1
+ import path from "path";
2
+ import { GnosysDB } from "./db.js";
3
+ export async function runRestoreCommand(backupFile, opts) {
4
+ const resolved = path.resolve(opts.from || backupFile);
5
+ let db = null;
6
+ try {
7
+ db = GnosysDB.restore(resolved);
8
+ const counts = db.getMemoryCount();
9
+ const projectCount = db.getAllProjects().length;
10
+ if (opts.json) {
11
+ console.log(JSON.stringify({
12
+ ok: true, source: resolved, memories: counts.total,
13
+ active: counts.active, archived: counts.archived, projects: projectCount,
14
+ }));
15
+ }
16
+ else {
17
+ console.log(`Database restored from ${resolved}`);
18
+ console.log(` Memories: ${counts.total} (${counts.active} active, ${counts.archived} archived)`);
19
+ console.log(` Projects: ${projectCount}`);
20
+ }
21
+ }
22
+ catch (err) {
23
+ if (opts.json) {
24
+ console.log(JSON.stringify({ ok: false, error: err instanceof Error ? err.message : String(err) }));
25
+ }
26
+ else {
27
+ console.error(`Restore failed: ${err instanceof Error ? err.message : err}`);
28
+ }
29
+ process.exitCode = 1;
30
+ return;
31
+ }
32
+ finally {
33
+ db?.close();
34
+ }
35
+ }
@@ -47,6 +47,14 @@ export declare function syncRules(centralDb: GnosysDB, projectDir: string, agent
47
47
  * If target is "global", syncs to ~/.claude/CLAUDE.md.
48
48
  */
49
49
  export declare function syncToTarget(centralDb: GnosysDB, projectDir: string, target: string, projectId: string | null): Promise<RulesGenResult[]>;
50
+ /**
51
+ * Remove the GNOSYS block from every known agent rules file in a project —
52
+ * the uninstall counterpart of syncToTarget (v5.12.1: wired into
53
+ * `gnosys cleanup --rules`). Checks every known target rather than only
54
+ * detected ones, so leftovers survive even if the agent dir was removed.
55
+ * Returns the relative paths actually cleaned.
56
+ */
57
+ export declare function removeRulesFromProject(projectDir: string): Promise<string[]>;
50
58
  /**
51
59
  * Remove the GNOSYS block from a rules file (cleanup).
52
60
  */
@@ -254,6 +254,22 @@ export async function syncToTarget(centralDb, projectDir, target, projectId) {
254
254
  }
255
255
  return results;
256
256
  }
257
+ /**
258
+ * Remove the GNOSYS block from every known agent rules file in a project —
259
+ * the uninstall counterpart of syncToTarget (v5.12.1: wired into
260
+ * `gnosys cleanup --rules`). Checks every known target rather than only
261
+ * detected ones, so leftovers survive even if the agent dir was removed.
262
+ * Returns the relative paths actually cleaned.
263
+ */
264
+ export async function removeRulesFromProject(projectDir) {
265
+ const cleaned = [];
266
+ for (const relPath of Object.values(TARGET_PATHS)) {
267
+ const filePath = path.join(projectDir, relPath);
268
+ if (await removeRulesBlock(filePath))
269
+ cleaned.push(relPath);
270
+ }
271
+ return cleaned;
272
+ }
257
273
  /**
258
274
  * Remove the GNOSYS block from a rules file (cleanup).
259
275
  */
@@ -0,0 +1,6 @@
1
+ export type SandboxStartCommandOptions = {
2
+ persistent?: boolean;
3
+ dbPath?: string;
4
+ json?: boolean;
5
+ };
6
+ export declare function runSandboxStartCommand(opts: SandboxStartCommandOptions): Promise<void>;
@@ -0,0 +1,25 @@
1
+ export async function runSandboxStartCommand(opts) {
2
+ try {
3
+ const { startSandbox } = await import("../sandbox/manager.js");
4
+ const pid = await startSandbox({
5
+ persistent: opts.persistent,
6
+ dbPath: opts.dbPath,
7
+ wait: true,
8
+ });
9
+ if (opts.json) {
10
+ console.log(JSON.stringify({ ok: true, pid }));
11
+ }
12
+ else {
13
+ console.log(`Gnosys sandbox running (pid: ${pid})`);
14
+ }
15
+ }
16
+ catch (err) {
17
+ if (opts.json) {
18
+ console.log(JSON.stringify({ ok: false, error: err instanceof Error ? err.message : String(err) }));
19
+ }
20
+ else {
21
+ console.error(`Failed to start sandbox: ${err instanceof Error ? err.message : err}`);
22
+ }
23
+ process.exit(1);
24
+ }
25
+ }
@@ -0,0 +1,4 @@
1
+ export type SandboxStatusCommandOptions = {
2
+ json?: boolean;
3
+ };
4
+ export declare function runSandboxStatusCommand(opts: SandboxStatusCommandOptions): Promise<void>;
@@ -0,0 +1,24 @@
1
+ export async function runSandboxStatusCommand(opts) {
2
+ try {
3
+ const { sandboxStatus } = await import("../sandbox/manager.js");
4
+ const status = await sandboxStatus();
5
+ if (opts.json) {
6
+ console.log(JSON.stringify(status, null, 2));
7
+ }
8
+ else if (status.running) {
9
+ console.log(`Sandbox running (pid: ${status.pid}, socket: ${status.socketPath})`);
10
+ }
11
+ else {
12
+ console.log("Sandbox is not running. Start with: gnosys sandbox start");
13
+ }
14
+ }
15
+ catch (err) {
16
+ if (opts.json) {
17
+ console.log(JSON.stringify({ ok: false, error: err instanceof Error ? err.message : String(err) }));
18
+ }
19
+ else {
20
+ console.error(`Error: ${err instanceof Error ? err.message : err}`);
21
+ }
22
+ process.exit(1);
23
+ }
24
+ }
@@ -0,0 +1,4 @@
1
+ export type SandboxStopCommandOptions = {
2
+ json?: boolean;
3
+ };
4
+ export declare function runSandboxStopCommand(opts: SandboxStopCommandOptions): Promise<void>;
@@ -0,0 +1,21 @@
1
+ export async function runSandboxStopCommand(opts) {
2
+ try {
3
+ const { stopSandbox } = await import("../sandbox/manager.js");
4
+ const wasRunning = await stopSandbox();
5
+ if (opts.json) {
6
+ console.log(JSON.stringify({ ok: true, wasRunning }));
7
+ }
8
+ else {
9
+ console.log(wasRunning ? "Sandbox stopped." : "Sandbox was not running.");
10
+ }
11
+ }
12
+ catch (err) {
13
+ if (opts.json) {
14
+ console.log(JSON.stringify({ ok: false, error: err instanceof Error ? err.message : String(err) }));
15
+ }
16
+ else {
17
+ console.error(`Failed to stop sandbox: ${err instanceof Error ? err.message : err}`);
18
+ }
19
+ process.exit(1);
20
+ }
21
+ }
@@ -17,8 +17,6 @@ export interface DiscoverResult {
17
17
  }
18
18
  export declare class GnosysSearch {
19
19
  private db;
20
- private storePath;
21
- private available;
22
20
  constructor(storePath: string);
23
21
  private initSchema;
24
22
  /**
@@ -3,7 +3,6 @@
3
3
  * FTS5-based search and discovery across all Gnosys stores.
4
4
  */
5
5
  // Dynamic import — gracefully handles missing native module (dlopen failures)
6
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
7
6
  let Database = null;
8
7
  try {
9
8
  Database = (await import("better-sqlite3")).default;
@@ -13,12 +12,8 @@ catch {
13
12
  }
14
13
  import path from "path";
15
14
  export class GnosysSearch {
16
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
17
15
  db = null;
18
- storePath;
19
- available = false;
20
16
  constructor(storePath) {
21
- this.storePath = storePath;
22
17
  if (!Database) {
23
18
  // Native module not available — search features disabled
24
19
  return;
@@ -34,7 +29,6 @@ export class GnosysSearch {
34
29
  this.initSchema();
35
30
  // Smoke-test: insert + delete to confirm journal ops work
36
31
  this.db.exec("CREATE TABLE IF NOT EXISTS _write_test (v INTEGER); INSERT INTO _write_test VALUES (1); DELETE FROM _write_test; DROP TABLE _write_test;");
37
- this.available = true;
38
32
  }
39
33
  catch {
40
34
  // Fallback to in-memory (works everywhere, rebuilt on each start)
@@ -44,7 +38,6 @@ export class GnosysSearch {
44
38
  catch { /* ignore */ }
45
39
  this.db = new Database(":memory:");
46
40
  this.initSchema();
47
- this.available = true;
48
41
  }
49
42
  }
50
43
  initSchema() {
@@ -0,0 +1,9 @@
1
+ export type SearchCommandOptions = {
2
+ limit: string;
3
+ json?: boolean;
4
+ federated?: boolean;
5
+ scope?: string;
6
+ directory?: string;
7
+ idFormat?: string;
8
+ };
9
+ export declare function runSearchCommand(query: string, opts: SearchCommandOptions): Promise<void>;
@@ -0,0 +1,90 @@
1
+ import { logError } from "./log.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 runSearchCommand(query, opts) {
11
+ // Federated search path — uses central DB with tier boosting
12
+ if (opts.federated || opts.scope) {
13
+ const { resolveClientRead } = await import("./clientReadResolve.js");
14
+ const resolved = resolveClientRead();
15
+ if (!resolved) {
16
+ console.error("Central DB not available. Run 'gnosys migrate --to-central' first.");
17
+ process.exit(1);
18
+ }
19
+ try {
20
+ const { federatedSearch, detectCurrentProject } = await import("./federated.js");
21
+ const projectId = await detectCurrentProject(resolved.db, opts.directory || undefined);
22
+ const scopeFilter = opts.scope ? opts.scope.split(",").map(s => s.trim()) : undefined;
23
+ const results = federatedSearch(resolved.db, query, {
24
+ limit: parseInt(opts.limit, 10),
25
+ projectId,
26
+ scopeFilter,
27
+ });
28
+ outputResult(!!opts.json, { query, projectId, count: results.length, results }, () => {
29
+ if (results.length === 0) {
30
+ console.log(`No results for "${query}".`);
31
+ return;
32
+ }
33
+ const ctx = projectId ? `Context: project ${projectId}` : "No project detected";
34
+ console.log(ctx);
35
+ for (const [i, r] of results.entries()) {
36
+ const proj = r.projectName ? ` [${r.projectName}]` : "";
37
+ console.log(`\n${i + 1}. ${r.title} (${r.category})${proj}`);
38
+ console.log(` scope: ${r.scope} | score: ${r.score.toFixed(4)} | boosts: ${r.boosts.join(", ")}`);
39
+ if (r.snippet)
40
+ console.log(` ${r.snippet.substring(0, 120)}`);
41
+ }
42
+ });
43
+ }
44
+ catch (err) {
45
+ logError(err, { module: "cli", op: "search" });
46
+ process.exit(1);
47
+ }
48
+ finally {
49
+ resolved.release();
50
+ }
51
+ return;
52
+ }
53
+ // DB-based search path — uses central DB FTS5 (+ v13 client overlay)
54
+ const { resolveClientRead, searchWithOverlay } = await import("./clientReadResolve.js");
55
+ const resolved = resolveClientRead();
56
+ if (!resolved) {
57
+ console.error("Central DB not available. Run 'gnosys init' first.");
58
+ process.exit(1);
59
+ }
60
+ try {
61
+ const results = searchWithOverlay(resolved, query, parseInt(opts.limit, 10));
62
+ if (results.length === 0) {
63
+ outputResult(!!opts.json, { query, results: [] }, () => {
64
+ console.log(`No results for "${query}".`);
65
+ });
66
+ return;
67
+ }
68
+ const { formatMemoryIdHyperlink: formatMemoryId, buildProjectNameLookup, parseIdFormat } = await import("./idFormat.js");
69
+ const idFormat = parseIdFormat(opts.idFormat);
70
+ const projectNames = buildProjectNameLookup(resolved.localDb);
71
+ outputResult(!!opts.json, { query, count: results.length, results }, () => {
72
+ console.log(`Found ${results.length} results for "${query}":\n`);
73
+ for (const r of results) {
74
+ const projectName = r.project_id ? projectNames.get(r.project_id) || null : null;
75
+ const displayId = formatMemoryId(r.id, projectName, idFormat);
76
+ console.log(` ${r.title}`);
77
+ console.log(` id: ${displayId}`);
78
+ console.log(` ${r.snippet.replace(/>>>/g, "").replace(/<<</g, "")}`);
79
+ console.log();
80
+ }
81
+ });
82
+ }
83
+ catch (err) {
84
+ logError(err, { module: "cli", op: "search" });
85
+ process.exit(1);
86
+ }
87
+ finally {
88
+ resolved.release();
89
+ }
90
+ }
@@ -0,0 +1,8 @@
1
+ import type { GnosysResolver } from "./resolver.js";
2
+ export type SemanticSearchCommandOptions = {
3
+ limit: string;
4
+ json?: boolean;
5
+ };
6
+ type GetResolver = () => Promise<GnosysResolver>;
7
+ export declare function runSemanticSearchCommand(getResolver: GetResolver, query: string, opts: SemanticSearchCommandOptions): Promise<void>;
8
+ export {};
@@ -0,0 +1,52 @@
1
+ import { GnosysSearch } from "./search.js";
2
+ function outputResult(json, data, humanFn) {
3
+ if (json) {
4
+ console.log(JSON.stringify(data, null, 2));
5
+ }
6
+ else {
7
+ humanFn();
8
+ }
9
+ }
10
+ export async function runSemanticSearchCommand(getResolver, query, opts) {
11
+ const resolver = await getResolver();
12
+ const stores = resolver.getStores();
13
+ if (stores.length === 0) {
14
+ console.error("No stores found.");
15
+ process.exit(1);
16
+ }
17
+ const storePath = stores[0].path;
18
+ const search = new GnosysSearch(storePath);
19
+ search.clearIndex();
20
+ for (const s of stores) {
21
+ await search.addStoreMemories(s.store, s.label);
22
+ }
23
+ const { GnosysEmbeddings } = await import("./embeddings.js");
24
+ const { GnosysHybridSearch } = await import("./hybridSearch.js");
25
+ const embeddings = new GnosysEmbeddings(storePath);
26
+ const hybridSearch = new GnosysHybridSearch(search, embeddings, resolver, storePath);
27
+ const results = await hybridSearch.hybridSearch(query, parseInt(opts.limit, 10), "semantic");
28
+ outputResult(!!opts.json, {
29
+ query,
30
+ count: results.length,
31
+ results: results.map((r) => ({
32
+ title: r.title,
33
+ relativePath: r.relativePath,
34
+ score: r.score,
35
+ snippet: r.snippet,
36
+ })),
37
+ }, () => {
38
+ if (results.length === 0) {
39
+ console.log(`No semantic results for "${query}". Run gnosys reindex first.`);
40
+ return;
41
+ }
42
+ console.log(`Found ${results.length} semantic results for "${query}":\n`);
43
+ for (const r of results) {
44
+ console.log(` ${r.title}`);
45
+ console.log(` Path: ${r.relativePath}`);
46
+ console.log(` Similarity: ${r.score.toFixed(4)}`);
47
+ console.log(` ${r.snippet.substring(0, 120)}...\n`);
48
+ }
49
+ });
50
+ search.close();
51
+ embeddings.close();
52
+ }
@@ -29,6 +29,8 @@ export const KNOWN_CONFIG_KEYS = [
29
29
  "lmstudio-model",
30
30
  "xai-model",
31
31
  "mistral-model",
32
+ "openrouter-model",
33
+ "openrouter-key",
32
34
  "custom-url",
33
35
  "custom-model",
34
36
  "custom-key",
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Terminal brand marks for LLM providers (single-width glyphs + color).
3
+ */
4
+ import type { LLMProviderName } from "../config.js";
5
+ export interface ProviderMark {
6
+ glyph: string;
7
+ /** ANSI foreground for the glyph */
8
+ ansi: string;
9
+ shortName: string;
10
+ }
11
+ export declare function getProviderMark(provider: string): ProviderMark;
12
+ /** Colored single-character (or short) logo for lists and tables. */
13
+ export declare function renderProviderMark(provider: string): string;
14
+ /** `◆ Anthropic` with brand-colored glyph. */
15
+ export declare function renderProviderLabel(provider: string): string;
16
+ /** Cloud providers that use API keys in the providers screen. */
17
+ export declare const CLOUD_PROVIDERS_FOR_KEYS: LLMProviderName[];
18
+ /** Local providers shown in the list (no key management). */
19
+ export declare const LOCAL_PROVIDERS: LLMProviderName[];
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Terminal brand marks for LLM providers (single-width glyphs + color).
3
+ */
4
+ import { c, color, RESET } from "./ui/tokens.js";
5
+ const MARKS = {
6
+ anthropic: { glyph: "◆", ansi: "\x1b[38;2;204;142;102m", shortName: "Anthropic" },
7
+ openai: { glyph: "◎", ansi: "\x1b[38;2;116;168;255m", shortName: "OpenAI" },
8
+ groq: { glyph: "⚡", ansi: "\x1b[38;2;255;200;87m", shortName: "Groq" },
9
+ xai: { glyph: "✕", ansi: "\x1b[38;2;230;230;230m", shortName: "xAI" },
10
+ mistral: { glyph: "◬", ansi: "\x1b[38;2;255;120;80m", shortName: "Mistral" },
11
+ openrouter: { glyph: "⬡", ansi: "\x1b[38;2;140;200;255m", shortName: "OpenRouter" },
12
+ ollama: { glyph: "○", ansi: c.ok, shortName: "Ollama" },
13
+ lmstudio: { glyph: "▣", ansi: c.ok, shortName: "LM Studio" },
14
+ custom: { glyph: "⚙", ansi: c.textMid, shortName: "Custom" },
15
+ skip: { glyph: "·", ansi: c.textGhost, shortName: "skip" },
16
+ };
17
+ const FALLBACK = { glyph: "•", ansi: c.textMid, shortName: "unknown" };
18
+ export function getProviderMark(provider) {
19
+ return MARKS[provider] ?? FALLBACK;
20
+ }
21
+ /** Colored single-character (or short) logo for lists and tables. */
22
+ export function renderProviderMark(provider) {
23
+ const m = getProviderMark(provider);
24
+ return `${m.ansi}${m.glyph}${RESET}`;
25
+ }
26
+ /** `◆ Anthropic` with brand-colored glyph. */
27
+ export function renderProviderLabel(provider) {
28
+ const m = getProviderMark(provider);
29
+ return `${m.ansi}${m.glyph}${RESET} ${color(c.text, m.shortName)}`;
30
+ }
31
+ /** Cloud providers that use API keys in the providers screen. */
32
+ export const CLOUD_PROVIDERS_FOR_KEYS = [
33
+ "anthropic",
34
+ "openai",
35
+ "groq",
36
+ "xai",
37
+ "mistral",
38
+ "openrouter",
39
+ "custom",
40
+ ];
41
+ /** Local providers shown in the list (no key management). */
42
+ export const LOCAL_PROVIDERS = ["ollama", "lmstudio"];
@@ -25,6 +25,20 @@ export interface ValidationSummaryInput {
25
25
  errors: string[];
26
26
  }
27
27
  export declare function renderValidationSummary(v: ValidationSummaryInput): string;
28
+ /** Exact phrase required when declining automatic master backups (v13 design). */
29
+ export declare const BACKUP_RISK_PHRASE = "I ACCEPT THE RISK OF DATA LOSS WITHOUT BACKUPS";
30
+ /** Instruction shown when the user declines automatic master backups (v13 design). */
31
+ export declare const BACKUP_DECLINE_ACK_INSTRUCTION = "If you answer No, you must type the following phrase to continue:";
32
+ /** Guide URL for Tailscale setup (inline fallback when unreachable — todo 14). */
33
+ export declare const TAILSCALE_GUIDE_URL = "https://gnosys.ai/docs/multi-machine-tailscale";
34
+ /**
35
+ * v13 first screen — rules before master vs client (design doc §What Happens When…).
36
+ */
37
+ export declare function renderV13ExplanationScreen(): string;
38
+ /** Master backup acknowledgement block (v13 design). */
39
+ export declare function renderMasterBackupWarning(): string;
40
+ /** Typed-phrase prompt when the user disables automatic master backups (v13 design). */
41
+ export declare function renderBackupDeclineAckPrompt(): string;
28
42
  /**
29
43
  * Render the leading Header + current-status line for the remote wizard.
30
44
  * Returns a multi-line string the wizard can print as-is.
@@ -37,6 +51,22 @@ export declare function renderRemoteIntro(localActive: number, localArchived: nu
37
51
  export interface RemoteDiffInput {
38
52
  previousRemote: string | null;
39
53
  newRemote: string;
40
- mode: SyncMode;
54
+ /** v13 master/client role, or legacy sync mode label for older configs. */
55
+ roleOrMode: string;
56
+ }
57
+ /** Shown when the client cannot verify the master is reachable (~30s heartbeat). */
58
+ export declare const MASTER_UNREACHABLE_MESSAGE = "Master unreachable; existing memories are unavailable until reconnect.";
59
+ export declare function formatMemoriesWaitingToSync(count: number): string;
60
+ export declare function formatFailedToSyncCount(count: number): string;
61
+ /** Reconnect banner when offline-staged files are about to push (design doc). */
62
+ export declare function formatOfflinePushStarting(count: number): string;
63
+ export interface ClientSyncStatusInput {
64
+ masterReachable: boolean;
65
+ waitingToSync: number;
66
+ failedToSync: number;
67
+ /** Pending offline adds visible while disconnected (read-your-own-writes overlay). */
68
+ pendingOfflineAdds?: number;
41
69
  }
70
+ /** Multi-line client sync status for panels, MCP, and CLI (pure strings). */
71
+ export declare function renderClientSyncStatusLines(input: ClientSyncStatusInput): string[];
42
72
  export declare function renderRemoteDiff(d: RemoteDiffInput): string;
@@ -34,6 +34,59 @@ export function renderValidationSummary(v) {
34
34
  lines.push(Status("fail", e));
35
35
  return lines.join("\n");
36
36
  }
37
+ /** Exact phrase required when declining automatic master backups (v13 design). */
38
+ export const BACKUP_RISK_PHRASE = "I ACCEPT THE RISK OF DATA LOSS WITHOUT BACKUPS";
39
+ /** Instruction shown when the user declines automatic master backups (v13 design). */
40
+ export const BACKUP_DECLINE_ACK_INSTRUCTION = "If you answer No, you must type the following phrase to continue:";
41
+ /** Guide URL for Tailscale setup (inline fallback when unreachable — todo 14). */
42
+ export const TAILSCALE_GUIDE_URL = "https://gnosys.ai/docs/multi-machine-tailscale";
43
+ /**
44
+ * v13 first screen — rules before master vs client (design doc §What Happens When…).
45
+ */
46
+ export function renderV13ExplanationScreen() {
47
+ const lines = [];
48
+ lines.push(Header(["gnosys", "setup", "multi-machine sync"]));
49
+ lines.push("");
50
+ lines.push(` ${color(c.text, "Multi-machine sync")}`);
51
+ lines.push("");
52
+ lines.push(` ${color(c.textDim, "Gnosys can share one brain across multiple machines, but only when they can all reach the same master folder.")}`);
53
+ lines.push("");
54
+ lines.push(` ${color(c.textDim, "This works best with a fast connection (Tailscale, good VPN, or machines on the same local network). Network shares like NAS or slow Tailscale mounts have caused timeouts and lost connections in practice.")}`);
55
+ lines.push("");
56
+ lines.push(` ${color(c.text, "When the master folder is reachable:")}`);
57
+ lines.push(` ${color(c.textDim, " • Every machine reads from a published snapshot of the master (copied locally).")}`);
58
+ lines.push(` ${color(c.textDim, " • New memories from client machines are staged as small files and later processed by the master (usually during idle time, invisibly).")}`);
59
+ lines.push("");
60
+ lines.push(` ${color(c.text, "When the master folder is NOT reachable:")}`);
61
+ lines.push(` ${color(c.textDim, " • The machine can still write new memories into a small temporary cache.")}`);
62
+ lines.push(` ${color(c.textDim, " • Old memories cannot be read.")}`);
63
+ lines.push(` ${color(c.textDim, " • When the machine reconnects, it will quietly push the staged files so the master can ingest them.")}`);
64
+ return lines.join("\n");
65
+ }
66
+ /** Master backup acknowledgement block (v13 design). */
67
+ export function renderMasterBackupWarning() {
68
+ const lines = [];
69
+ lines.push("");
70
+ lines.push(` ${color(c.text, "Master folder backup")}`);
71
+ lines.push("");
72
+ lines.push(` ${color(c.textDim, "The master folder will become the ONLY copy of your brain.")}`);
73
+ lines.push(` ${color(c.textDim, "If this machine's disk fails, your data is lost unless you have a backup.")}`);
74
+ lines.push("");
75
+ lines.push(` ${color(c.textDim, "By default, Gnosys will automatically create daily snapshots of the master database (last 7 days) using SQLite's backup API and store them in master-folder/backups/.")}`);
76
+ lines.push("");
77
+ lines.push(` ${color(c.textDim, "These are local rollback snapshots for corruption or accidental deletion. They do not protect against disk failure.")}`);
78
+ lines.push("");
79
+ lines.push(` ${color(c.textDim, "You may optionally provide an off-disk backup location (e.g., external drive or cloud folder) for an extra copy that survives disk loss.")}`);
80
+ return lines.join("\n");
81
+ }
82
+ /** Typed-phrase prompt when the user disables automatic master backups (v13 design). */
83
+ export function renderBackupDeclineAckPrompt() {
84
+ const lines = [];
85
+ lines.push("");
86
+ lines.push(` ${color(c.textDim, BACKUP_DECLINE_ACK_INSTRUCTION)}`);
87
+ lines.push(` ${color(c.text, BACKUP_RISK_PHRASE)}`);
88
+ return lines.join("\n");
89
+ }
37
90
  /**
38
91
  * Render the leading Header + current-status line for the remote wizard.
39
92
  * Returns a multi-line string the wizard can print as-is.
@@ -43,22 +96,60 @@ export function renderRemoteIntro(localActive, localArchived, currentRemote) {
43
96
  lines.push(Header(["gnosys", "setup", "remote"]));
44
97
  lines.push("");
45
98
  lines.push(` ${color(c.text, "Multi-machine sync")}`);
46
- lines.push(` ${color(c.textDim, "share your memory store across machines via a path on a NAS, iCloud, Dropbox, etc.")}`);
99
+ lines.push(` ${color(c.textDim, "reconfigure or disconnect your master folder (v13 master/client model)")}`);
47
100
  lines.push("");
48
101
  const remoteTxt = currentRemote ?? "not configured";
49
102
  lines.push(` ${color(c.textDim, "local DB")} ${color(c.text, `~/.gnosys/gnosys.db (${localActive} active, ${localArchived} archived)`)}`);
50
103
  lines.push(` ${color(c.textDim, "current")} ${color(c.text, remoteTxt)}`);
51
104
  return lines.join("\n");
52
105
  }
106
+ // ─── v13 sync status copy (design doc — offline / staging / ingest) ─────
107
+ /** Shown when the client cannot verify the master is reachable (~30s heartbeat). */
108
+ export const MASTER_UNREACHABLE_MESSAGE = "Master unreachable; existing memories are unavailable until reconnect.";
109
+ export function formatMemoriesWaitingToSync(count) {
110
+ const n = Math.max(0, Math.floor(count));
111
+ return `${n} ${n === 1 ? "memory" : "memories"} waiting to sync`;
112
+ }
113
+ export function formatFailedToSyncCount(count) {
114
+ const n = Math.max(0, Math.floor(count));
115
+ return `${n} failed to sync`;
116
+ }
117
+ /** Reconnect banner when offline-staged files are about to push (design doc). */
118
+ export function formatOfflinePushStarting(count) {
119
+ const n = Math.max(0, Math.floor(count));
120
+ return `Found ${n} ${n === 1 ? "memory" : "memories"} written while offline. Starting a background task to add them to the master brain.`;
121
+ }
122
+ /** Multi-line client sync status for panels, MCP, and CLI (pure strings). */
123
+ export function renderClientSyncStatusLines(input) {
124
+ const lines = [];
125
+ if (!input.masterReachable) {
126
+ lines.push(Status("warn", MASTER_UNREACHABLE_MESSAGE));
127
+ if ((input.pendingOfflineAdds ?? 0) > 0) {
128
+ const n = input.pendingOfflineAdds;
129
+ lines.push(Status("progress", `Offline — ${n} new ${n === 1 ? "memory" : "memories"} queued locally; older memories hidden until reconnect.`));
130
+ }
131
+ else {
132
+ lines.push(Status("warn", "Offline — only new memories can be added until the master folder is reachable again."));
133
+ }
134
+ return lines;
135
+ }
136
+ if (input.waitingToSync > 0) {
137
+ lines.push(Status("progress", formatMemoriesWaitingToSync(input.waitingToSync)));
138
+ }
139
+ if (input.failedToSync > 0) {
140
+ lines.push(Status("fail", formatFailedToSyncCount(input.failedToSync), "gnosys sync doctor"));
141
+ }
142
+ return lines;
143
+ }
53
144
  export function renderRemoteDiff(d) {
54
145
  const lines = [];
55
146
  const indent = " ";
56
147
  const arrow = color(c.textGhost, glyph.arrow);
57
148
  const fromR = color(c.textMid, (d.previousRemote ?? "not configured").padEnd(20));
58
- const labelR = color(c.textDim, "remote".padEnd(8));
149
+ const labelR = color(c.textDim, "master".padEnd(8));
59
150
  lines.push(`${indent}${labelR} ${fromR} ${arrow} ${color(c.accentHi, d.newRemote)}`);
60
- const labelM = color(c.textDim, "mode".padEnd(8));
151
+ const labelM = color(c.textDim, "role".padEnd(8));
61
152
  const fromM = color(c.textMid, "—".padEnd(20));
62
- lines.push(`${indent}${labelM} ${fromM} ${arrow} ${color(c.accentHi, d.mode)}`);
153
+ lines.push(`${indent}${labelM} ${fromM} ${arrow} ${color(c.accentHi, d.roleOrMode)}`);
63
154
  return lines.join("\n");
64
155
  }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Setup: Providers — API keys and provider credentials.
3
+ *
4
+ * `gnosys setup providers` or summary menu row "providers".
5
+ */
6
+ import type { Interface as ReadlineInterface } from "readline/promises";
7
+ import { type GnosysConfig } from "../../config.js";
8
+ export interface ProvidersSetupOptions {
9
+ rl: ReadlineInterface;
10
+ directory: string;
11
+ }
12
+ /**
13
+ * Providers + API key management screen.
14
+ */
15
+ export declare function runProvidersSetup(opts: ProvidersSetupOptions): Promise<boolean>;
16
+ /** Summary line: how many providers have keys. */
17
+ export declare function describeProvidersSummary(cfg: GnosysConfig): Promise<string>;