gnosys 5.11.3 → 5.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (244) hide show
  1. package/dist/cli.js +332 -5151
  2. package/dist/index.js +364 -235
  3. package/dist/lib/addCommand.d.ts +9 -0
  4. package/dist/lib/addCommand.js +103 -0
  5. package/dist/lib/addStructuredCommand.d.ts +16 -0
  6. package/dist/lib/addStructuredCommand.js +103 -0
  7. package/dist/lib/ambiguityCommand.d.ts +4 -0
  8. package/dist/lib/ambiguityCommand.js +36 -0
  9. package/dist/lib/apiKeyVault.d.ts +78 -0
  10. package/dist/lib/apiKeyVault.js +447 -0
  11. package/dist/lib/askCommand.d.ts +13 -0
  12. package/dist/lib/askCommand.js +145 -0
  13. package/dist/lib/audioExtract.js +4 -1
  14. package/dist/lib/auditCommand.d.ts +7 -0
  15. package/dist/lib/auditCommand.js +27 -0
  16. package/dist/lib/backupCommand.d.ts +6 -0
  17. package/dist/lib/backupCommand.js +54 -0
  18. package/dist/lib/bootstrapCommand.d.ts +15 -0
  19. package/dist/lib/bootstrapCommand.js +51 -0
  20. package/dist/lib/briefingCommand.d.ts +7 -0
  21. package/dist/lib/briefingCommand.js +92 -0
  22. package/dist/lib/centralizeCommand.d.ts +5 -0
  23. package/dist/lib/centralizeCommand.js +16 -0
  24. package/dist/lib/chatCommand.d.ts +12 -0
  25. package/dist/lib/chatCommand.js +46 -0
  26. package/dist/lib/checkCommand.d.ts +4 -0
  27. package/dist/lib/checkCommand.js +133 -0
  28. package/dist/lib/clientReadOverlay.d.ts +27 -0
  29. package/dist/lib/clientReadOverlay.js +73 -0
  30. package/dist/lib/clientReadResolve.d.ts +32 -0
  31. package/dist/lib/clientReadResolve.js +84 -0
  32. package/dist/lib/commitContextCommand.d.ts +9 -0
  33. package/dist/lib/commitContextCommand.js +142 -0
  34. package/dist/lib/config.d.ts +43 -3
  35. package/dist/lib/config.js +58 -57
  36. package/dist/lib/configCommand.d.ts +10 -0
  37. package/dist/lib/configCommand.js +321 -0
  38. package/dist/lib/connectCommand.d.ts +8 -0
  39. package/dist/lib/connectCommand.js +19 -0
  40. package/dist/lib/db.d.ts +52 -0
  41. package/dist/lib/db.js +169 -1
  42. package/dist/lib/dearchiveCommand.d.ts +7 -0
  43. package/dist/lib/dearchiveCommand.js +41 -0
  44. package/dist/lib/discoverCommand.d.ts +9 -0
  45. package/dist/lib/discoverCommand.js +87 -0
  46. package/dist/lib/doctorCommand.d.ts +6 -0
  47. package/dist/lib/doctorCommand.js +256 -0
  48. package/dist/lib/dream.d.ts +42 -2
  49. package/dist/lib/dream.js +290 -30
  50. package/dist/lib/dreamCommand.d.ts +10 -0
  51. package/dist/lib/dreamCommand.js +195 -0
  52. package/dist/lib/dreamLaunchd.d.ts +2 -0
  53. package/dist/lib/dreamLaunchd.js +72 -0
  54. package/dist/lib/dreamLogCommand.d.ts +10 -0
  55. package/dist/lib/dreamLogCommand.js +58 -0
  56. package/dist/lib/dreamReport.d.ts +7 -0
  57. package/dist/lib/dreamReport.js +114 -0
  58. package/dist/lib/dreamRunLog.d.ts +121 -0
  59. package/dist/lib/dreamRunLog.js +212 -0
  60. package/dist/lib/embeddings.js +3 -0
  61. package/dist/lib/exportCommand.d.ts +18 -0
  62. package/dist/lib/exportCommand.js +101 -0
  63. package/dist/lib/fsearchCommand.d.ts +8 -0
  64. package/dist/lib/fsearchCommand.js +44 -0
  65. package/dist/lib/graphCommand.d.ts +4 -0
  66. package/dist/lib/graphCommand.js +68 -0
  67. package/dist/lib/helperGenerateCommand.d.ts +5 -0
  68. package/dist/lib/helperGenerateCommand.js +27 -0
  69. package/dist/lib/historyCommand.d.ts +5 -0
  70. package/dist/lib/historyCommand.js +51 -0
  71. package/dist/lib/hybridSearchCommand.d.ts +12 -0
  72. package/dist/lib/hybridSearchCommand.js +95 -0
  73. package/dist/lib/ideMcpInstall.d.ts +30 -0
  74. package/dist/lib/ideMcpInstall.js +102 -0
  75. package/dist/lib/importCommand.d.ts +16 -0
  76. package/dist/lib/importCommand.js +89 -0
  77. package/dist/lib/importProjectCommand.d.ts +6 -0
  78. package/dist/lib/importProjectCommand.js +43 -0
  79. package/dist/lib/ingestCommand.d.ts +13 -0
  80. package/dist/lib/ingestCommand.js +95 -0
  81. package/dist/lib/installOutput.d.ts +36 -0
  82. package/dist/lib/installOutput.js +55 -0
  83. package/dist/lib/lensCommand.d.ts +20 -0
  84. package/dist/lib/lensCommand.js +61 -0
  85. package/dist/lib/lensing.d.ts +1 -0
  86. package/dist/lib/lensing.js +50 -9
  87. package/dist/lib/linksCommand.d.ts +7 -0
  88. package/dist/lib/linksCommand.js +48 -0
  89. package/dist/lib/listCommand.d.ts +8 -0
  90. package/dist/lib/listCommand.js +74 -0
  91. package/dist/lib/llm.d.ts +1 -1
  92. package/dist/lib/llm.js +26 -8
  93. package/dist/lib/localDiskCheck.d.ts +17 -0
  94. package/dist/lib/localDiskCheck.js +54 -0
  95. package/dist/lib/machineConfig.d.ts +11 -1
  96. package/dist/lib/machineConfig.js +16 -0
  97. package/dist/lib/machineRegistry.d.ts +61 -0
  98. package/dist/lib/machineRegistry.js +80 -0
  99. package/dist/lib/maintainCommand.d.ts +8 -0
  100. package/dist/lib/maintainCommand.js +34 -0
  101. package/dist/lib/masterLease.d.ts +20 -0
  102. package/dist/lib/masterLease.js +68 -0
  103. package/dist/lib/migrateCommand.d.ts +7 -0
  104. package/dist/lib/migrateCommand.js +158 -0
  105. package/dist/lib/migrateDbCommand.d.ts +9 -0
  106. package/dist/lib/migrateDbCommand.js +94 -0
  107. package/dist/lib/modelValidation.d.ts +5 -0
  108. package/dist/lib/modelValidation.js +27 -0
  109. package/dist/lib/openrouterTiers.d.ts +29 -0
  110. package/dist/lib/openrouterTiers.js +113 -0
  111. package/dist/lib/prefCommand.d.ts +10 -0
  112. package/dist/lib/prefCommand.js +118 -0
  113. package/dist/lib/projectsCommand.d.ts +8 -0
  114. package/dist/lib/projectsCommand.js +131 -0
  115. package/dist/lib/readCommand.d.ts +7 -0
  116. package/dist/lib/readCommand.js +62 -0
  117. package/dist/lib/recall.d.ts +3 -0
  118. package/dist/lib/recall.js +19 -4
  119. package/dist/lib/recallCommand.d.ts +11 -0
  120. package/dist/lib/recallCommand.js +112 -0
  121. package/dist/lib/reflectCommand.d.ts +8 -0
  122. package/dist/lib/reflectCommand.js +61 -0
  123. package/dist/lib/reindexCommand.d.ts +4 -0
  124. package/dist/lib/reindexCommand.js +34 -0
  125. package/dist/lib/reindexGraphCommand.d.ts +4 -0
  126. package/dist/lib/reindexGraphCommand.js +12 -0
  127. package/dist/lib/reinforceCommand.d.ts +8 -0
  128. package/dist/lib/reinforceCommand.js +40 -0
  129. package/dist/lib/remote.d.ts +5 -1
  130. package/dist/lib/remote.js +5 -1
  131. package/dist/lib/remoteWizard.d.ts +24 -5
  132. package/dist/lib/remoteWizard.js +308 -319
  133. package/dist/lib/restoreCommand.d.ts +5 -0
  134. package/dist/lib/restoreCommand.js +35 -0
  135. package/dist/lib/sandboxStartCommand.d.ts +6 -0
  136. package/dist/lib/sandboxStartCommand.js +25 -0
  137. package/dist/lib/sandboxStatusCommand.d.ts +4 -0
  138. package/dist/lib/sandboxStatusCommand.js +24 -0
  139. package/dist/lib/sandboxStopCommand.d.ts +4 -0
  140. package/dist/lib/sandboxStopCommand.js +21 -0
  141. package/dist/lib/searchCommand.d.ts +9 -0
  142. package/dist/lib/searchCommand.js +90 -0
  143. package/dist/lib/semanticSearchCommand.d.ts +8 -0
  144. package/dist/lib/semanticSearchCommand.js +52 -0
  145. package/dist/lib/setup/configSetRender.js +2 -0
  146. package/dist/lib/setup/providerGlyphs.d.ts +19 -0
  147. package/dist/lib/setup/providerGlyphs.js +42 -0
  148. package/dist/lib/setup/remoteRender.d.ts +31 -1
  149. package/dist/lib/setup/remoteRender.js +95 -4
  150. package/dist/lib/setup/sections/ides.d.ts +7 -0
  151. package/dist/lib/setup/sections/ides.js +24 -2
  152. package/dist/lib/setup/sections/providers.d.ts +17 -0
  153. package/dist/lib/setup/sections/providers.js +255 -0
  154. package/dist/lib/setup/sections/routing.d.ts +2 -6
  155. package/dist/lib/setup/sections/routing.js +33 -85
  156. package/dist/lib/setup/sections/taskRoutingEditor.d.ts +17 -0
  157. package/dist/lib/setup/sections/taskRoutingEditor.js +149 -0
  158. package/dist/lib/setup/summary.d.ts +9 -0
  159. package/dist/lib/setup/summary.js +51 -37
  160. package/dist/lib/setup/ui/status.d.ts +1 -0
  161. package/dist/lib/setup/ui/status.js +2 -0
  162. package/dist/lib/setup.d.ts +108 -3
  163. package/dist/lib/setup.js +813 -303
  164. package/dist/lib/setupKeys.d.ts +42 -0
  165. package/dist/lib/setupKeys.js +564 -0
  166. package/dist/lib/setupRemoteCommand.d.ts +4 -0
  167. package/dist/lib/setupRemoteCommand.js +28 -0
  168. package/dist/lib/setupRemotePullCommand.d.ts +5 -0
  169. package/dist/lib/setupRemotePullCommand.js +52 -0
  170. package/dist/lib/setupRemotePushCommand.d.ts +5 -0
  171. package/dist/lib/setupRemotePushCommand.js +57 -0
  172. package/dist/lib/setupRemoteResolveCommand.d.ts +4 -0
  173. package/dist/lib/setupRemoteResolveCommand.js +48 -0
  174. package/dist/lib/setupRemoteStatusCommand.d.ts +4 -0
  175. package/dist/lib/setupRemoteStatusCommand.js +73 -0
  176. package/dist/lib/setupRemoteSyncCommand.d.ts +6 -0
  177. package/dist/lib/setupRemoteSyncCommand.js +65 -0
  178. package/dist/lib/setupSyncProjectsCommand.d.ts +4 -0
  179. package/dist/lib/setupSyncProjectsCommand.js +292 -0
  180. package/dist/lib/staleCommand.d.ts +8 -0
  181. package/dist/lib/staleCommand.js +34 -0
  182. package/dist/lib/statsCommand.d.ts +6 -0
  183. package/dist/lib/statsCommand.js +142 -0
  184. package/dist/lib/statusCommand.d.ts +18 -0
  185. package/dist/lib/statusCommand.js +250 -0
  186. package/dist/lib/storesCommand.d.ts +2 -0
  187. package/dist/lib/storesCommand.js +4 -0
  188. package/dist/lib/syncClient.d.ts +47 -0
  189. package/dist/lib/syncClient.js +212 -0
  190. package/dist/lib/syncCommand.d.ts +6 -0
  191. package/dist/lib/syncCommand.js +57 -0
  192. package/dist/lib/syncDoctorCommand.d.ts +5 -0
  193. package/dist/lib/syncDoctorCommand.js +100 -0
  194. package/dist/lib/syncIngest.d.ts +19 -0
  195. package/dist/lib/syncIngest.js +152 -0
  196. package/dist/lib/syncIngestLaunchd.d.ts +8 -0
  197. package/dist/lib/syncIngestLaunchd.js +93 -0
  198. package/dist/lib/syncIngestStartup.d.ts +5 -0
  199. package/dist/lib/syncIngestStartup.js +29 -0
  200. package/dist/lib/syncIngestSystemd.d.ts +10 -0
  201. package/dist/lib/syncIngestSystemd.js +97 -0
  202. package/dist/lib/syncIngestTimer.d.ts +8 -0
  203. package/dist/lib/syncIngestTimer.js +27 -0
  204. package/dist/lib/syncIngestTimerCommand.d.ts +7 -0
  205. package/dist/lib/syncIngestTimerCommand.js +83 -0
  206. package/dist/lib/syncLock.d.ts +6 -0
  207. package/dist/lib/syncLock.js +74 -0
  208. package/dist/lib/syncSnapshot.d.ts +30 -0
  209. package/dist/lib/syncSnapshot.js +184 -0
  210. package/dist/lib/syncStaging.d.ts +81 -0
  211. package/dist/lib/syncStaging.js +239 -0
  212. package/dist/lib/tagsAddCommand.d.ts +8 -0
  213. package/dist/lib/tagsAddCommand.js +18 -0
  214. package/dist/lib/tagsCommand.d.ts +4 -0
  215. package/dist/lib/tagsCommand.js +16 -0
  216. package/dist/lib/timelineCommand.d.ts +7 -0
  217. package/dist/lib/timelineCommand.js +49 -0
  218. package/dist/lib/traceCommand.d.ts +6 -0
  219. package/dist/lib/traceCommand.js +39 -0
  220. package/dist/lib/traverseCommand.d.ts +6 -0
  221. package/dist/lib/traverseCommand.js +58 -0
  222. package/dist/lib/updateCommand.d.ts +13 -0
  223. package/dist/lib/updateCommand.js +67 -0
  224. package/dist/lib/updateStatusCommand.d.ts +5 -0
  225. package/dist/lib/updateStatusCommand.js +38 -0
  226. package/dist/lib/webAddCommand.d.ts +8 -0
  227. package/dist/lib/webAddCommand.js +55 -0
  228. package/dist/lib/webBuildCommand.d.ts +10 -0
  229. package/dist/lib/webBuildCommand.js +65 -0
  230. package/dist/lib/webBuildIndexCommand.d.ts +8 -0
  231. package/dist/lib/webBuildIndexCommand.js +37 -0
  232. package/dist/lib/webIngestCommand.d.ts +11 -0
  233. package/dist/lib/webIngestCommand.js +51 -0
  234. package/dist/lib/webInitCommand.d.ts +9 -0
  235. package/dist/lib/webInitCommand.js +167 -0
  236. package/dist/lib/webRemoveCommand.d.ts +5 -0
  237. package/dist/lib/webRemoveCommand.js +41 -0
  238. package/dist/lib/webStatusCommand.d.ts +5 -0
  239. package/dist/lib/webStatusCommand.js +94 -0
  240. package/dist/lib/webUpdateCommand.d.ts +7 -0
  241. package/dist/lib/webUpdateCommand.js +72 -0
  242. package/dist/lib/workingSetCommand.d.ts +6 -0
  243. package/dist/lib/workingSetCommand.js +37 -0
  244. package/package.json +2 -1
