@leemour/cli-messaging 0.141.0 → 0.143.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 (128) hide show
  1. package/dist/cli/config-command.js +5 -0
  2. package/dist/cli/config-command.js.map +1 -1
  3. package/dist/cli/messenger/archive-commands.d.ts.map +1 -1
  4. package/dist/cli/messenger/archive-commands.js +91 -7
  5. package/dist/cli/messenger/archive-commands.js.map +1 -1
  6. package/dist/cli/messenger/catch-up.d.ts +17 -0
  7. package/dist/cli/messenger/catch-up.d.ts.map +1 -0
  8. package/dist/cli/messenger/catch-up.js +30 -0
  9. package/dist/cli/messenger/catch-up.js.map +1 -0
  10. package/dist/cli/messenger/conversations-command.d.ts.map +1 -1
  11. package/dist/cli/messenger/conversations-command.js +213 -27
  12. package/dist/cli/messenger/conversations-command.js.map +1 -1
  13. package/dist/cli/messenger/export-folder.d.ts +54 -0
  14. package/dist/cli/messenger/export-folder.d.ts.map +1 -0
  15. package/dist/cli/messenger/export-folder.js +106 -0
  16. package/dist/cli/messenger/export-folder.js.map +1 -0
  17. package/dist/cli/messenger/inbox.d.ts +4 -3
  18. package/dist/cli/messenger/inbox.d.ts.map +1 -1
  19. package/dist/cli/messenger/inbox.js +28 -32
  20. package/dist/cli/messenger/inbox.js.map +1 -1
  21. package/dist/cli/messenger/messages-command.d.ts.map +1 -1
  22. package/dist/cli/messenger/messages-command.js +2 -0
  23. package/dist/cli/messenger/messages-command.js.map +1 -1
  24. package/dist/cli/messenger/messages-stats-command.d.ts +4 -0
  25. package/dist/cli/messenger/messages-stats-command.d.ts.map +1 -0
  26. package/dist/cli/messenger/messages-stats-command.js +49 -0
  27. package/dist/cli/messenger/messages-stats-command.js.map +1 -0
  28. package/dist/cli/messenger/password.d.ts +11 -0
  29. package/dist/cli/messenger/password.d.ts.map +1 -0
  30. package/dist/cli/messenger/password.js +26 -0
  31. package/dist/cli/messenger/password.js.map +1 -0
  32. package/dist/cli/messenger/points.d.ts +21 -0
  33. package/dist/cli/messenger/points.d.ts.map +1 -0
  34. package/dist/cli/messenger/points.js +39 -0
  35. package/dist/cli/messenger/points.js.map +1 -0
  36. package/dist/cli/messenger/review.d.ts.map +1 -1
  37. package/dist/cli/messenger/review.js +55 -20
  38. package/dist/cli/messenger/review.js.map +1 -1
  39. package/dist/cli/messenger/store-maintenance-command.d.ts.map +1 -1
  40. package/dist/cli/messenger/store-maintenance-command.js +75 -20
  41. package/dist/cli/messenger/store-maintenance-command.js.map +1 -1
  42. package/dist/cli/permission-migration.d.ts.map +1 -1
  43. package/dist/cli/permission-migration.js +14 -9
  44. package/dist/cli/permission-migration.js.map +1 -1
  45. package/dist/cli/settings.d.ts +4 -0
  46. package/dist/cli/settings.d.ts.map +1 -1
  47. package/dist/cli/settings.js +12 -22
  48. package/dist/cli/settings.js.map +1 -1
  49. package/dist/domain/models.d.ts +4 -0
  50. package/dist/domain/models.d.ts.map +1 -1
  51. package/dist/mcp/server.d.ts.map +1 -1
  52. package/dist/mcp/server.js +2 -1
  53. package/dist/mcp/server.js.map +1 -1
  54. package/dist/mcp/tool.d.ts +1 -1
  55. package/dist/mcp/tool.d.ts.map +1 -1
  56. package/dist/mcp/tools/conversations.d.ts +1 -1
  57. package/dist/mcp/tools/conversations.d.ts.map +1 -1
  58. package/dist/mcp/tools/conversations.js +76 -5
  59. package/dist/mcp/tools/conversations.js.map +1 -1
  60. package/dist/mcp/tools/messages.d.ts.map +1 -1
  61. package/dist/mcp/tools/messages.js +8 -1
  62. package/dist/mcp/tools/messages.js.map +1 -1
  63. package/dist/mcp/tools/search.d.ts +24 -0
  64. package/dist/mcp/tools/search.d.ts.map +1 -1
  65. package/dist/mcp/tools/search.js +25 -0
  66. package/dist/mcp/tools/search.js.map +1 -1
  67. package/dist/sealed.d.ts +39 -0
  68. package/dist/sealed.d.ts.map +1 -0
  69. package/dist/sealed.js +140 -0
  70. package/dist/sealed.js.map +1 -0
  71. package/dist/search/lucene/dates.d.ts +2 -2
  72. package/dist/search/lucene/dates.d.ts.map +1 -1
  73. package/dist/search/lucene/dates.js +27 -5
  74. package/dist/search/lucene/dates.js.map +1 -1
  75. package/dist/search/lucene/registry.d.ts +1 -1
  76. package/dist/search/lucene/registry.d.ts.map +1 -1
  77. package/dist/search/lucene/registry.js +1 -1
  78. package/dist/search/lucene/registry.js.map +1 -1
  79. package/dist/sends/index.d.ts +1 -1
  80. package/dist/sends/index.d.ts.map +1 -1
  81. package/dist/sends/index.js +1 -1
  82. package/dist/sends/index.js.map +1 -1
  83. package/dist/sends/permissions.d.ts +9 -0
  84. package/dist/sends/permissions.d.ts.map +1 -1
  85. package/dist/sends/permissions.js +19 -0
  86. package/dist/sends/permissions.js.map +1 -1
  87. package/dist/services/archive.d.ts +22 -1
  88. package/dist/services/archive.d.ts.map +1 -1
  89. package/dist/services/archive.js +25 -0
  90. package/dist/services/archive.js.map +1 -1
  91. package/dist/services/embeddings.d.ts +108 -3
  92. package/dist/services/embeddings.d.ts.map +1 -1
  93. package/dist/services/embeddings.js +250 -59
  94. package/dist/services/embeddings.js.map +1 -1
  95. package/dist/services/inbox.d.ts +27 -9
  96. package/dist/services/inbox.d.ts.map +1 -1
  97. package/dist/services/inbox.js +57 -22
  98. package/dist/services/inbox.js.map +1 -1
  99. package/dist/services/messages-search.d.ts +21 -1
  100. package/dist/services/messages-search.d.ts.map +1 -1
  101. package/dist/services/messages-search.js +90 -26
  102. package/dist/services/messages-search.js.map +1 -1
  103. package/dist/services/messages.d.ts +8 -1
  104. package/dist/services/messages.d.ts.map +1 -1
  105. package/dist/services/messages.js +7 -1
  106. package/dist/services/messages.js.map +1 -1
  107. package/dist/store/sqlite/lucene.d.ts +11 -0
  108. package/dist/store/sqlite/lucene.d.ts.map +1 -1
  109. package/dist/store/sqlite/lucene.js +53 -18
  110. package/dist/store/sqlite/lucene.js.map +1 -1
  111. package/dist/store/sqlite/messages.d.ts +2 -2
  112. package/dist/store/sqlite/messages.d.ts.map +1 -1
  113. package/dist/store/sqlite/messages.js +5 -2
  114. package/dist/store/sqlite/messages.js.map +1 -1
  115. package/dist/store/sqlite/reads.d.ts +10 -0
  116. package/dist/store/sqlite/reads.d.ts.map +1 -1
  117. package/dist/store/sqlite/reads.js +25 -2
  118. package/dist/store/sqlite/reads.js.map +1 -1
  119. package/dist/store/sqlite/vectors.d.ts +49 -1
  120. package/dist/store/sqlite/vectors.d.ts.map +1 -1
  121. package/dist/store/sqlite/vectors.js +121 -6
  122. package/dist/store/sqlite/vectors.js.map +1 -1
  123. package/dist/store/store.d.ts +51 -1
  124. package/dist/store/store.d.ts.map +1 -1
  125. package/dist/store/store.js +55 -7
  126. package/dist/store/store.js.map +1 -1
  127. package/package.json +1 -1
  128. package/parity.json +280 -4
