meeting-context-hub 1.0.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 (315) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +217 -0
  3. package/dist/ai/clients/claude.client.d.ts +10 -0
  4. package/dist/ai/clients/claude.client.d.ts.map +1 -0
  5. package/dist/ai/clients/claude.client.js +71 -0
  6. package/dist/ai/clients/claude.client.js.map +1 -0
  7. package/dist/ai/clients/embedding.client.d.ts +8 -0
  8. package/dist/ai/clients/embedding.client.d.ts.map +1 -0
  9. package/dist/ai/clients/embedding.client.js +22 -0
  10. package/dist/ai/clients/embedding.client.js.map +1 -0
  11. package/dist/ai/clients/index.d.ts +4 -0
  12. package/dist/ai/clients/index.d.ts.map +1 -0
  13. package/dist/ai/clients/index.js +4 -0
  14. package/dist/ai/clients/index.js.map +1 -0
  15. package/dist/ai/clients/whisper.client.d.ts +7 -0
  16. package/dist/ai/clients/whisper.client.d.ts.map +1 -0
  17. package/dist/ai/clients/whisper.client.js +17 -0
  18. package/dist/ai/clients/whisper.client.js.map +1 -0
  19. package/dist/ai/index.d.ts +4 -0
  20. package/dist/ai/index.d.ts.map +1 -0
  21. package/dist/ai/index.js +4 -0
  22. package/dist/ai/index.js.map +1 -0
  23. package/dist/ai/interfaces/index.d.ts +25 -0
  24. package/dist/ai/interfaces/index.d.ts.map +1 -0
  25. package/dist/ai/interfaces/index.js +2 -0
  26. package/dist/ai/interfaces/index.js.map +1 -0
  27. package/dist/ai/prompts/index.d.ts +3 -0
  28. package/dist/ai/prompts/index.d.ts.map +1 -0
  29. package/dist/ai/prompts/index.js +3 -0
  30. package/dist/ai/prompts/index.js.map +1 -0
  31. package/dist/ai/prompts/meeting-summary.prompt.d.ts +3 -0
  32. package/dist/ai/prompts/meeting-summary.prompt.d.ts.map +1 -0
  33. package/dist/ai/prompts/meeting-summary.prompt.js +44 -0
  34. package/dist/ai/prompts/meeting-summary.prompt.js.map +1 -0
  35. package/dist/ai/prompts/summarize.prompt.d.ts +4 -0
  36. package/dist/ai/prompts/summarize.prompt.d.ts.map +1 -0
  37. package/dist/ai/prompts/summarize.prompt.js +33 -0
  38. package/dist/ai/prompts/summarize.prompt.js.map +1 -0
  39. package/dist/ai/prompts/tagging.prompt.d.ts +4 -0
  40. package/dist/ai/prompts/tagging.prompt.d.ts.map +1 -0
  41. package/dist/ai/prompts/tagging.prompt.js +42 -0
  42. package/dist/ai/prompts/tagging.prompt.js.map +1 -0
  43. package/dist/cli/commands/add.command.d.ts +3 -0
  44. package/dist/cli/commands/add.command.d.ts.map +1 -0
  45. package/dist/cli/commands/add.command.js +80 -0
  46. package/dist/cli/commands/add.command.js.map +1 -0
  47. package/dist/cli/commands/config.command.d.ts +3 -0
  48. package/dist/cli/commands/config.command.d.ts.map +1 -0
  49. package/dist/cli/commands/config.command.js +75 -0
  50. package/dist/cli/commands/config.command.js.map +1 -0
  51. package/dist/cli/commands/index.d.ts +5 -0
  52. package/dist/cli/commands/index.d.ts.map +1 -0
  53. package/dist/cli/commands/index.js +5 -0
  54. package/dist/cli/commands/index.js.map +1 -0
  55. package/dist/cli/commands/list.command.d.ts +3 -0
  56. package/dist/cli/commands/list.command.d.ts.map +1 -0
  57. package/dist/cli/commands/list.command.js +57 -0
  58. package/dist/cli/commands/list.command.js.map +1 -0
  59. package/dist/cli/commands/search.command.d.ts +3 -0
  60. package/dist/cli/commands/search.command.d.ts.map +1 -0
  61. package/dist/cli/commands/search.command.js +68 -0
  62. package/dist/cli/commands/search.command.js.map +1 -0
  63. package/dist/cli/index.d.ts +3 -0
  64. package/dist/cli/index.d.ts.map +1 -0
  65. package/dist/cli/index.js +33 -0
  66. package/dist/cli/index.js.map +1 -0
  67. package/dist/cli/utils/cli-runner.d.ts +14 -0
  68. package/dist/cli/utils/cli-runner.d.ts.map +1 -0
  69. package/dist/cli/utils/cli-runner.js +28 -0
  70. package/dist/cli/utils/cli-runner.js.map +1 -0
  71. package/dist/cli/utils/formatters.d.ts +19 -0
  72. package/dist/cli/utils/formatters.d.ts.map +1 -0
  73. package/dist/cli/utils/formatters.js +79 -0
  74. package/dist/cli/utils/formatters.js.map +1 -0
  75. package/dist/cli/utils/index.d.ts +3 -0
  76. package/dist/cli/utils/index.d.ts.map +1 -0
  77. package/dist/cli/utils/index.js +3 -0
  78. package/dist/cli/utils/index.js.map +1 -0
  79. package/dist/config/config.d.ts +9 -0
  80. package/dist/config/config.d.ts.map +1 -0
  81. package/dist/config/config.js +25 -0
  82. package/dist/config/config.js.map +1 -0
  83. package/dist/config/env.d.ts +5 -0
  84. package/dist/config/env.d.ts.map +1 -0
  85. package/dist/config/env.js +18 -0
  86. package/dist/config/env.js.map +1 -0
  87. package/dist/config/index.d.ts +4 -0
  88. package/dist/config/index.d.ts.map +1 -0
  89. package/dist/config/index.js +4 -0
  90. package/dist/config/index.js.map +1 -0
  91. package/dist/config/keychain.d.ts +8 -0
  92. package/dist/config/keychain.d.ts.map +1 -0
  93. package/dist/config/keychain.js +33 -0
  94. package/dist/config/keychain.js.map +1 -0
  95. package/dist/core/add-context.usecase.d.ts +11 -0
  96. package/dist/core/add-context.usecase.d.ts.map +1 -0
  97. package/dist/core/add-context.usecase.js +65 -0
  98. package/dist/core/add-context.usecase.js.map +1 -0
  99. package/dist/core/add-context.usecase.test.d.ts +2 -0
  100. package/dist/core/add-context.usecase.test.d.ts.map +1 -0
  101. package/dist/core/add-context.usecase.test.js +99 -0
  102. package/dist/core/add-context.usecase.test.js.map +1 -0
  103. package/dist/core/factories.d.ts +24 -0
  104. package/dist/core/factories.d.ts.map +1 -0
  105. package/dist/core/factories.js +51 -0
  106. package/dist/core/factories.js.map +1 -0
  107. package/dist/core/index.d.ts +4 -0
  108. package/dist/core/index.d.ts.map +1 -0
  109. package/dist/core/index.js +4 -0
  110. package/dist/core/index.js.map +1 -0
  111. package/dist/core/search-context.usecase.d.ts +17 -0
  112. package/dist/core/search-context.usecase.d.ts.map +1 -0
  113. package/dist/core/search-context.usecase.js +45 -0
  114. package/dist/core/search-context.usecase.js.map +1 -0
  115. package/dist/core/search-context.usecase.test.d.ts +2 -0
  116. package/dist/core/search-context.usecase.test.d.ts.map +1 -0
  117. package/dist/core/search-context.usecase.test.js +152 -0
  118. package/dist/core/search-context.usecase.test.js.map +1 -0
  119. package/dist/core/summarize-meeting.usecase.d.ts +17 -0
  120. package/dist/core/summarize-meeting.usecase.d.ts.map +1 -0
  121. package/dist/core/summarize-meeting.usecase.js +126 -0
  122. package/dist/core/summarize-meeting.usecase.js.map +1 -0
  123. package/dist/errors/index.d.ts +41 -0
  124. package/dist/errors/index.d.ts.map +1 -0
  125. package/dist/errors/index.js +65 -0
  126. package/dist/errors/index.js.map +1 -0
  127. package/dist/input/audio.handler.d.ts +8 -0
  128. package/dist/input/audio.handler.d.ts.map +1 -0
  129. package/dist/input/audio.handler.js +20 -0
  130. package/dist/input/audio.handler.js.map +1 -0
  131. package/dist/input/file.handler.d.ts +5 -0
  132. package/dist/input/file.handler.d.ts.map +1 -0
  133. package/dist/input/file.handler.js +17 -0
  134. package/dist/input/file.handler.js.map +1 -0
  135. package/dist/input/image.handler.d.ts +8 -0
  136. package/dist/input/image.handler.d.ts.map +1 -0
  137. package/dist/input/image.handler.js +38 -0
  138. package/dist/input/image.handler.js.map +1 -0
  139. package/dist/input/index.d.ts +5 -0
  140. package/dist/input/index.d.ts.map +1 -0
  141. package/dist/input/index.js +5 -0
  142. package/dist/input/index.js.map +1 -0
  143. package/dist/input/meeting.handler.d.ts +3 -0
  144. package/dist/input/meeting.handler.d.ts.map +1 -0
  145. package/dist/input/meeting.handler.js +16 -0
  146. package/dist/input/meeting.handler.js.map +1 -0
  147. package/dist/input/text.handler.d.ts +5 -0
  148. package/dist/input/text.handler.d.ts.map +1 -0
  149. package/dist/input/text.handler.js +9 -0
  150. package/dist/input/text.handler.js.map +1 -0
  151. package/dist/repositories/context.repository.d.ts +48 -0
  152. package/dist/repositories/context.repository.d.ts.map +1 -0
  153. package/dist/repositories/context.repository.js +2 -0
  154. package/dist/repositories/context.repository.js.map +1 -0
  155. package/dist/repositories/index.d.ts +2 -0
  156. package/dist/repositories/index.d.ts.map +1 -0
  157. package/dist/repositories/index.js +2 -0
  158. package/dist/repositories/index.js.map +1 -0
  159. package/dist/storage/obsidian/context.obsidian.d.ts +36 -0
  160. package/dist/storage/obsidian/context.obsidian.d.ts.map +1 -0
  161. package/dist/storage/obsidian/context.obsidian.js +236 -0
  162. package/dist/storage/obsidian/context.obsidian.js.map +1 -0
  163. package/dist/storage/obsidian/frontmatter.d.ts +17 -0
  164. package/dist/storage/obsidian/frontmatter.d.ts.map +1 -0
  165. package/dist/storage/obsidian/frontmatter.js +48 -0
  166. package/dist/storage/obsidian/frontmatter.js.map +1 -0
  167. package/dist/storage/obsidian/index.d.ts +3 -0
  168. package/dist/storage/obsidian/index.d.ts.map +1 -0
  169. package/dist/storage/obsidian/index.js +3 -0
  170. package/dist/storage/obsidian/index.js.map +1 -0
  171. package/dist/tui/App.d.ts +17 -0
  172. package/dist/tui/App.d.ts.map +1 -0
  173. package/dist/tui/App.js +100 -0
  174. package/dist/tui/App.js.map +1 -0
  175. package/dist/tui/components/ContextCard.d.ts +15 -0
  176. package/dist/tui/components/ContextCard.d.ts.map +1 -0
  177. package/dist/tui/components/ContextCard.js +22 -0
  178. package/dist/tui/components/ContextCard.js.map +1 -0
  179. package/dist/tui/components/ErrorBanner.d.ts +6 -0
  180. package/dist/tui/components/ErrorBanner.d.ts.map +1 -0
  181. package/dist/tui/components/ErrorBanner.js +6 -0
  182. package/dist/tui/components/ErrorBanner.js.map +1 -0
  183. package/dist/tui/components/Header.d.ts +7 -0
  184. package/dist/tui/components/Header.d.ts.map +1 -0
  185. package/dist/tui/components/Header.js +6 -0
  186. package/dist/tui/components/Header.js.map +1 -0
  187. package/dist/tui/components/KeyHint.d.ts +11 -0
  188. package/dist/tui/components/KeyHint.d.ts.map +1 -0
  189. package/dist/tui/components/KeyHint.js +9 -0
  190. package/dist/tui/components/KeyHint.js.map +1 -0
  191. package/dist/tui/components/Menu.d.ts +11 -0
  192. package/dist/tui/components/Menu.d.ts.map +1 -0
  193. package/dist/tui/components/Menu.js +6 -0
  194. package/dist/tui/components/Menu.js.map +1 -0
  195. package/dist/tui/components/Spinner.d.ts +6 -0
  196. package/dist/tui/components/Spinner.d.ts.map +1 -0
  197. package/dist/tui/components/Spinner.js +7 -0
  198. package/dist/tui/components/Spinner.js.map +1 -0
  199. package/dist/tui/components/index.d.ts +7 -0
  200. package/dist/tui/components/index.d.ts.map +1 -0
  201. package/dist/tui/components/index.js +7 -0
  202. package/dist/tui/components/index.js.map +1 -0
  203. package/dist/tui/hooks/index.d.ts +4 -0
  204. package/dist/tui/hooks/index.d.ts.map +1 -0
  205. package/dist/tui/hooks/index.js +4 -0
  206. package/dist/tui/hooks/index.js.map +1 -0
  207. package/dist/tui/hooks/useAsyncAction.d.ts +18 -0
  208. package/dist/tui/hooks/useAsyncAction.d.ts.map +1 -0
  209. package/dist/tui/hooks/useAsyncAction.js +20 -0
  210. package/dist/tui/hooks/useAsyncAction.js.map +1 -0
  211. package/dist/tui/hooks/useNavigation.d.ts +15 -0
  212. package/dist/tui/hooks/useNavigation.d.ts.map +1 -0
  213. package/dist/tui/hooks/useNavigation.js +33 -0
  214. package/dist/tui/hooks/useNavigation.js.map +1 -0
  215. package/dist/tui/hooks/useServices.d.ts +3 -0
  216. package/dist/tui/hooks/useServices.d.ts.map +1 -0
  217. package/dist/tui/hooks/useServices.js +6 -0
  218. package/dist/tui/hooks/useServices.js.map +1 -0
  219. package/dist/tui/index.d.ts +2 -0
  220. package/dist/tui/index.d.ts.map +1 -0
  221. package/dist/tui/index.js +7 -0
  222. package/dist/tui/index.js.map +1 -0
  223. package/dist/tui/screens/AddScreen.d.ts +9 -0
  224. package/dist/tui/screens/AddScreen.d.ts.map +1 -0
  225. package/dist/tui/screens/AddScreen.js +165 -0
  226. package/dist/tui/screens/AddScreen.js.map +1 -0
  227. package/dist/tui/screens/ConfigScreen.d.ts +8 -0
  228. package/dist/tui/screens/ConfigScreen.d.ts.map +1 -0
  229. package/dist/tui/screens/ConfigScreen.js +102 -0
  230. package/dist/tui/screens/ConfigScreen.js.map +1 -0
  231. package/dist/tui/screens/DetailScreen.d.ts +11 -0
  232. package/dist/tui/screens/DetailScreen.d.ts.map +1 -0
  233. package/dist/tui/screens/DetailScreen.js +92 -0
  234. package/dist/tui/screens/DetailScreen.js.map +1 -0
  235. package/dist/tui/screens/ListScreen.d.ts +11 -0
  236. package/dist/tui/screens/ListScreen.d.ts.map +1 -0
  237. package/dist/tui/screens/ListScreen.js +198 -0
  238. package/dist/tui/screens/ListScreen.js.map +1 -0
  239. package/dist/tui/screens/MainMenu.d.ts +8 -0
  240. package/dist/tui/screens/MainMenu.d.ts.map +1 -0
  241. package/dist/tui/screens/MainMenu.js +26 -0
  242. package/dist/tui/screens/MainMenu.js.map +1 -0
  243. package/dist/tui/screens/SearchScreen.d.ts +11 -0
  244. package/dist/tui/screens/SearchScreen.d.ts.map +1 -0
  245. package/dist/tui/screens/SearchScreen.js +130 -0
  246. package/dist/tui/screens/SearchScreen.js.map +1 -0
  247. package/dist/tui/screens/index.d.ts +7 -0
  248. package/dist/tui/screens/index.d.ts.map +1 -0
  249. package/dist/tui/screens/index.js +7 -0
  250. package/dist/tui/screens/index.js.map +1 -0
  251. package/dist/types/config.types.d.ts +19 -0
  252. package/dist/types/config.types.d.ts.map +1 -0
  253. package/dist/types/config.types.js +8 -0
  254. package/dist/types/config.types.js.map +1 -0
  255. package/dist/types/context.schema.d.ts +81 -0
  256. package/dist/types/context.schema.d.ts.map +1 -0
  257. package/dist/types/context.schema.js +33 -0
  258. package/dist/types/context.schema.js.map +1 -0
  259. package/dist/types/context.types.d.ts +37 -0
  260. package/dist/types/context.types.d.ts.map +1 -0
  261. package/dist/types/context.types.js +5 -0
  262. package/dist/types/context.types.js.map +1 -0
  263. package/dist/types/index.d.ts +6 -0
  264. package/dist/types/index.d.ts.map +1 -0
  265. package/dist/types/index.js +6 -0
  266. package/dist/types/index.js.map +1 -0
  267. package/dist/types/meeting.schema.d.ts +195 -0
  268. package/dist/types/meeting.schema.d.ts.map +1 -0
  269. package/dist/types/meeting.schema.js +33 -0
  270. package/dist/types/meeting.schema.js.map +1 -0
  271. package/dist/types/meeting.types.d.ts +34 -0
  272. package/dist/types/meeting.types.d.ts.map +1 -0
  273. package/dist/types/meeting.types.js +2 -0
  274. package/dist/types/meeting.types.js.map +1 -0
  275. package/dist/types/prompt.types.d.ts +22 -0
  276. package/dist/types/prompt.types.d.ts.map +1 -0
  277. package/dist/types/prompt.types.js +9 -0
  278. package/dist/types/prompt.types.js.map +1 -0
  279. package/dist/types/tag.types.d.ts +9 -0
  280. package/dist/types/tag.types.d.ts.map +1 -0
  281. package/dist/types/tag.types.js +2 -0
  282. package/dist/types/tag.types.js.map +1 -0
  283. package/dist/utils/file-validator.d.ts +14 -0
  284. package/dist/utils/file-validator.d.ts.map +1 -0
  285. package/dist/utils/file-validator.js +35 -0
  286. package/dist/utils/file-validator.js.map +1 -0
  287. package/dist/utils/filter.d.ts +15 -0
  288. package/dist/utils/filter.d.ts.map +1 -0
  289. package/dist/utils/filter.js +40 -0
  290. package/dist/utils/filter.js.map +1 -0
  291. package/dist/utils/filter.test.d.ts +2 -0
  292. package/dist/utils/filter.test.d.ts.map +1 -0
  293. package/dist/utils/filter.test.js +90 -0
  294. package/dist/utils/filter.test.js.map +1 -0
  295. package/dist/utils/index.d.ts +9 -0
  296. package/dist/utils/index.d.ts.map +1 -0
  297. package/dist/utils/index.js +9 -0
  298. package/dist/utils/index.js.map +1 -0
  299. package/dist/utils/json-parser.d.ts +25 -0
  300. package/dist/utils/json-parser.d.ts.map +1 -0
  301. package/dist/utils/json-parser.js +70 -0
  302. package/dist/utils/json-parser.js.map +1 -0
  303. package/dist/utils/json-parser.test.d.ts +2 -0
  304. package/dist/utils/json-parser.test.d.ts.map +1 -0
  305. package/dist/utils/json-parser.test.js +102 -0
  306. package/dist/utils/json-parser.test.js.map +1 -0
  307. package/dist/utils/math.d.ts +8 -0
  308. package/dist/utils/math.d.ts.map +1 -0
  309. package/dist/utils/math.js +22 -0
  310. package/dist/utils/math.js.map +1 -0
  311. package/dist/utils/related-links.d.ts +13 -0
  312. package/dist/utils/related-links.d.ts.map +1 -0
  313. package/dist/utils/related-links.js +28 -0
  314. package/dist/utils/related-links.js.map +1 -0
  315. package/package.json +78 -0
