vault-forge 2.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 (224) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +336 -0
  3. package/dist/actions/dummy.d.ts +2 -0
  4. package/dist/actions/dummy.d.ts.map +1 -0
  5. package/dist/actions/dummy.js +3 -0
  6. package/dist/actions/dummy.js.map +1 -0
  7. package/dist/actions/mainAction.d.ts +5 -0
  8. package/dist/actions/mainAction.d.ts.map +1 -0
  9. package/dist/actions/mainAction.js +68 -0
  10. package/dist/actions/mainAction.js.map +1 -0
  11. package/dist/commands/ai.d.ts +3 -0
  12. package/dist/commands/ai.d.ts.map +1 -0
  13. package/dist/commands/ai.js +20 -0
  14. package/dist/commands/ai.js.map +1 -0
  15. package/dist/commands/ask.d.ts +3 -0
  16. package/dist/commands/ask.d.ts.map +1 -0
  17. package/dist/commands/ask.js +15 -0
  18. package/dist/commands/ask.js.map +1 -0
  19. package/dist/commands/completion.d.ts +34 -0
  20. package/dist/commands/completion.d.ts.map +1 -0
  21. package/dist/commands/completion.js +134 -0
  22. package/dist/commands/completion.js.map +1 -0
  23. package/dist/commands/diary.d.ts +3 -0
  24. package/dist/commands/diary.d.ts.map +1 -0
  25. package/dist/commands/diary.js +15 -0
  26. package/dist/commands/diary.js.map +1 -0
  27. package/dist/commands/dummy.d.ts +2 -0
  28. package/dist/commands/dummy.d.ts.map +1 -0
  29. package/dist/commands/dummy.js +3 -0
  30. package/dist/commands/dummy.js.map +1 -0
  31. package/dist/commands/find.d.ts +2 -0
  32. package/dist/commands/find.d.ts.map +1 -0
  33. package/dist/commands/find.js +3 -0
  34. package/dist/commands/find.js.map +1 -0
  35. package/dist/commands/init.d.ts +3 -0
  36. package/dist/commands/init.d.ts.map +1 -0
  37. package/dist/commands/init.js +46 -0
  38. package/dist/commands/init.js.map +1 -0
  39. package/dist/commands/search.d.ts +3 -0
  40. package/dist/commands/search.d.ts.map +1 -0
  41. package/dist/commands/search.js +29 -0
  42. package/dist/commands/search.js.map +1 -0
  43. package/dist/commands/tag.d.ts +3 -0
  44. package/dist/commands/tag.d.ts.map +1 -0
  45. package/dist/commands/tag.js +37 -0
  46. package/dist/commands/tag.js.map +1 -0
  47. package/dist/config/locales/en.d.ts +188 -0
  48. package/dist/config/locales/en.d.ts.map +1 -0
  49. package/dist/config/locales/en.js +190 -0
  50. package/dist/config/locales/en.js.map +1 -0
  51. package/dist/config/locales/ja.d.ts +188 -0
  52. package/dist/config/locales/ja.d.ts.map +1 -0
  53. package/dist/config/locales/ja.js +190 -0
  54. package/dist/config/locales/ja.js.map +1 -0
  55. package/dist/config/prompts/en.d.ts +6 -0
  56. package/dist/config/prompts/en.d.ts.map +1 -0
  57. package/dist/config/prompts/en.js +25 -0
  58. package/dist/config/prompts/en.js.map +1 -0
  59. package/dist/config/prompts/ja.d.ts +6 -0
  60. package/dist/config/prompts/ja.d.ts.map +1 -0
  61. package/dist/config/prompts/ja.js +25 -0
  62. package/dist/config/prompts/ja.js.map +1 -0
  63. package/dist/config/text.d.ts +195 -0
  64. package/dist/config/text.d.ts.map +1 -0
  65. package/dist/config/text.js +15 -0
  66. package/dist/config/text.js.map +1 -0
  67. package/dist/core/PromptLoader.d.ts +30 -0
  68. package/dist/core/PromptLoader.d.ts.map +1 -0
  69. package/dist/core/PromptLoader.js +187 -0
  70. package/dist/core/PromptLoader.js.map +1 -0
  71. package/dist/core/PromptSmith.d.ts +21 -0
  72. package/dist/core/PromptSmith.d.ts.map +1 -0
  73. package/dist/core/PromptSmith.js +197 -0
  74. package/dist/core/PromptSmith.js.map +1 -0
  75. package/dist/core/VaultForge.d.ts +17 -0
  76. package/dist/core/VaultForge.d.ts.map +1 -0
  77. package/dist/core/VaultForge.js +75 -0
  78. package/dist/core/VaultForge.js.map +1 -0
  79. package/dist/index.d.ts +3 -0
  80. package/dist/index.d.ts.map +1 -0
  81. package/dist/index.js +28 -0
  82. package/dist/index.js.map +1 -0
  83. package/dist/lib/completion.d.ts +8 -0
  84. package/dist/lib/completion.d.ts.map +1 -0
  85. package/dist/lib/completion.js +55 -0
  86. package/dist/lib/completion.js.map +1 -0
  87. package/dist/lib/dummy.d.ts +2 -0
  88. package/dist/lib/dummy.d.ts.map +1 -0
  89. package/dist/lib/dummy.js +3 -0
  90. package/dist/lib/dummy.js.map +1 -0
  91. package/dist/lib/mainAction.d.ts +8 -0
  92. package/dist/lib/mainAction.d.ts.map +1 -0
  93. package/dist/lib/mainAction.js +126 -0
  94. package/dist/lib/mainAction.js.map +1 -0
  95. package/dist/lib/search.d.ts +4 -0
  96. package/dist/lib/search.d.ts.map +1 -0
  97. package/dist/lib/search.js +87 -0
  98. package/dist/lib/search.js.map +1 -0
  99. package/dist/lib/stdin.d.ts +10 -0
  100. package/dist/lib/stdin.d.ts.map +1 -0
  101. package/dist/lib/stdin.js +20 -0
  102. package/dist/lib/stdin.js.map +1 -0
  103. package/dist/services/AIModelService.d.ts +33 -0
  104. package/dist/services/AIModelService.d.ts.map +1 -0
  105. package/dist/services/AIModelService.js +116 -0
  106. package/dist/services/AIModelService.js.map +1 -0
  107. package/dist/services/AIOrchestratorService.d.ts +57 -0
  108. package/dist/services/AIOrchestratorService.d.ts.map +1 -0
  109. package/dist/services/AIOrchestratorService.js +164 -0
  110. package/dist/services/AIOrchestratorService.js.map +1 -0
  111. package/dist/services/ConfigService.d.ts +61 -0
  112. package/dist/services/ConfigService.d.ts.map +1 -0
  113. package/dist/services/ConfigService.js +132 -0
  114. package/dist/services/ConfigService.js.map +1 -0
  115. package/dist/services/ObsidianService.d.ts +97 -0
  116. package/dist/services/ObsidianService.d.ts.map +1 -0
  117. package/dist/services/ObsidianService.js +264 -0
  118. package/dist/services/ObsidianService.js.map +1 -0
  119. package/dist/services/TagService.d.ts +26 -0
  120. package/dist/services/TagService.d.ts.map +1 -0
  121. package/dist/services/TagService.js +73 -0
  122. package/dist/services/TagService.js.map +1 -0
  123. package/dist/services/UserInteraction.d.ts +100 -0
  124. package/dist/services/UserInteraction.d.ts.map +1 -0
  125. package/dist/services/UserInteraction.js +169 -0
  126. package/dist/services/UserInteraction.js.map +1 -0
  127. package/dist/services/XService.d.ts +15 -0
  128. package/dist/services/XService.d.ts.map +1 -0
  129. package/dist/services/XService.js +40 -0
  130. package/dist/services/XService.js.map +1 -0
  131. package/dist/services/ai/AIServiceFactory.d.ts +26 -0
  132. package/dist/services/ai/AIServiceFactory.d.ts.map +1 -0
  133. package/dist/services/ai/AIServiceFactory.js +69 -0
  134. package/dist/services/ai/AIServiceFactory.js.map +1 -0
  135. package/dist/services/ai/ClaudeService.d.ts +9 -0
  136. package/dist/services/ai/ClaudeService.d.ts.map +1 -0
  137. package/dist/services/ai/ClaudeService.js +59 -0
  138. package/dist/services/ai/ClaudeService.js.map +1 -0
  139. package/dist/services/ai/GeminiService.d.ts +9 -0
  140. package/dist/services/ai/GeminiService.d.ts.map +1 -0
  141. package/dist/services/ai/GeminiService.js +46 -0
  142. package/dist/services/ai/GeminiService.js.map +1 -0
  143. package/dist/services/ai/GroqService.d.ts +9 -0
  144. package/dist/services/ai/GroqService.d.ts.map +1 -0
  145. package/dist/services/ai/GroqService.js +53 -0
  146. package/dist/services/ai/GroqService.js.map +1 -0
  147. package/dist/services/ai/MockAIService.d.ts +8 -0
  148. package/dist/services/ai/MockAIService.d.ts.map +1 -0
  149. package/dist/services/ai/MockAIService.js +24 -0
  150. package/dist/services/ai/MockAIService.js.map +1 -0
  151. package/dist/services/ai/OpenAIService.d.ts +9 -0
  152. package/dist/services/ai/OpenAIService.d.ts.map +1 -0
  153. package/dist/services/ai/OpenAIService.js +51 -0
  154. package/dist/services/ai/OpenAIService.js.map +1 -0
  155. package/dist/strategies/BaseStrategy.d.ts +36 -0
  156. package/dist/strategies/BaseStrategy.d.ts.map +1 -0
  157. package/dist/strategies/BaseStrategy.js +110 -0
  158. package/dist/strategies/BaseStrategy.js.map +1 -0
  159. package/dist/strategies/DebugStrategy.d.ts +13 -0
  160. package/dist/strategies/DebugStrategy.d.ts.map +1 -0
  161. package/dist/strategies/DebugStrategy.js +16 -0
  162. package/dist/strategies/DebugStrategy.js.map +1 -0
  163. package/dist/strategies/DiaryStrategy.d.ts +19 -0
  164. package/dist/strategies/DiaryStrategy.d.ts.map +1 -0
  165. package/dist/strategies/DiaryStrategy.js +69 -0
  166. package/dist/strategies/DiaryStrategy.js.map +1 -0
  167. package/dist/strategies/GeneralStrategy.d.ts +8 -0
  168. package/dist/strategies/GeneralStrategy.d.ts.map +1 -0
  169. package/dist/strategies/GeneralStrategy.js +11 -0
  170. package/dist/strategies/GeneralStrategy.js.map +1 -0
  171. package/dist/strategies/InitStrategy.d.ts +19 -0
  172. package/dist/strategies/InitStrategy.d.ts.map +1 -0
  173. package/dist/strategies/InitStrategy.js +122 -0
  174. package/dist/strategies/InitStrategy.js.map +1 -0
  175. package/dist/strategies/SearchStrategy.d.ts +19 -0
  176. package/dist/strategies/SearchStrategy.d.ts.map +1 -0
  177. package/dist/strategies/SearchStrategy.js +112 -0
  178. package/dist/strategies/SearchStrategy.js.map +1 -0
  179. package/dist/strategies/XPostStrategy.d.ts +27 -0
  180. package/dist/strategies/XPostStrategy.d.ts.map +1 -0
  181. package/dist/strategies/XPostStrategy.js +119 -0
  182. package/dist/strategies/XPostStrategy.js.map +1 -0
  183. package/dist/templates/completion.bash +24 -0
  184. package/dist/templates/dailyNote.d.ts +2 -0
  185. package/dist/templates/dailyNote.d.ts.map +1 -0
  186. package/dist/templates/dailyNote.js +8 -0
  187. package/dist/templates/dailyNote.js.map +1 -0
  188. package/dist/templates/defaultPrompt.d.ts +2 -0
  189. package/dist/templates/defaultPrompt.d.ts.map +1 -0
  190. package/dist/templates/defaultPrompt.js +28 -0
  191. package/dist/templates/defaultPrompt.js.map +1 -0
  192. package/dist/templates/obsidianNote.d.ts +3 -0
  193. package/dist/templates/obsidianNote.d.ts.map +1 -0
  194. package/dist/templates/obsidianNote.js +17 -0
  195. package/dist/templates/obsidianNote.js.map +1 -0
  196. package/dist/templates/tokenUsage.d.ts +20 -0
  197. package/dist/templates/tokenUsage.d.ts.map +1 -0
  198. package/dist/templates/tokenUsage.js +50 -0
  199. package/dist/templates/tokenUsage.js.map +1 -0
  200. package/dist/test-tabtab.d.ts +2 -0
  201. package/dist/test-tabtab.d.ts.map +1 -0
  202. package/dist/test-tabtab.js +50 -0
  203. package/dist/test-tabtab.js.map +1 -0
  204. package/dist/types/constants.d.ts +16 -0
  205. package/dist/types/constants.d.ts.map +1 -0
  206. package/dist/types/constants.js +14 -0
  207. package/dist/types/constants.js.map +1 -0
  208. package/dist/types/interfaces.d.ts +56 -0
  209. package/dist/types/interfaces.d.ts.map +1 -0
  210. package/dist/types/interfaces.js +6 -0
  211. package/dist/types/interfaces.js.map +1 -0
  212. package/dist/types/schemas.d.ts +18 -0
  213. package/dist/types/schemas.d.ts.map +1 -0
  214. package/dist/types/schemas.js +13 -0
  215. package/dist/types/schemas.js.map +1 -0
  216. package/dist/utils/completion.d.ts +8 -0
  217. package/dist/utils/completion.d.ts.map +1 -0
  218. package/dist/utils/completion.js +58 -0
  219. package/dist/utils/completion.js.map +1 -0
  220. package/dist/utils/dummy.d.ts +2 -0
  221. package/dist/utils/dummy.d.ts.map +1 -0
  222. package/dist/utils/dummy.js +3 -0
  223. package/dist/utils/dummy.js.map +1 -0
  224. package/package.json +55 -0