@@ -104,6 +104,11 @@ export const configCommand = (app, config) => {
104
104
  const scopeOf = (kind, profile) => [kind, profile === undefined ? "defaults" : `profiles.${profile}`].filter(Boolean).join(".");
105
105
  /** A shared setting from what was resolved; a messenger's own from the file, where it lives. */
106
106
  const sourced = (settings, setting) => {
107
+ // Every layer adds to `permissions`, so the nearest layer's object alone is not what holds.
108
+ if (setting === "permissions") {
109
+ const from = Object.keys(settings.permissions).length > 0 ? "config file" : "default";
110
+ return { setting, value: settings.permissions, from, sources: settings.permissionSources };
111
+ }
107
112
  if (setting in settings.sources) {
108
113
  const value = settings[setting];
109
114
  // No list is every action, and `null` would read as none.
@@ -1 +1 @@
1
- {"version":3,"file":"config-command.js","sourceRoot":"","sources":["../../src/cli/config-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AACjD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EACL,QAAQ,EACR,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,YAAY,EACZ,cAAc,GACf,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAA;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAC5B,OAAO,EAAoB,OAAO,EAAE,MAAM,UAAU,CAAA;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAA;AACxF,OAAO,EAAsB,QAAQ,EAAiB,MAAM,eAAe,CAAA;AAE3E;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,GAAgB,EAAE,MAAqB,EAAW,EAAE;IAChF,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,qDAAqD,CAAC,CAAA;IAExG,OAAO,CAAC,UAAU,CAChB,QAAQ,CAAC,IAAI,OAAO,CAAC,SAAS,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;SAC7D,WAAW,CAAC,0FAA0F,CAAC;SACvG,MAAM,CAAC,WAAW,EAAE,6CAA6C,CAAC;SAClE,MAAM,CAAC;QACN,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,eAAe,CAAC,CAAA;QACnE,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,EAAwB,CAAC,MAAM,KAAK,IAAI,CAAA;QAChE,IAAI,CAAC,MAAM,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;YAC9C,MAAM,IAAI,QAAQ,CAAC,kBAAkB,EAAE,qEAAqE,CAAC,CAAA;QAC/G,MAAM,IAAI,GAAG,cAAc,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,CAAA;QACtG,MAAM,QAAQ,GAAG,uBAAuB,CAAC,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAA;QACvG,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;YACrB,MAAM,OAAO,GAAG,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAA;YAC3D,IAAI,CAAC,OAAO,CAAC,OAAO;gBAClB,MAAM,IAAI,QAAQ,CAChB,qBAAqB,EACrB,oEAAoE,CACrE,CAAA;YACH,IAAI,CAAC,MAAM;gBAAE,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;QACnD,CAAC;QACD,QAAQ,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAA;IACrG,CAAC,CAAC,CACL,CAAA;IAED,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,gFAAgF,CAAC;SAC7F,MAAM,CAAC,OAAO,EAAE,qFAAqF,CAAC;SACtG,MAAM,CAAC;QACN,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,EAAqB,CAAC,GAAG,KAAK,IAAI,CAAA;QACvD,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CACvE,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,EAAE,GAAG,OAAO,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAC/E,CAAA;QACD,MAAM,UAAU,GAAG,kBAAkB,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,CAAA;QAE3F,QAAQ,CAAC,MAAM,CAAC;YACd,OAAO,EAAE,QAAQ,CAAC,OAAO;YACzB,WAAW,EAAE,QAAQ,CAAC,OAAO,CAAC,OAAO;YACrC,QAAQ,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,kBAAkB,EAAE,GAAG,oBAAoB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;YAClG,UAAU,EAAE,QAAQ,CAAC,UAAU;YAC/B,WAAW,EAAE,QAAQ,CAAC,WAAW;YACjC,eAAe,EAAE,UAAU;YAC3B,QAAQ,EAAE,CAAC,GAAG,MAAM,CAAC,WAAW,EAAE,kBAAkB,CAAC;iBAClD,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,IAAI,OAAO,KAAK,eAAe,CAAC;iBACvD,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;SAChD,CAAC,CAAA;QAEF,IAAI,UAAU,EAAE,CAAC;YACf,QAAQ,CAAC,IAAI,CACX,GAAG,OAAO,CAAC,GAAG,EAAE,YAAY,CAAC,KAAK,OAAO,CAAC,GAAG,EAAE,WAAW,CAAC,OAAO,OAAO,CAAC,GAAG,EAAE,WAAW,CAAC,YAAY;gBACrG,8FAA8F,CACjG,CAAA;QACH,CAAC;IACH,CAAC,CAAC,CAAA;IAEJ,KAAK,MAAM,MAAM,IAAI,CAAC,KAAK,EAAE,OAAO,CAAU,EAAE,CAAC;QAC/C,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;aAC1E,QAAQ,CAAC,WAAW,EAAE,WAAW,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;aACjE,MAAM,CAAC,YAAY,EAAE,0DAA0D,CAAC;aAChF,MAAM,CAAC,YAAY,EAAE,+DAA+D,CAAC;aACrF,MAAM,CAAC,OAAO,EAAE,6CAA6C,CAAC,CAAA;QACjE,IAAI,MAAM,KAAK,KAAK;YAClB,GAAG;iBACA,QAAQ,CAAC,SAAS,EAAE,iEAAiE,CAAC;iBACtF,WAAW,CAAC,0CAA0C,CAAC,CAAA;;YACvD,GAAG,CAAC,WAAW,CAAC,8CAA8C,CAAC,CAAA;QAEpE,GAAG,CAAC,MAAM,CAAC,UAAyB,OAAe,EAAE,KAAc;YACjE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,eAAe,CAAC,CAAA;YAC7E,MAAM,EACJ,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EACR,GAAG,GACJ,GAAG,IAAI,CAAC,IAAI,EAA6D,CAAA;YAC1E,MAAM,QAAQ,GAAG,QAAQ,KAAK,IAAI,CAAA;YAClC,IAAI,QAAQ,IAAI,GAAG;gBACjB,MAAM,IAAI,QAAQ,CAAC,kBAAkB,EAAE,uDAAuD,CAAC,CAAA;YACjG,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAA;YAC5D,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE,cAAc,CAAC,CAAA;YACzC,IAAI,QAAQ,IAAI,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC1B,uDAAuD;gBACvD,MAAM,IAAI,QAAQ,CAChB,kBAAkB,EAClB,qCAAqC,QAAQ,CAAC,OAAO,KAAK,IAAI,sCAAsC,CACrG,CAAA;YACH,CAAC;YACD,IACE,CAAC,UAAU,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC;gBACnD,mBAAmB,CAAC,cAAc,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,EACjG,CAAC;gBACD,MAAM,IAAI,QAAQ,CAChB,kBAAkB,EAClB,GAAG,OAAO,mGAAmG,CAC9G,CAAA;YACH,CAAC;YACD,MAAM,KAAK,GAAG,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,UAAU,EAAE;gBACtD,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO;gBAChD,OAAO;gBACP,KAAK,EAAE,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS;gBACnD,IAAI;aACL,CAAC,CAAA;YACF,QAAQ,CAAC,MAAM,CAAC;gBACd,UAAU,EAAE,QAAQ,CAAC,UAAU;gBAC/B,KAAK,EAAE,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAC7D,OAAO;gBACP,KAAK,EAAE,KAAK;aACb,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA;AAED,MAAM,OAAO,GAAG,CAAC,IAAwB,EAAE,OAA2B,EAAU,EAAE,CAChF,CAAC,IAAI,EAAE,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAE9F,gGAAgG;AAChG,MAAM,OAAO,GAAG,CAAC,QAAkB,EAAE,OAAe,EAAE,EAAE;IACtD,IAAI,OAAO,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;QAChC,MAAM,KAAK,GAAI,QAA+C,CAAC,OAAO,CAAC,CAAA;QACvE,0DAA0D;QAC1D,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAA;IACtH,CAAC;IACD,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,QAAQ,CAAU,QAAQ,EAAE,OAAO,EAAE,iBAAiB,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,CAAA;IAChG,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAA;AACjC,CAAC,CAAA;AAED,6GAA6G;AAC7G,MAAM,iBAAiB,GAA4B,EAAE,cAAc,EAAE,MAAM,EAAE,CAAA;AAE7E,4FAA4F;AAC5F,MAAM,oBAAoB,GAAG,CAAC,GAAgB,EAAE,GAAsB,EAAY,EAAE;IAClF,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC,KAAK,EAAE,UAAU,CAAC,CAAA;IACtG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,CAAA;IAC/B,OAAO,WAAW,CAAC,GAAG,CAAC;SACpB,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;SACxC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAA;AAClD,CAAC,CAAA"}
1
+ {"version":3,"file":"config-command.js","sourceRoot":"","sources":["../../src/cli/config-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AACjD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EACL,QAAQ,EACR,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,YAAY,EACZ,cAAc,GACf,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAA;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAC5B,OAAO,EAAoB,OAAO,EAAE,MAAM,UAAU,CAAA;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAA;AACxF,OAAO,EAAsB,QAAQ,EAAiB,MAAM,eAAe,CAAA;AAE3E;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,GAAgB,EAAE,MAAqB,EAAW,EAAE;IAChF,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,qDAAqD,CAAC,CAAA;IAExG,OAAO,CAAC,UAAU,CAChB,QAAQ,CAAC,IAAI,OAAO,CAAC,SAAS,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;SAC7D,WAAW,CAAC,0FAA0F,CAAC;SACvG,MAAM,CAAC,WAAW,EAAE,6CAA6C,CAAC;SAClE,MAAM,CAAC;QACN,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,eAAe,CAAC,CAAA;QACnE,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,EAAwB,CAAC,MAAM,KAAK,IAAI,CAAA;QAChE,IAAI,CAAC,MAAM,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;YAC9C,MAAM,IAAI,QAAQ,CAAC,kBAAkB,EAAE,qEAAqE,CAAC,CAAA;QAC/G,MAAM,IAAI,GAAG,cAAc,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,CAAA;QACtG,MAAM,QAAQ,GAAG,uBAAuB,CAAC,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAA;QACvG,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;YACrB,MAAM,OAAO,GAAG,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAA;YAC3D,IAAI,CAAC,OAAO,CAAC,OAAO;gBAClB,MAAM,IAAI,QAAQ,CAChB,qBAAqB,EACrB,oEAAoE,CACrE,CAAA;YACH,IAAI,CAAC,MAAM;gBAAE,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;QACnD,CAAC;QACD,QAAQ,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAA;IACrG,CAAC,CAAC,CACL,CAAA;IAED,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,gFAAgF,CAAC;SAC7F,MAAM,CAAC,OAAO,EAAE,qFAAqF,CAAC;SACtG,MAAM,CAAC;QACN,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,EAAqB,CAAC,GAAG,KAAK,IAAI,CAAA;QACvD,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CACvE,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,EAAE,GAAG,OAAO,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAC/E,CAAA;QACD,MAAM,UAAU,GAAG,kBAAkB,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,CAAA;QAE3F,QAAQ,CAAC,MAAM,CAAC;YACd,OAAO,EAAE,QAAQ,CAAC,OAAO;YACzB,WAAW,EAAE,QAAQ,CAAC,OAAO,CAAC,OAAO;YACrC,QAAQ,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,kBAAkB,EAAE,GAAG,oBAAoB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;YAClG,UAAU,EAAE,QAAQ,CAAC,UAAU;YAC/B,WAAW,EAAE,QAAQ,CAAC,WAAW;YACjC,eAAe,EAAE,UAAU;YAC3B,QAAQ,EAAE,CAAC,GAAG,MAAM,CAAC,WAAW,EAAE,kBAAkB,CAAC;iBAClD,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,IAAI,OAAO,KAAK,eAAe,CAAC;iBACvD,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;SAChD,CAAC,CAAA;QAEF,IAAI,UAAU,EAAE,CAAC;YACf,QAAQ,CAAC,IAAI,CACX,GAAG,OAAO,CAAC,GAAG,EAAE,YAAY,CAAC,KAAK,OAAO,CAAC,GAAG,EAAE,WAAW,CAAC,OAAO,OAAO,CAAC,GAAG,EAAE,WAAW,CAAC,YAAY;gBACrG,8FAA8F,CACjG,CAAA;QACH,CAAC;IACH,CAAC,CAAC,CAAA;IAEJ,KAAK,MAAM,MAAM,IAAI,CAAC,KAAK,EAAE,OAAO,CAAU,EAAE,CAAC;QAC/C,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;aAC1E,QAAQ,CAAC,WAAW,EAAE,WAAW,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;aACjE,MAAM,CAAC,YAAY,EAAE,0DAA0D,CAAC;aAChF,MAAM,CAAC,YAAY,EAAE,+DAA+D,CAAC;aACrF,MAAM,CAAC,OAAO,EAAE,6CAA6C,CAAC,CAAA;QACjE,IAAI,MAAM,KAAK,KAAK;YAClB,GAAG;iBACA,QAAQ,CAAC,SAAS,EAAE,iEAAiE,CAAC;iBACtF,WAAW,CAAC,0CAA0C,CAAC,CAAA;;YACvD,GAAG,CAAC,WAAW,CAAC,8CAA8C,CAAC,CAAA;QAEpE,GAAG,CAAC,MAAM,CAAC,UAAyB,OAAe,EAAE,KAAc;YACjE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,eAAe,CAAC,CAAA;YAC7E,MAAM,EACJ,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EACR,GAAG,GACJ,GAAG,IAAI,CAAC,IAAI,EAA6D,CAAA;YAC1E,MAAM,QAAQ,GAAG,QAAQ,KAAK,IAAI,CAAA;YAClC,IAAI,QAAQ,IAAI,GAAG;gBACjB,MAAM,IAAI,QAAQ,CAAC,kBAAkB,EAAE,uDAAuD,CAAC,CAAA;YACjG,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAA;YAC5D,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE,cAAc,CAAC,CAAA;YACzC,IAAI,QAAQ,IAAI,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC1B,uDAAuD;gBACvD,MAAM,IAAI,QAAQ,CAChB,kBAAkB,EAClB,qCAAqC,QAAQ,CAAC,OAAO,KAAK,IAAI,sCAAsC,CACrG,CAAA;YACH,CAAC;YACD,IACE,CAAC,UAAU,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC;gBACnD,mBAAmB,CAAC,cAAc,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,EACjG,CAAC;gBACD,MAAM,IAAI,QAAQ,CAChB,kBAAkB,EAClB,GAAG,OAAO,mGAAmG,CAC9G,CAAA;YACH,CAAC;YACD,MAAM,KAAK,GAAG,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,UAAU,EAAE;gBACtD,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO;gBAChD,OAAO;gBACP,KAAK,EAAE,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS;gBACnD,IAAI;aACL,CAAC,CAAA;YACF,QAAQ,CAAC,MAAM,CAAC;gBACd,UAAU,EAAE,QAAQ,CAAC,UAAU;gBAC/B,KAAK,EAAE,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAC7D,OAAO;gBACP,KAAK,EAAE,KAAK;aACb,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA;AAED,MAAM,OAAO,GAAG,CAAC,IAAwB,EAAE,OAA2B,EAAU,EAAE,CAChF,CAAC,IAAI,EAAE,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAE9F,gGAAgG;AAChG,MAAM,OAAO,GAAG,CAAC,QAAkB,EAAE,OAAe,EAAE,EAAE;IACtD,4FAA4F;IAC5F,IAAI,OAAO,KAAK,aAAa,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAA;QACrF,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,iBAAiB,EAAE,CAAA;IAC5F,CAAC;IACD,IAAI,OAAO,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;QAChC,MAAM,KAAK,GAAI,QAA+C,CAAC,OAAO,CAAC,CAAA;QACvE,0DAA0D;QAC1D,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAA;IACtH,CAAC;IACD,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,QAAQ,CAAU,QAAQ,EAAE,OAAO,EAAE,iBAAiB,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,CAAA;IAChG,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAA;AACjC,CAAC,CAAA;AAED,6GAA6G;AAC7G,MAAM,iBAAiB,GAA4B,EAAE,cAAc,EAAE,MAAM,EAAE,CAAA;AAE7E,4FAA4F;AAC5F,MAAM,oBAAoB,GAAG,CAAC,GAAgB,EAAE,GAAsB,EAAY,EAAE;IAClF,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC,KAAK,EAAE,UAAU,CAAC,CAAA;IACtG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,CAAA;IAC/B,OAAO,WAAW,CAAC,GAAG,CAAC;SACpB,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;SACxC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAA;AAClD,CAAC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"archive-commands.d.ts","sourceRoot":"","sources":["../../../src/cli/messenger/archive-commands.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAMnC,OAAO,EAAE,KAAK,SAAS,EAAoB,MAAM,cAAc,CAAA;AAG/D,oHAAoH;AACpH,eAAO,MAAM,YAAY,cAAe,SAAS,KAAG,OAUnD,CAAA"}
1
+ {"version":3,"file":"archive-commands.d.ts","sourceRoot":"","sources":["../../../src/cli/messenger/archive-commands.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAUnC,OAAO,EAAE,KAAK,SAAS,EAAoB,MAAM,cAAc,CAAA;AAK/D,oHAAoH;AACpH,eAAO,MAAM,YAAY,cAAe,SAAS,KAAG,OAUnD,CAAA"}
@@ -1,13 +1,19 @@
1
1
  import { writeFileSync } from "node:fs";
2
2
  import { resolve } from "node:path";
3
+ import { Readable } from "node:stream";
3
4
  import { CliError } from "@leemour/cli-core";
4
5
  import { Command } from "commander";
5
6
  import { toMarkdown } from "../../render/markdown.js";
6
7
  import { renderMessages } from "../../render/messages.js";
8
+ import { seal } from "../../sealed.js";
9
+ import { CHAT_KINDS } from "../../services/chats.js";
10
+ import { kindsOf } from "../../services/inbox.js";
7
11
  import { momentOf } from "../../services/moment.js";
8
12
  import { renderList } from "../paging.js";
9
13
  import { fetchCommand, jobsCommand } from "./backfill-command.js";
10
14
  import { messengerContext } from "./context.js";
15
+ import { admitPassword, linesOf, openFolder, runFileFor, saveManifest, sealRun, writeChanges } from "./export-folder.js";
16
+ import { ENCRYPT_OPTION, passwordOf } from "./password.js";
11
17
  import { storeMaintenanceCommands } from "./store-maintenance-command.js";
12
18
  /** `store`: the local store of messages — what it holds, filling it, reading it out, and looking after the file. */
13
19
  export const storeCommand = (messenger) => {
@@ -65,21 +71,91 @@ const clearCommand = (messenger) => new Command("clear")
65
71
  });
66
72
  /**
67
73
  * One chat's stored messages, oldest first — `--jsonl` for a file or a pipe, one message per line,
68
- * `--format markdown` for a transcript a person reads.
74
+ * `--format markdown` for a transcript a person reads. With `--to`, any number of chats into a
75
+ * folder, and each later run into the same folder adds only what changed.
69
76
  */
70
77
  const exportCommand = (messenger) => new Command("export")
71
78
  .description("a chat's stored messages as JSON lines, oldest first; never asks the messenger")
72
- .argument("<chat>", messenger.chatArgument)
79
+ .argument("[chats...]", `${messenger.chatArgument}; several with --to`)
73
80
  .option("--format <format>", "jsonl (the default): one message per line; markdown: a transcript with a heading per day, replies and forwards quoted")
74
81
  .option("--since-time <time>", "only from this ISO 8601 time, or 30m / 2h / 1d ago, on")
75
82
  .option("--output <file>", "write JSON lines, or the transcript, to this new file, readable only by you")
76
- .action(async function (chat) {
77
- const { format, sinceTime: since, output } = this.opts();
83
+ .option("--to <dir>", "write into this folder, a file per chat and a manifest; run again on it for only what changed since")
84
+ .option("--kind <kinds>", `with --to: every stored chat of these kinds, comma-separated: ${CHAT_KINDS.join(", ")}`)
85
+ .option("--all", "with --to: every stored chat of this account")
86
+ .option(...ENCRYPT_OPTION)
87
+ .action(async function (chats) {
88
+ const { format, sinceTime: since, output, to, kind, all, encrypt, } = this.opts();
78
89
  if (format !== undefined && format !== "markdown" && format !== "jsonl") {
79
90
  throw new CliError("validation_error", `--format is jsonl or markdown, not "${format}"`);
80
91
  }
81
- const from = since === undefined ? undefined : new Date(momentOf(since, "--since-time")).toISOString();
82
92
  const context = messengerContext(this, messenger);
93
+ if (to !== undefined) {
94
+ if (format === "markdown" || since !== undefined || output !== undefined) {
95
+ throw new CliError("validation_error", "--to writes JSON lines and keeps its own point — not with --format markdown, --since-time or --output");
96
+ }
97
+ if (chats.length === 0 && kind === undefined && all !== true) {
98
+ throw new CliError("validation_error", "--to needs chats, --kind or --all");
99
+ }
100
+ const kinds = kind === undefined ? undefined : kindsOf(kind);
101
+ const dir = resolve(to);
102
+ const password = encrypt ? await passwordOf(this, { twice: true }) : undefined;
103
+ context.renderer.result(await context.withServices(async (services) => {
104
+ const { account, chats: chosen } = await services.archive.exportable({
105
+ chats,
106
+ ...(kinds === undefined ? {} : { kinds }),
107
+ });
108
+ const manifest = openFolder(dir, account, password !== undefined);
109
+ if (password !== undefined)
110
+ await admitPassword(manifest, password);
111
+ const run = runFileFor(new Date().toISOString());
112
+ const written = [];
113
+ const exportChat = async function* ({ id, title: named }) {
114
+ const title = password === undefined ? named : null;
115
+ const before = manifest.chats[id];
116
+ const changes = await services.archive.changes(id, before?.mark);
117
+ const empty = changes.messages.length === 0 && changes.deleted.length === 0;
118
+ let file = null;
119
+ if (password !== undefined) {
120
+ yield* linesOf(id, changes);
121
+ if (!empty)
122
+ file = run;
123
+ }
124
+ else if (before === undefined || !empty)
125
+ file = writeChanges(dir, id, changes.mark, changes);
126
+ manifest.chats[id] = {
127
+ title,
128
+ mark: changes.mark,
129
+ files: [...(before?.files ?? []), ...(file === null ? [] : [file])],
130
+ messages: (before?.messages ?? 0) + changes.messages.length,
131
+ deleted: (before?.deleted ?? 0) + changes.deleted.length,
132
+ };
133
+ written.push({ id, title, file, messages: changes.messages.length, deleted: changes.deleted.length });
134
+ };
135
+ const everyChat = async function* () {
136
+ for (const chat of chosen)
137
+ yield* exportChat(chat);
138
+ };
139
+ if (password !== undefined)
140
+ await sealRun(dir, run, everyChat(), password);
141
+ // Unsealed, each chat is written as it is read; nothing is yielded, the walk is the work.
142
+ else
143
+ for await (const _ of everyChat())
144
+ void _;
145
+ saveManifest(dir, manifest);
146
+ return { path: dir, ...(password === undefined ? {} : { encrypted: true }), chats: written };
147
+ }));
148
+ return;
149
+ }
150
+ if (chats.length !== 1 || kind !== undefined || all === true) {
151
+ throw new CliError("validation_error", "one chat at a time without --to; --kind and --all need --to");
152
+ }
153
+ if (encrypt && output === undefined) {
154
+ throw new CliError("validation_error", "--encrypt writes a file — with --output or --to");
155
+ }
156
+ const password = encrypt ? await passwordOf(this, { twice: true }) : undefined;
157
+ const chat = chats[0];
158
+ const from = since === undefined ? undefined : new Date(momentOf(since, "--since-time")).toISOString();
83
159
  const { title, messages } = await context.withServices((services) => services.archive.export(chat, from === undefined ? {} : { since: from }));
84
160
  if (output !== undefined) {
85
161
  const path = resolve(output);
@@ -87,14 +163,22 @@ const exportCommand = (messenger) => new Command("export")
87
163
  ? toMarkdown(title, messages)
88
164
  : messages.map((message) => `${JSON.stringify(message)}\n`).join("");
89
165
  try {
90
- writeFileSync(path, body, { flag: "wx", mode: 0o600 });
166
+ if (password !== undefined)
167
+ await seal(() => Readable.from([body]), path, password);
168
+ else
169
+ writeFileSync(path, body, { flag: "wx", mode: 0o600 });
91
170
  }
92
171
  catch (error) {
93
172
  if (error.code === "EEXIST")
94
173
  throw new CliError("validation_error", `${path} exists — an export never overwrites a file`);
95
174
  throw error;
96
175
  }
97
- context.renderer.result({ path, format: format ?? "jsonl", count: messages.length });
176
+ context.renderer.result({
177
+ path,
178
+ format: format ?? "jsonl",
179
+ count: messages.length,
180
+ ...(password === undefined ? {} : { encrypted: true }),
181
+ });
98
182
  return;
99
183
  }
100
184
  if (format === "markdown")
@@ -1 +1 @@
1
- {"version":3,"file":"archive-commands.js","sourceRoot":"","sources":["../../../src/cli/messenger/archive-commands.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"archive-commands.js","sourceRoot":"","sources":["../../../src/cli/messenger/archive-commands.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { Id, Message } from "../../domain/models.js";
2
+ import type { MarkedRead } from "../../services/chats.js";
3
+ import type { Services } from "../../services/index.js";
4
+ import type { Settings } from "../settings.js";
5
+ export declare const MARK_READ_OPTION: readonly ["--mark-read", "also mark each chat shown read, up to the newest message shown; the other side sees it"];
6
+ export declare const NO_MARK_READ_OPTION: readonly ["--no-mark-read", "do not, whatever the catchUpMarksRead setting says"];
7
+ /** The typed flag decides; without one, the owner's `catchUpMarksRead` setting, off unless turned on (NEED-566). */
8
+ export declare const marksRead: (typed: boolean | undefined, settings: Settings) => boolean;
9
+ /**
10
+ * Marks each chat read up to the newest message shown in it — never further, so what arrived after
11
+ * the read stays unread. Through the send guard, so `permissions.chats.mark-read` applies.
12
+ */
13
+ export declare const markShown: (services: Services, chats: {
14
+ id: Id;
15
+ messages: Pick<Message, "id" | "timestamp">[];
16
+ }[]) => Promise<MarkedRead[]>;
17
+ //# sourceMappingURL=catch-up.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catch-up.d.ts","sourceRoot":"","sources":["../../../src/cli/messenger/catch-up.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAA;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AACvD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAE9C,eAAO,MAAM,gBAAgB,YAC3B,aAAa,EACb,wFAAwF,CAChF,CAAA;AACV,eAAO,MAAM,mBAAmB,YAAI,gBAAgB,EAAE,oDAAoD,CAAU,CAAA;AAEpH,oHAAoH;AACpH,eAAO,MAAM,SAAS,UAAW,OAAO,GAAG,SAAS,YAAY,QAAQ,KAAG,OAM1E,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,SAAS,aACV,QAAQ,SACX;IAAE,EAAE,EAAE,EAAE,CAAC;IAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,GAAG,WAAW,CAAC,EAAE,CAAA;CAAE,EAAE,KACjE,OAAO,CAAC,UAAU,EAAE,CAYtB,CAAA"}
@@ -0,0 +1,30 @@
1
+ import { CliError } from "@leemour/cli-core";
2
+ export const MARK_READ_OPTION = [
3
+ "--mark-read",
4
+ "also mark each chat shown read, up to the newest message shown; the other side sees it",
5
+ ];
6
+ export const NO_MARK_READ_OPTION = ["--no-mark-read", "do not, whatever the catchUpMarksRead setting says"];
7
+ /** The typed flag decides; without one, the owner's `catchUpMarksRead` setting, off unless turned on (NEED-566). */
8
+ export const marksRead = (typed, settings) => {
9
+ const marking = typed ?? settings.catchUpMarksRead;
10
+ if (marking && settings.offline) {
11
+ throw new CliError("validation_error", "--mark-read tells the messenger; not with --offline");
12
+ }
13
+ return marking;
14
+ };
15
+ /**
16
+ * Marks each chat read up to the newest message shown in it — never further, so what arrived after
17
+ * the read stays unread. Through the send guard, so `permissions.chats.mark-read` applies.
18
+ */
19
+ export const markShown = async (services, chats) => {
20
+ const marked = [];
21
+ for (const { id, messages } of chats) {
22
+ const newest = messages.reduce((last, one) => (last === undefined || Date.parse(one.timestamp) >= Date.parse(last.timestamp) ? one : last), undefined);
23
+ if (newest === undefined)
24
+ continue;
25
+ const { chatId, until } = await services.chats.markRead({ chat: id, until: newest.id });
26
+ marked.push({ chatId, until });
27
+ }
28
+ return marked;
29
+ };
30
+ //# sourceMappingURL=catch-up.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catch-up.js","sourceRoot":"","sources":["../../../src/cli/messenger/catch-up.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAM5C,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,aAAa;IACb,wFAAwF;CAChF,CAAA;AACV,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,gBAAgB,EAAE,oDAAoD,CAAU,CAAA;AAEpH,oHAAoH;AACpH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,KAA0B,EAAE,QAAkB,EAAW,EAAE;IACnF,MAAM,OAAO,GAAG,KAAK,IAAI,QAAQ,CAAC,gBAAgB,CAAA;IAClD,IAAI,OAAO,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;QAChC,MAAM,IAAI,QAAQ,CAAC,kBAAkB,EAAE,qDAAqD,CAAC,CAAA;IAC/F,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,EAC5B,QAAkB,EAClB,KAAkE,EAC3C,EAAE;IACzB,MAAM,MAAM,GAAiB,EAAE,CAAA;IAC/B,KAAK,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,KAAK,EAAE,CAAC;QACrC,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAC5B,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAC3G,SAAS,CACV,CAAA;QACD,IAAI,MAAM,KAAK,SAAS;YAAE,SAAQ;QAClC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAA;QACvF,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAA;IAChC,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"conversations-command.d.ts","sourceRoot":"","sources":["../../../src/cli/messenger/conversations-command.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAYnC,OAAO,EAAE,KAAK,SAAS,EAA2C,MAAM,cAAc,CAAA;AAGtF;;;GAGG;AACH,eAAO,MAAM,oBAAoB,cAAe,SAAS,KAAG,OA0T3D,CAAA;AAqID,8EAA8E;AAC9E,eAAO,MAAM,YAAY,cAAe,SAAS,KAAG,OAwB9C,CAAA"}
1
+ {"version":3,"file":"conversations-command.d.ts","sourceRoot":"","sources":["../../../src/cli/messenger/conversations-command.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAoBnC,OAAO,EAAE,KAAK,SAAS,EAA2C,MAAM,cAAc,CAAA;AAGtF;;;GAGG;AACH,eAAO,MAAM,oBAAoB,cAAe,SAAS,KAAG,OAqb3D,CAAA;AA0MD,8EAA8E;AAC9E,eAAO,MAAM,YAAY,cAAe,SAAS,KAAG,OAwB9C,CAAA"}
@@ -5,9 +5,10 @@ import { isLocal, remoteModel } from "../../embeddings/remote.js";
5
5
  import { renderMessages } from "../../render/messages.js";
6
6
  import { levelFor } from "../../sends/permissions.js";
7
7
  import { BATCH_SIZE } from "../../services/conversations.js";
8
+ import { REFRESH_BOUNDS, } from "../../services/embeddings.js";
8
9
  import { momentOf } from "../../services/moment.js";
9
10
  import { embeddingKeys } from "../embedding-keys.js";
10
- import { positiveCount } from "../paging.js";
11
+ import { positiveCount, renderList } from "../paging.js";
11
12
  import { answerOf as askOwner } from "./ask.js";
12
13
  import { messengerContext } from "./context.js";
13
14
  import { readAll } from "./stdin.js";
@@ -17,13 +18,22 @@ import { readAll } from "./stdin.js";
17
18
  */
18
19
  export const conversationsCommand = (messenger) => {
19
20
  const conversations = new Command("conversations").description("the conversations inside a chat, found in the stored messages by replies, mentions and who wrote next");
20
- conversations
21
+ boundOptions(conversations
21
22
  .command("build")
22
- .description("find a chat's conversations in what the store holds, replacing the last build; never asks the messenger")
23
- .requiredOption("--chat <chat>", messenger.chatArgument)
24
- .action(async function () {
25
- const { chat } = this.opts();
23
+ .description("find a chat's conversations in what the store holds, replacing the last build; without --chat, every " +
24
+ "chat that changed since its build and every group never built; never asks the messenger")
25
+ .option("--chat <chat>", messenger.chatArgument), { chunks: false }).action(async function () {
26
+ const { chat, maxChats } = this.opts();
26
27
  const context = messengerContext(this, messenger);
28
+ if (chat === undefined) {
29
+ const refreshed = await context.withServices((services) => services.embeddings.refresh({
30
+ embed: false,
31
+ ...(maxChats ? { maxChats } : {}),
32
+ progress: (note) => context.renderer.note(note),
33
+ }));
34
+ renderRefreshed(context, refreshed, messenger.app.command);
35
+ return;
36
+ }
27
37
  const built = await context.withServices((services) => services.conversations.build(chat));
28
38
  if (context.format === "pretty") {
29
39
  context.streams.data(`${built.messages} messages → ${built.conversations} conversations, ${built.links} links (rules v${built.rulesVersion})\n`);
@@ -81,44 +91,124 @@ export const conversationsCommand = (messenger) => {
81
91
  else
82
92
  context.renderer.result({ ...summary, messages });
83
93
  });
84
- withModelOptions(conversations.command("search"))
94
+ withModelOptions(conversations
95
+ .command("related")
96
+ .description("the conversations nearest in meaning to the one a message is in, in every built chat, best first — " +
97
+ "from the vectors `conversations embed` stored; runs no model")
98
+ .argument("<chat>", messenger.chatArgument)
99
+ .argument("<message>", "a message id in that chat")
100
+ .option("--limit <n>", "how many", positiveCount("--limit"))).action(async function (chat, message) {
101
+ const options = this.opts();
102
+ const context = messengerContext(this, messenger);
103
+ const model = choiceOf(options, messenger, context, { needKey: false });
104
+ const { limit } = context.settings;
105
+ const found = await context.withServices((services) => services.embeddings.related(chat, message, { model, limit }));
106
+ if (context.format === "pretty") {
107
+ context.streams.data(`like ${line(found.source)}\n\n${found.hits.map((hit) => `${hitLine(hit)}\n`).join("")}`);
108
+ if (found.hits.length === 0)
109
+ context.renderer.note(`no other conversation has vectors of ${found.model}`);
110
+ }
111
+ else if (context.format === "jsonl")
112
+ context.renderer.stream(found.hits);
113
+ else {
114
+ const { model: id, source, hits, readiness } = found;
115
+ context.renderer.result({ model: id, source, items: hits, limit, readiness });
116
+ }
117
+ const command = messenger.app.command;
118
+ const unseen = found.readiness.wordsOnly;
119
+ if (unseen.length > 0) {
120
+ context.renderer.note(`not searched, no vector of ${found.model}: chat ${unseen.join(", ")} — \`${command} conversations embed --chat <chat>\``);
121
+ }
122
+ // `unavailable` keeps out the note about word matches: related searches no words.
123
+ for (const note of readinessNotes({ ...found, meaning: "unavailable", embeddedOnlyElsewhere: [] }, command)) {
124
+ context.renderer.note(note);
125
+ }
126
+ });
127
+ withModelOptions(conversations
128
+ .command("status")
129
+ .description("how fresh each built chat's conversations and vectors are: messages the build has not seen, chunks " +
130
+ "with a current, stale or missing vector")
131
+ .option("--chat <chat>", `only this chat: ${messenger.chatArgument}`)).action(async function () {
132
+ const options = this.opts();
133
+ const context = messengerContext(this, messenger);
134
+ const model = choiceOf(options, messenger, context, { needKey: false });
135
+ const { model: id, chats } = await context.withServices((services) => services.embeddings.readiness({ ...(options.chat === undefined ? {} : { chat: options.chat }), model }));
136
+ if (context.format !== "pretty") {
137
+ renderList(context.renderer, context.format, chats, { model: id });
138
+ return;
139
+ }
140
+ context.streams.data(chats.map((one) => `${readinessLine(one, id)}\n`).join(""));
141
+ if (chats.length === 0)
142
+ context.renderer.note("no chat has conversations yet — `conversations build --chat <chat>`");
143
+ });
144
+ boundOptions(withModelOptions(conversations.command("search")))
85
145
  .description("the conversations nearest to a query in meaning and in words, best first, in one chat or every one — " +
86
146
  "meaning after `conversations embed`; runs on this machine")
87
147
  .argument("<query>", "what to look for, in your own words, in any language the model reads")
88
148
  .option("--chat <chat>", `only this chat: ${messenger.chatArgument}`)
89
149
  .option("--since-time <time>", "only those still going at this ISO 8601 time, or 30m / 2h / 1d ago, or later")
90
150
  .option("--limit <n>", "how many", positiveCount("--limit"))
151
+ .option("--refresh", "first build and embed, on this machine, the chats in scope that changed or were never built — within " +
152
+ "--max-chats and --max-chunks")
91
153
  .action(async function (query) {
92
154
  const options = this.opts();
93
155
  const { chat, sinceTime: since } = options;
94
156
  const context = messengerContext(this, messenger);
95
157
  const model = choiceOf(options, messenger, context);
158
+ if (options.refresh) {
159
+ localOnly(model, "--refresh");
160
+ writable(context, messenger.app.command, EMBED_KEY);
161
+ }
96
162
  const { limit } = context.settings;
97
- const found = await context.withServices((services) => services.embeddings.search(query, {
98
- limit,
99
- ...(chat === undefined ? {} : { chat }),
100
- model,
101
- ...(since === undefined ? {} : { since: new Date(momentOf(since, "--since-time")).toISOString() }),
102
- }));
163
+ const { found, refreshed } = await context.withServices(async (services) => {
164
+ const refreshed = options.refresh
165
+ ? await services.embeddings.refresh({
166
+ ...(chat === undefined ? {} : { chat }),
167
+ model: model,
168
+ ...bounds(options),
169
+ progress: (note) => context.renderer.note(note),
170
+ })
171
+ : undefined;
172
+ const found = await services.embeddings.search(query, {
173
+ limit,
174
+ ...(chat === undefined ? {} : { chat }),
175
+ model,
176
+ ...(since === undefined ? {} : { since: new Date(momentOf(since, "--since-time")).toISOString() }),
177
+ });
178
+ return { found, refreshed };
179
+ });
180
+ if (refreshed)
181
+ for (const note of leftNotes(refreshed, messenger.app.command))
182
+ context.renderer.note(note);
103
183
  if (context.format === "pretty") {
104
- context.streams.data(found.hits
105
- .map(({ summary, chunk, score }) => `${score === null ? " — " : score.toFixed(3)} ${line(summary)} (messages ${chunk.firstMessageId}–${chunk.lastMessageId})\n`)
106
- .join(""));
184
+ context.streams.data(found.hits.map((hit) => `${hitLine(hit)}\n`).join(""));
107
185
  if (found.hits.length === 0) {
108
- context.renderer.note(`nothing matches in words, nor in meaning among the chats embedded with ${found.model} — ` +
109
- "`conversations embed --chat <chat>` for meaning");
186
+ context.renderer.note(found.meaning === "unavailable"
187
+ ? "nothing matches in words"
188
+ : `nothing matches in words, nor in meaning among the chats embedded with ${found.model} — ` +
189
+ "`conversations embed --chat <chat>` for meaning");
110
190
  }
111
191
  }
112
192
  else if (context.format === "jsonl")
113
193
  context.renderer.stream(found.hits);
114
194
  else {
115
- const { model, hits, embeddedOnlyElsewhere } = found;
116
- context.renderer.result({ model, items: hits, limit, embeddedOnlyElsewhere });
195
+ const { model, meaning, hits, readiness, embeddedOnlyElsewhere } = found;
196
+ context.renderer.result({
197
+ model,
198
+ meaning,
199
+ items: hits,
200
+ limit,
201
+ readiness,
202
+ embeddedOnlyElsewhere,
203
+ ...(refreshed ? { refreshed } : {}),
204
+ });
117
205
  }
118
- if (found.embeddedOnlyElsewhere.length > 0) {
119
- context.renderer.note(`not searched by meaning, embedded only with another model: chat ${found.embeddedOnlyElsewhere.join(", ")} — ` +
120
- "give that model with --model, or `conversations embed` them with this one");
206
+ const command = messenger.app.command;
207
+ if (found.meaning === "unavailable") {
208
+ context.renderer.note(`searched by words only: ${found.model} is not downloaded — \`${command} models text download ${found.model}\``);
121
209
  }
210
+ for (const note of readinessNotes(found, command))
211
+ context.renderer.note(note);
122
212
  });
123
213
  const batches = conversations
124
214
  .command("batches")
@@ -199,18 +289,33 @@ export const conversationsCommand = (messenger) => {
199
289
  });
200
290
  const embed = withModelOptions(new Command("embed")
201
291
  .description("compute a vector for each chunk of a chat's conversations for search by meaning — on this machine, or " +
202
- "with --provider through a service and your key; resumes where it stopped")
292
+ "with --provider through a service and your key; resumes where it stopped; without --chat, every " +
293
+ "built chat with chunks left, on this machine only")
203
294
  .option("--chat <chat>", messenger.chatArgument))
204
295
  .option("--workers <n>", "local: sessions in parallel, each with its own copy of the model (~0.7 GB each)", positiveCount("--workers"))
205
296
  .option("--threads <n>", "local: threads in all (default: min(8, cores))", positiveCount("--threads"))
206
297
  .option("--concurrency <n>", "remote: requests at once (default: 4)", positiveCount("--concurrency"))
207
- .option("--max-tokens <n>", "remote: stop before a run that could send more tokens than this", positiveCount("--max-tokens"))
208
- .action(async function () {
298
+ .option("--max-tokens <n>", "remote: stop before a run that could send more tokens than this", positiveCount("--max-tokens"));
299
+ boundOptions(embed);
300
+ embed.action(async function () {
209
301
  const options = this.optsWithGlobals();
210
- const chat = chatOf(options);
211
302
  const context = messengerContext(this, messenger);
212
303
  writable(context, messenger.app.command, EMBED_KEY);
213
304
  const model = choiceOf(options, messenger, context);
305
+ if (options.chat === undefined) {
306
+ localOnly(model, "embedding without --chat");
307
+ const refreshed = await context.withServices((services) => services.embeddings.refresh({
308
+ build: false,
309
+ model: model,
310
+ ...bounds(options),
311
+ ...(options.workers ? { workers: options.workers } : {}),
312
+ ...(options.threads ? { threads: options.threads } : {}),
313
+ progress: (note) => context.renderer.note(note),
314
+ }));
315
+ renderRefreshed(context, refreshed, messenger.app.command);
316
+ return;
317
+ }
318
+ const chat = options.chat;
214
319
  const done = await context.withServices(async (services) => {
215
320
  const status = await services.embeddings.status(chat, model);
216
321
  context.renderer.note(`${status.left} of ${status.chunks} chunks to embed with ${status.model}` +
@@ -222,6 +327,7 @@ export const conversationsCommand = (messenger) => {
222
327
  model,
223
328
  ...(options.workers ? { workers: options.workers } : {}),
224
329
  ...(options.threads ? { threads: options.threads } : {}),
330
+ ...(options.maxChunks ? { maxChunks: options.maxChunks } : {}),
225
331
  progress: (embedded, left) => context.renderer.note(`${embedded} embedded, ${left} left`),
226
332
  });
227
333
  });
@@ -295,6 +401,53 @@ const withModelOptions = (command) => command
295
401
  .option("--provider <provider>", "embed through a service with your key instead of on this machine: openai")
296
402
  .option("--base-url <url>", "a server with OpenAI's /v1/embeddings: Gemini, Jina, or Ollama and LM Studio on this machine")
297
403
  .option("--dims <n>", "remote: the vector size — needed with --base-url; shortens an OpenAI model's", positiveCount("--dims"));
404
+ /** How much one run over many chats may do: the owner's machine, not a background job, pays for it. */
405
+ const boundOptions = (command, { chunks = true } = {}) => {
406
+ command.option("--max-chats <n>", `at most this many chats in one run; ${REFRESH_BOUNDS.maxChats} if not given`, positiveCount("--max-chats"));
407
+ if (chunks) {
408
+ command.option("--max-chunks <n>", `at most this many chunks embedded in one run; ${REFRESH_BOUNDS.maxChunks} if not given`, positiveCount("--max-chunks"));
409
+ }
410
+ return command;
411
+ };
412
+ const bounds = ({ maxChats, maxChunks }) => ({
413
+ ...(maxChats ? { maxChats } : {}),
414
+ ...(maxChunks ? { maxChunks } : {}),
415
+ });
416
+ /** Work nobody named chat by chat never sends chat text off the machine. */
417
+ const localOnly = (model, what) => {
418
+ if (typeof model !== "string") {
419
+ throw new CliError("validation_error", `${what} uses the model on this machine only — drop --provider and --base-url, or embed one chat with --chat`);
420
+ }
421
+ };
422
+ const renderRefreshed = (context, refreshed, command) => {
423
+ if (context.format === "pretty") {
424
+ context.streams.data([
425
+ ...refreshed.built.map((one) => `${one.chat} built: ${one.messages} messages → ${one.conversations} conversations\n`),
426
+ ...refreshed.embedded.map((one) => `${one.chat} ${one.embedded} chunks embedded with ${one.model}\n`),
427
+ ].join(""));
428
+ if (refreshed.built.length + refreshed.embedded.length === 0 && refreshed.left.length === 0) {
429
+ context.renderer.note("every chat is up to date");
430
+ }
431
+ }
432
+ else
433
+ context.renderer.result(refreshed);
434
+ for (const note of leftNotes(refreshed, command))
435
+ context.renderer.note(note);
436
+ };
437
+ const leftNotes = ({ model, modelAvailable, embedded, left }, command) => {
438
+ const of = (needs) => left.filter((one) => one.needs === needs).map(({ chat }) => chat);
439
+ const build = of("build");
440
+ const embed = of("embed");
441
+ return [
442
+ build.length > 0 ? `still to build: chat ${build.join(", ")} — run it again, or raise --max-chats` : "",
443
+ embed.length > 0 && modelAvailable
444
+ ? `still to embed: chat ${embed.join(", ")} — run it again, or raise --max-chats and --max-chunks`
445
+ : "",
446
+ embed.length > 0 && !modelAvailable && embedded.length === 0
447
+ ? `nothing embedded: ${model} is not downloaded — \`${command} models text download ${model}\``
448
+ : "",
449
+ ].filter(Boolean);
450
+ };
298
451
  /** A local model id, or a remote model with its key from `models text key set`. */
299
452
  const choiceOf = ({ model, provider, baseUrl, dims, concurrency }, messenger, context, { needKey = true } = {}) => {
300
453
  if (provider === undefined && baseUrl === undefined)
@@ -376,4 +529,37 @@ export const linksCommand = (messenger) => new Command("links")
376
529
  });
377
530
  const line = (one) => `${one.id} ${one.firstAt.slice(0, 16).replace("T", " ")}–${one.lastAt.slice(11, 16)} ` +
378
531
  `${one.messageCount} messages · ${one.senders} people · from message ${one.firstMessageId}`;
532
+ const hitLine = ({ summary, chunk, score, stale }) => `${score === null ? " — " : score.toFixed(3)} ${line(summary)} ` +
533
+ `(messages ${chunk.firstMessageId}–${chunk.lastMessageId})${stale ? " stale" : ""}`;
534
+ const readinessLine = ({ chat, state, graph, pending, vectors }, model) => graph === null
535
+ ? `${chat} ${state} — \`conversations build --chat ${chat}\``
536
+ : `${chat} ${state} built ${graph.builtAt.slice(0, 16).replace("T", " ")}, rules v${graph.rulesVersion}` +
537
+ `${graph.outdatedRules ? " (outdated)" : ""} · not in the build: ${pending.new} new, ${pending.edited} edited, ` +
538
+ `${pending.deleted} deleted · ${model}: ${vectors.current} current, ${vectors.stale} stale, ` +
539
+ `${vectors.missing} missing of ${vectors.chunks} chunks`;
540
+ /** What the search could not see, and the command that fixes each. */
541
+ const readinessNotes = ({ meaning, model, readiness, embeddedOnlyElsewhere, }, command) => {
542
+ const chats = (ids) => `chat ${ids.join(", ")}`;
543
+ const elsewhere = new Set(embeddedOnlyElsewhere);
544
+ const neverEmbedded = readiness.wordsOnly.filter((id) => !elsewhere.has(id));
545
+ return [
546
+ embeddedOnlyElsewhere.length > 0
547
+ ? `not searched by meaning, embedded only with another model: ${chats(embeddedOnlyElsewhere)} — ` +
548
+ "give that model with --model, or `conversations embed` them with this one"
549
+ : "",
550
+ meaning === "searched" && neverEmbedded.length > 0
551
+ ? `searched by words only, no vector of ${model}: ${chats(neverEmbedded)} — \`${command} conversations embed --chat <chat>\``
552
+ : "",
553
+ readiness.partial.length > 0
554
+ ? `some chunks have no vector yet: ${chats(readiness.partial)} — \`${command} conversations embed --chat <chat>\``
555
+ : "",
556
+ readiness.stale.length > 0
557
+ ? `changed since the last build: ${chats(readiness.stale)} — \`${command} conversations build --chat <chat>\``
558
+ : "",
559
+ readiness.notBuilt.length > 0
560
+ ? `never built, so their matches are not shown: ${chats(readiness.notBuilt)} — ` +
561
+ `\`${command} conversations build --chat <chat>\``
562
+ : "",
563
+ ].filter(Boolean);
564
+ };
379
565
  //# sourceMappingURL=conversations-command.js.map