@@ -0,0 +1,9 @@
1
+ export class TextHandler {
2
+ handle(text) {
3
+ return {
4
+ type: "text",
5
+ content: text.trim(),
6
+ };
7
+ }
8
+ }
9
+ //# sourceMappingURL=text.handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.handler.js","sourceRoot":"","sources":["../../src/input/text.handler.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,WAAW;IACtB,MAAM,CAAC,IAAY;QACjB,OAAO;YACL,IAAI,EAAE,MAAM;YACZ,OAAO,EAAE,IAAI,CAAC,IAAI,EAAE;SACrB,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,48 @@
1
+ import type { Context, ListOptions, ContextWithSimilarity } from "../types/context.types.js";
2
+ /**
3
+ * Context Repository Interface
4
+ * Infrastructure Layer에서 구현체 제공
5
+ */
6
+ export interface ContextRepository {
7
+ /**
8
+ * Context를 저장하고 ID를 반환합니다.
9
+ */
10
+ save(context: Context): Promise<string>;
11
+ /**
12
+ * ID로 Context를 조회합니다.
13
+ */
14
+ findById(id: string): Promise<Context | null>;
15
+ /**
16
+ * 태그로 Context를 조회합니다.
17
+ */
18
+ findByTags(tags: string[]): Promise<Context[]>;
19
+ /**
20
+ * 임베딩 유사도로 Context를 검색합니다.
21
+ */
22
+ findSimilar(embedding: number[], limit?: number): Promise<ContextWithSimilarity[]>;
23
+ /**
24
+ * 모든 Context를 조회합니다.
25
+ */
26
+ findAll(options?: ListOptions): Promise<Context[]>;
27
+ /**
28
+ * Context를 삭제합니다.
29
+ */
30
+ delete(id: string): Promise<void>;
31
+ /**
32
+ * Context의 태그를 업데이트합니다.
33
+ */
34
+ updateTags(id: string, tags: string[]): Promise<void>;
35
+ /**
36
+ * Context의 임베딩을 업데이트합니다.
37
+ */
38
+ updateEmbedding(id: string, embedding: number[]): Promise<void>;
39
+ /**
40
+ * ID로 파일명을 조회합니다 (Obsidian 링크용).
41
+ */
42
+ getFileNameById(id: string): Promise<string | null>;
43
+ /**
44
+ * 관련 문서 링크를 추가합니다.
45
+ */
46
+ appendRelatedLinks(id: string, relatedIds: string[]): Promise<void>;
47
+ }
48
+ //# sourceMappingURL=context.repository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.repository.d.ts","sourceRoot":"","sources":["../../src/repositories/context.repository.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAE7F;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC;;OAEG;IACH,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAExC;;OAEG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IAE9C;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAE/C;;OAEG;IACH,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,EAAE,CAAC,CAAC;IAEnF;;OAEG;IACH,OAAO,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAEnD;;OAEG;IACH,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAElC;;OAEG;IACH,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtD;;OAEG;IACH,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhE;;OAEG;IACH,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAEpD;;OAEG;IACH,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACrE"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=context.repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.repository.js","sourceRoot":"","sources":["../../src/repositories/context.repository.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export type { ContextRepository } from "./context.repository.js";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/repositories/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/repositories/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,36 @@
1
+ import type { ContextRepository } from "../../repositories/context.repository.js";
2
+ import type { Context, ListOptions, ContextWithSimilarity } from "../../types/context.types.js";
3
+ export declare class ObsidianContextRepository implements ContextRepository {
4
+ private readonly basePath;
5
+ constructor(basePath: string);
6
+ private ensureDir;
7
+ /**
8
+ * 파일명 생성: {short-title}_{short-id}.md
9
+ * 예: PG연동-완료_a64cbac7.md
10
+ */
11
+ private generateFileName;
12
+ /**
13
+ * 요약에서 짧은 제목 추출 (15자 제한)
14
+ */
15
+ private extractShortTitle;
16
+ private getFilePath;
17
+ save(context: Context): Promise<string>;
18
+ findById(id: string): Promise<Context | null>;
19
+ private findByIdFromAll;
20
+ findByTags(tags: string[]): Promise<Context[]>;
21
+ findSimilar(embedding: number[], limit?: number): Promise<ContextWithSimilarity[]>;
22
+ findAll(options?: ListOptions): Promise<Context[]>;
23
+ delete(id: string): Promise<void>;
24
+ updateTags(id: string, tags: string[]): Promise<void>;
25
+ updateEmbedding(id: string, embedding: number[]): Promise<void>;
26
+ private findFilePathById;
27
+ /**
28
+ * ID로 파일명 조회 (확장자 제외, Obsidian 링크용)
29
+ */
30
+ getFileNameById(id: string): Promise<string | null>;
31
+ /**
32
+ * 관련 문서 섹션 추가
33
+ */
34
+ appendRelatedLinks(id: string, relatedIds: string[]): Promise<void>;
35
+ }
36
+ //# sourceMappingURL=context.obsidian.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.obsidian.d.ts","sourceRoot":"","sources":["../../../src/storage/obsidian/context.obsidian.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAC;AAClF,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAKhG,qBAAa,yBAA0B,YAAW,iBAAiB;IACrD,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,MAAM;YAE/B,SAAS;IAMvB;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAMxB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAkBzB,OAAO,CAAC,WAAW;IAUb,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IASvC,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;YAerC,eAAe;IA6BvB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAO9C,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,KAAK,SAAK,GAAG,OAAO,CAAC,qBAAqB,EAAE,CAAC;IAa9E,OAAO,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IA6BlD,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBjC,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBrD,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;YAUvD,gBAAgB;IAoB9B;;OAEG;IACG,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAOzD;;OAEG;IACG,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CA2B1E"}
@@ -0,0 +1,236 @@
1
+ import { readFile, writeFile, readdir, unlink, mkdir } from "fs/promises";
2
+ import { existsSync } from "fs";
3
+ import { join } from "path";
4
+ import { contextToMarkdown, markdownToContext, updateFrontmatter } from "./frontmatter.js";
5
+ import { applyFilters, cosineSimilarity } from "../../utils/index.js";
6
+ import { NotFoundError } from "../../errors/index.js";
7
+ export class ObsidianContextRepository {
8
+ basePath;
9
+ constructor(basePath) {
10
+ this.basePath = basePath;
11
+ }
12
+ async ensureDir() {
13
+ if (!existsSync(this.basePath)) {
14
+ await mkdir(this.basePath, { recursive: true });
15
+ }
16
+ }
17
+ /**
18
+ * 파일명 생성: {short-title}_{short-id}.md
19
+ * 예: PG연동-완료_a64cbac7.md
20
+ */
21
+ generateFileName(context) {
22
+ const shortId = context.id.slice(0, 8);
23
+ const title = this.extractShortTitle(context.summary);
24
+ return `${title}_${shortId}.md`;
25
+ }
26
+ /**
27
+ * 요약에서 짧은 제목 추출 (15자 제한)
28
+ */
29
+ extractShortTitle(summary) {
30
+ // 불필요한 조사/어미 제거하고 핵심만
31
+ const cleaned = summary
32
+ .replace(/했습니다|합니다|입니다|됩니다|있습니다/g, "")
33
+ .replace(/[을를이가은는의에서로](?=\s|$)/g, "")
34
+ .replace(/[<>:"/\\|?*.,!?]/g, "")
35
+ .replace(/\s+/g, "-")
36
+ .replace(/-+/g, "-")
37
+ .replace(/^-|-$/g, "");
38
+ // 15자 제한, 단어 중간에서 자르지 않기
39
+ if (cleaned.length <= 15)
40
+ return cleaned;
41
+ const truncated = cleaned.slice(0, 15);
42
+ const lastDash = truncated.lastIndexOf("-");
43
+ return lastDash > 5 ? truncated.slice(0, lastDash) : truncated;
44
+ }
45
+ getFilePath(id, summary) {
46
+ if (summary) {
47
+ const shortId = id.slice(0, 8);
48
+ const title = this.extractShortTitle(summary);
49
+ return join(this.basePath, `${title}_${shortId}.md`);
50
+ }
51
+ // fallback: UUID 파일명 (구버전 호환)
52
+ return join(this.basePath, `${id}.md`);
53
+ }
54
+ async save(context) {
55
+ await this.ensureDir();
56
+ const fileName = this.generateFileName(context);
57
+ const filePath = join(this.basePath, fileName);
58
+ const markdown = contextToMarkdown(context);
59
+ await writeFile(filePath, markdown, "utf-8");
60
+ return context.id;
61
+ }
62
+ async findById(id) {
63
+ // 1. 먼저 전체 파일 스캔해서 frontmatter id로 찾기
64
+ const context = await this.findByIdFromAll(id);
65
+ if (context)
66
+ return context;
67
+ // 2. fallback: 구버전 UUID 파일명
68
+ const legacyPath = join(this.basePath, `${id}.md`);
69
+ if (existsSync(legacyPath)) {
70
+ const markdown = await readFile(legacyPath, "utf-8");
71
+ return markdownToContext(markdown);
72
+ }
73
+ return null;
74
+ }
75
+ async findByIdFromAll(id) {
76
+ await this.ensureDir();
77
+ const files = await readdir(this.basePath);
78
+ const shortId = id.slice(0, 8);
79
+ // short ID가 포함된 파일 먼저 찾기 (빠른 경로)
80
+ const matchingFile = files.find(f => f.includes(shortId) && f.endsWith(".md"));
81
+ if (matchingFile) {
82
+ const filePath = join(this.basePath, matchingFile);
83
+ const markdown = await readFile(filePath, "utf-8");
84
+ const ctx = markdownToContext(markdown);
85
+ if (ctx.id === id)
86
+ return ctx;
87
+ }
88
+ // 전체 스캔 (fallback)
89
+ for (const file of files.filter(f => f.endsWith(".md"))) {
90
+ const filePath = join(this.basePath, file);
91
+ const markdown = await readFile(filePath, "utf-8");
92
+ try {
93
+ const ctx = markdownToContext(markdown);
94
+ if (ctx.id === id)
95
+ return ctx;
96
+ }
97
+ catch {
98
+ // Skip invalid files
99
+ }
100
+ }
101
+ return null;
102
+ }
103
+ async findByTags(tags) {
104
+ const all = await this.findAll();
105
+ return all.filter((ctx) => tags.some((tag) => ctx.tags.includes(tag)));
106
+ }
107
+ async findSimilar(embedding, limit = 10) {
108
+ const all = await this.findAll();
109
+ const withSimilarity = all
110
+ .filter((ctx) => ctx.embedding && ctx.embedding.length > 0)
111
+ .map((ctx) => ({
112
+ ...ctx,
113
+ similarity: cosineSimilarity(embedding, ctx.embedding),
114
+ }))
115
+ .sort((a, b) => b.similarity - a.similarity)
116
+ .slice(0, limit);
117
+ return withSimilarity;
118
+ }
119
+ async findAll(options) {
120
+ await this.ensureDir();
121
+ const files = await readdir(this.basePath);
122
+ const mdFiles = files.filter((f) => f.endsWith(".md"));
123
+ let contexts = [];
124
+ for (const file of mdFiles) {
125
+ const filePath = join(this.basePath, file);
126
+ const markdown = await readFile(filePath, "utf-8");
127
+ try {
128
+ const ctx = markdownToContext(markdown);
129
+ contexts.push(ctx);
130
+ }
131
+ catch {
132
+ // Skip invalid files
133
+ }
134
+ }
135
+ // Apply filters using utility
136
+ contexts = applyFilters(contexts, options);
137
+ // Sort by createdAt descending
138
+ contexts.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
139
+ // Apply pagination
140
+ const offset = options?.offset ?? 0;
141
+ const limit = options?.limit ?? contexts.length;
142
+ return contexts.slice(offset, offset + limit);
143
+ }
144
+ async delete(id) {
145
+ // ID로 파일 찾기
146
+ const context = await this.findById(id);
147
+ if (!context)
148
+ return;
149
+ // 새 파일명 형식
150
+ const newPath = this.getFilePath(id, context.summary);
151
+ if (existsSync(newPath)) {
152
+ await unlink(newPath);
153
+ return;
154
+ }
155
+ // 구버전 UUID 파일명
156
+ const legacyPath = join(this.basePath, `${id}.md`);
157
+ if (existsSync(legacyPath)) {
158
+ await unlink(legacyPath);
159
+ }
160
+ }
161
+ async updateTags(id, tags) {
162
+ const context = await this.findById(id);
163
+ if (!context) {
164
+ throw new NotFoundError("Context", id);
165
+ }
166
+ const filePath = await this.findFilePathById(id);
167
+ if (!filePath) {
168
+ throw new NotFoundError("Context file", id);
169
+ }
170
+ const markdown = await readFile(filePath, "utf-8");
171
+ const updated = updateFrontmatter(markdown, { tags });
172
+ await writeFile(filePath, updated, "utf-8");
173
+ }
174
+ async updateEmbedding(id, embedding) {
175
+ const filePath = await this.findFilePathById(id);
176
+ if (!filePath) {
177
+ throw new NotFoundError("Context", id);
178
+ }
179
+ const markdown = await readFile(filePath, "utf-8");
180
+ const updated = updateFrontmatter(markdown, { embedding });
181
+ await writeFile(filePath, updated, "utf-8");
182
+ }
183
+ async findFilePathById(id) {
184
+ await this.ensureDir();
185
+ const files = await readdir(this.basePath);
186
+ const shortId = id.slice(0, 8);
187
+ // short ID로 빠른 검색
188
+ const matchingFile = files.find(f => f.includes(shortId) && f.endsWith(".md"));
189
+ if (matchingFile) {
190
+ return join(this.basePath, matchingFile);
191
+ }
192
+ // 구버전 UUID 파일명
193
+ const legacyPath = join(this.basePath, `${id}.md`);
194
+ if (existsSync(legacyPath)) {
195
+ return legacyPath;
196
+ }
197
+ return null;
198
+ }
199
+ /**
200
+ * ID로 파일명 조회 (확장자 제외, Obsidian 링크용)
201
+ */
202
+ async getFileNameById(id) {
203
+ const filePath = await this.findFilePathById(id);
204
+ if (!filePath)
205
+ return null;
206
+ const fileName = filePath.split("/").pop();
207
+ return fileName ? fileName.replace(/\.md$/, "") : null;
208
+ }
209
+ /**
210
+ * 관련 문서 섹션 추가
211
+ */
212
+ async appendRelatedLinks(id, relatedIds) {
213
+ const filePath = await this.findFilePathById(id);
214
+ if (!filePath)
215
+ return;
216
+ // 관련 문서 파일명 조회
217
+ const links = [];
218
+ for (const relatedId of relatedIds) {
219
+ const fileName = await this.getFileNameById(relatedId);
220
+ if (fileName) {
221
+ links.push(`- [[${fileName}]]`);
222
+ }
223
+ }
224
+ if (links.length === 0)
225
+ return;
226
+ // 파일에 관련 문서 섹션 추가
227
+ let content = await readFile(filePath, "utf-8");
228
+ // 기존 관련 문서 섹션 제거 (있으면)
229
+ content = content.replace(/\n## 관련 문서\n[\s\S]*$/, "");
230
+ // 새 섹션 추가
231
+ const relatedSection = `\n## 관련 문서\n${links.join("\n")}\n`;
232
+ content = content.trimEnd() + "\n" + relatedSection;
233
+ await writeFile(filePath, content, "utf-8");
234
+ }
235
+ }
236
+ //# sourceMappingURL=context.obsidian.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.obsidian.js","sourceRoot":"","sources":["../../../src/storage/obsidian/context.obsidian.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { Context } from "../../types/context.types.js";
2
+ export interface Frontmatter {
3
+ id: string;
4
+ type: string;
5
+ summary: string;
6
+ tags: string[];
7
+ embedding?: number[];
8
+ source?: string;
9
+ project?: string;
10
+ sprint?: string;
11
+ createdAt: string;
12
+ updatedAt: string;
13
+ }
14
+ export declare function contextToMarkdown(context: Context): string;
15
+ export declare function markdownToContext(markdown: string): Context;
16
+ export declare function updateFrontmatter(markdown: string, updates: Partial<Frontmatter>): string;
17
+ //# sourceMappingURL=frontmatter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontmatter.d.ts","sourceRoot":"","sources":["../../../src/storage/obsidian/frontmatter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,8BAA8B,CAAC;AAE5D,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAyB1D;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAiB3D;AAED,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,GAC5B,MAAM,CAIR"}
@@ -0,0 +1,48 @@
1
+ import matter from "gray-matter";
2
+ export function contextToMarkdown(context) {
3
+ const frontmatter = {
4
+ id: context.id,
5
+ type: context.type,
6
+ summary: context.summary,
7
+ tags: context.tags,
8
+ createdAt: context.createdAt.toISOString(),
9
+ updatedAt: context.updatedAt.toISOString(),
10
+ };
11
+ // undefined 값은 제외
12
+ if (context.source) {
13
+ frontmatter.source = context.source;
14
+ }
15
+ if (context.embedding && context.embedding.length > 0) {
16
+ frontmatter.embedding = context.embedding;
17
+ }
18
+ if (context.project) {
19
+ frontmatter.project = context.project;
20
+ }
21
+ if (context.sprint) {
22
+ frontmatter.sprint = context.sprint;
23
+ }
24
+ return matter.stringify(context.content, frontmatter);
25
+ }
26
+ export function markdownToContext(markdown) {
27
+ const { data, content } = matter(markdown);
28
+ const fm = data;
29
+ return {
30
+ id: fm.id,
31
+ type: fm.type,
32
+ content: content.trim(),
33
+ summary: fm.summary,
34
+ tags: fm.tags || [],
35
+ embedding: fm.embedding,
36
+ source: fm.source,
37
+ project: fm.project,
38
+ sprint: fm.sprint,
39
+ createdAt: new Date(fm.createdAt),
40
+ updatedAt: new Date(fm.updatedAt),
41
+ };
42
+ }
43
+ export function updateFrontmatter(markdown, updates) {
44
+ const { data, content } = matter(markdown);
45
+ const updatedData = { ...data, ...updates, updatedAt: new Date().toISOString() };
46
+ return matter.stringify(content, updatedData);
47
+ }
48
+ //# sourceMappingURL=frontmatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontmatter.js","sourceRoot":"","sources":["../../../src/storage/obsidian/frontmatter.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AAgBjC,MAAM,UAAU,iBAAiB,CAAC,OAAgB;IAChD,MAAM,WAAW,GAA4B;QAC3C,EAAE,EAAE,OAAO,CAAC,EAAE;QACd,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,SAAS,EAAE,OAAO,CAAC,SAAS,CAAC,WAAW,EAAE;QAC1C,SAAS,EAAE,OAAO,CAAC,SAAS,CAAC,WAAW,EAAE;KAC3C,CAAC;IAEF,kBAAkB;IAClB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,WAAW,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IACtC,CAAC;IACD,IAAI,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtD,WAAW,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;IAC5C,CAAC;IACD,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,WAAW,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IACxC,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,WAAW,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IACtC,CAAC;IAED,OAAO,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;AACxD,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,QAAgB;IAChD,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC3C,MAAM,EAAE,GAAG,IAAmB,CAAC;IAE/B,OAAO;QACL,EAAE,EAAE,EAAE,CAAC,EAAE;QACT,IAAI,EAAE,EAAE,CAAC,IAAuB;QAChC,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE;QACvB,OAAO,EAAE,EAAE,CAAC,OAAO;QACnB,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,EAAE;QACnB,SAAS,EAAE,EAAE,CAAC,SAAS;QACvB,MAAM,EAAE,EAAE,CAAC,MAAM;QACjB,OAAO,EAAE,EAAE,CAAC,OAAO;QACnB,MAAM,EAAE,EAAE,CAAC,MAAM;QACjB,SAAS,EAAE,IAAI,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC;QACjC,SAAS,EAAE,IAAI,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC;KAClC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,QAAgB,EAChB,OAA6B;IAE7B,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC3C,MAAM,WAAW,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,OAAO,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;IACjF,OAAO,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;AAChD,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { ObsidianContextRepository } from "./context.obsidian.js";
2
+ export { contextToMarkdown, markdownToContext, updateFrontmatter } from "./frontmatter.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/storage/obsidian/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { ObsidianContextRepository } from "./context.obsidian.js";
2
+ export { contextToMarkdown, markdownToContext, updateFrontmatter } from "./frontmatter.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/storage/obsidian/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,17 @@
1
+ export type Screen = "main" | "add" | "search" | "list" | "detail" | "config";
2
+ export interface NavigationState {
3
+ screen: Screen;
4
+ params?: {
5
+ contextId?: string;
6
+ query?: string;
7
+ };
8
+ history: Screen[];
9
+ }
10
+ export interface NavigationContext {
11
+ navigate: (screen: Screen, params?: NavigationState["params"]) => void;
12
+ goBack: () => void;
13
+ currentScreen: Screen;
14
+ params?: NavigationState["params"];
15
+ }
16
+ export declare function App(): import("react/jsx-runtime").JSX.Element;
17
+ //# sourceMappingURL=App.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/tui/App.tsx"],"names":[],"mappings":"AAaA,MAAM,MAAM,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE9E,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE;QACP,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,eAAe,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC;IACvE,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,eAAe,CAAC,QAAQ,CAAC,CAAC;CACpC;AAED,wBAAgB,GAAG,4CA+IlB"}
@@ -0,0 +1,100 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState, useCallback, useMemo } from "react";
3
+ import { Box, Text, useApp, useInput } from "ink";
4
+ import { createServices } from "../core/factories.js";
5
+ import { MainMenu } from "./screens/MainMenu.js";
6
+ import { AddScreen } from "./screens/AddScreen.js";
7
+ import { SearchScreen } from "./screens/SearchScreen.js";
8
+ import { ListScreen } from "./screens/ListScreen.js";
9
+ import { DetailScreen } from "./screens/DetailScreen.js";
10
+ import { ConfigScreen } from "./screens/ConfigScreen.js";
11
+ import { Header, KeyHintBar } from "./components/index.js";
12
+ export function App() {
13
+ const { exit } = useApp();
14
+ const [navigation, setNavigation] = useState({
15
+ screen: "main",
16
+ history: [],
17
+ });
18
+ const [selectedContext, setSelectedContext] = useState(null);
19
+ const [configVersion, setConfigVersion] = useState(0);
20
+ // Services initialization (re-runs when configVersion changes)
21
+ const { services, initError } = useMemo(() => {
22
+ try {
23
+ return { services: createServices(), initError: null };
24
+ }
25
+ catch (err) {
26
+ const message = err instanceof Error ? err.message : "Failed to initialize services";
27
+ return { services: null, initError: message };
28
+ }
29
+ }, [configVersion]);
30
+ // Re-initialize services when config changes
31
+ const handleConfigured = useCallback(() => {
32
+ setConfigVersion((v) => v + 1);
33
+ setNavigation({ screen: "main", history: [] });
34
+ }, []);
35
+ const navigate = useCallback((screen, params) => {
36
+ setNavigation((prev) => ({
37
+ screen,
38
+ params,
39
+ history: [...prev.history, prev.screen],
40
+ }));
41
+ }, []);
42
+ const goBack = useCallback(() => {
43
+ setNavigation((prev) => {
44
+ const history = [...prev.history];
45
+ const previousScreen = history.pop() || "main";
46
+ return {
47
+ screen: previousScreen,
48
+ history,
49
+ params: undefined,
50
+ };
51
+ });
52
+ }, []);
53
+ // Global keyboard shortcuts
54
+ useInput((input, key) => {
55
+ // q = quit (only on main screen)
56
+ if (input === "q" && navigation.screen === "main") {
57
+ exit();
58
+ }
59
+ // Esc = go back
60
+ if (key.escape && navigation.screen !== "main") {
61
+ goBack();
62
+ }
63
+ });
64
+ const handleSelectContext = useCallback((context) => {
65
+ setSelectedContext(context);
66
+ navigate("detail", { contextId: context.id });
67
+ }, [navigate]);
68
+ const navigationContext = {
69
+ navigate,
70
+ goBack,
71
+ currentScreen: navigation.screen,
72
+ params: navigation.params,
73
+ };
74
+ const renderScreen = () => {
75
+ // Config screen is always accessible
76
+ if (navigation.screen === "config") {
77
+ return (_jsx(ConfigScreen, { navigation: navigationContext, onConfigured: handleConfigured }));
78
+ }
79
+ // Show config error for screens that require services
80
+ if (!services && navigation.screen !== "main") {
81
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Header, { title: "Configuration Error" }), _jsxs(Box, { flexDirection: "column", gap: 1, children: [_jsx(Text, { color: "red", bold: true, children: "Services not initialized" }), _jsx(Text, { children: initError || "API keys may not be configured." }), _jsx(Box, { marginTop: 1, flexDirection: "column", children: _jsx(Text, { bold: true, children: "Select \"Config\" from main menu to set API keys" }) })] }), _jsx(KeyHintBar, { bindings: [{ key: "Esc", description: "Back" }] })] }));
82
+ }
83
+ switch (navigation.screen) {
84
+ case "main":
85
+ return _jsx(MainMenu, { navigation: navigationContext, onExit: exit });
86
+ case "add":
87
+ return _jsx(AddScreen, { navigation: navigationContext, services: services });
88
+ case "search":
89
+ return (_jsx(SearchScreen, { navigation: navigationContext, services: services, onSelectContext: handleSelectContext }));
90
+ case "list":
91
+ return (_jsx(ListScreen, { navigation: navigationContext, services: services, onSelectContext: handleSelectContext }));
92
+ case "detail":
93
+ return (_jsx(DetailScreen, { navigation: navigationContext, services: services, context: selectedContext }));
94
+ default:
95
+ return _jsx(MainMenu, { navigation: navigationContext, onExit: exit });
96
+ }
97
+ };
98
+ return _jsx(Box, { flexDirection: "column", children: renderScreen() });
99
+ }
100
+ //# sourceMappingURL=App.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"App.js","sourceRoot":"","sources":["../../src/tui/App.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { Context, ContextWithSimilarity } from "../../types/context.types.js";
2
+ interface ContextCardProps {
3
+ context: Context | ContextWithSimilarity;
4
+ selected?: boolean;
5
+ showSimilarity?: boolean;
6
+ }
7
+ export declare function ContextCard({ context, selected, showSimilarity }: ContextCardProps): import("react/jsx-runtime").JSX.Element;
8
+ interface ContextListProps {
9
+ contexts: (Context | ContextWithSimilarity)[];
10
+ selectedIndex: number;
11
+ showSimilarity?: boolean;
12
+ }
13
+ export declare function ContextList({ contexts, selectedIndex, showSimilarity }: ContextListProps): import("react/jsx-runtime").JSX.Element;
14
+ export {};
15
+ //# sourceMappingURL=ContextCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ContextCard.d.ts","sourceRoot":"","sources":["../../../src/tui/components/ContextCard.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAEnF,UAAU,gBAAgB;IACxB,OAAO,EAAE,OAAO,GAAG,qBAAqB,CAAC;IACzC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAeD,wBAAgB,WAAW,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,EAAE,gBAAgB,2CA4BlF;AAED,UAAU,gBAAgB;IACxB,QAAQ,EAAE,CAAC,OAAO,GAAG,qBAAqB,CAAC,EAAE,CAAC;IAC9C,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,wBAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,aAAa,EAAE,cAAc,EAAE,EAAE,gBAAgB,2CAaxF"}