@wirecat/cli-memo 0.0.0 → 0.5.1

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 (191) hide show
  1. package/LICENSE +204 -0
  2. package/README.md +315 -0
  3. package/dist/answers/command.d.ts +35 -0
  4. package/dist/answers/command.d.ts.map +1 -0
  5. package/dist/answers/command.js +117 -0
  6. package/dist/answers/command.js.map +1 -0
  7. package/dist/app.d.ts +9 -0
  8. package/dist/app.d.ts.map +1 -0
  9. package/dist/app.js +10 -0
  10. package/dist/app.js.map +1 -0
  11. package/dist/bin/memo.d.ts +3 -0
  12. package/dist/bin/memo.d.ts.map +1 -0
  13. package/dist/bin/memo.js +14 -0
  14. package/dist/bin/memo.js.map +1 -0
  15. package/dist/config.d.ts +39 -0
  16. package/dist/config.d.ts.map +1 -0
  17. package/dist/config.js +40 -0
  18. package/dist/config.js.map +1 -0
  19. package/dist/context/command.d.ts +6 -0
  20. package/dist/context/command.d.ts.map +1 -0
  21. package/dist/context/command.js +73 -0
  22. package/dist/context/command.js.map +1 -0
  23. package/dist/context/context.d.ts +28 -0
  24. package/dist/context/context.d.ts.map +1 -0
  25. package/dist/context/context.js +49 -0
  26. package/dist/context/context.js.map +1 -0
  27. package/dist/knowledge/command.d.ts +4 -0
  28. package/dist/knowledge/command.d.ts.map +1 -0
  29. package/dist/knowledge/command.js +158 -0
  30. package/dist/knowledge/command.js.map +1 -0
  31. package/dist/mail/command.d.ts +4 -0
  32. package/dist/mail/command.d.ts.map +1 -0
  33. package/dist/mail/command.js +61 -0
  34. package/dist/mail/command.js.map +1 -0
  35. package/dist/mail/gmail.d.ts +18 -0
  36. package/dist/mail/gmail.d.ts.map +1 -0
  37. package/dist/mail/gmail.js +103 -0
  38. package/dist/mail/gmail.js.map +1 -0
  39. package/dist/mail/himalaya.d.ts +4 -0
  40. package/dist/mail/himalaya.d.ts.map +1 -0
  41. package/dist/mail/himalaya.js +13 -0
  42. package/dist/mail/himalaya.js.map +1 -0
  43. package/dist/mail/import.d.ts +53 -0
  44. package/dist/mail/import.d.ts.map +1 -0
  45. package/dist/mail/import.js +170 -0
  46. package/dist/mail/import.js.map +1 -0
  47. package/dist/mail/parse.d.ts +21 -0
  48. package/dist/mail/parse.d.ts.map +1 -0
  49. package/dist/mail/parse.js +86 -0
  50. package/dist/mail/parse.js.map +1 -0
  51. package/dist/notes/about.d.ts +31 -0
  52. package/dist/notes/about.d.ts.map +1 -0
  53. package/dist/notes/about.js +69 -0
  54. package/dist/notes/about.js.map +1 -0
  55. package/dist/notes/bound.d.ts +24 -0
  56. package/dist/notes/bound.d.ts.map +1 -0
  57. package/dist/notes/bound.js +57 -0
  58. package/dist/notes/bound.js.map +1 -0
  59. package/dist/notes/command.d.ts +4 -0
  60. package/dist/notes/command.d.ts.map +1 -0
  61. package/dist/notes/command.js +222 -0
  62. package/dist/notes/command.js.map +1 -0
  63. package/dist/notes/dialects/common.d.ts +18 -0
  64. package/dist/notes/dialects/common.d.ts.map +1 -0
  65. package/dist/notes/dialects/common.js +79 -0
  66. package/dist/notes/dialects/common.js.map +1 -0
  67. package/dist/notes/dialects/index.d.ts +5 -0
  68. package/dist/notes/dialects/index.d.ts.map +1 -0
  69. package/dist/notes/dialects/index.js +6 -0
  70. package/dist/notes/dialects/index.js.map +1 -0
  71. package/dist/notes/dialects/markdown.d.ts +7 -0
  72. package/dist/notes/dialects/markdown.d.ts.map +1 -0
  73. package/dist/notes/dialects/markdown.js +51 -0
  74. package/dist/notes/dialects/markdown.js.map +1 -0
  75. package/dist/notes/dialects/obsidian.d.ts +6 -0
  76. package/dist/notes/dialects/obsidian.d.ts.map +1 -0
  77. package/dist/notes/dialects/obsidian.js +33 -0
  78. package/dist/notes/dialects/obsidian.js.map +1 -0
  79. package/dist/notes/dialects/types.d.ts +39 -0
  80. package/dist/notes/dialects/types.d.ts.map +1 -0
  81. package/dist/notes/dialects/types.js +2 -0
  82. package/dist/notes/dialects/types.js.map +1 -0
  83. package/dist/notes/embed.d.ts +51 -0
  84. package/dist/notes/embed.d.ts.map +1 -0
  85. package/dist/notes/embed.js +109 -0
  86. package/dist/notes/embed.js.map +1 -0
  87. package/dist/notes/export.d.ts +27 -0
  88. package/dist/notes/export.d.ts.map +1 -0
  89. package/dist/notes/export.js +76 -0
  90. package/dist/notes/export.js.map +1 -0
  91. package/dist/notes/files.d.ts +14 -0
  92. package/dist/notes/files.d.ts.map +1 -0
  93. package/dist/notes/files.js +77 -0
  94. package/dist/notes/files.js.map +1 -0
  95. package/dist/notes/folders-command.d.ts +4 -0
  96. package/dist/notes/folders-command.d.ts.map +1 -0
  97. package/dist/notes/folders-command.js +113 -0
  98. package/dist/notes/folders-command.js.map +1 -0
  99. package/dist/notes/folders.d.ts +27 -0
  100. package/dist/notes/folders.d.ts.map +1 -0
  101. package/dist/notes/folders.js +46 -0
  102. package/dist/notes/folders.js.map +1 -0
  103. package/dist/notes/import.d.ts +33 -0
  104. package/dist/notes/import.d.ts.map +1 -0
  105. package/dist/notes/import.js +183 -0
  106. package/dist/notes/import.js.map +1 -0
  107. package/dist/notes/internal.d.ts +17 -0
  108. package/dist/notes/internal.d.ts.map +1 -0
  109. package/dist/notes/internal.js +47 -0
  110. package/dist/notes/internal.js.map +1 -0
  111. package/dist/notes/links.d.ts +18 -0
  112. package/dist/notes/links.d.ts.map +1 -0
  113. package/dist/notes/links.js +44 -0
  114. package/dist/notes/links.js.map +1 -0
  115. package/dist/notes/renames.d.ts +11 -0
  116. package/dist/notes/renames.d.ts.map +1 -0
  117. package/dist/notes/renames.js +24 -0
  118. package/dist/notes/renames.js.map +1 -0
  119. package/dist/notes/search.d.ts +5 -0
  120. package/dist/notes/search.d.ts.map +1 -0
  121. package/dist/notes/search.js +20 -0
  122. package/dist/notes/search.js.map +1 -0
  123. package/dist/notes/state.d.ts +14 -0
  124. package/dist/notes/state.d.ts.map +1 -0
  125. package/dist/notes/state.js +21 -0
  126. package/dist/notes/state.js.map +1 -0
  127. package/dist/options.d.ts +4 -0
  128. package/dist/options.d.ts.map +1 -0
  129. package/dist/options.js +12 -0
  130. package/dist/options.js.map +1 -0
  131. package/dist/people/command.d.ts +5 -0
  132. package/dist/people/command.d.ts.map +1 -0
  133. package/dist/people/command.js +57 -0
  134. package/dist/people/command.js.map +1 -0
  135. package/dist/people/identity.d.ts +4 -0
  136. package/dist/people/identity.d.ts.map +1 -0
  137. package/dist/people/identity.js +13 -0
  138. package/dist/people/identity.js.map +1 -0
  139. package/dist/people/notes-map.d.ts +13 -0
  140. package/dist/people/notes-map.d.ts.map +1 -0
  141. package/dist/people/notes-map.js +49 -0
  142. package/dist/people/notes-map.js.map +1 -0
  143. package/dist/people/subject.d.ts +8 -0
  144. package/dist/people/subject.d.ts.map +1 -0
  145. package/dist/people/subject.js +19 -0
  146. package/dist/people/subject.js.map +1 -0
  147. package/dist/program.d.ts +7 -0
  148. package/dist/program.d.ts.map +1 -0
  149. package/dist/program.js +34 -0
  150. package/dist/program.js.map +1 -0
  151. package/dist/run/auto.d.ts +20 -0
  152. package/dist/run/auto.d.ts.map +1 -0
  153. package/dist/run/auto.js +139 -0
  154. package/dist/run/auto.js.map +1 -0
  155. package/dist/run/import.d.ts +18 -0
  156. package/dist/run/import.d.ts.map +1 -0
  157. package/dist/run/import.js +114 -0
  158. package/dist/run/import.js.map +1 -0
  159. package/dist/search/command.d.ts +38 -0
  160. package/dist/search/command.d.ts.map +1 -0
  161. package/dist/search/command.js +269 -0
  162. package/dist/search/command.js.map +1 -0
  163. package/dist/store/gone.d.ts +17 -0
  164. package/dist/store/gone.d.ts.map +1 -0
  165. package/dist/store/gone.js +52 -0
  166. package/dist/store/gone.js.map +1 -0
  167. package/dist/store/scope.d.ts +19 -0
  168. package/dist/store/scope.d.ts.map +1 -0
  169. package/dist/store/scope.js +34 -0
  170. package/dist/store/scope.js.map +1 -0
  171. package/dist/store/source-target.d.ts +18 -0
  172. package/dist/store/source-target.d.ts.map +1 -0
  173. package/dist/store/source-target.js +28 -0
  174. package/dist/store/source-target.js.map +1 -0
  175. package/dist/tags/command.d.ts +4 -0
  176. package/dist/tags/command.d.ts.map +1 -0
  177. package/dist/tags/command.js +166 -0
  178. package/dist/tags/command.js.map +1 -0
  179. package/dist/tasks/command.d.ts +4 -0
  180. package/dist/tasks/command.d.ts.map +1 -0
  181. package/dist/tasks/command.js +83 -0
  182. package/dist/tasks/command.js.map +1 -0
  183. package/dist/tasks/context.d.ts +16 -0
  184. package/dist/tasks/context.d.ts.map +1 -0
  185. package/dist/tasks/context.js +68 -0
  186. package/dist/tasks/context.js.map +1 -0
  187. package/dist/version.d.ts +2 -0
  188. package/dist/version.d.ts.map +1 -0
  189. package/dist/version.js +2 -0
  190. package/dist/version.js.map +1 -0
  191. package/package.json +48 -3