@@ -0,0 +1,52 @@
1
+ import { GnosysDB } from "./db.js";
2
+ export async function runSetupRemotePullCommand(opts) {
3
+ let centralDb = null;
4
+ try {
5
+ centralDb = GnosysDB.openLocal();
6
+ if (!centralDb.isAvailable()) {
7
+ console.error("Central DB not available.");
8
+ process.exitCode = 1;
9
+ return;
10
+ }
11
+ const remotePath = centralDb.getMeta("remote_path");
12
+ if (!remotePath) {
13
+ console.error("Remote not configured.");
14
+ process.exitCode = 1;
15
+ return;
16
+ }
17
+ const { RemoteSync: RemoteSyncCtor } = await import("./remote.js");
18
+ const { withHeartbeat } = await import("./heartbeat.js");
19
+ const { createProgress } = await import("./progress.js");
20
+ const progress = createProgress(!!opts.verbose);
21
+ let sync = null;
22
+ try {
23
+ sync = new RemoteSyncCtor(centralDb, remotePath);
24
+ const runPull = () => sync.pull({
25
+ strategy: opts.newerWins ? "newer-wins" : "skip-and-flag",
26
+ onProgress: progress.noop ? undefined : progress.emit.bind(progress),
27
+ });
28
+ const result = opts.verbose
29
+ ? await runPull()
30
+ : await withHeartbeat("Pulling from remote", runPull);
31
+ const projParts = (result.projectsPulled || 0) > 0 ? ` | Projects pulled: ${result.projectsPulled}` : "";
32
+ const auditParts = (result.auditPulled || 0) > 0 ? ` | Audit pulled: ${result.auditPulled}` : "";
33
+ console.log(`Pulled: ${result.pulled} | Skipped: ${result.skipped} | Conflicts: ${result.conflicts.length}${projParts}${auditParts}`);
34
+ if (result.errors.length > 0) {
35
+ console.log("\nErrors:");
36
+ for (const e of result.errors)
37
+ console.log(` ${e}`);
38
+ }
39
+ }
40
+ finally {
41
+ sync?.closeRemote();
42
+ }
43
+ }
44
+ catch (err) {
45
+ console.error(`Error: ${err instanceof Error ? err.message : err}`);
46
+ process.exitCode = 1;
47
+ return;
48
+ }
49
+ finally {
50
+ centralDb?.close();
51
+ }
52
+ }
@@ -0,0 +1,5 @@
1
+ export type SetupRemotePushCommandOptions = {
2
+ newerWins?: boolean;
3
+ verbose?: boolean;
4
+ };
5
+ export declare function runSetupRemotePushCommand(opts: SetupRemotePushCommandOptions): Promise<void>;
@@ -0,0 +1,57 @@
1
+ import { GnosysDB } from "./db.js";
2
+ export async function runSetupRemotePushCommand(opts) {
3
+ let centralDb = null;
4
+ try {
5
+ centralDb = GnosysDB.openLocal();
6
+ if (!centralDb.isAvailable()) {
7
+ console.error("Central DB not available.");
8
+ process.exitCode = 1;
9
+ return;
10
+ }
11
+ const remotePath = centralDb.getMeta("remote_path");
12
+ if (!remotePath) {
13
+ console.error("Remote not configured.");
14
+ process.exitCode = 1;
15
+ return;
16
+ }
17
+ const { RemoteSync: RemoteSyncCtor } = await import("./remote.js");
18
+ const { withHeartbeat } = await import("./heartbeat.js");
19
+ const { createProgress } = await import("./progress.js");
20
+ const progress = createProgress(!!opts.verbose);
21
+ let sync = null;
22
+ try {
23
+ sync = new RemoteSyncCtor(centralDb, remotePath);
24
+ const runPush = () => sync.push({
25
+ strategy: opts.newerWins ? "newer-wins" : "skip-and-flag",
26
+ onProgress: progress.noop ? undefined : progress.emit.bind(progress),
27
+ });
28
+ const result = opts.verbose
29
+ ? await runPush()
30
+ : await withHeartbeat("Pushing to remote", runPush);
31
+ const projParts = (result.projectsPushed || 0) > 0 ? ` | Projects pushed: ${result.projectsPushed}` : "";
32
+ const auditParts = (result.auditPushed || 0) > 0 ? ` | Audit pushed: ${result.auditPushed}` : "";
33
+ console.log(`Pushed: ${result.pushed} | Skipped: ${result.skipped} | Conflicts: ${result.conflicts.length}${projParts}${auditParts}`);
34
+ if (result.errors.length > 0) {
35
+ console.log("\nErrors:");
36
+ for (const e of result.errors)
37
+ console.log(` ${e}`);
38
+ }
39
+ if (result.conflicts.length > 0) {
40
+ console.log("\nConflicts flagged (run 'gnosys setup remote status' for details):");
41
+ for (const c of result.conflicts)
42
+ console.log(` ${c.memoryId} — ${c.title}`);
43
+ }
44
+ }
45
+ finally {
46
+ sync?.closeRemote();
47
+ }
48
+ }
49
+ catch (err) {
50
+ console.error(`Error: ${err instanceof Error ? err.message : err}`);
51
+ process.exitCode = 1;
52
+ return;
53
+ }
54
+ finally {
55
+ centralDb?.close();
56
+ }
57
+ }
@@ -0,0 +1,4 @@
1
+ export type SetupRemoteResolveCommandOptions = {
2
+ keep: string;
3
+ };
4
+ export declare function runSetupRemoteResolveCommand(memoryId: string, opts: SetupRemoteResolveCommandOptions): Promise<void>;
@@ -0,0 +1,48 @@
1
+ import { GnosysDB } from "./db.js";
2
+ export async function runSetupRemoteResolveCommand(memoryId, opts) {
3
+ if (opts.keep !== "local" && opts.keep !== "remote") {
4
+ console.error(`--keep must be 'local' or 'remote' (got: ${opts.keep})`);
5
+ process.exitCode = 1;
6
+ return;
7
+ }
8
+ let centralDb = null;
9
+ try {
10
+ centralDb = GnosysDB.openLocal();
11
+ if (!centralDb.isAvailable()) {
12
+ console.error("Central DB not available.");
13
+ process.exitCode = 1;
14
+ return;
15
+ }
16
+ const remotePath = centralDb.getMeta("remote_path");
17
+ if (!remotePath) {
18
+ console.error("Remote not configured.");
19
+ process.exitCode = 1;
20
+ return;
21
+ }
22
+ const { RemoteSync: RemoteSyncCtor } = await import("./remote.js");
23
+ let sync = null;
24
+ try {
25
+ sync = new RemoteSyncCtor(centralDb, remotePath);
26
+ const result = await sync.resolve(memoryId, opts.keep);
27
+ if (result.ok) {
28
+ console.log(`Resolved ${memoryId}: kept ${opts.keep} version.`);
29
+ }
30
+ else {
31
+ console.error(`Failed to resolve: ${result.error}`);
32
+ process.exitCode = 1;
33
+ return;
34
+ }
35
+ }
36
+ finally {
37
+ sync?.closeRemote();
38
+ }
39
+ }
40
+ catch (err) {
41
+ console.error(`Error: ${err instanceof Error ? err.message : err}`);
42
+ process.exitCode = 1;
43
+ return;
44
+ }
45
+ finally {
46
+ centralDb?.close();
47
+ }
48
+ }
@@ -0,0 +1,4 @@
1
+ export type SetupRemoteStatusCommandOptions = {
2
+ json?: boolean;
3
+ };
4
+ export declare function runSetupRemoteStatusCommand(opts: SetupRemoteStatusCommandOptions): Promise<void>;
@@ -0,0 +1,73 @@
1
+ import { GnosysDB } from "./db.js";
2
+ export async function runSetupRemoteStatusCommand(opts) {
3
+ let centralDb = null;
4
+ try {
5
+ centralDb = GnosysDB.openLocal();
6
+ if (!centralDb.isAvailable()) {
7
+ console.error("Central DB not available.");
8
+ process.exitCode = 1;
9
+ return;
10
+ }
11
+ const { getConfiguredRemotePath } = await import("./remote.js");
12
+ const remotePath = getConfiguredRemotePath(centralDb);
13
+ if (!remotePath) {
14
+ if (opts.json) {
15
+ console.log(JSON.stringify({ configured: false, message: "Remote not configured. Run 'gnosys setup remote'." }, null, 2));
16
+ }
17
+ else {
18
+ console.log("Remote sync: not configured.");
19
+ console.log("Run 'gnosys setup remote' to set up multi-machine sync.");
20
+ }
21
+ return;
22
+ }
23
+ const mc = (await import("./machineConfig.js")).readMachineConfig();
24
+ if (mc?.remote.role) {
25
+ const { getV13SyncStatus } = await import("./syncClient.js");
26
+ const v13 = getV13SyncStatus(centralDb);
27
+ if (opts.json) {
28
+ console.log(JSON.stringify(v13, null, 2));
29
+ }
30
+ else {
31
+ console.log(`Multi-machine sync (${v13.role}) — ${v13.masterPath}`);
32
+ for (const line of v13.lines)
33
+ console.log(line);
34
+ if (v13.snapshotAge)
35
+ console.log(`Snapshot as of ${v13.snapshotAge}`);
36
+ }
37
+ return;
38
+ }
39
+ const { RemoteSync: RemoteSyncCtor, formatStatus } = await import("./remote.js");
40
+ const { withHeartbeat } = await import("./heartbeat.js");
41
+ let sync = null;
42
+ try {
43
+ sync = new RemoteSyncCtor(centralDb, remotePath);
44
+ const status = await withHeartbeat("Checking remote sync status", () => sync.getStatus());
45
+ if (opts.json) {
46
+ console.log(JSON.stringify(status, null, 2));
47
+ }
48
+ else {
49
+ console.log(formatStatus(status));
50
+ if (status.conflicts.length > 0) {
51
+ console.log("\nConflicts:");
52
+ for (const c of status.conflicts) {
53
+ console.log(` ${c.memoryId}: ${c.title}`);
54
+ console.log(` local: ${c.localModified}`);
55
+ console.log(` remote: ${c.remoteModified}`);
56
+ }
57
+ console.log("\nResolve with: gnosys setup remote resolve <memory-id> --keep <local|remote>");
58
+ }
59
+ }
60
+ }
61
+ finally {
62
+ sync?.closeRemote();
63
+ }
64
+ }
65
+ catch (err) {
66
+ console.error(`Error: ${err instanceof Error ? err.message : err}`);
67
+ process.exitCode = 1;
68
+ return;
69
+ }
70
+ finally {
71
+ centralDb?.close();
72
+ }
73
+ }
@@ -0,0 +1,6 @@
1
+ export type SetupRemoteSyncCommandOptions = {
2
+ auto?: boolean;
3
+ newerWins?: boolean;
4
+ verbose?: boolean;
5
+ };
6
+ export declare function runSetupRemoteSyncCommand(opts: SetupRemoteSyncCommandOptions): Promise<void>;
@@ -0,0 +1,65 @@
1
+ import { GnosysDB } from "./db.js";
2
+ export async function runSetupRemoteSyncCommand(opts) {
3
+ let centralDb = null;
4
+ try {
5
+ centralDb = GnosysDB.openLocal();
6
+ if (!centralDb.isAvailable()) {
7
+ if (!opts.auto)
8
+ console.error("Central DB not available.");
9
+ process.exitCode = 1;
10
+ return;
11
+ }
12
+ const remotePath = centralDb.getMeta("remote_path");
13
+ if (!remotePath) {
14
+ if (!opts.auto)
15
+ console.error("Remote not configured.");
16
+ process.exitCode = opts.auto ? 0 : 1;
17
+ return;
18
+ }
19
+ const { RemoteSync: RemoteSyncCtor } = await import("./remote.js");
20
+ const { withHeartbeat } = await import("./heartbeat.js");
21
+ const { createProgress } = await import("./progress.js");
22
+ const progress = createProgress(!!opts.verbose);
23
+ let sync = null;
24
+ try {
25
+ sync = new RemoteSyncCtor(centralDb, remotePath);
26
+ const runSync = () => sync.sync({
27
+ auto: opts.auto,
28
+ strategy: opts.newerWins ? "newer-wins" : "skip-and-flag",
29
+ onProgress: progress.noop ? undefined : progress.emit.bind(progress),
30
+ });
31
+ const result = opts.auto || opts.verbose
32
+ ? await runSync()
33
+ : await withHeartbeat("Syncing with remote", runSync);
34
+ if (!opts.auto || result.conflicts.length > 0 || result.errors.length > 0) {
35
+ const pp = result.projectsPushed || 0;
36
+ const pl = result.projectsPulled || 0;
37
+ const ap = result.auditPushed || 0;
38
+ const al = result.auditPulled || 0;
39
+ const projParts = pp + pl > 0 ? ` | Projects: ↑${pp}/↓${pl}` : "";
40
+ const auditParts = ap + al > 0 ? ` | Audit: ↑${ap}/↓${al}` : "";
41
+ console.log(`Pushed: ${result.pushed} | Pulled: ${result.pulled} | Conflicts: ${result.conflicts.length}${projParts}${auditParts}`);
42
+ if (result.errors.length > 0) {
43
+ console.log("\nErrors:");
44
+ for (const e of result.errors)
45
+ console.log(` ${e}`);
46
+ }
47
+ if (result.conflicts.length > 0) {
48
+ console.log("\nConflicts need resolution (run 'gnosys setup remote status' for details).");
49
+ }
50
+ }
51
+ }
52
+ finally {
53
+ sync?.closeRemote();
54
+ }
55
+ }
56
+ catch (err) {
57
+ if (!opts.auto)
58
+ console.error(`Error: ${err instanceof Error ? err.message : err}`);
59
+ process.exitCode = 1;
60
+ return;
61
+ }
62
+ finally {
63
+ centralDb?.close();
64
+ }
65
+ }
@@ -0,0 +1,4 @@
1
+ export type SetupSyncProjectsCommandOptions = {
2
+ skipDashboard?: boolean;
3
+ };
4
+ export declare function runSetupSyncProjectsCommand(opts: SetupSyncProjectsCommandOptions): Promise<void>;
@@ -0,0 +1,292 @@
1
+ import path from "path";
2
+ import fs from "fs/promises";
3
+ import os from "os";
4
+ import { fileURLToPath } from "url";
5
+ import { GnosysDB } from "./db.js";
6
+ import { GnosysResolver } from "./resolver.js";
7
+ import { createProjectIdentity } from "./projectIdentity.js";
8
+ const __filename = fileURLToPath(import.meta.url);
9
+ const __dirname = path.dirname(__filename);
10
+ async function packageVersion() {
11
+ const pkgPath = path.resolve(__dirname, "..", "..", "package.json");
12
+ const pkg = JSON.parse(await fs.readFile(pkgPath, "utf-8"));
13
+ return pkg.version;
14
+ }
15
+ export async function runSetupSyncProjectsCommand(opts) {
16
+ const currentVersion = await packageVersion();
17
+ // v5.9.3 Screen 10 — Header + leading spinner + hierarchical sections.
18
+ const { renderSyncHeader, renderUpgradedSection, renderSkippedSection, renderFailedSection, renderMachinesSection, renderDivider, renderDoneLine, renderDashboardSummary, } = await import("./setup/syncProjectsRender.js");
19
+ const { Spinner } = await import("./setup/ui/spinner.js");
20
+ console.log("");
21
+ console.log(renderSyncHeader(currentVersion));
22
+ console.log("");
23
+ // 1. Read registered projects from file registry AND central DB
24
+ const home = process.env.HOME || process.env.USERPROFILE || "/tmp";
25
+ const registryPath = path.join(home, ".config", "gnosys", "projects.json");
26
+ let fileProjects = [];
27
+ try {
28
+ fileProjects = JSON.parse(await fs.readFile(registryPath, "utf-8"));
29
+ }
30
+ catch {
31
+ // No file registry yet
32
+ }
33
+ // Also check central DB for projects not in the file registry. Also
34
+ // capture project titles so the Screen 10 row labels can use the
35
+ // human-readable name where available.
36
+ let dbProjects = [];
37
+ const titleByDir = new Map();
38
+ try {
39
+ const centralDb = GnosysDB.openCentral();
40
+ if (centralDb.isAvailable()) {
41
+ const allProjects = centralDb.getAllProjects();
42
+ dbProjects = allProjects.map((p) => p.working_directory);
43
+ for (const p of allProjects)
44
+ titleByDir.set(p.working_directory, p.name);
45
+ centralDb.close();
46
+ }
47
+ }
48
+ catch {
49
+ // non-critical
50
+ }
51
+ // Merge: deduplicate by resolved path
52
+ const seen = new Set();
53
+ const projects = [];
54
+ for (const p of [...fileProjects, ...dbProjects]) {
55
+ const resolved = path.resolve(p);
56
+ if (!seen.has(resolved)) {
57
+ seen.add(resolved);
58
+ projects.push(resolved);
59
+ }
60
+ }
61
+ if (projects.length === 0) {
62
+ console.log(" no registered projects found");
63
+ console.log(" run `gnosys init` in each project first");
64
+ return;
65
+ }
66
+ // Lead-in spinner: shows we're churning through the registry. Resolves
67
+ // to ✓ summary after the iteration loop completes (or fail on hard error).
68
+ const syncSpinner = Spinner(`syncing ${projects.length} registered projects…`);
69
+ // Sync the merged list back to file registry
70
+ try {
71
+ await fs.mkdir(path.dirname(registryPath), { recursive: true });
72
+ await fs.writeFile(registryPath, JSON.stringify(projects, null, 2), "utf-8");
73
+ }
74
+ catch {
75
+ // non-critical
76
+ }
77
+ // 2. Iterate and upgrade each project that exists on this machine
78
+ const upgraded = [];
79
+ const skipped = [];
80
+ const failed = [];
81
+ for (const projectDir of projects) {
82
+ // Skip test/temp directories
83
+ if (projectDir.startsWith("/tmp/") || projectDir.startsWith("/private/tmp/") || projectDir.startsWith("/var/folders/") || projectDir.startsWith("/private/var/folders/")) {
84
+ continue;
85
+ }
86
+ const storePath = path.join(projectDir, ".gnosys");
87
+ try {
88
+ await fs.stat(storePath);
89
+ }
90
+ catch {
91
+ skipped.push(projectDir);
92
+ continue;
93
+ }
94
+ try {
95
+ // Re-create project identity (re-syncs with central DB)
96
+ let centralDb = null;
97
+ try {
98
+ centralDb = GnosysDB.openCentral();
99
+ if (!centralDb.isAvailable())
100
+ centralDb = null;
101
+ }
102
+ catch {
103
+ centralDb = null;
104
+ }
105
+ await createProjectIdentity(projectDir, { centralDb: centralDb || undefined });
106
+ // Re-register in file-based registry (idempotent)
107
+ const tempResolver = new GnosysResolver();
108
+ await tempResolver.registerProject(projectDir);
109
+ // Re-generate agent rules for all detected IDEs
110
+ if (centralDb) {
111
+ const { syncToTarget } = await import("./rulesGen.js");
112
+ const { readProjectIdentity } = await import("./projectIdentity.js");
113
+ const identity = await readProjectIdentity(projectDir);
114
+ const projectId = identity?.projectId || null;
115
+ try {
116
+ await syncToTarget(centralDb, projectDir, "all", projectId);
117
+ }
118
+ catch {
119
+ // Some projects may not have IDE configs — that's ok
120
+ }
121
+ centralDb.close();
122
+ }
123
+ // Configure IDE hooks for automatic memory recall
124
+ const { configureIdeHooks } = await import("./projectIdentity.js");
125
+ await configureIdeHooks(projectDir);
126
+ upgraded.push(projectDir);
127
+ }
128
+ catch (err) {
129
+ failed.push(`${projectDir} (${err.message})`);
130
+ }
131
+ }
132
+ // Stop the lead-in spinner now that the iteration is done. Resolved
133
+ // before any per-section output so the cursor is on a fresh line.
134
+ syncSpinner.ok(`synced ${projects.length} registered projects`, `${upgraded.length} upgraded · ${skipped.length} skipped · ${failed.length} failed`);
135
+ // 3. Update global agent rules
136
+ try {
137
+ let centralDb = null;
138
+ try {
139
+ centralDb = GnosysDB.openCentral();
140
+ if (!centralDb.isAvailable())
141
+ centralDb = null;
142
+ }
143
+ catch {
144
+ centralDb = null;
145
+ }
146
+ if (centralDb) {
147
+ const { syncToTarget } = await import("./rulesGen.js");
148
+ await syncToTarget(centralDb, process.cwd(), "global", null);
149
+ centralDb.close();
150
+ const { printStatus } = await import("./setup/ui/status.js");
151
+ printStatus("ok", "global agent rules updated", "~/.claude/CLAUDE.md");
152
+ }
153
+ }
154
+ catch {
155
+ const { printStatus } = await import("./setup/ui/status.js");
156
+ printStatus("warn", "could not update global agent rules");
157
+ }
158
+ // 4. Stamp the central DB with current version and machine info
159
+ try {
160
+ const centralDb = GnosysDB.openCentral();
161
+ if (centralDb.isAvailable()) {
162
+ const hostname = os.hostname();
163
+ centralDb.setMeta("app_version", currentVersion);
164
+ centralDb.setMeta("last_upgrade", new Date().toISOString());
165
+ centralDb.setMeta("upgraded_by", hostname);
166
+ // Record this machine in the connected-machines registry. Keyed by
167
+ // hostname, but we pass machineId + any previous hostnames so a renamed
168
+ // machine prunes its own orphaned entry instead of showing up twice.
169
+ const { ensureMachineConfig } = await import("./machineConfig.js");
170
+ const { recordMachine } = await import("./machineRegistry.js");
171
+ const machine = ensureMachineConfig().config;
172
+ recordMachine(centralDb, {
173
+ hostname,
174
+ version: currentVersion,
175
+ machineId: machine.machineId,
176
+ aliases: machine.previousHostnames,
177
+ });
178
+ centralDb.close();
179
+ }
180
+ }
181
+ catch {
182
+ // non-critical
183
+ }
184
+ // 5. Report — v5.9.3 Screen 10 hierarchical layout. Section helpers
185
+ // turn the raw path arrays into ProjectRow lists (title + fullPath)
186
+ // and emit dividers between groups.
187
+ function rowFor(p) {
188
+ const title = titleByDir.get(p) ?? titleByDir.get(path.resolve(p)) ?? path.basename(p);
189
+ return { title, fullPath: p };
190
+ }
191
+ const upgradedRows = upgraded.map(rowFor);
192
+ const skippedRows = skipped.map(rowFor);
193
+ const failedRows = failed.map((f) => {
194
+ // failed entries are "<path> (<err>)" — extract path for the title.
195
+ const match = f.match(/^(.+?)\s\((.+)\)$/);
196
+ const projectPath = match ? match[1] : f;
197
+ return { title: titleByDir.get(projectPath) ?? path.basename(projectPath), fullPath: f };
198
+ });
199
+ console.log("");
200
+ for (const line of renderUpgradedSection(upgradedRows))
201
+ console.log(line);
202
+ if (upgradedRows.length > 0 && (skippedRows.length > 0 || failedRows.length > 0)) {
203
+ console.log("");
204
+ }
205
+ for (const line of renderSkippedSection(skippedRows))
206
+ console.log(line);
207
+ if (failedRows.length > 0) {
208
+ console.log("");
209
+ for (const line of renderFailedSection(failedRows))
210
+ console.log(line);
211
+ }
212
+ // Connected-machines callout (separate divider per design spec).
213
+ let machineLines = [];
214
+ try {
215
+ const centralDb = GnosysDB.openCentral();
216
+ if (centralDb.isAvailable()) {
217
+ const { readMachineRegistry } = await import("./machineRegistry.js");
218
+ const machines = readMachineRegistry(centralDb);
219
+ const entries = Object.entries(machines);
220
+ if (entries.length > 0) {
221
+ const currentHost = os.hostname();
222
+ const machineRows = entries.map(([host, info]) => ({
223
+ hostname: host,
224
+ version: info.version,
225
+ lastSeen: info.lastSeen,
226
+ isCurrent: host === currentHost,
227
+ }));
228
+ machineLines = renderMachinesSection(machineRows, currentVersion);
229
+ }
230
+ centralDb.close();
231
+ }
232
+ }
233
+ catch {
234
+ // non-critical
235
+ }
236
+ if (machineLines.length > 0) {
237
+ console.log("");
238
+ console.log(renderDivider());
239
+ console.log("");
240
+ for (const line of machineLines)
241
+ console.log(line);
242
+ }
243
+ console.log("");
244
+ console.log(renderDivider());
245
+ console.log("");
246
+ console.log(renderDoneLine(currentVersion));
247
+ if (skippedRows.length > 0) {
248
+ // v5.9.3 Phase H: offer one-keystroke cleanup. Stays interactive
249
+ // by default; users on a TTY get the prompt, non-TTY runs silently
250
+ // (sync-projects is sometimes invoked from CI).
251
+ console.log("");
252
+ if (process.stdout.isTTY) {
253
+ try {
254
+ const { cleanupRegistry } = await import("./cleanup.js");
255
+ await cleanupRegistry({ interactive: true });
256
+ }
257
+ catch (err) {
258
+ const { printStatus } = await import("./setup/ui/status.js");
259
+ printStatus("warn", "cleanup skipped", err instanceof Error ? err.message : String(err));
260
+ }
261
+ }
262
+ else {
263
+ const { printStatus } = await import("./setup/ui/status.js");
264
+ printStatus("progress", "tip", "run `gnosys cleanup` to remove stale entries");
265
+ }
266
+ }
267
+ // 6. Regenerate portfolio dashboard
268
+ if (!opts.skipDashboard) {
269
+ try {
270
+ const dashboardPath = path.join(home, "gnosys-dashboard.html");
271
+ const dashboardMdPath = path.join(home, "gnosys-dashboard.md");
272
+ const centralDb = GnosysDB.openCentral();
273
+ if (centralDb.isAvailable()) {
274
+ const { generatePortfolio, formatPortfolioMarkdown } = await import("./portfolio.js");
275
+ const { generatePortfolioHtml } = await import("./portfolioHtml.js");
276
+ const report = generatePortfolio(centralDb);
277
+ await fs.writeFile(dashboardPath, generatePortfolioHtml(report, dashboardPath), "utf-8");
278
+ await fs.writeFile(dashboardMdPath, formatPortfolioMarkdown(report), "utf-8");
279
+ centralDb.close();
280
+ console.log("");
281
+ for (const line of renderDashboardSummary(dashboardPath, dashboardMdPath)) {
282
+ console.log(line);
283
+ }
284
+ }
285
+ }
286
+ catch {
287
+ const { printStatus } = await import("./setup/ui/status.js");
288
+ console.log("");
289
+ printStatus("warn", "could not regenerate portfolio dashboard");
290
+ }
291
+ }
292
+ }
@@ -0,0 +1,8 @@
1
+ import type { GnosysResolver } from "./resolver.js";
2
+ export type StaleCommandOptions = {
3
+ days: string;
4
+ limit: string;
5
+ };
6
+ type GetResolver = () => Promise<GnosysResolver>;
7
+ export declare function runStaleCommand(getResolver: GetResolver, opts: StaleCommandOptions): Promise<void>;
8
+ export {};
@@ -0,0 +1,34 @@
1
+ export async function runStaleCommand(getResolver, opts) {
2
+ const resolver = await getResolver();
3
+ const threshold = parseInt(opts.days);
4
+ const cutoff = new Date();
5
+ cutoff.setDate(cutoff.getDate() - threshold);
6
+ const cutoffStr = cutoff.toISOString().split("T")[0];
7
+ const allMemories = await resolver.getAllMemories();
8
+ const stale = allMemories
9
+ .filter((m) => {
10
+ const lastTouched = m.frontmatter.last_reviewed ||
11
+ m.frontmatter.modified;
12
+ return lastTouched && lastTouched < cutoffStr;
13
+ })
14
+ .sort((a, b) => {
15
+ const aDate = a.frontmatter.last_reviewed ||
16
+ a.frontmatter.modified;
17
+ const bDate = b.frontmatter.last_reviewed ||
18
+ b.frontmatter.modified;
19
+ return (aDate || "").localeCompare(bDate || "");
20
+ })
21
+ .slice(0, parseInt(opts.limit));
22
+ if (stale.length === 0) {
23
+ console.log(`No memories older than ${threshold} days.`);
24
+ return;
25
+ }
26
+ console.log(`${stale.length} memories not touched in ${threshold}+ days:\n`);
27
+ for (const m of stale) {
28
+ const lr = m.frontmatter.last_reviewed;
29
+ console.log(` ${m.frontmatter.title}`);
30
+ console.log(` ${m.sourceLabel}:${m.relativePath}`);
31
+ console.log(` Modified: ${m.frontmatter.modified}${lr ? `, Reviewed: ${lr}` : ""}`);
32
+ console.log();
33
+ }
34
+ }
@@ -0,0 +1,6 @@
1
+ export type StatsCommandOptions = {
2
+ json?: boolean;
3
+ byProject?: boolean;
4
+ all?: boolean;
5
+ };
6
+ export declare function runStatsCommand(opts: StatsCommandOptions): Promise<void>;