@@ -0,0 +1,132 @@
1
+ import { AIProvider } from '../types/constants.js';
2
+ import { TEXT } from '../config/text.js';
3
+ import * as dotenv from 'dotenv';
4
+ import * as path from 'path';
5
+ import * as fs from 'fs';
6
+ /**
7
+ * 環境変数や設定値を一元管理するサービスクラス。
8
+ * アプリケーション全体で process.env を直接参照せず、このクラスを通じて値を取得する。
9
+ * Service class for centralized management of environment variables and configuration values.
10
+ * The application should access values through this class instead of referencing process.env directly.
11
+ */
12
+ export class ConfigService {
13
+ constructor() {
14
+ if (process.env.NODE_ENV === 'test' && process.env.VAULT_PATH_FOR_TEST) {
15
+ const envPath = path.join(process.env.VAULT_PATH_FOR_TEST, '.env');
16
+ if (fs.existsSync(envPath)) {
17
+ dotenv.config({ path: envPath });
18
+ }
19
+ return;
20
+ }
21
+ if (process.env.NODE_ENV !== 'test') {
22
+ const envPath = path.join(process.cwd(), '.env');
23
+ if (fs.existsSync(envPath)) {
24
+ dotenv.config({ path: envPath });
25
+ }
26
+ }
27
+ }
28
+ /**
29
+ * .env ファイルが存在するかどうかを確認する。
30
+ * Checks if the .env file exists.
31
+ */
32
+ hasEnvFile() {
33
+ if (process.env.NODE_ENV === 'test' && process.env.VAULT_PATH_FOR_TEST) {
34
+ return fs.existsSync(path.join(process.env.VAULT_PATH_FOR_TEST, '.env'));
35
+ }
36
+ return fs.existsSync(path.join(process.cwd(), '.env'));
37
+ }
38
+ /**
39
+ * Vault Path が設定されているかどうかを確認する。
40
+ * Checks if the Vault Path is set.
41
+ */
42
+ hasVaultPath() {
43
+ return !!process.env.OBSIDIAN_VAULT_PATH;
44
+ }
45
+ /**
46
+ * Obsidian Vaultのパスを取得する。
47
+ * Gets the path to the Obsidian Vault.
48
+ * @throws {Error} 環境変数が設定されていない場合 / If the environment variable is not set.
49
+ */
50
+ get vaultPath() {
51
+ const path = process.env.OBSIDIAN_VAULT_PATH;
52
+ if (!path) {
53
+ throw new Error(TEXT.errors.vaultPathNotSet);
54
+ }
55
+ return path;
56
+ }
57
+ /**
58
+ * 使用するエディタのコマンドを取得する。
59
+ * Gets the editor command to use.
60
+ * @returns {string | undefined} エディタコマンド、または未設定の場合はundefined / Editor command, or undefined if not set.
61
+ */
62
+ get editor() {
63
+ return process.env.EDITOR;
64
+ }
65
+ /**
66
+ * アプリケーションの言語設定を取得する。
67
+ * Gets the application language setting.
68
+ * @returns {string} 言語コード (デフォルトは 'en') / Language code (defaults to 'en').
69
+ */
70
+ get language() {
71
+ return process.env.APP_LANG || 'en';
72
+ }
73
+ /**
74
+ * テスト環境かどうかを判定する。
75
+ * Determines if the application is running in a test environment.
76
+ */
77
+ get isTestEnv() {
78
+ return process.env.NODE_ENV === 'test';
79
+ }
80
+ /**
81
+ * バックグラウンド(デタッチ)モードで実行されているかどうかを判定する。
82
+ * Determines if the application is running in detached mode.
83
+ */
84
+ get isDetachedMode() {
85
+ return process.env.VF_DETACHED_MODE === 'true';
86
+ }
87
+ /**
88
+ * 指定されたプロバイダーのAPIキーを取得する。
89
+ * Gets the API key for the specified provider.
90
+ * @param {string} provider - AIプロバイダー名 / The name of the AI provider.
91
+ * @returns {string} APIキー / The API key.
92
+ * @throws {Error} APIキーが設定されていない場合 / If the API key is not set.
93
+ */
94
+ getApiKey(provider) {
95
+ let apiKey = "";
96
+ switch (provider) {
97
+ case AIProvider.OPENAI:
98
+ apiKey = process.env.OPENAI_API_KEY || "";
99
+ break;
100
+ case AIProvider.GROQ:
101
+ apiKey = process.env.GROQ_API_KEY || "";
102
+ break;
103
+ case AIProvider.CLAUDE:
104
+ apiKey = process.env.CLAUDE_API_KEY || process.env.ANTHROPIC_API_KEY || "";
105
+ break;
106
+ case AIProvider.GEMINI:
107
+ default:
108
+ apiKey = process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY || "";
109
+ break;
110
+ }
111
+ if (!apiKey) {
112
+ throw new Error(TEXT.errors.noAiKeys);
113
+ }
114
+ return apiKey;
115
+ }
116
+ /**
117
+ * 利用可能な(APIキーが設定されている)プロバイダーのリストを取得する。
118
+ * Gets a list of available providers (those with API keys set).
119
+ */
120
+ getAvailableProviders() {
121
+ return Object.values(AIProvider).filter(provider => {
122
+ try {
123
+ this.getApiKey(provider);
124
+ return true;
125
+ }
126
+ catch (e) {
127
+ return false;
128
+ }
129
+ });
130
+ }
131
+ }
132
+ //# sourceMappingURL=ConfigService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfigService.js","sourceRoot":"","sources":["../../src/services/ConfigService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,97 @@
1
+ import { AppMode } from '../types/constants.js';
2
+ import type { TokenUsage } from '../types/interfaces.js';
3
+ export declare class ObsidianService {
4
+ private vaultPath;
5
+ private tagService;
6
+ private ui;
7
+ private configService;
8
+ constructor(vaultPath: string);
9
+ /**
10
+ * Vaultのルートパスを取得する
11
+ * Gets the root path of the Vault.
12
+ */
13
+ getVaultPath(): string;
14
+ /**
15
+ * ログファイルの初期作成を行う高レベルAPI
16
+ * High-level API for creating initial log files.
17
+ * @param date 作成日時 / Creation date
18
+ * @param mode アプリケーションモード / Application mode
19
+ * @param inputData 入力データ / Input data
20
+ * @param relativePath 保存先の相対パス / Relative path to save
21
+ * @returns 作成されたファイルの絶対パス / Absolute path of the created file
22
+ */
23
+ createInitialLog(date: Date, mode: AppMode, inputData: string, relativePath: string): Promise<string>;
24
+ /**
25
+ * AI解析結果をフォーマットして追記する
26
+ * Formats and appends AI analysis results.
27
+ * @param relativePath 対象ファイルの相対パス / Relative path of the target file
28
+ * @param responseText AIからの応答テキスト / Response text from AI
29
+ * @param header セクションヘッダー / Section header
30
+ */
31
+ appendAnalysisResult(relativePath: string, responseText: string, header: string): Promise<void>;
32
+ /**
33
+ * トークン使用量を記録する
34
+ * Records token usage.
35
+ * @param mode 使用モード / Usage mode
36
+ * @param provider AIプロバイダー / AI provider
37
+ * @param model AIモデル / AI model
38
+ * @param usage トークン使用量データ / Token usage data
39
+ */
40
+ recordTokenUsage(mode: string, provider: string, model: string, usage: TokenUsage): Promise<void>;
41
+ /**
42
+ * Daily Noteに追記する
43
+ * Appends content to the Daily Note.
44
+ * @param content 追記する内容 / Content to append
45
+ * @param tags 関連タグ / Related tags
46
+ * @param isHeader 見出しとして追加するかどうか / Whether to add as a header
47
+ * @returns 更新されたファイルのフルパス / Full path of the updated file
48
+ */
49
+ appendToDailyNote(content: string, tags: string[], isHeader?: boolean): Promise<string>;
50
+ /**
51
+ * 新しいノートを作成する (基本操作)
52
+ * Creates a new note (basic operation).
53
+ * @param relativePath 作成するファイルの相対パス / Relative path of the file to create
54
+ * @param content ファイルの内容 / File content
55
+ * @returns 作成されたファイルの絶対パス / Absolute path of the created file
56
+ */
57
+ createNote(relativePath: string, content: string): Promise<string>;
58
+ /**
59
+ * ノートの内容を読み込む (基本操作)
60
+ * Reads the content of a note (basic operation).
61
+ * @param relativePath 読み込むファイルの相対パス / Relative path of the file to read
62
+ * @returns ファイルの内容 / File content
63
+ */
64
+ readNote(relativePath: string): Promise<string>;
65
+ /**
66
+ * コンテキストとしてノートを読み込む(ログ出力付き)
67
+ * Reads a note as context (with log output).
68
+ * @param relativePath 読み込むファイルの相対パス / Relative path of the file to read
69
+ * @returns ファイルの内容 / File content
70
+ */
71
+ readContextNote(relativePath: string): Promise<string>;
72
+ /**
73
+ * ノートに追記する (基本操作)
74
+ * Appends content to a note (basic operation).
75
+ * @param relativePath 対象ファイルの相対パス / Relative path of the target file
76
+ * @param content 追記する内容 / Content to append
77
+ */
78
+ appendNote(relativePath: string, content: string): Promise<void>;
79
+ /**
80
+ * ノートを削除する (基本操作)
81
+ * Deletes a note (basic operation).
82
+ * @param relativePath 削除するファイルの相対パス / Relative path of the file to delete
83
+ */
84
+ deleteNote(relativePath: string): Promise<void>;
85
+ /**
86
+ * 指定されたファイルを環境変数EDITORで開く
87
+ * Opens the specified file with the EDITOR environment variable.
88
+ */
89
+ openFileInEditor(filePath: string): Promise<void>;
90
+ /**
91
+ * 指定されたファイルをObsidianで開く
92
+ * Opens the specified file in Obsidian.
93
+ * @param filePath 開くファイルのパス / Path of the file to open
94
+ */
95
+ openFileInObsidian(filePath: string): Promise<void>;
96
+ }
97
+ //# sourceMappingURL=ObsidianService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ObsidianService.d.ts","sourceRoot":"","sources":["../../src/services/ObsidianService.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAIhD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AASzD,qBAAa,eAAe;IACxB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,EAAE,CAAkB;IAC5B,OAAO,CAAC,aAAa,CAAgB;gBAEzB,SAAS,EAAE,MAAM;IAO7B;;;OAGG;IACH,YAAY,IAAI,MAAM;IAQtB;;;;;;;;OAQG;IACG,gBAAgB,CAClB,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,OAAO,EACb,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,GACrB,OAAO,CAAC,MAAM,CAAC;IAYlB;;;;;;OAMG;IACG,oBAAoB,CAAC,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOrG;;;;;;;OAOG;IACG,gBAAgB,CAClB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,UAAU,GAClB,OAAO,CAAC,IAAI,CAAC;IAgEhB;;;;;;;OAOG;IACG,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,QAAQ,GAAE,OAAe,GAAG,OAAO,CAAC,MAAM,CAAC;IAuCpG;;;;;;OAMG;IACG,UAAU,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IASxE;;;;;OAKG;IACG,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAKrD;;;;;OAKG;IACG,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAK5D;;;;;OAKG;IACG,UAAU,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKtE;;;;OAIG;IACG,UAAU,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASrD;;;OAGG;IACG,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBvD;;;;OAIG;IACG,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAU5D"}
@@ -0,0 +1,264 @@
1
+ import * as fs from 'fs/promises';
2
+ import * as path from 'path';
3
+ import { TEXT } from '../config/text.js';
4
+ import { AppMode } from '../types/constants.js';
5
+ import { createNoteContent } from '../templates/obsidianNote.js';
6
+ import { createTokenUsageTemplate } from '../templates/tokenUsage.js';
7
+ import { createDailyNoteTemplate } from '../templates/dailyNote.js';
8
+ import { TagService } from './TagService.js';
9
+ import { UserInteraction } from './UserInteraction.js';
10
+ import { ConfigService } from './ConfigService.js';
11
+ import { exec, spawn } from 'child_process';
12
+ import { promisify } from 'util';
13
+ const execAsync = promisify(exec);
14
+ export class ObsidianService {
15
+ vaultPath;
16
+ tagService;
17
+ ui;
18
+ configService;
19
+ constructor(vaultPath) {
20
+ this.vaultPath = vaultPath;
21
+ this.tagService = new TagService(vaultPath);
22
+ this.ui = new UserInteraction();
23
+ this.configService = new ConfigService();
24
+ }
25
+ /**
26
+ * Vaultのルートパスを取得する
27
+ * Gets the root path of the Vault.
28
+ */
29
+ getVaultPath() {
30
+ return this.vaultPath;
31
+ }
32
+ // ============================================================
33
+ // High-Level APIs (Business Logic)
34
+ // ============================================================
35
+ /**
36
+ * ログファイルの初期作成を行う高レベルAPI
37
+ * High-level API for creating initial log files.
38
+ * @param date 作成日時 / Creation date
39
+ * @param mode アプリケーションモード / Application mode
40
+ * @param inputData 入力データ / Input data
41
+ * @param relativePath 保存先の相対パス / Relative path to save
42
+ * @returns 作成されたファイルの絶対パス / Absolute path of the created file
43
+ */
44
+ async createInitialLog(date, mode, inputData, relativePath) {
45
+ const frontmatter = createNoteContent({
46
+ date: date,
47
+ mode: mode,
48
+ inputData: inputData
49
+ });
50
+ const fullPath = await this.createNote(relativePath, frontmatter);
51
+ await this.ui.info(`\n${TEXT.logs.obsidianSaved}: ${fullPath}`);
52
+ return fullPath;
53
+ }
54
+ /**
55
+ * AI解析結果をフォーマットして追記する
56
+ * Formats and appends AI analysis results.
57
+ * @param relativePath 対象ファイルの相対パス / Relative path of the target file
58
+ * @param responseText AIからの応答テキスト / Response text from AI
59
+ * @param header セクションヘッダー / Section header
60
+ */
61
+ async appendAnalysisResult(relativePath, responseText, header) {
62
+ const analysisSection = `\n${header}\n${responseText}\n`;
63
+ await this.appendNote(relativePath, analysisSection);
64
+ await this.ui.info(`\n${TEXT.logs.fileRecorded}: ${relativePath}`);
65
+ }
66
+ /**
67
+ * トークン使用量を記録する
68
+ * Records token usage.
69
+ * @param mode 使用モード / Usage mode
70
+ * @param provider AIプロバイダー / AI provider
71
+ * @param model AIモデル / AI model
72
+ * @param usage トークン使用量データ / Token usage data
73
+ */
74
+ async recordTokenUsage(mode, provider, model, usage) {
75
+ const now = new Date();
76
+ const offset = now.getTimezoneOffset() * 60000;
77
+ const localDate = new Date(now.getTime() - offset);
78
+ const yearMonth = localDate.toISOString().slice(0, 7);
79
+ const dateStr = localDate.toISOString().slice(0, 10);
80
+ const timeStr = now.toTimeString().slice(0, 8);
81
+ const relativePath = path.join('_AI_Prompts', 'TokenUsage', provider, `${yearMonth}.md`);
82
+ const fullPath = path.join(this.vaultPath, relativePath);
83
+ const newLog = {
84
+ date: dateStr,
85
+ time: timeStr,
86
+ mode,
87
+ model,
88
+ input: usage.promptTokens,
89
+ output: usage.completionTokens,
90
+ total: usage.totalTokens,
91
+ };
92
+ let existingLogs = [];
93
+ try {
94
+ const fileContent = await fs.readFile(fullPath, 'utf-8');
95
+ const logTableMatch = fileContent.match(/\| Date \| Time \|(.|\n)*$/);
96
+ if (logTableMatch) {
97
+ const rows = logTableMatch[0].split('\n').slice(2);
98
+ existingLogs = rows.map(row => {
99
+ const cells = row.split('|').map(cell => cell.trim());
100
+ if (cells.length < 8)
101
+ return null;
102
+ return {
103
+ date: cells[1],
104
+ time: cells[2],
105
+ mode: cells[3],
106
+ model: cells[4],
107
+ input: parseInt(cells[5] || "0", 10) || 0,
108
+ output: parseInt(cells[6] || "0", 10) || 0,
109
+ total: parseInt(cells[7] || "0", 10) || 0,
110
+ };
111
+ }).filter((log) => log !== null);
112
+ }
113
+ }
114
+ catch (e) {
115
+ }
116
+ const allLogs = [...existingLogs, newLog];
117
+ const dailyStatsMap = new Map();
118
+ for (const log of allLogs) {
119
+ const stat = dailyStatsMap.get(log.date) || { date: log.date, input: 0, output: 0 };
120
+ stat.input += log.input;
121
+ stat.output += log.output;
122
+ dailyStatsMap.set(log.date, stat);
123
+ }
124
+ const dailyStats = Array.from(dailyStatsMap.values());
125
+ const newContent = createTokenUsageTemplate(provider, yearMonth, dailyStats, allLogs);
126
+ const dirPath = path.dirname(fullPath);
127
+ await fs.mkdir(dirPath, { recursive: true });
128
+ await fs.writeFile(fullPath, newContent, 'utf-8');
129
+ }
130
+ /**
131
+ * Daily Noteに追記する
132
+ * Appends content to the Daily Note.
133
+ * @param content 追記する内容 / Content to append
134
+ * @param tags 関連タグ / Related tags
135
+ * @param isHeader 見出しとして追加するかどうか / Whether to add as a header
136
+ * @returns 更新されたファイルのフルパス / Full path of the updated file
137
+ */
138
+ async appendToDailyNote(content, tags, isHeader = false) {
139
+ const now = new Date();
140
+ const offset = now.getTimezoneOffset() * 60000;
141
+ const localDate = new Date(now.getTime() - offset);
142
+ const dateStr = localDate.toISOString().slice(0, 10);
143
+ const timeStr = now.toTimeString().slice(0, 5);
144
+ const relativePath = path.join('Daily', `${dateStr}.md`);
145
+ const fullPath = path.join(this.vaultPath, relativePath);
146
+ let fileContent = "";
147
+ try {
148
+ fileContent = await fs.readFile(fullPath, 'utf-8');
149
+ }
150
+ catch (e) {
151
+ fileContent = createDailyNoteTemplate(dateStr);
152
+ }
153
+ const contentWithUpdatedTags = this.tagService.updateFrontmatterTags(fileContent, tags);
154
+ let logEntry = "";
155
+ if (isHeader) {
156
+ logEntry = `\n\n${content}\n(${timeStr})`;
157
+ }
158
+ else {
159
+ logEntry = `\n- **${timeStr}** ${content}`;
160
+ }
161
+ const finalContent = contentWithUpdatedTags + logEntry;
162
+ const dirPath = path.dirname(fullPath);
163
+ await fs.mkdir(dirPath, { recursive: true });
164
+ await fs.writeFile(fullPath, finalContent, 'utf-8');
165
+ await this.ui.info(`\n${TEXT.logs.obsidianSaved}: ${relativePath}`);
166
+ return fullPath;
167
+ }
168
+ // ============================================================
169
+ // Basic File Operations (Low-Level APIs)
170
+ // ============================================================
171
+ /**
172
+ * 新しいノートを作成する (基本操作)
173
+ * Creates a new note (basic operation).
174
+ * @param relativePath 作成するファイルの相対パス / Relative path of the file to create
175
+ * @param content ファイルの内容 / File content
176
+ * @returns 作成されたファイルの絶対パス / Absolute path of the created file
177
+ */
178
+ async createNote(relativePath, content) {
179
+ const fullPath = path.join(this.vaultPath, relativePath);
180
+ const dirPath = path.dirname(fullPath);
181
+ await fs.mkdir(dirPath, { recursive: true });
182
+ await fs.writeFile(fullPath, content, 'utf-8');
183
+ return fullPath;
184
+ }
185
+ /**
186
+ * ノートの内容を読み込む (基本操作)
187
+ * Reads the content of a note (basic operation).
188
+ * @param relativePath 読み込むファイルの相対パス / Relative path of the file to read
189
+ * @returns ファイルの内容 / File content
190
+ */
191
+ async readNote(relativePath) {
192
+ const fullPath = path.join(this.vaultPath, relativePath);
193
+ return await fs.readFile(fullPath, 'utf-8');
194
+ }
195
+ /**
196
+ * コンテキストとしてノートを読み込む(ログ出力付き)
197
+ * Reads a note as context (with log output).
198
+ * @param relativePath 読み込むファイルの相対パス / Relative path of the file to read
199
+ * @returns ファイルの内容 / File content
200
+ */
201
+ async readContextNote(relativePath) {
202
+ await this.ui.info(`${TEXT.logs.readingFromObsidian}: ${relativePath}`);
203
+ return await this.readNote(relativePath);
204
+ }
205
+ /**
206
+ * ノートに追記する (基本操作)
207
+ * Appends content to a note (basic operation).
208
+ * @param relativePath 対象ファイルの相対パス / Relative path of the target file
209
+ * @param content 追記する内容 / Content to append
210
+ */
211
+ async appendNote(relativePath, content) {
212
+ const fullPath = path.join(this.vaultPath, relativePath);
213
+ await fs.appendFile(fullPath, content, 'utf-8');
214
+ }
215
+ /**
216
+ * ノートを削除する (基本操作)
217
+ * Deletes a note (basic operation).
218
+ * @param relativePath 削除するファイルの相対パス / Relative path of the file to delete
219
+ */
220
+ async deleteNote(relativePath) {
221
+ const fullPath = path.join(this.vaultPath, relativePath);
222
+ await fs.unlink(fullPath);
223
+ }
224
+ // ============================================================
225
+ // External Tools Integration
226
+ // ============================================================
227
+ /**
228
+ * 指定されたファイルを環境変数EDITORで開く
229
+ * Opens the specified file with the EDITOR environment variable.
230
+ */
231
+ async openFileInEditor(filePath) {
232
+ const editor = this.configService.editor;
233
+ if (!editor) {
234
+ throw new Error(TEXT.errors.editorNotSet);
235
+ }
236
+ const child = spawn(editor, [filePath], {
237
+ stdio: 'inherit'
238
+ });
239
+ return new Promise((resolve, reject) => {
240
+ child.on('exit', (code) => {
241
+ if (code === 0)
242
+ resolve();
243
+ else
244
+ reject(new Error(TEXT.errors.editorExitError.replace('{code}', (code ?? 'unknown').toString())));
245
+ });
246
+ child.on('error', reject);
247
+ });
248
+ }
249
+ /**
250
+ * 指定されたファイルをObsidianで開く
251
+ * Opens the specified file in Obsidian.
252
+ * @param filePath 開くファイルのパス / Path of the file to open
253
+ */
254
+ async openFileInObsidian(filePath) {
255
+ const vaultName = path.basename(this.vaultPath);
256
+ const relativePath = filePath.replace(this.vaultPath + '/', '');
257
+ const encodedFile = encodeURIComponent(relativePath);
258
+ const uri = `obsidian://open?vault=${vaultName}&file=${encodedFile}`;
259
+ const openCommand = process.platform === 'darwin' ? 'open'
260
+ : (process.platform === 'win32' ? 'start' : 'xdg-open');
261
+ await execAsync(`${openCommand} "${uri}"`);
262
+ }
263
+ }
264
+ //# sourceMappingURL=ObsidianService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ObsidianService.js","sourceRoot":"","sources":["../../src/services/ObsidianService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ export declare class TagService {
2
+ private vaultPath;
3
+ private tagsCachePath;
4
+ constructor(vaultPath: string);
5
+ /**
6
+ * tags.jsonを初期化する
7
+ * @returns true if a new file was created
8
+ */
9
+ initialize(): Promise<boolean>;
10
+ /**
11
+ * テキストからハッシュタグを抽出する
12
+ * Extracts hashtags from the text.
13
+ */
14
+ extractTags(text: string): string[];
15
+ /**
16
+ * Frontmatterのtagsフィールドを更新する
17
+ * Updates the tags field in Frontmatter.
18
+ */
19
+ updateFrontmatterTags(content: string, newTags: string[]): string;
20
+ /**
21
+ * タグインデックス(tags.json)を更新する
22
+ * Updates the tag index (tags.json).
23
+ */
24
+ updateTagsIndex(newTags: string[]): Promise<void>;
25
+ }
26
+ //# sourceMappingURL=TagService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TagService.d.ts","sourceRoot":"","sources":["../../src/services/TagService.ts"],"names":[],"mappings":"AAQA,qBAAa,UAAU;IACnB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,aAAa,CAAS;gBAElB,SAAS,EAAE,MAAM;IAK7B;;;OAGG;IACG,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IAUpC;;;OAGG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE;IAOnC;;;OAGG;IACH,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM;IAiBjE;;;OAGG;IACG,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAc1D"}
@@ -0,0 +1,73 @@
1
+ import * as fs from 'fs/promises';
2
+ import * as path from 'path';
3
+ import { exec } from 'child_process';
4
+ import { promisify } from 'util';
5
+ import matter from 'gray-matter';
6
+ const execAsync = promisify(exec);
7
+ export class TagService {
8
+ vaultPath;
9
+ tagsCachePath;
10
+ constructor(vaultPath) {
11
+ this.vaultPath = vaultPath;
12
+ this.tagsCachePath = path.join(vaultPath, '_AI_Prompts', 'tags.json');
13
+ }
14
+ /**
15
+ * tags.jsonを初期化する
16
+ * @returns true if a new file was created
17
+ */
18
+ async initialize() {
19
+ try {
20
+ await fs.access(this.tagsCachePath);
21
+ return false;
22
+ }
23
+ catch (e) {
24
+ await this.updateTagsIndex([]);
25
+ return true;
26
+ }
27
+ }
28
+ /**
29
+ * テキストからハッシュタグを抽出する
30
+ * Extracts hashtags from the text.
31
+ */
32
+ extractTags(text) {
33
+ const regex = /#[\w\u00C0-\u00FF\u3040-\u309F\u30A0-\u30FF\u4E00-\u9FAF\u3400-\u4DBF]+/g;
34
+ const matches = text.match(regex);
35
+ if (!matches)
36
+ return [];
37
+ return matches.map(tag => tag.substring(1)); // #を除去
38
+ }
39
+ /**
40
+ * Frontmatterのtagsフィールドを更新する
41
+ * Updates the tags field in Frontmatter.
42
+ */
43
+ updateFrontmatterTags(content, newTags) {
44
+ if (newTags.length === 0)
45
+ return content;
46
+ const file = matter(content);
47
+ const existingTags = file.data.tags || [];
48
+ const currentTags = Array.isArray(existingTags)
49
+ ? existingTags
50
+ : (typeof existingTags === 'string' ? [existingTags] : []);
51
+ const mergedTags = Array.from(new Set([...currentTags, ...newTags]));
52
+ file.data.tags = mergedTags;
53
+ return matter.stringify(file.content, file.data);
54
+ }
55
+ /**
56
+ * タグインデックス(tags.json)を更新する
57
+ * Updates the tag index (tags.json).
58
+ */
59
+ async updateTagsIndex(newTags) {
60
+ if (newTags.length === 0)
61
+ return;
62
+ let tags = [];
63
+ try {
64
+ const data = await fs.readFile(this.tagsCachePath, 'utf-8');
65
+ tags = JSON.parse(data);
66
+ }
67
+ catch (e) { }
68
+ const updatedTags = Array.from(new Set([...tags, ...newTags]));
69
+ await fs.mkdir(path.dirname(this.tagsCachePath), { recursive: true });
70
+ await fs.writeFile(this.tagsCachePath, JSON.stringify(updatedTags, null, 2), 'utf-8');
71
+ }
72
+ }
73
+ //# sourceMappingURL=TagService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TagService.js","sourceRoot":"","sources":["../../src/services/TagService.ts"],"names":[],"mappings":"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"}