@@ -0,0 +1,183 @@
1
+ import { createHash } from "node:crypto";
2
+ import { readFileSync, statSync } from "node:fs";
3
+ import { basename, extname, relative, sep } from "node:path";
4
+ import { normalizeTag } from "@wirecat/cli-messaging";
5
+ import { extractText, importEngine, MAX_FILE_BYTES } from "@wirecat/cli-messaging/documents";
6
+ import { dialectOf } from "./dialects/index.js";
7
+ import { NOTE_EXTENSIONS, noteFiles, readMemoId } from "./files.js";
8
+ import { documentOf, fileLinks } from "./links.js";
9
+ import { detectRenames } from "./renames.js";
10
+ import { loadFolderState, saveFolderState } from "./state.js";
11
+ const MAX_TEXT = 200_000;
12
+ const MAX_DELETED_SHARE = 0.2;
13
+ const MIN_DELETIONS_CAPPED = 5;
14
+ const PAGE = 500;
15
+ const TEXT_NOTE = /\.(md|markdown|txt)$/i;
16
+ const MEMO = "memo:";
17
+ const inside = (folder, path) => relative(folder, path).split(sep).join("/");
18
+ export const folderNotes = async (store, folderId) => {
19
+ const notes = [];
20
+ for (let offset = 0;; offset += PAGE) {
21
+ const page = await store.notes.notes({ folderId, source: "file", limit: PAGE, offset });
22
+ notes.push(...page.items);
23
+ if (!page.hasMore)
24
+ return notes;
25
+ }
26
+ };
27
+ /** Tags as the store takes them; a nested Obsidian tag (`area/work`) or any other spelling it refuses is left out. */
28
+ const storable = (tags) => [
29
+ ...new Set(tags.flatMap((tag) => {
30
+ try {
31
+ return [normalizeTag(tag)];
32
+ }
33
+ catch {
34
+ return [];
35
+ }
36
+ })),
37
+ ].sort();
38
+ /**
39
+ * Each file is one note of its folder, named by its path inside the folder. What this computer last saw of
40
+ * each file is kept beside the config (`state.ts`), so an untouched file is not even opened; the store's own
41
+ * content hash keeps an unchanged file from being saved again on a computer importing it for the first time.
42
+ * A file gone from one path whose content appears at a new one is a move. A file memo exported is not a note.
43
+ */
44
+ export const importNotes = async (store, folder, { ignore = [], env = process.env, loadEngine = importEngine, } = {}) => {
45
+ const before = loadFolderState(env, folder.id);
46
+ const after = { files: {}, documents: { ...before?.documents } };
47
+ const dialect = dialectOf(folder.format);
48
+ const stored = new Map((await folderNotes(store, folder.id)).map((note) => [note.path, note]));
49
+ const notRead = [];
50
+ const truncated = [];
51
+ const unreadable = [];
52
+ const read = [];
53
+ const files = noteFiles(folder.path, ignore, NOTE_EXTENSIONS, { skipExported: false });
54
+ for (const path of files) {
55
+ const id = inside(folder.path, path);
56
+ const stat = statSync(path);
57
+ const stamp = `${stat.mtimeMs}:${stat.size}:`;
58
+ const previous = before?.files[id];
59
+ if (previous?.startsWith(stamp) || previous?.startsWith(`${MEMO}${stamp}`)) {
60
+ after.files[id] = previous;
61
+ continue;
62
+ }
63
+ if (stat.size > MAX_FILE_BYTES) {
64
+ after.files[id] = stamp;
65
+ notRead.push({ path: id, status: "too-large" });
66
+ unreadable.push(id);
67
+ continue;
68
+ }
69
+ // Only a file that changed is opened, so this check costs nothing on an untouched folder.
70
+ if (TEXT_NOTE.test(id) && readMemoId(path) !== null) {
71
+ after.files[id] = `${MEMO}${stamp}`;
72
+ continue;
73
+ }
74
+ const bytes = readFileSync(path);
75
+ const hash = createHash("sha256").update(bytes).digest("hex");
76
+ after.files[id] = `${stamp}${hash}`;
77
+ read.push({ id, path, bytes, hash });
78
+ }
79
+ const listed = new Set(Object.keys(after.files).filter((id) => !after.files[id]?.startsWith(MEMO)));
80
+ const goneHashes = Object.fromEntries([...stored.values()]
81
+ .filter((note) => !listed.has(note.path) && note.contentHash !== null)
82
+ .map((note) => [note.path, note.contentHash]));
83
+ const newHashes = Object.fromEntries(read.filter(({ id }) => !stored.has(id)).map(({ id, hash }) => [id, hash]));
84
+ let renamed = 0;
85
+ for (const move of detectRenames(goneHashes, newHashes)) {
86
+ const note = await store.notes.renameFileNote(folder.id, move.from, move.to);
87
+ stored.delete(move.from);
88
+ stored.set(move.to, note);
89
+ renamed++;
90
+ }
91
+ const parsed = new Map();
92
+ let changed = 0;
93
+ let added = 0;
94
+ for (const { id, path, bytes, hash } of read) {
95
+ if (stored.get(id)?.contentHash === hash)
96
+ continue;
97
+ const extraction = await extractText(bytes, { kind: "file", name: basename(path), mime: null, path }, loadEngine);
98
+ if (extraction.status !== "extracted") {
99
+ notRead.push({
100
+ path: id,
101
+ status: extraction.status,
102
+ ...("engine" in extraction ? { engine: extraction.engine } : {}),
103
+ });
104
+ unreadable.push(id);
105
+ continue;
106
+ }
107
+ const text = extraction.text.replace(/\r\n?/g, "\n");
108
+ if (extraction.truncated || text.length > MAX_TEXT)
109
+ truncated.push(id);
110
+ const note = TEXT_NOTE.test(id) ? dialect.parse(text, id) : undefined;
111
+ const saved = await store.notes.saveFileNote({
112
+ folderId: folder.id,
113
+ path: id,
114
+ title: note?.title ?? basename(id).replace(/\.[^.]+$/, ""),
115
+ text: text.slice(0, MAX_TEXT),
116
+ ...(note && Object.keys(note.frontMatter).length ? { frontMatter: note.frontMatter } : {}),
117
+ contentHash: hash,
118
+ });
119
+ if (!stored.has(id))
120
+ added++;
121
+ stored.set(id, saved.note);
122
+ if (note)
123
+ parsed.set(id, note);
124
+ after.documents[id] = {
125
+ extractor: extraction.extractor,
126
+ format: extname(id),
127
+ provenance: extname(id).toLowerCase() === ".xlsx" ? "sheet-cell" : "source-text",
128
+ truncated: truncated.includes(id),
129
+ ...("spans" in extraction && extraction.spans ? { spans: extraction.spans } : {}),
130
+ ...("cells" in extraction && extraction.cells ? { cells: extraction.cells } : {}),
131
+ };
132
+ if (saved.changed)
133
+ changed++;
134
+ }
135
+ const gone = [...stored.keys()].filter((id) => !listed.has(id));
136
+ let deleted = 0;
137
+ let deletionsSkipped;
138
+ if (gone.length >= MIN_DELETIONS_CAPPED && gone.length > stored.size * MAX_DELETED_SHARE) {
139
+ deletionsSkipped = `${gone.length} of ${stored.size} stored notes are missing from the folder — too many to trust; nothing deleted`;
140
+ }
141
+ else if (gone.length > 0) {
142
+ deleted = await store.notes.deleteFileNotes(folder.id, gone);
143
+ for (const id of gone) {
144
+ stored.delete(id);
145
+ delete after.documents[id];
146
+ }
147
+ }
148
+ const dropped = unreadable.filter((id) => stored.has(id));
149
+ if (dropped.length) {
150
+ deleted += await store.notes.deleteFileNotes(folder.id, dropped);
151
+ for (const id of dropped)
152
+ stored.delete(id);
153
+ }
154
+ const documents = [...stored.values()].map(documentOf);
155
+ const relink = new Map(parsed);
156
+ if (renamed + deleted + added > 0) {
157
+ // A note added or moved can be what an older note's unresolved link was waiting for.
158
+ const waiting = new Set((await store.notes.links({ unresolved: true })).map(({ from }) => from.replace(/^note:/, "")));
159
+ for (const note of stored.values())
160
+ if (waiting.has(note.id) && !relink.has(note.path) && TEXT_NOTE.test(note.path))
161
+ relink.set(note.path, dialect.parse(note.text, note.path));
162
+ }
163
+ for (const [id, note] of relink) {
164
+ const record = stored.get(id);
165
+ if (record)
166
+ await store.notes.replaceFileLinks(record.id, fileLinks(id, note.links, documents));
167
+ }
168
+ for (const [id, note] of parsed)
169
+ await store.notes.replaceFileTags(stored.get(id).id, storable(note.tags));
170
+ saveFolderState(env, folder.id, after);
171
+ return {
172
+ folder: folder.path,
173
+ folderId: folder.id,
174
+ notes: listed.size,
175
+ changed,
176
+ renamed,
177
+ deleted,
178
+ ...(notRead.length ? { notRead } : {}),
179
+ ...(truncated.length ? { truncated } : {}),
180
+ ...(deletionsSkipped === undefined ? {} : { deletionsSkipped }),
181
+ };
182
+ };
183
+ //# sourceMappingURL=import.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"import.js","sourceRoot":"","sources":["../../src/notes/import.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { MessageStore, Note } from "@wirecat/cli-messaging/store";
2
+ import type { Config } from "../config.js";
3
+ import { type DialectName } from "./dialects/index.js";
4
+ import { type ExportResult } from "./export.js";
5
+ export declare const internalNotes: (store: MessageStore) => Promise<Note[]>;
6
+ /** Where an export goes: the folder given, else the config's `notes.export`. */
7
+ export declare const exportTarget: (config: Config, dir: string | true | undefined, format: DialectName | undefined) => {
8
+ dir: string;
9
+ format: DialectName;
10
+ };
11
+ /** Writes internal notes as files, each with what it is about as links and its tags. */
12
+ export declare const exportInternal: (store: MessageStore, { dir, format, notes }: {
13
+ dir: string;
14
+ format: DialectName;
15
+ notes: Note[];
16
+ }) => Promise<ExportResult>;
17
+ //# sourceMappingURL=internal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../../src/notes/internal.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAA;AACtE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,EAAE,KAAK,WAAW,EAAa,MAAM,qBAAqB,CAAA;AACjE,OAAO,EAAqB,KAAK,YAAY,EAAe,MAAM,aAAa,CAAA;AAK/E,eAAO,MAAM,aAAa,UAAiB,YAAY,KAAG,OAAO,CAAC,IAAI,EAAE,CAOvE,CAAA;AAWD,gFAAgF;AAChF,eAAO,MAAM,YAAY,WACf,MAAM,OACT,MAAM,GAAG,IAAI,GAAG,SAAS,UACtB,WAAW,GAAG,SAAS,KAC9B;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,WAAW,CAAA;CAQpC,CAAA;AAED,wFAAwF;AACxF,eAAO,MAAM,cAAc,UAClB,YAAY,0BACK;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,IAAI,EAAE,CAAA;CAAE,KAC1E,OAAO,CAAC,YAAY,CAetB,CAAA"}
@@ -0,0 +1,47 @@
1
+ import { resolve } from "node:path";
2
+ import { CliError } from "@wirecat/cli-core";
3
+ import { dialectOf } from "./dialects/index.js";
4
+ import { exportNotes } from "./export.js";
5
+ const PAGE = 500;
6
+ const MAX_TITLE = 80;
7
+ export const internalNotes = async (store) => {
8
+ const notes = [];
9
+ for (let offset = 0;; offset += PAGE) {
10
+ const page = await store.notes.notes({ source: "internal", limit: PAGE, offset });
11
+ notes.push(...page.items);
12
+ if (!page.hasMore)
13
+ return notes;
14
+ }
15
+ };
16
+ const titleOf = (note) => note.title ??
17
+ (note.text
18
+ .split("\n")
19
+ .find((line) => line.trim())
20
+ ?.trim()
21
+ .slice(0, MAX_TITLE) ||
22
+ note.id);
23
+ /** Where an export goes: the folder given, else the config's `notes.export`. */
24
+ export const exportTarget = (config, dir, format) => {
25
+ const chosen = typeof dir === "string" ? dir : config.notes?.export?.dir;
26
+ if (chosen === undefined)
27
+ throw new CliError("configuration_error", "name a folder — --to <dir>, --export <dir>, or notes.export.dir in the config");
28
+ return { dir: resolve(chosen), format: format ?? config.notes?.export?.format ?? "obsidian" };
29
+ };
30
+ /** Writes internal notes as files, each with what it is about as links and its tags. */
31
+ export const exportInternal = async (store, { dir, format, notes }) => {
32
+ const exported = [];
33
+ for (const note of notes) {
34
+ const about = (await store.notes.links({ from: `note:${note.id}` })).filter((link) => link.to !== null);
35
+ exported.push({
36
+ id: note.id,
37
+ title: titleOf(note),
38
+ text: note.text,
39
+ aliases: [],
40
+ tags: (await store.notes.noteTags(note.id)).map(({ tag }) => tag),
41
+ links: about.map((link) => ({ target: link.to, anchor: link.anchor, label: null })),
42
+ frontMatter: {},
43
+ });
44
+ }
45
+ return exportNotes({ dir, dialect: dialectOf(format), notes: exported });
46
+ };
47
+ //# sourceMappingURL=internal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"internal.js","sourceRoot":"","sources":["../../src/notes/internal.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { LinkInput, Note } from "@wirecat/cli-messaging/store";
2
+ import type { NoteLink } from "./dialects/index.js";
3
+ /** A stored file note as links see it: where it is and every name it answers to. */
4
+ export interface FolderDocument {
5
+ id: string;
6
+ path: string;
7
+ aliases: string[];
8
+ }
9
+ export declare const documentOf: (note: Note) => FolderDocument;
10
+ /** The notes a written target names: by path (relative when it starts with `./` or `../`), else by file name or alias. */
11
+ export declare const notesNamed: (source: string, target: string, documents: FolderDocument[]) => FolderDocument[];
12
+ /**
13
+ * What a file's links become in the store. A record (`person:…`, `msg:…`) is linked as written; a note
14
+ * named once is linked by id. A name no note has — or several have — stays as written, so the store can
15
+ * resolve it to a person the moment one by that name, alias or username appears.
16
+ */
17
+ export declare const fileLinks: (source: string, links: NoteLink[], documents: FolderDocument[]) => Omit<LinkInput, "from" | "origin">[];
18
+ //# sourceMappingURL=links.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"links.d.ts","sourceRoot":"","sources":["../../src/notes/links.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAA;AAEnE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAEnD,oFAAoF;AACpF,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,EAAE,CAAA;CAClB;AAaD,eAAO,MAAM,UAAU,SAAU,IAAI,KAAG,cAItC,CAAA;AAEF,0HAA0H;AAC1H,eAAO,MAAM,UAAU,WAAY,MAAM,UAAU,MAAM,aAAa,cAAc,EAAE,KAAG,cAAc,EAYtG,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,SAAS,WACZ,MAAM,SACP,QAAQ,EAAE,aACN,cAAc,EAAE,KAC1B,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,QAAQ,CAAC,EAQjC,CAAA"}
@@ -0,0 +1,44 @@
1
+ import { posix } from "node:path";
2
+ import { isReference } from "./dialects/common.js";
3
+ const fold = (value) => value.normalize("NFC").toLocaleLowerCase("en");
4
+ const stem = (path) => path.replace(/\.(md|markdown|txt|csv|tsv|pdf|docx|xlsx)$/i, "");
5
+ const aliasesOf = (frontMatter) => {
6
+ const value = frontMatter?.aliases ??
7
+ frontMatter?.alias;
8
+ if (typeof value === "string")
9
+ return [value];
10
+ return Array.isArray(value) ? value.filter((alias) => typeof alias === "string") : [];
11
+ };
12
+ export const documentOf = (note) => ({
13
+ id: note.id,
14
+ path: note.path,
15
+ aliases: aliasesOf(note.frontMatter),
16
+ });
17
+ /** The notes a written target names: by path (relative when it starts with `./` or `../`), else by file name or alias. */
18
+ export const notesNamed = (source, target, documents) => {
19
+ const normalized = stem(posix.normalize(target.replace(/\\/g, "/").replace(/^\//, "")));
20
+ const relative = stem(posix.normalize(posix.join(posix.dirname(source), normalized)));
21
+ const explicit = target.startsWith("./") || target.startsWith("../") || target.startsWith("/") || normalized.includes("/");
22
+ const preferred = target.startsWith("./") || target.startsWith("../") ? relative : normalized;
23
+ if (target === "")
24
+ return documents.filter((doc) => doc.path === source);
25
+ if (explicit)
26
+ return documents.filter((doc) => fold(stem(doc.path)) === fold(preferred));
27
+ const name = fold(stem(target));
28
+ return documents.filter((doc) => [stem(posix.basename(doc.path)), ...doc.aliases].some((known) => fold(known) === name));
29
+ };
30
+ /**
31
+ * What a file's links become in the store. A record (`person:…`, `msg:…`) is linked as written; a note
32
+ * named once is linked by id. A name no note has — or several have — stays as written, so the store can
33
+ * resolve it to a person the moment one by that name, alias or username appears.
34
+ */
35
+ export const fileLinks = (source, links, documents) => links.map(({ target, anchor }) => {
36
+ const at = anchor === null ? {} : { anchor };
37
+ if (isReference(target))
38
+ return { to: target, kind: "links-to", ...at };
39
+ const named = notesNamed(source, target, documents);
40
+ return named.length === 1
41
+ ? { to: `note:${named[0].id}`, kind: "links-to", ...at }
42
+ : { targetText: posix.basename(target.replace(/\\/g, "/")) || target, kind: "links-to", ...at };
43
+ });
44
+ //# sourceMappingURL=links.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"links.js","sourceRoot":"","sources":["../../src/notes/links.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ export interface Rename {
2
+ from: string;
3
+ to: string;
4
+ }
5
+ /**
6
+ * Files that moved between two listings: a path gone from `before` whose content hash appears at a path
7
+ * new in `after`. A hash shared by two gone or two new files names no single move, so it is left out —
8
+ * a wrong guess would hand one note's links and tags to another.
9
+ */
10
+ export declare const detectRenames: (before: Record<string, string>, after: Record<string, string>) => Rename[];
11
+ //# sourceMappingURL=renames.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renames.d.ts","sourceRoot":"","sources":["../../src/notes/renames.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,MAAM,CAAA;CACX;AAED;;;;GAIG;AACH,eAAO,MAAM,aAAa,WAAY,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAG,MAAM,EAuBnG,CAAA"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Files that moved between two listings: a path gone from `before` whose content hash appears at a path
3
+ * new in `after`. A hash shared by two gone or two new files names no single move, so it is left out —
4
+ * a wrong guess would hand one note's links and tags to another.
5
+ */
6
+ export const detectRenames = (before, after) => {
7
+ const byHash = (paths, hashes) => {
8
+ const grouped = new Map();
9
+ for (const path of paths) {
10
+ const hash = hashes[path];
11
+ grouped.set(hash, [...(grouped.get(hash) ?? []), path]);
12
+ }
13
+ return grouped;
14
+ };
15
+ const gone = byHash(Object.keys(before).filter((path) => !(path in after)), before);
16
+ const added = byHash(Object.keys(after).filter((path) => !(path in before)), after);
17
+ return [...gone]
18
+ .flatMap(([hash, from]) => {
19
+ const to = added.get(hash);
20
+ return from.length === 1 && to?.length === 1 ? [{ from: from[0], to: to[0] }] : [];
21
+ })
22
+ .sort((a, b) => a.from.localeCompare(b.from));
23
+ };
24
+ //# sourceMappingURL=renames.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renames.js","sourceRoot":"","sources":["../../src/notes/renames.ts"],"names":[],"mappings":"AAKA;;;;GAIG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,MAA8B,EAAE,KAA6B,EAAY,EAAE;IACvG,MAAM,MAAM,GAAG,CAAC,KAAe,EAAE,MAA8B,EAAE,EAAE;QACjE,MAAM,OAAO,GAAG,IAAI,GAAG,EAAoB,CAAA;QAC3C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAW,CAAA;YACnC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,CAAA;QACzD,CAAC;QACD,OAAO,OAAO,CAAA;IAChB,CAAC,CAAA;IACD,MAAM,IAAI,GAAG,MAAM,CACjB,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,KAAK,CAAC,CAAC,EACtD,MAAM,CACP,CAAA;IACD,MAAM,KAAK,GAAG,MAAM,CAClB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,MAAM,CAAC,CAAC,EACtD,KAAK,CACN,CAAA;IACD,OAAO,CAAC,GAAG,IAAI,CAAC;SACb,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE;QACxB,MAAM,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QAC1B,OAAO,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,EAAE,EAAE,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAW,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAW,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IACxG,CAAC,CAAC;SACD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;AACjD,CAAC,CAAA"}
@@ -0,0 +1,5 @@
1
+ import type { NotesFound as NotesSearch } from "@wirecat/cli-messaging/services";
2
+ export type { FoundNote as NoteHit, LinkedRecord, NotesFound as NotesSearch } from "@wirecat/cli-messaging/services";
3
+ export { searchNotes } from "@wirecat/cli-messaging/services";
4
+ export declare const searchText: (result: NotesSearch) => string;
5
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/notes/search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,IAAI,WAAW,EAAE,MAAM,iCAAiC,CAAA;AAEhF,YAAY,EAAE,SAAS,IAAI,OAAO,EAAE,YAAY,EAAE,UAAU,IAAI,WAAW,EAAE,MAAM,iCAAiC,CAAA;AACpH,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAA;AAE7D,eAAO,MAAM,UAAU,WAAY,WAAW,KAAG,MAsBnC,CAAA"}
@@ -0,0 +1,20 @@
1
+ export { searchNotes } from "@wirecat/cli-messaging/services";
2
+ export const searchText = (result) => [
3
+ ...(result.hits.length === 0
4
+ ? [
5
+ result.tag === undefined
6
+ ? `No note holds "${result.query}". Run memo notes import if notes changed.`
7
+ : `No note tagged ${result.tag} matches "${result.query}".`,
8
+ ]
9
+ : []),
10
+ ...result.hits.map((hit) => `${hit.path ?? hit.ref}${hit.foundBy.includes("words") ? "" : " (by meaning)"}\n ${hit.line}`),
11
+ ...(result.hasMore ? ["More notes match; raise --limit or follow nextOffset."] : []),
12
+ ...(result.linked.length === 0
13
+ ? []
14
+ : [
15
+ "",
16
+ "Linked from these notes",
17
+ ...result.linked.map(({ ref, name, notes }) => ` ${name ?? ref} ${ref ?? "(nobody by that name yet)"} (${notes})`),
18
+ ]),
19
+ ].join("\n");
20
+ //# sourceMappingURL=search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/notes/search.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAA;AAE7D,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,MAAmB,EAAU,EAAE,CACxD;IACE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC;QAC1B,CAAC,CAAC;YACE,MAAM,CAAC,GAAG,KAAK,SAAS;gBACtB,CAAC,CAAC,kBAAkB,MAAM,CAAC,KAAK,4CAA4C;gBAC5E,CAAC,CAAC,kBAAkB,MAAM,CAAC,GAAG,aAAa,MAAM,CAAC,KAAK,IAAI;SAC9D;QACH,CAAC,CAAC,EAAE,CAAC;IACP,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAChB,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,gBAAgB,OAAO,GAAG,CAAC,IAAI,EAAE,CACzG;IACD,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,uDAAuD,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACpF,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC;QAC5B,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC;YACE,EAAE;YACF,yBAAyB;YACzB,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAClB,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,IAAI,IAAI,GAAG,KAAK,GAAG,IAAI,2BAA2B,MAAM,KAAK,GAAG,CAChG;SACF,CAAC;CACP,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * What one computer last saw of a folder. It is kept here, not in the shared store: a file's change time
3
+ * belongs to this disk, and another computer's copy of the folder has its own.
4
+ */
5
+ export interface FolderState {
6
+ /** Path inside the folder → `mtimeMs:size:sha256`; `memo:` in front for a file memo exported. */
7
+ files: Record<string, string>;
8
+ /** Where the text of a PDF, sheet or document came from inside it. */
9
+ documents: Record<string, unknown>;
10
+ }
11
+ /** `undefined` before this computer's first import of the folder. */
12
+ export declare const loadFolderState: (env: NodeJS.ProcessEnv, id: string) => FolderState | undefined;
13
+ export declare const saveFolderState: (env: NodeJS.ProcessEnv, id: string, state: FolderState) => void;
14
+ //# sourceMappingURL=state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/notes/state.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,iGAAiG;IACjG,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC7B,sEAAsE;IACtE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACnC;AAOD,qEAAqE;AACrE,eAAO,MAAM,eAAe,QAAS,MAAM,CAAC,UAAU,MAAM,MAAM,KAAG,WAAW,GAAG,SAMlF,CAAA;AAED,eAAO,MAAM,eAAe,QAAS,MAAM,CAAC,UAAU,MAAM,MAAM,SAAS,WAAW,KAAG,IAKxF,CAAA"}
@@ -0,0 +1,21 @@
1
+ import { mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { resolvePaths } from "@wirecat/cli-core";
4
+ const empty = () => ({ files: {}, documents: {} });
5
+ const fileOf = (env, id) => join(resolvePaths({ appName: "cli-memo", prefix: "MEMO", env }).state, "folders", `${id}.json`);
6
+ /** `undefined` before this computer's first import of the folder. */
7
+ export const loadFolderState = (env, id) => {
8
+ try {
9
+ return { ...empty(), ...JSON.parse(readFileSync(fileOf(env, id), "utf8")) };
10
+ }
11
+ catch {
12
+ return undefined;
13
+ }
14
+ };
15
+ export const saveFolderState = (env, id, state) => {
16
+ const file = fileOf(env, id);
17
+ mkdirSync(join(file, ".."), { recursive: true });
18
+ writeFileSync(`${file}.tmp`, JSON.stringify(state));
19
+ renameSync(`${file}.tmp`, file);
20
+ };
21
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/notes/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAC5E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAahD,MAAM,KAAK,GAAG,GAAgB,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAA;AAE/D,MAAM,MAAM,GAAG,CAAC,GAAsB,EAAE,EAAU,EAAE,EAAE,CACpD,IAAI,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,OAAO,CAAC,CAAA;AAEjG,qEAAqE;AACrE,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,GAAsB,EAAE,EAAU,EAA2B,EAAE;IAC7F,IAAI,CAAC;QACH,OAAO,EAAE,GAAG,KAAK,EAAE,EAAE,GAAI,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,MAAM,CAAC,CAA0B,EAAE,CAAA;IACvG,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,GAAsB,EAAE,EAAU,EAAE,KAAkB,EAAQ,EAAE;IAC9F,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,EAAE,EAAE,CAAC,CAAA;IAC5B,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAChD,aAAa,CAAC,GAAG,IAAI,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAA;IACnD,UAAU,CAAC,GAAG,IAAI,MAAM,EAAE,IAAI,CAAC,CAAA;AACjC,CAAC,CAAA"}
@@ -0,0 +1,4 @@
1
+ import { type Command } from "commander";
2
+ export declare const positive: (value: string) => number;
3
+ export declare const accountOptions: (command: Command) => Command;
4
+ //# sourceMappingURL=options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAwB,MAAM,WAAW,CAAA;AAE9D,eAAO,MAAM,QAAQ,UAAW,MAAM,KAAG,MAIxC,CAAA;AAED,eAAO,MAAM,cAAc,YAAa,OAAO,YAIZ,CAAA"}
@@ -0,0 +1,12 @@
1
+ import { InvalidArgumentError } from "commander";
2
+ export const positive = (value) => {
3
+ const number = Number(value);
4
+ if (!Number.isInteger(number) || number < 1)
5
+ throw new InvalidArgumentError("a whole number above zero");
6
+ return number;
7
+ };
8
+ export const accountOptions = (command) => command
9
+ .option("--provider <provider>", "source provider")
10
+ .option("--account <account>", "exact stored account")
11
+ .option("--json", "print JSON");
12
+ //# sourceMappingURL=options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"options.js","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,oBAAoB,EAAE,MAAM,WAAW,CAAA;AAE9D,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,KAAa,EAAU,EAAE;IAChD,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;IAC5B,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC;QAAE,MAAM,IAAI,oBAAoB,CAAC,2BAA2B,CAAC,CAAA;IACxG,OAAO,MAAM,CAAA;AACf,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,OAAgB,EAAE,EAAE,CACjD,OAAO;KACJ,MAAM,CAAC,uBAAuB,EAAE,iBAAiB,CAAC;KAClD,MAAM,CAAC,qBAAqB,EAAE,sBAAsB,CAAC;KACrD,MAAM,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAA"}
@@ -0,0 +1,5 @@
1
+ import { type Streams } from "@wirecat/cli-core";
2
+ import type { Command } from "commander";
3
+ /** Who is who is linked in messaging (`tg contacts link`); the note about a person is an `about` link. */
4
+ export declare const noteCommand: (program: Command, streams: Streams, env: NodeJS.ProcessEnv) => void;
5
+ //# sourceMappingURL=command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../src/people/command.ts"],"names":[],"mappings":"AACA,OAAO,EAAY,KAAK,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAE1D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAMxC,0GAA0G;AAC1G,eAAO,MAAM,WAAW,YAAa,OAAO,WAAW,OAAO,OAAO,MAAM,CAAC,UAAU,KAAG,IAwCxF,CAAA"}
@@ -0,0 +1,57 @@
1
+ import { join } from "node:path";
2
+ import { CliError } from "@wirecat/cli-core";
3
+ import { openStore } from "@wirecat/cli-messaging/store";
4
+ import { boundFolders, folderOfFile } from "../notes/bound.js";
5
+ import { folderNotes } from "../notes/import.js";
6
+ import { identityOf } from "./identity.js";
7
+ import { importNotesMap } from "./notes-map.js";
8
+ /** Who is who is linked in messaging (`tg contacts link`); the note about a person is an `about` link. */
9
+ export const noteCommand = (program, streams, env) => {
10
+ program
11
+ .command("note")
12
+ .description("Name the note that is about a person, or show it")
13
+ .argument("<identity>", "<messenger>:<name or id> of any identity of the person")
14
+ .argument("[path]", "the note about them, a file in a configured folder")
15
+ .option("--clear", "forget which file note is about them")
16
+ .action(async (identity, path, options) => {
17
+ const store = await openStore({ env });
18
+ try {
19
+ const folders = await boundFolders(store, env, { strict: false });
20
+ await importNotesMap(store, env, folders);
21
+ const person = await store.personOf(await identityOf(store, identity));
22
+ if (person === undefined)
23
+ throw new CliError("not_found", `the store has no person for "${identity}"`);
24
+ const to = `person:${person.uid}`;
25
+ const files = async () => {
26
+ const found = [];
27
+ for (const link of await store.notes.links({ to })) {
28
+ if (link.kind !== "about" || link.origin !== "owner")
29
+ continue;
30
+ const note = await store.notes.note(link.from.replace(/^note:/, "")).catch(() => undefined);
31
+ if (note?.source === "file" && note.deletedAt === null)
32
+ found.push({ link, note });
33
+ }
34
+ return found;
35
+ };
36
+ if (options.clear)
37
+ for (const { link } of await files())
38
+ await store.notes.removeLink(link.id);
39
+ else if (path !== undefined) {
40
+ const { folder, path: inside } = folderOfFile(folders, path);
41
+ const note = (await folderNotes(store, folder.id)).find((candidate) => candidate.path === inside);
42
+ if (!note)
43
+ throw new CliError("not_found", `${path} is not imported yet — memo notes import`);
44
+ await store.notes.addLink({ from: `note:${note.id}`, to, kind: "about", origin: "owner" });
45
+ }
46
+ const shown = (await files()).map(({ note }) => {
47
+ const folder = folders.find((candidate) => candidate.id === note.folderId);
48
+ return folder ? join(folder.path, note.path) : `note:${note.id}`;
49
+ });
50
+ streams.data(`${person.name ?? person.uid}: ${shown.join(", ") || "no note"}\n`);
51
+ }
52
+ finally {
53
+ await store.close();
54
+ }
55
+ });
56
+ };
57
+ //# sourceMappingURL=command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command.js","sourceRoot":"","sources":["../../src/people/command.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { IdentityRef, MessageStore } from "@wirecat/cli-messaging/store";
2
+ /** `telegram:Ana`, `max:12345`, `email:ana@example.com` — the messenger is always named. */
3
+ export declare const identityOf: (store: MessageStore, reference: string) => Promise<IdentityRef>;
4
+ //# sourceMappingURL=identity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/people/identity.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAA;AAE7E,4FAA4F;AAC5F,eAAO,MAAM,UAAU,UAAiB,YAAY,aAAa,MAAM,KAAG,OAAO,CAAC,WAAW,CAQ5F,CAAA"}
@@ -0,0 +1,13 @@
1
+ import { CliError } from "@wirecat/cli-core";
2
+ import { pickPerson } from "@wirecat/cli-messaging";
3
+ /** `telegram:Ana`, `max:12345`, `email:ana@example.com` — the messenger is always named. */
4
+ export const identityOf = async (store, reference) => {
5
+ const match = /^([a-z][a-z0-9-]*):(.+)$/.exec(reference.trim());
6
+ if (match === null)
7
+ throw new CliError("validation_error", `"${reference}" names no messenger — write it as <messenger>:<name or id>`);
8
+ const [, provider = "", who = ""] = match;
9
+ const people = await store.people(provider);
10
+ const exact = people.get(provider === "email" ? who.toLowerCase() : who);
11
+ return { provider, id: exact?.id ?? pickPerson(who, people).id };
12
+ };
13
+ //# sourceMappingURL=identity.js.map