bluelamp 2.0.10 → 3.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 (170) hide show
  1. package/README.md +12 -25
  2. package/bin/bluelamp +368 -0
  3. package/bin/bluelamp-base +368 -0
  4. package/bin/bluelamp10 +368 -0
  5. package/bin/bluelamp100 +368 -0
  6. package/bin/bluelamp11 +368 -0
  7. package/bin/bluelamp12 +368 -0
  8. package/bin/bluelamp13 +368 -0
  9. package/bin/bluelamp14 +368 -0
  10. package/bin/bluelamp15 +368 -0
  11. package/bin/bluelamp16 +368 -0
  12. package/bin/bluelamp17 +368 -0
  13. package/bin/bluelamp18 +368 -0
  14. package/bin/bluelamp19 +368 -0
  15. package/bin/bluelamp2 +368 -0
  16. package/bin/bluelamp20 +368 -0
  17. package/bin/bluelamp21 +368 -0
  18. package/bin/bluelamp22 +368 -0
  19. package/bin/bluelamp23 +368 -0
  20. package/bin/bluelamp24 +368 -0
  21. package/bin/bluelamp25 +368 -0
  22. package/bin/bluelamp26 +368 -0
  23. package/bin/bluelamp27 +368 -0
  24. package/bin/bluelamp28 +368 -0
  25. package/bin/bluelamp29 +368 -0
  26. package/bin/bluelamp3 +368 -0
  27. package/bin/bluelamp30 +368 -0
  28. package/bin/bluelamp31 +368 -0
  29. package/bin/bluelamp32 +368 -0
  30. package/bin/bluelamp33 +368 -0
  31. package/bin/bluelamp34 +368 -0
  32. package/bin/bluelamp35 +368 -0
  33. package/bin/bluelamp36 +368 -0
  34. package/bin/bluelamp37 +368 -0
  35. package/bin/bluelamp38 +368 -0
  36. package/bin/bluelamp39 +368 -0
  37. package/bin/bluelamp4 +368 -0
  38. package/bin/bluelamp40 +368 -0
  39. package/bin/bluelamp41 +368 -0
  40. package/bin/bluelamp42 +368 -0
  41. package/bin/bluelamp43 +368 -0
  42. package/bin/bluelamp44 +368 -0
  43. package/bin/bluelamp45 +368 -0
  44. package/bin/bluelamp46 +368 -0
  45. package/bin/bluelamp47 +368 -0
  46. package/bin/bluelamp48 +368 -0
  47. package/bin/bluelamp49 +368 -0
  48. package/bin/bluelamp5 +368 -0
  49. package/bin/bluelamp50 +368 -0
  50. package/bin/bluelamp51 +368 -0
  51. package/bin/bluelamp52 +368 -0
  52. package/bin/bluelamp53 +368 -0
  53. package/bin/bluelamp54 +368 -0
  54. package/bin/bluelamp55 +368 -0
  55. package/bin/bluelamp56 +368 -0
  56. package/bin/bluelamp57 +368 -0
  57. package/bin/bluelamp58 +368 -0
  58. package/bin/bluelamp59 +368 -0
  59. package/bin/bluelamp6 +368 -0
  60. package/bin/bluelamp60 +368 -0
  61. package/bin/bluelamp61 +368 -0
  62. package/bin/bluelamp62 +368 -0
  63. package/bin/bluelamp63 +368 -0
  64. package/bin/bluelamp64 +368 -0
  65. package/bin/bluelamp65 +368 -0
  66. package/bin/bluelamp66 +368 -0
  67. package/bin/bluelamp67 +368 -0
  68. package/bin/bluelamp68 +368 -0
  69. package/bin/bluelamp69 +368 -0
  70. package/bin/bluelamp7 +368 -0
  71. package/bin/bluelamp70 +368 -0
  72. package/bin/bluelamp71 +368 -0
  73. package/bin/bluelamp72 +368 -0
  74. package/bin/bluelamp73 +368 -0
  75. package/bin/bluelamp74 +368 -0
  76. package/bin/bluelamp75 +368 -0
  77. package/bin/bluelamp76 +368 -0
  78. package/bin/bluelamp77 +368 -0
  79. package/bin/bluelamp78 +368 -0
  80. package/bin/bluelamp79 +368 -0
  81. package/bin/bluelamp8 +368 -0
  82. package/bin/bluelamp80 +368 -0
  83. package/bin/bluelamp81 +368 -0
  84. package/bin/bluelamp82 +368 -0
  85. package/bin/bluelamp83 +368 -0
  86. package/bin/bluelamp84 +368 -0
  87. package/bin/bluelamp85 +368 -0
  88. package/bin/bluelamp86 +368 -0
  89. package/bin/bluelamp87 +368 -0
  90. package/bin/bluelamp88 +368 -0
  91. package/bin/bluelamp89 +368 -0
  92. package/bin/bluelamp9 +368 -0
  93. package/bin/bluelamp90 +368 -0
  94. package/bin/bluelamp91 +368 -0
  95. package/bin/bluelamp92 +368 -0
  96. package/bin/bluelamp93 +368 -0
  97. package/bin/bluelamp94 +368 -0
  98. package/bin/bluelamp95 +368 -0
  99. package/bin/bluelamp96 +368 -0
  100. package/bin/bluelamp97 +368 -0
  101. package/bin/bluelamp98 +368 -0
  102. package/bin/bluelamp99 +368 -0
  103. package/lib/mcp-server/dist/bluelamp-system.js +32 -0
  104. package/lib/mcp-server/dist/crypto-utils.js +27 -0
  105. package/lib/mcp-server/dist/database-version.js +33 -0
  106. package/lib/mcp-server/dist/index.js +62 -0
  107. package/lib/mcp-server/dist/plugins/base-plugin.js +24 -0
  108. package/lib/mcp-server/dist/plugins/plugin-manager.js +31 -0
  109. package/lib/mcp-server/dist/plugins/services/leonardo-plugin.js +95 -0
  110. package/lib/mcp-server/dist/plugins/services/leonardo-prompt-parser.js +36 -0
  111. package/lib/mcp-server/dist/plugins/services/portal-api-client.js +22 -0
  112. package/lib/mcp-server/dist/plugins/services/portal-plugin.js +52 -0
  113. package/lib/mcp-server/dist/secure-mcp-server.js +76 -0
  114. package/lib/mcp-server/dist/security/ApiKeyManager.js +24 -0
  115. package/lib/mcp-server/dist/security/InteractiveLogin.js +32 -0
  116. package/lib/mcp-server/dist/security/PortalAuthClient.js +1 -0
  117. package/lib/mcp-server/dist/security/SimpleAuthManager.js +1 -0
  118. package/lib/mcp-server/dist/security/TokenManager.js +25 -0
  119. package/lib/mcp-server/package.json +21 -0
  120. package/package.json +119 -35
  121. package/INSTALLATION_GUIDE.md +0 -109
  122. package/bin/blcf +0 -2
  123. package/bin/blcf2 +0 -28
  124. package/bin/blcf3 +0 -2
  125. package/bin/blcf4 +0 -2
  126. package/knowledge-injection/hooks/inject-encrypted.sh +0 -321
  127. package/lib/agents//343/203/225/343/202/231/343/203/253/343/203/274/343/203/251/343/203/263/343/203/225/343/202/232.md +0 -106
  128. package/lib/mcp-server/dist_optimized/bluelamp-system.d.ts +0 -29
  129. package/lib/mcp-server/dist_optimized/bluelamp-system.d.ts.map +0 -1
  130. package/lib/mcp-server/dist_optimized/bluelamp-system.js +0 -1
  131. package/lib/mcp-server/dist_optimized/bluelamp-system.js.bak +0 -340
  132. package/lib/mcp-server/dist_optimized/bluelamp-system.js.map +0 -1
  133. package/lib/mcp-server/dist_optimized/crypto-utils.d.ts +0 -33
  134. package/lib/mcp-server/dist_optimized/crypto-utils.d.ts.map +0 -1
  135. package/lib/mcp-server/dist_optimized/crypto-utils.js +0 -1
  136. package/lib/mcp-server/dist_optimized/crypto-utils.js.map +0 -1
  137. package/lib/mcp-server/dist_optimized/database-version.d.ts +0 -72
  138. package/lib/mcp-server/dist_optimized/database-version.d.ts.map +0 -1
  139. package/lib/mcp-server/dist_optimized/database-version.js +0 -2
  140. package/lib/mcp-server/dist_optimized/database-version.js.bak +0 -374
  141. package/lib/mcp-server/dist_optimized/database-version.js.map +0 -1
  142. package/lib/mcp-server/dist_optimized/index.d.ts +0 -3
  143. package/lib/mcp-server/dist_optimized/index.d.ts.map +0 -1
  144. package/lib/mcp-server/dist_optimized/index.js +0 -2
  145. package/lib/mcp-server/dist_optimized/index.js.map +0 -1
  146. package/lib/mcp-server/dist_optimized/secure-mcp-server.d.ts +0 -64
  147. package/lib/mcp-server/dist_optimized/secure-mcp-server.d.ts.map +0 -1
  148. package/lib/mcp-server/dist_optimized/secure-mcp-server.js +0 -1
  149. package/lib/mcp-server/dist_optimized/secure-mcp-server.js.bak +0 -1
  150. package/lib/mcp-server/dist_optimized/secure-mcp-server.js.bak2 +0 -1
  151. package/lib/mcp-server/dist_optimized/secure-mcp-server.js.map +0 -1
  152. package/lib/mcp-server/dist_optimized/security/InteractiveLogin.d.ts +0 -47
  153. package/lib/mcp-server/dist_optimized/security/InteractiveLogin.d.ts.map +0 -1
  154. package/lib/mcp-server/dist_optimized/security/InteractiveLogin.js +0 -1
  155. package/lib/mcp-server/dist_optimized/security/InteractiveLogin.js.map +0 -1
  156. package/lib/mcp-server/dist_optimized/security/PortalAuthClient.d.ts +0 -65
  157. package/lib/mcp-server/dist_optimized/security/PortalAuthClient.d.ts.map +0 -1
  158. package/lib/mcp-server/dist_optimized/security/PortalAuthClient.js +0 -1
  159. package/lib/mcp-server/dist_optimized/security/PortalAuthClient.js.map +0 -1
  160. package/lib/mcp-server/dist_optimized/security/SimpleAuthManager.backup +0 -294
  161. package/lib/mcp-server/dist_optimized/security/SimpleAuthManager.d.ts +0 -71
  162. package/lib/mcp-server/dist_optimized/security/SimpleAuthManager.d.ts.map +0 -1
  163. package/lib/mcp-server/dist_optimized/security/SimpleAuthManager.js +0 -1
  164. package/lib/mcp-server/dist_optimized/security/SimpleAuthManager.js.backup +0 -25
  165. package/lib/mcp-server/dist_optimized/security/SimpleAuthManager.js.map +0 -1
  166. package/lib/mcp-server/dist_optimized/security/TokenManager.d.ts +0 -61
  167. package/lib/mcp-server/dist_optimized/security/TokenManager.d.ts.map +0 -1
  168. package/lib/mcp-server/dist_optimized/security/TokenManager.js +0 -1
  169. package/lib/mcp-server/dist_optimized/security/TokenManager.js.map +0 -1
  170. package/scripts/setup-agents.js +0 -9
package/bin/bluelamp99 ADDED
@@ -0,0 +1,368 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * BlueLamp - AI Agent Orchestration System with Portal Authentication
5
+ * Base script that handles slot-based command routing
6
+ *
7
+ * Features:
8
+ * - Portal統合認証システム
9
+ * - 3箇所分散保存によるセキュリティ強化
10
+ * - bypassmode=true (--dangerously-skip-permissions)
11
+ * - orchestrator Knowledge Injection
12
+ * - 24 AI Agents available as sub-agents
13
+ * - Auto slot detection from command name
14
+ */
15
+
16
+ const { spawn } = require('child_process');
17
+ const path = require('path');
18
+ const fs = require('fs');
19
+ const os = require('os');
20
+
21
+ // パッケージのルートディレクトリを取得
22
+ const packageRoot = path.dirname(__dirname);
23
+ const mcpServerPath = path.join(packageRoot, 'lib/mcp-server/dist/secure-mcp-server.js');
24
+
25
+ // Portal認証モジュールのインポート(ES Modules対応)
26
+ const securityPath = path.join(packageRoot, 'lib/mcp-server/dist/security');
27
+
28
+ /**
29
+ * コマンド名からスロット番号を自動判定
30
+ */
31
+ function detectSlotNumber() {
32
+ try {
33
+ // process.argv[1] から実行されたコマンドのパスを取得
34
+ const commandPath = process.argv[1];
35
+ const commandName = path.basename(commandPath);
36
+
37
+ // コマンド名から数字部分を抽出
38
+ if (commandName === 'bluelamp') {
39
+ return 1; // デフォルトはスロット1
40
+ }
41
+
42
+ const match = commandName.match(/^bluelamp(\d+)$/);
43
+ if (match) {
44
+ const slotNumber = parseInt(match[1], 10);
45
+ if (slotNumber >= 1 && slotNumber <= 100) {
46
+ return slotNumber;
47
+ }
48
+ }
49
+
50
+ throw new Error(`Invalid command name: ${commandName}. Expected format: bluelamp or bluelamp[1-100]`);
51
+
52
+ } catch (error) {
53
+ console.error('❌ スロット番号の自動判定に失敗しました:', error.message);
54
+ console.error('');
55
+ console.error('有効なコマンド名:');
56
+ console.error('- bluelamp (スロット1)');
57
+ console.error('- bluelamp2〜bluelamp100');
58
+ process.exit(1);
59
+ }
60
+ }
61
+
62
+ // スロット番号を取得
63
+ const SLOT_NUMBER = detectSlotNumber();
64
+
65
+ console.log(`🔵 BlueLamp - AIエージェント統合システム (スロット${SLOT_NUMBER})`);
66
+ console.log(' ポータル統合認証 + 知識注入 + 24種類のAIエージェント');
67
+ console.log('');
68
+
69
+ /**
70
+ * Portal認証の実行
71
+ */
72
+ async function performPortalAuth() {
73
+ try {
74
+ // 動的インポートでES Modulesを読み込み
75
+ const { InteractiveLogin } = await import(`file://${securityPath}/InteractiveLogin.js`);
76
+
77
+ console.log('🔐 Portal認証を開始します...');
78
+ const authResult = await InteractiveLogin.performLogin();
79
+
80
+ InteractiveLogin.displayLoginSuccess(authResult);
81
+
82
+ return authResult.token;
83
+
84
+ } catch (error) {
85
+ console.error('❌ Portal認証エラー:', error.message);
86
+ console.error('');
87
+ console.error('解決方法:');
88
+ console.error('1. インターネット接続を確認してください');
89
+ console.error('2. Portal認証情報が正しいか確認してください');
90
+ console.error('3. https://geniemon.vercel.app にアクセスできるか確認してください');
91
+ process.exit(1);
92
+ }
93
+ }
94
+
95
+ /**
96
+ * シンプル保存システムの実行
97
+ */
98
+ async function performDistributedStorage(cliToken) {
99
+ try {
100
+ // SimpleAuthManagerを読み込み
101
+ const { SimpleAuthManager } = await import(`file://${securityPath}/SimpleAuthManager.js`);
102
+
103
+ console.log('🔒 APIキーを安全に保存中...');
104
+ const success = SimpleAuthManager.saveApiKey(cliToken);
105
+
106
+ if (success) {
107
+ console.log('✅ APIキー保存完了');
108
+ console.log('🛡️ セキュリティレベル: 高');
109
+ }
110
+
111
+ return {
112
+ success: success,
113
+ distributionTime: 1
114
+ };
115
+
116
+ } catch (error) {
117
+ console.error('❌ APIキー保存エラー:', error.message);
118
+ return {
119
+ success: false,
120
+ error: error.message
121
+ };
122
+ }
123
+ }
124
+
125
+ /**
126
+ * エージェントセットアップの確認と実行
127
+ */
128
+ function ensureAgentsSetup() {
129
+ const agentsDir = path.join(os.homedir(), '.claude/agents');
130
+ const blueLampAgent = path.join(agentsDir, 'ブルーランプ.md');
131
+
132
+ // ブルーランプエージェントが存在しない場合はセットアップを実行
133
+ if (!fs.existsSync(blueLampAgent)) {
134
+ console.log('🔧 エージェントセットアップが必要です...');
135
+
136
+ try {
137
+ const setupScript = path.join(packageRoot, 'scripts/setup-agents.js');
138
+ require(setupScript);
139
+ console.log('✅ エージェントセットアップ完了');
140
+ } catch (error) {
141
+ console.warn('⚠️ エージェント自動セットアップに失敗しました:', error.message);
142
+ console.warn('手動でセットアップを実行してください: npm run postinstall');
143
+ }
144
+ }
145
+ }
146
+
147
+ /**
148
+ * スロット認証の実行
149
+ */
150
+ async function performSlotAuth(token) {
151
+ try {
152
+ const fetch = (await import('node-fetch')).default;
153
+
154
+ console.log(`🎯 スロット${SLOT_NUMBER}の認証を実行中...`);
155
+
156
+ const response = await fetch(`https://bluelamp-portal-235426778039.asia-northeast1.run.app/api/slots/${SLOT_NUMBER}`, {
157
+ method: 'GET',
158
+ headers: {
159
+ 'Content-Type': 'application/json',
160
+ 'Authorization': `Bearer ${token}`
161
+ }
162
+ });
163
+
164
+ if (!response.ok) {
165
+ throw new Error(`スロット認証失敗 (${response.status}): ${response.statusText}`);
166
+ }
167
+
168
+ const result = await response.json();
169
+ console.log(`✅ スロット${SLOT_NUMBER}認証完了`);
170
+
171
+ return result;
172
+
173
+ } catch (error) {
174
+ console.error(`❌ スロット${SLOT_NUMBER}認証エラー:`, error.message);
175
+ console.error('');
176
+ console.error('解決方法:');
177
+ console.error('1. インターネット接続を確認してください');
178
+ console.error('2. Portalでスロット権限があることを確認してください');
179
+ console.error('3. しばらく待ってから再試行してください');
180
+ process.exit(1);
181
+ }
182
+ }
183
+
184
+ /**
185
+ * メイン処理
186
+ */
187
+ async function main() {
188
+ // コマンドライン引数の処理
189
+ const args = process.argv.slice(2);
190
+
191
+ // ログアウトコマンド
192
+ if (args.includes('--logout')) {
193
+ try {
194
+ const { InteractiveLogin } = await import(`file://${securityPath}/InteractiveLogin.js`);
195
+ await InteractiveLogin.logout();
196
+ process.exit(0);
197
+ } catch (error) {
198
+ console.error('❌ ログアウトエラー:', error.message);
199
+ process.exit(1);
200
+ }
201
+ }
202
+
203
+ // ログイン状態確認コマンド
204
+ if (args.includes('--status')) {
205
+ try {
206
+ const { InteractiveLogin } = await import(`file://${securityPath}/InteractiveLogin.js`);
207
+ await InteractiveLogin.checkLoginStatus();
208
+ process.exit(0);
209
+ } catch (error) {
210
+ console.error('❌ ステータス確認エラー:', error.message);
211
+ process.exit(1);
212
+ }
213
+ }
214
+
215
+ // エージェントセットアップの確認
216
+ ensureAgentsSetup();
217
+
218
+ // Portal認証の実行
219
+ const cliToken = await performPortalAuth();
220
+
221
+ // スロット認証の実行
222
+ await performSlotAuth(cliToken);
223
+
224
+ // シンプル保存システムの実行
225
+ console.log('🔒 APIキーを保存中...');
226
+ const distributed = await performDistributedStorage(cliToken);
227
+
228
+ if (!distributed.success) {
229
+ console.error('❌ APIキー保存に失敗しました:', distributed.error);
230
+ console.error('フォールバックモードで起動します...');
231
+ }
232
+
233
+ // TTY検出とフォールバック処理
234
+ const isTTY = process.stdout.isTTY && process.stdin.isTTY;
235
+ if (!isTTY) {
236
+ console.warn('⚠️ TTY環境が検出されませんでした。互換モードで起動します。');
237
+ }
238
+
239
+ // 環境変数の設定(スロット番号を追加)
240
+ const env = {
241
+ ...process.env,
242
+ BLUELAMP_ENCRYPTION_KEY: process.env.BLUELAMP_ENCRYPTION_KEY || 'bluelamp-default-key-2024',
243
+ BLUELAMP_TOKEN: cliToken, // Portal認証で取得した実際のCLIトークンを使用
244
+ BLUELAMP_DISTRIBUTED: distributed.success ? 'true' : 'false',
245
+ BLUELAMP_SLOT_NUMBER: SLOT_NUMBER.toString(), // スロット番号を環境変数として設定
246
+ NODE_ENV: 'production'
247
+ };
248
+
249
+ // MCP設定ファイルの作成
250
+ const tempConfigPath = path.join(os.tmpdir(), `bluelamp-mcp-slot${SLOT_NUMBER}-${Date.now()}.json`);
251
+
252
+ const mcpConfig = {
253
+ mcpServers: {
254
+ "bluelamp-secure": {
255
+ command: "node",
256
+ args: [mcpServerPath],
257
+ env: {
258
+ BLUELAMP_ENCRYPTION_KEY: env.BLUELAMP_ENCRYPTION_KEY,
259
+ BLUELAMP_TOKEN: env.BLUELAMP_TOKEN,
260
+ BLUELAMP_SLOT_NUMBER: env.BLUELAMP_SLOT_NUMBER
261
+ }
262
+ }
263
+ }
264
+ // 自動フックは削除 - 起動プロンプトで手動実行を指示
265
+ };
266
+
267
+ fs.writeFileSync(tempConfigPath, JSON.stringify(mcpConfig, null, 2));
268
+
269
+ // オーケストレーター起動プロンプト(スロット情報を追加)
270
+ const orchestratorPrompt = `> オーケストレーターモードで起動 (スロット${SLOT_NUMBER})
271
+
272
+ 🔵 BlueLamp 統合認証システム が有効化されました
273
+
274
+ \x1b[34m╭─────────────────────────────────────────────────────────────────╮\x1b[0m
275
+ \x1b[34m│ │\x1b[0m
276
+ \x1b[34m│ B l u e L a m p │\x1b[0m
277
+ \x1b[34m│ ───────────────── │\x1b[0m
278
+ \x1b[34m│ スロット${SLOT_NUMBER.toString().padStart(2, ' ')} でお待ちしています │\x1b[0m
279
+ \x1b[34m│ │\x1b[0m
280
+ \x1b[34m╰─────────────────────────────────────────────────────────────────╯\x1b[0m
281
+
282
+ **最初に必ずオーケストレーター専門知識を注入してください**
283
+ inject_knowledge ツールで "オーケストレーター" を実行してから開始してください。(初回必須)
284
+
285
+ 準備完了です。まず知識注入を実行してから、何を実装するか教えてください。`;
286
+
287
+ // 一時プロンプトファイルの作成
288
+ const tempPromptPath = path.join(os.tmpdir(), `bluelamp-prompt-slot${SLOT_NUMBER}-${Date.now()}.txt`);
289
+ fs.writeFileSync(tempPromptPath, orchestratorPrompt);
290
+
291
+ console.log('🚀 Claude Code起動中...');
292
+ console.log(` - スロット番号: ${SLOT_NUMBER}`);
293
+ console.log(' - Portal認証: ON');
294
+ console.log(' - 単一ファイル保存: ON');
295
+ console.log(' - bypassmode: ON (--dangerously-skip-permissions)');
296
+ console.log(' - Knowledge Injection: ON');
297
+ console.log(' - MCP Server: BlueLamp Secure');
298
+ console.log(' - TTY互換モード: ON');
299
+ console.log('');
300
+
301
+ // Claude Codeを起動(claude-flow方式: プロンプト引数渡し + TTY維持)
302
+ const claudeArgs = [
303
+ orchestratorPrompt, // 初期プロンプトを第1引数で渡す(claude-flow方式)
304
+ '--dangerously-skip-permissions', // bypassmode=true(開発モード)
305
+ '--mcp-config', tempConfigPath, // MCP設定ファイル
306
+ ];
307
+
308
+ const child = spawn('claude', claudeArgs, {
309
+ stdio: 'inherit', // TTY完全維持(claude-flow方式)
310
+ env: env,
311
+
312
+ // プロセス設定
313
+ detached: false, // プロセスグループ分離を無効
314
+ windowsHide: false, // Windows環境でのウィンドウ表示
315
+ shell: false // シェル経由実行を無効化
316
+ });
317
+
318
+ // TTY維持によりsetRawMode不要(問題の原因を完全除去)
319
+ // stdin操作も不要(引数でプロンプト渡し済み)
320
+
321
+ // エラーハンドリング
322
+ child.on('error', (error) => {
323
+ console.error('❌ Claude Code起動エラー:', error.message);
324
+ console.error('');
325
+ console.error('解決方法:');
326
+ console.error('1. Claude Codeがインストールされているか確認');
327
+ console.error('2. PATHにclaudeコマンドが含まれているか確認');
328
+ console.error('3. Claude Codeのバージョンが最新か確認');
329
+
330
+ // 一時ファイルをクリーンアップ
331
+ try {
332
+ fs.unlinkSync(tempConfigPath);
333
+ fs.unlinkSync(tempPromptPath);
334
+ } catch (e) {
335
+ // ignore cleanup errors
336
+ }
337
+
338
+ process.exit(1);
339
+ });
340
+
341
+ // 終了時のクリーンアップ
342
+ child.on('exit', (code) => {
343
+ console.log('');
344
+ console.log(`🔵 BlueLamp セッション終了 (スロット${SLOT_NUMBER})`);
345
+
346
+ // 一時ファイルをクリーンアップ
347
+ try {
348
+ fs.unlinkSync(tempConfigPath);
349
+ fs.unlinkSync(tempPromptPath);
350
+ } catch (e) {
351
+ // ignore cleanup errors
352
+ }
353
+
354
+ process.exit(code || 0);
355
+ });
356
+
357
+ // SIGINT (Ctrl+C) ハンドリング
358
+ process.on('SIGINT', () => {
359
+ console.log(`\n🔵 BlueLamp を終了しています... (スロット${SLOT_NUMBER})`);
360
+ child.kill('SIGINT');
361
+ });
362
+ }
363
+
364
+ // メイン処理の実行
365
+ main().catch((error) => {
366
+ console.error('❌ 予期しないエラーが発生しました:', error.message);
367
+ process.exit(1);
368
+ });
@@ -0,0 +1,32 @@
1
+ "use strict"
2
+ var __createBinding=this&&this.__createBinding||(Object.create?function(e,t,s,n){void 0===n&&(n=s)
3
+ var r=Object.getOwnPropertyDescriptor(t,s)
4
+ r&&!("get"in r?!t.__esModule:r.writable||r.configurable)||(r={enumerable:!0,get:function(){return t[s]}}),Object.defineProperty(e,n,r)}:function(e,t,s,n){void 0===n&&(n=s),e[n]=t[s]}),__setModuleDefault=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),__importStar=this&&this.__importStar||function(){var e=function(t){return e=Object.getOwnPropertyNames||function(e){var t=[]
5
+ for(var s in e)Object.prototype.hasOwnProperty.call(e,s)&&(t[t.length]=s)
6
+ return t},e(t)}
7
+ return function(t){if(t&&t.__esModule)return t
8
+ var s={}
9
+ if(null!=t)for(var n=e(t),r=0;r<n.length;r++)"default"!==n[r]&&__createBinding(s,t,n[r])
10
+ return __setModuleDefault(s,t),s}}()
11
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.BlueLampProtectionSystem=void 0
12
+ const index_js_1=require("@modelcontextprotocol/sdk/server/index.js"),stdio_js_1=require("@modelcontextprotocol/sdk/server/stdio.js"),types_js_1=require("@modelcontextprotocol/sdk/types.js"),fs=__importStar(require("fs")),path=__importStar(require("path"))
13
+ class BlueLampProtectionSystem{constructor(){this.server=new index_js_1.Server({name:"bluelamp-protection-system",version:"1.0.0"},{capabilities:{tools:{}}}),this.validTokens=new Set,this.accessLogs=[],this.initializeTokens(),this.setupHandlers()}initializeTokens(){const e=process.env.BLUELAMP_TOKEN
14
+ e&&this.validTokens.add(e),this.validTokens.add("test-token-12345"),this.validTokens.add("bluelamp-secure-token-67890")}setupHandlers(){this.server.setRequestHandler(types_js_1.ListToolsRequestSchema,async()=>({tools:[{name:"authenticate_agent",description:"Authenticate access to protected agent",inputSchema:{type:"object",properties:{token:{type:"string",description:"Authentication token"},agentName:{type:"string",description:"Name of the agent to access"}},required:["token","agentName"]}},{name:"get_protected_prompt",description:"Get protected prompt for authenticated agent",inputSchema:{type:"object",properties:{token:{type:"string",description:"Authentication token"},agentName:{type:"string",description:"Name of the agent"},promptId:{type:"string",description:"ID of the prompt to retrieve"}},required:["token","agentName","promptId"]}},{name:"list_protected_agents",description:"List all protected agents available",inputSchema:{type:"object",properties:{token:{type:"string",description:"Authentication token"}},required:["token"]}}]})),this.server.setRequestHandler(types_js_1.CallToolRequestSchema,async e=>{const{name:t,arguments:s}=e.params
15
+ try{switch(t){case"authenticate_agent":return await this.handleAuthenticateAgent(s)
16
+ case"get_protected_prompt":return await this.handleGetProtectedPrompt(s)
17
+ case"list_protected_agents":return await this.handleListProtectedAgents(s)
18
+ default:throw new types_js_1.McpError(types_js_1.ErrorCode.MethodNotFound,"Unknown tool: "+t)}}catch(e){if(e instanceof types_js_1.McpError)throw e
19
+ throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError,`Tool execution failed: ${t}: ${e}`)}})}validateToken(token){return this.validTokens.has(token)}logAccess(token,e,t){this.accessLogs.push({timestamp:new Date,token:token.substring(0,8)+"...",agentName:e,success:t}),this.accessLogs.length>100&&(this.accessLogs=this.accessLogs.slice(-100))}async handleAuthenticateAgent(e){const{token:token,agentName:t}=e
20
+ return this.validateToken(token)?(this.logAccess(token,t,!0),{content:[{type:"text",text:JSON.stringify({success:!0,message:"Authentication successful for agent: "+t,sessionId:"session_"+Date.now(),expiresAt:new Date(Date.now()+36e5).toISOString()})}]}):(this.logAccess(token,t,!1),{content:[{type:"text",text:JSON.stringify({success:!1,error:"Invalid authentication token",code:"AUTH_FAILED"})}]})}async handleGetProtectedPrompt(e){const{token:token,agentName:t,promptId:s}=e
21
+ if(!this.validateToken(token))return this.logAccess(token,t,!1),{content:[{type:"text",text:JSON.stringify({success:!1,error:"Invalid authentication token",code:"AUTH_FAILED"})}]}
22
+ try{const e=path.join(process.cwd(),"protected-prompts",t),n=path.join(e,s+".md")
23
+ if(!fs.existsSync(n))return{content:[{type:"text",text:JSON.stringify({success:!1,error:`Prompt not found: ${s} for agent: ${t}`,code:"PROMPT_NOT_FOUND"})}]}
24
+ const r=fs.readFileSync(n,"utf-8")
25
+ return this.logAccess(token,t,!0),{content:[{type:"text",text:JSON.stringify({success:!0,agentName:t,promptId:s,content:r,retrievedAt:(new Date).toISOString()})}]}}catch(e){return this.logAccess(token,t,!1),{content:[{type:"text",text:JSON.stringify({success:!1,error:"Failed to retrieve prompt: "+e.message,code:"RETRIEVAL_ERROR"})}]}}}async handleListProtectedAgents(e){const{token:token}=e
26
+ if(!this.validateToken(token))return{content:[{type:"text",text:JSON.stringify({success:!1,error:"Invalid authentication token",code:"AUTH_FAILED"})}]}
27
+ try{const e=path.join(process.cwd(),"protected-prompts")
28
+ if(!fs.existsSync(e))return{content:[{type:"text",text:JSON.stringify({success:!0,agents:[],message:"No protected agents directory found"})}]}
29
+ const t=fs.readdirSync(e,{withFileTypes:!0}).filter(e=>e.isDirectory()).map(t=>{const s=path.join(e,t.name),n=fs.readdirSync(s).filter(e=>e.endsWith(".md")).map(e=>e.replace(".md",""))
30
+ return{name:t.name,promptCount:n.length,prompts:n}})
31
+ return{content:[{type:"text",text:JSON.stringify({success:!0,agents:t,totalAgents:t.length,accessLogs:this.accessLogs.slice(-10)})}]}}catch(e){return{content:[{type:"text",text:JSON.stringify({success:!1,error:"Failed to list agents: "+e.message,code:"LIST_ERROR"})}]}}}async run(){const e=new stdio_js_1.StdioServerTransport
32
+ await this.server.connect(e)}}exports.BlueLampProtectionSystem=BlueLampProtectionSystem,require.main===module&&new BlueLampProtectionSystem
@@ -0,0 +1,27 @@
1
+ "use strict"
2
+ var __createBinding=this&&this.__createBinding||(Object.create?function(t,e,r,i){void 0===i&&(i=r)
3
+ var s=Object.getOwnPropertyDescriptor(e,r)
4
+ s&&!("get"in s?!e.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return e[r]}}),Object.defineProperty(t,i,s)}:function(t,e,r,i){void 0===i&&(i=r),t[i]=e[r]}),__setModuleDefault=this&&this.__setModuleDefault||(Object.create?function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}:function(t,e){t.default=e}),__importStar=this&&this.__importStar||function(){var t=function(e){return t=Object.getOwnPropertyNames||function(t){var e=[]
5
+ for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[e.length]=r)
6
+ return e},t(e)}
7
+ return function(e){if(e&&e.__esModule)return e
8
+ var r={}
9
+ if(null!=e)for(var i=t(e),s=0;s<i.length;s++)"default"!==i[s]&&__createBinding(r,e,i[s])
10
+ return __setModuleDefault(r,e),r}}()
11
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.CryptoUtils=void 0
12
+ const crypto=__importStar(require("crypto")),fs=__importStar(require("fs")),path=__importStar(require("path"))
13
+ class CryptoUtils{static deriveKey(t,e){return crypto.pbkdf2Sync(t,e,this.iterations,this.keyLength,"sha256")}static encryptFile(t,e,r){const i=fs.readFileSync(t,"utf-8"),s=crypto.randomBytes(this.saltLength),n=crypto.randomBytes(this.ivLength),c=this.deriveKey(r,s),o=crypto.createCipheriv(this.algorithm,c,n),a=Buffer.concat([o.update(i,"utf8"),o.final()]),l=o.getAuthTag(),p=Buffer.concat([s,n,l,a])
14
+ fs.writeFileSync(e,p)}static decryptFile(t,e){const r=fs.readFileSync(t)
15
+ let i=0
16
+ const s=r.slice(i,i+this.saltLength)
17
+ i+=this.saltLength
18
+ const n=r.slice(i,i+this.ivLength)
19
+ i+=this.ivLength
20
+ const c=r.slice(i,i+this.tagLength)
21
+ i+=this.tagLength
22
+ const o=r.slice(i),a=this.deriveKey(e,s),l=crypto.createDecipheriv(this.algorithm,a,n)
23
+ return l.setAuthTag(c),Buffer.concat([l.update(o),l.final()]).toString("utf-8")}static encryptString(t,e,r){const i=crypto.randomBytes(this.saltLength),s=crypto.randomBytes(this.ivLength),n=this.deriveKey(r,i),c=crypto.createCipheriv(this.algorithm,n,s),o=Buffer.concat([c.update(t,"utf8"),c.final()]),a=c.getAuthTag(),l=Buffer.concat([i,s,a,o])
24
+ fs.writeFileSync(e,l)}static async encryptPerformerDemo(){const t="/Users/tatsuya/Desktop/マルチエージェントウェブ/mcp-sample-server/secure-prompts",e=path.join(t,"performer-protected.enc")
25
+ fs.existsSync(t)||fs.mkdirSync(t,{recursive:!0})
26
+ const r=process.env.BLUELAMP_ENCRYPTION_KEY||"demo-encryption-password-2024"
27
+ try{this.encryptFile("/Users/tatsuya/Desktop/マルチエージェントウェブ/.claude/agents/core/パフォーマー.md",e,r),fs.statSync(e),fs.readFileSync(e).slice(0,100),this.decryptFile(e,r)}catch(t){throw t}}}exports.CryptoUtils=CryptoUtils,CryptoUtils.algorithm="aes-256-gcm",CryptoUtils.saltLength=32,CryptoUtils.tagLength=16,CryptoUtils.ivLength=16,CryptoUtils.iterations=1e5,CryptoUtils.keyLength=32
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env node
2
+ "use strict"
3
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.PromptDatabase=exports.DatabaseMCPServer=void 0
4
+ const index_js_1=require("@modelcontextprotocol/sdk/server/index.js"),stdio_js_1=require("@modelcontextprotocol/sdk/server/stdio.js"),types_js_1=require("@modelcontextprotocol/sdk/types.js")
5
+ function debugLog(e,t){}class PromptDatabase{constructor(){}initializeDatabase(){debugLog("データベーススキーマ初期化",{schema:"\n CREATE TABLE IF NOT EXISTS prompts (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n uri TEXT UNIQUE NOT NULL,\n title TEXT NOT NULL,\n content TEXT NOT NULL,\n category TEXT DEFAULT 'general',\n tags TEXT DEFAULT '',\n created_at DATETIME DEFAULT CURRENT_TIMESTAMP,\n updated_at DATETIME DEFAULT CURRENT_TIMESTAMP\n );\n\n CREATE INDEX IF NOT EXISTS idx_prompts_category ON prompts(category);\n CREATE INDEX IF NOT EXISTS idx_prompts_uri ON prompts(uri);\n CREATE VIRTUAL TABLE IF NOT EXISTS prompts_fts USING fts5(\n title, content, tags, content='prompts', content_rowid='id'\n );\n "})}async searchPrompts(e,t,r=10){debugLog("プロンプト検索",{query:e,category:t,limit:r})
6
+ let s=[{id:1,uri:"prompt://sample/greeting",title:"挨拶プロンプト",content:"こんにちは!私はAIアシスタントです。",category:"general",tags:"挨拶,基本",created_at:(new Date).toISOString(),updated_at:(new Date).toISOString()},{id:2,uri:"prompt://sample/analysis",title:"分析プロンプト",content:"データを詳細に分析し、洞察を提供します。",category:"analysis",tags:"分析,データ",created_at:(new Date).toISOString(),updated_at:(new Date).toISOString()}]
7
+ if(t&&(s=s.filter(e=>e.category===t)),e){const t=e.toLowerCase()
8
+ s=s.filter(e=>e.title.toLowerCase().includes(t)||e.content.toLowerCase().includes(t)||e.tags.toLowerCase().includes(t))}return s.slice(0,r)}async getPromptByUri(e){return debugLog("URI検索",{uri:e}),(await this.searchPrompts()).find(t=>t.uri===e)||null}async addPrompt(e){return debugLog("プロンプト追加",e),{id:Date.now(),uri:e.uri,title:e.title,content:e.content,category:e.category||"general",tags:e.tags||"",created_at:(new Date).toISOString(),updated_at:(new Date).toISOString()}}async getCategories(){return debugLog("カテゴリ一覧取得"),["general","analysis","creative","technical"]}}exports.PromptDatabase=PromptDatabase
9
+ class DatabaseMCPServer{constructor(){this.server=new index_js_1.Server({name:"database-mcp-server",version:"1.0.0"},{capabilities:{resources:{},tools:{}}}),this.database=new PromptDatabase,this.setupHandlers()}setupHandlers(){this.server.setRequestHandler(types_js_1.ListResourcesRequestSchema,async()=>{debugLog("リソース一覧要求")
10
+ try{const e=(await this.database.searchPrompts()).map(e=>({uri:e.uri,name:e.title,description:`${e.category} - ${e.content.substring(0,100)}...`,mimeType:"text/plain"}))
11
+ return debugLog("リソース一覧応答",{count:e.length}),{resources:e}}catch(e){return debugLog("リソース一覧エラー",{error:e.message}),{resources:[]}}}),this.server.setRequestHandler(types_js_1.ReadResourceRequestSchema,async e=>{const{uri:t}=e.params
12
+ debugLog("リソース読み取り要求",{uri:t})
13
+ try{const e=await this.database.getPromptByUri(t)
14
+ if(!e)throw new types_js_1.McpError(types_js_1.ErrorCode.InvalidRequest,"プロンプトが見つかりません: "+t)
15
+ return debugLog("リソース読み取り成功",{uri:t,title:e.title}),{contents:[{uri:e.uri,mimeType:"text/plain",text:e.content}]}}catch(e){if(debugLog("リソース読み取りエラー",{uri:t,error:e.message}),e instanceof types_js_1.McpError)throw e
16
+ throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError,"リソース読み取りエラー: "+e.message)}}),this.server.setRequestHandler(types_js_1.ListToolsRequestSchema,async()=>(debugLog("ツール一覧要求"),{tools:[{name:"search_prompts",description:"データベースからプロンプトを検索します",inputSchema:{type:"object",properties:{query:{type:"string",description:"検索クエリ(タイトル、内容、タグを対象)"},category:{type:"string",description:"カテゴリでフィルタ"},limit:{type:"number",description:"取得件数の上限",default:10}},required:[]}},{name:"add_prompt",description:"データベースに新しいプロンプトを追加します",inputSchema:{type:"object",properties:{uri:{type:"string",description:"プロンプトのURI"},title:{type:"string",description:"プロンプトのタイトル"},content:{type:"string",description:"プロンプトの内容"},category:{type:"string",description:"カテゴリ",default:"general"},tags:{type:"string",description:"タグ(カンマ区切り)"}},required:["uri","title","content"]}},{name:"get_categories",description:"利用可能なカテゴリ一覧を取得します",inputSchema:{type:"object",properties:{},required:[]}}]})),this.server.setRequestHandler(types_js_1.CallToolRequestSchema,async e=>{const{name:name,arguments:t}=e.params
17
+ debugLog("ツール実行要求: "+name,t)
18
+ try{switch(name){case"search_prompts":return await this.handleSearchPrompts(t||{})
19
+ case"add_prompt":return await this.handleAddPrompt(t)
20
+ case"get_categories":return await this.handleGetCategories()
21
+ default:throw new types_js_1.McpError(types_js_1.ErrorCode.MethodNotFound,"不明なツール: "+name)}}catch(e){if(debugLog("ツール実行エラー",{name:name,error:e.message}),e instanceof types_js_1.McpError)throw e
22
+ throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError,"ツール実行エラー: "+e.message)}})}async handleSearchPrompts(e){const{query:t,category:r,limit:s=10}=e
23
+ debugLog("プロンプト検索実行",{query:t,category:r,limit:s})
24
+ try{const e=await this.database.searchPrompts(t,r,s),a={type:"text",text:`検索結果: ${e.length}件\n\n`+e.map(e=>`【${e.title}】\nURI: ${e.uri}\nカテゴリ: ${e.category}\n内容: ${e.content.substring(0,100)}...\nタグ: ${e.tags}\n`).join("\n")}
25
+ return debugLog("プロンプト検索完了",{count:e.length}),{content:[a]}}catch(e){throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError,"検索エラー: "+e.message)}}async handleAddPrompt(e){const{uri:t,title:r,content:s,category:a,tags:o}=e
26
+ if(!t||!r||!s)throw new types_js_1.McpError(types_js_1.ErrorCode.InvalidParams,"uri, title, contentは必須です")
27
+ debugLog("プロンプト追加実行",{uri:t,title:r,category:a})
28
+ try{const e=await this.database.addPrompt({uri:t,title:r,content:s,category:a,tags:o}),n={type:"text",text:`プロンプトを追加しました:\n\n【${e.title}】\nURI: ${e.uri}\nカテゴリ: ${e.category}\nID: ${e.id}\n作成日時: `+e.created_at}
29
+ return debugLog("プロンプト追加完了",{id:e.id,uri:e.uri}),{content:[n]}}catch(e){throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError,"追加エラー: "+e.message)}}async handleGetCategories(){debugLog("カテゴリ一覧取得実行")
30
+ try{const e=await this.database.getCategories(),t={type:"text",text:"利用可能なカテゴリ:\n\n"+e.map(e=>"- "+e).join("\n")}
31
+ return debugLog("カテゴリ一覧取得完了",{count:e.length}),{content:[t]}}catch(e){throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError,"カテゴリ取得エラー: "+e.message)}}async run(){debugLog("データベース版MCPサーバー開始")
32
+ const e=new stdio_js_1.StdioServerTransport
33
+ await this.server.connect(e),debugLog("データベース版MCPサーバー接続完了")}}exports.DatabaseMCPServer=DatabaseMCPServer,require.main===module&&(new DatabaseMCPServer).run().catch(e=>{process.exit(1)})
@@ -0,0 +1,62 @@
1
+ #!/usr/bin/env node
2
+ "use strict"
3
+ var __createBinding=this&&this.__createBinding||(Object.create?function(e,t,r,n){void 0===n&&(n=r)
4
+ var s=Object.getOwnPropertyDescriptor(t,r)
5
+ s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,n,s)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]}),__setModuleDefault=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),__importStar=this&&this.__importStar||function(){var e=function(t){return e=Object.getOwnPropertyNames||function(e){var t=[]
6
+ for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[t.length]=r)
7
+ return t},e(t)}
8
+ return function(t){if(t&&t.__esModule)return t
9
+ var r={}
10
+ if(null!=t)for(var n=e(t),s=0;s<n.length;s++)"default"!==n[s]&&__createBinding(r,t,n[s])
11
+ return __setModuleDefault(r,t),r}}()
12
+ Object.defineProperty(exports,"__esModule",{value:!0})
13
+ const index_js_1=require("@modelcontextprotocol/sdk/server/index.js"),stdio_js_1=require("@modelcontextprotocol/sdk/server/stdio.js"),types_js_1=require("@modelcontextprotocol/sdk/types.js"),plugin_manager_js_1=require("./plugins/plugin-manager.js")
14
+ function debugLog(e,t){}class SampleMCPServer{constructor(){this.server=new index_js_1.Server({name:"bluelamp-mcp-server",version:"1.2.0"},{capabilities:{tools:{},resources:{}}}),this.setupHandlers()}setupHandlers(){this.server.setRequestHandler(types_js_1.ListResourcesRequestSchema,async()=>(debugLog("リソース一覧要求"),{resources:[]})),this.server.setRequestHandler(types_js_1.ReadResourceRequestSchema,async e=>{const{uri:t}=e.params
15
+ throw debugLog("リソース読み取り要求",{uri:t}),new types_js_1.McpError(types_js_1.ErrorCode.InvalidRequest,"リソースが見つかりません: "+t)}),this.server.setRequestHandler(types_js_1.ListToolsRequestSchema,async()=>{debugLog("ツール一覧要求")
16
+ const e=[{name:"get_current_time",description:"現在の日時を取得します",inputSchema:{type:"object",properties:{timezone:{type:"string",description:"タイムゾーン (例: Asia/Tokyo)",default:"Asia/Tokyo"}},required:[]}},{name:"calculate",description:"数学的な計算を実行します",inputSchema:{type:"object",properties:{expression:{type:"string",description:"計算式 (例: 2 + 3 * 4)"}},required:["expression"]}},{name:"echo",description:"メッセージをそのまま返します",inputSchema:{type:"object",properties:{message:{type:"string",description:"返すメッセージ"}},required:["message"]}},{name:"inject_knowledge",description:"Portal APIから専門知識を注入します",inputSchema:{type:"object",properties:{keyword:{type:"string",description:"注入する知識のキーワード",enum:["オーケストレーター","要件定義質問テンプレート","要件定義","デザイナー","デザイン設計","UIUX","本番環境準備ガイドテンプレート","データ設計","デプロイ","GitHub","実装計画","プロトタイプ","検証","バックエンド","総合テスト","テスター","フロントエンド","認証追加テンプレート","ブルーランプ","ディレクトリ構造"]},context:{type:"string",description:"追加のコンテキスト情報"},token:{type:"string",description:"Portal APIトークン(省略時は自動取得)",default:"auto"}},required:["keyword"]}}]
17
+ let t=[]
18
+ try{plugin_manager_js_1.pluginManager&&(t=plugin_manager_js_1.pluginManager.getAvailableTools(),debugLog(`プラグインツール取得完了: ${t.length}個`))}catch(e){debugLog("プラグインツール取得エラー",e)}const r=[...e,...t]
19
+ return debugLog(`全ツール数: ${r.length} (基本: ${e.length}, プラグイン: ${t.length})`),{tools:r}}),this.server.setRequestHandler(types_js_1.CallToolRequestSchema,async e=>{const{name:name,arguments:t}=e.params
20
+ debugLog("ツール実行要求: "+name,t)
21
+ try{switch(name){case"get_current_time":return await this.handleGetCurrentTime(t||{})
22
+ case"calculate":return await this.handleCalculate(t||{})
23
+ case"echo":return await this.handleEcho(t||{})
24
+ case"inject_knowledge":return await this.handleInjectKnowledge(t||{})}const e=await this.handlePluginTool(name,t)
25
+ if(e)return e
26
+ throw new types_js_1.McpError(types_js_1.ErrorCode.MethodNotFound,"不明なツール: "+name)}catch(e){if(debugLog("ツール実行エラー",{name:name,error:e.message}),e instanceof types_js_1.McpError)throw e
27
+ throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError,"ツール実行中にエラーが発生しました: "+e.message)}})}async handleGetCurrentTime(e){const{timezone:t="Asia/Tokyo"}=e
28
+ debugLog("現在時刻取得",{timezone:t})
29
+ try{const e=(new Date).toLocaleString("ja-JP",{timeZone:t,year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit"}),r={type:"text",text:`現在の日時: ${e} (${t})`}
30
+ return debugLog("現在時刻取得完了",{timeString:e,timezone:t}),{content:[r]}}catch(e){throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError,"時刻取得エラー: "+e.message)}}async handleCalculate(e){const{expression:t}=e
31
+ if(!t)throw new types_js_1.McpError(types_js_1.ErrorCode.InvalidParams,"計算式が指定されていません")
32
+ debugLog("計算実行",{expression:t})
33
+ try{const e=t.replace(/[^0-9+\-*/().\s]/g,"")
34
+ if(e!==t)throw Error("無効な文字が含まれています")
35
+ const r=Function(`"use strict"; return (${e})`)(),n={type:"text",text:`計算結果: ${t} = ${r}`}
36
+ return debugLog("計算完了",{expression:t,result:r}),{content:[n]}}catch(e){throw new types_js_1.McpError(types_js_1.ErrorCode.InvalidParams,"計算エラー: "+e.message)}}async handleEcho(e){const{message:t}=e
37
+ if(!t)throw new types_js_1.McpError(types_js_1.ErrorCode.InvalidParams,"メッセージが指定されていません")
38
+ debugLog("エコー実行",{message:t})
39
+ const r={type:"text",text:"エコー: "+t}
40
+ return debugLog("エコー完了",{message:t}),{content:[r]}}async handleInjectKnowledge(e){const{keyword:keyword,token:token="auto"}=e
41
+ if(!keyword)throw new types_js_1.McpError(types_js_1.ErrorCode.InvalidParams,"キーワードが指定されていません")
42
+ debugLog("Knowledge Injection実行",{keyword:keyword,token:token}),Date.now()
43
+ try{const{spawn:e}=await Promise.resolve().then(()=>__importStar(require("child_process"))),t="/Users/tatsuya/Desktop/bluelamp-test/knowledge-injection/hooks/inject-encrypted.sh",r={...process.env}
44
+ "auto"!==token&&(r.PORTAL_TOKEN=token),r.KNOWLEDGE_KEYWORD=keyword,debugLog("スクリプト実行開始",{scriptPath:t,keyword:keyword})
45
+ const n=e("bash",[t],{env:r,stdio:["pipe","pipe","pipe"]})
46
+ let s="",o=""
47
+ n.stdout.on("data",e=>{s+=e.toString()}),n.stderr.on("data",e=>{o+=e.toString()})
48
+ const a=await new Promise(e=>{n.on("close",e)})
49
+ if(debugLog("スクリプト実行完了",{exitCode:a,stdout:s.substring(0,200),stderr:o.substring(0,200)}),Date.now(),0===a)return{content:[{type:"text",text:`Knowledge Injection成功: "${keyword}" の知識が注入されました。\n\n実行結果:\n${s}\n\n統計記録: ⚠️ スキップ`}]}
50
+ throw Error(`スクリプト実行失敗 (exit code: ${a})\nstderr: ${o}`)}catch(e){throw debugLog("Knowledge Injectionエラー",{keyword:keyword,error:e.message}),new types_js_1.McpError(types_js_1.ErrorCode.InternalError,"Knowledge Injection実行エラー: "+e.message)}}async handlePluginTool(e,t){try{if(!plugin_manager_js_1.pluginManager)return null
51
+ if(!plugin_manager_js_1.pluginManager.getAvailableTools().find(t=>t.name===e))return null
52
+ debugLog("プラグインツール実行: "+e,t)
53
+ const r={userId:"current_user",service:"leonardo",apiKey:process.env.LEONARDO_API_KEY,settings:{}}
54
+ let n="leonardo"
55
+ e.startsWith("leonardo_")?n="leonardo":e.startsWith("notion_")?n="notion":e.startsWith("slack_")&&(n="slack")
56
+ const s=await plugin_manager_js_1.pluginManager.executePlugin(n,e,t,r)
57
+ if(s.success)return debugLog("プラグインツール実行成功: "+e),{content:s.content,_meta:s.metadata}
58
+ throw debugLog("プラグインツール実行失敗: "+e,s.error),new types_js_1.McpError(types_js_1.ErrorCode.InternalError,"プラグインツール実行エラー: "+s.error)}catch(t){if(debugLog("プラグインツール処理エラー: "+e,t),t instanceof types_js_1.McpError)throw t
59
+ throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError,"プラグイン処理中にエラーが発生しました: "+t.message)}}async run(){debugLog("MCPサーバー開始")
60
+ try{await plugin_manager_js_1.pluginManager.initialize(),debugLog("プラグインマネージャー初期化完了")}catch(e){debugLog("プラグインマネージャー初期化エラー",e)}const e=new stdio_js_1.StdioServerTransport
61
+ await this.server.connect(e),debugLog("MCPサーバー接続完了")}}const server=new SampleMCPServer
62
+ server.run().catch(e=>{process.exit(1)})
@@ -0,0 +1,24 @@
1
+ "use strict"
2
+ var __createBinding=this&&this.__createBinding||(Object.create?function(e,t,i,s){void 0===s&&(s=i)
3
+ var n=Object.getOwnPropertyDescriptor(t,i)
4
+ n&&!("get"in n?!t.__esModule:n.writable||n.configurable)||(n={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,s,n)}:function(e,t,i,s){void 0===s&&(s=i),e[s]=t[i]}),__setModuleDefault=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),__importStar=this&&this.__importStar||function(){var e=function(t){return e=Object.getOwnPropertyNames||function(e){var t=[]
5
+ for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[t.length]=i)
6
+ return t},e(t)}
7
+ return function(t){if(t&&t.__esModule)return t
8
+ var i={}
9
+ if(null!=t)for(var s=e(t),n=0;n<s.length;n++)"default"!==s[n]&&__createBinding(i,t,s[n])
10
+ return __setModuleDefault(i,t),i}}()
11
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.PluginLoader=exports.BasePlugin=void 0
12
+ const zod_1=require("zod")
13
+ class BasePlugin{constructor(){this._initialized=!1,this._credentials=new Map}get isInitialized(){return this._initialized}markInitialized(){this._initialized=!0}validateArgs(e,t){try{return t.parse(e)}catch(e){if(e instanceof zod_1.z.ZodError){const t=e.issues.map(e=>`${e.path.join(".")}: ${e.message}`).join(", ")
14
+ throw Error("引数の検証に失敗しました: "+t)}throw e}}async getCredentials(e){const t=`${e}-${this.manifest.id}`
15
+ if(this._credentials.has(t))return this._credentials.get(t)
16
+ const i=await this.fetchCredentialsFromPortal(e)
17
+ return this._credentials.set(t,i),i}async fetchCredentialsFromPortal(e){const t=process.env[this.manifest.id.toUpperCase()+"_API_KEY"]
18
+ return{userId:e,service:this.manifest.id,apiKey:t,settings:{}}}async recordUsage(e,t,i,s,n){const a={userId:t,pluginId:this.manifest.id,toolName:e,executionTime:s,success:i,timestamp:new Date,metadata:n}
19
+ await this.sendStatsToPortal(a)}async sendStatsToPortal(e){}handleError(e,t){return{success:!1,error:`${t}: ${e?.message||e+""}`,metadata:{errorCode:e?.code||"UNKNOWN_ERROR",pluginId:this.manifest.id,timestamp:(new Date).toISOString()}}}createSuccessResponse(e,t){return{success:!0,content:e,metadata:{pluginId:this.manifest.id,timestamp:(new Date).toISOString(),...t}}}supportsTool(e){return this.manifest.tools.some(t=>t.name===e)}async healthCheck(){try{return this.isInitialized?(await this.performHealthCheck(),{status:"healthy",details:{initialized:!0,toolCount:this.manifest.tools.length,version:this.manifest.version}}):{status:"unhealthy",message:"プラグインが初期化されていません"}}catch(e){return{status:"unhealthy",message:"ヘルスチェックに失敗しました: "+e,details:{error:e+""}}}}async performHealthCheck(){}}exports.BasePlugin=BasePlugin
20
+ class PluginLoader{constructor(){this.loadedPlugins=new Map}static getInstance(){return PluginLoader.instance||(PluginLoader.instance=new PluginLoader),PluginLoader.instance}async loadPlugin(e){try{if(this.loadedPlugins.has(e))return this.loadedPlugins.get(e)
21
+ const t=await Promise.resolve(`./services/${e}-plugin.js`).then(e=>__importStar(require(e))),i=new(t.default||t[Object.keys(t)[0]])
22
+ return await i.initialize(),this.loadedPlugins.set(e,i),i}catch(e){return null}}async unloadPlugin(e){const t=this.loadedPlugins.get(e)
23
+ t&&(await t.shutdown(),this.loadedPlugins.delete(e))}async unloadAllPlugins(){const e=Array.from(this.loadedPlugins.keys()).map(e=>this.unloadPlugin(e))
24
+ await Promise.all(e)}getLoadedPlugins(){return Array.from(this.loadedPlugins.keys())}}exports.PluginLoader=PluginLoader
@@ -0,0 +1,31 @@
1
+ "use strict"
2
+ Object.defineProperty(exports,"__esModule",{value:!0}),exports.pluginManager=exports.PluginManager=void 0
3
+ const base_plugin_js_1=require("./base-plugin.js")
4
+ class PluginManager{constructor(e={}){this.pluginCache=new Map,this.pluginStats=new Map,this.executionQueue=[],this.isProcessingQueue=!1,this.initialized=!1,this.manifestRegistry=new Map,this.config={maxLoadedPlugins:100,pluginTimeoutMs:3e5,maxConcurrentExecution:50,healthCheckIntervalMs:6e4,portalBaseUrl:process.env.PORTAL_URL||"http://localhost:8080",...e},this.pluginLoader=base_plugin_js_1.PluginLoader.getInstance()}async initialize(){this.initialized||(await this.loadPluginManifests(),this.startHealthCheckTimer(),this.startExecutionQueueProcessor(),this.initialized=!0)}async loadPluginManifests(){try{const e=await this.getBuiltinManifests()
5
+ for(const t of e)this.manifestRegistry.set(t.id,t),this.pluginStats.set(t.id,{pluginId:t.id,loadTime:0,totalExecutions:0,successfulExecutions:0,failedExecutions:0,averageExecutionTime:0,lastExecuted:new Date(0),healthStatus:"healthy"})}catch(e){throw e}}async getBuiltinManifests(){return[{id:"leonardo",name:"Leonardo AI",version:"1.0.0",category:"AI",description:"Leonardo AIによる高品質な画像生成",authType:"api_key",loadPriority:"high",tools:[{name:"leonardo_generate",description:"Leonardo AIで画像を生成します",inputSchema:{type:"object",properties:{prompt:{type:"string",description:"画像生成のプロンプト"},width:{type:"number",description:"画像の幅(512-2048)",default:1024},height:{type:"number",description:"画像の高さ(512-2048)",default:1024},num_images:{type:"number",description:"生成する画像数(1-8)",default:1},modelId:{type:"string",description:"Leonardo AIのモデルID(省略時はデフォルト)"},negativePrompt:{type:"string",description:"ネガティブプロンプト"},photoReal:{type:"boolean",description:"フォトリアル画像の生成",default:!1},alchemy:{type:"boolean",description:"Alchemy v2の使用",default:!0},guidance_scale:{type:"number",description:"ガイダンススケール(1-30)",default:7},outputPath:{type:"string",description:"保存先ディレクトリ(省略時: ./outputs)"}},required:["prompt"]},outputExample:{success:!0,content:[{type:"text",text:"✅ Leonardo AIで1枚の画像を生成しました\\n📁 保存先: ./outputs/leonardo_20250830_001.png"}]}}]},{id:"portal",name:"Portal Integration",version:"1.0.0",category:"Integration",description:"Portal APIとの統合機能(エージェント委譲、知識注入、認証管理)",authType:"token",loadPriority:"high",tools:[{name:"delegate_to_agent",description:"専門エージェントにタスクを委譲します。動的スロット解決により適切なオーケストレーターに接続します。",inputSchema:{type:"object",properties:{agentName:{type:"string",description:"エージェント名(orchestrator, orchestrator2など)"},token:{type:"string",description:"認証トークン(オプション、自動取得される)"}},required:["agentName"]},outputExample:{success:!0,content:[{type:"text",text:"✅ orchestrator2 にタスクを委譲しました\\n🔗 エンドポイント: https://orchestrator-slot2.example.com"}]}},{name:"inject_knowledge",description:"Portal APIから専門知識を注入します。キーワードに基づいて関連する知識ベースからコンテンツを取得します。",inputSchema:{type:"object",properties:{keyword:{type:"string",description:"検索キーワード"},context:{type:"string",description:"追加コンテキスト(オプション)"},level:{type:"string",description:"知識の詳細レベル",default:"detailed"}},required:["keyword"]},outputExample:{success:!0,content:[{type:"text",text:"🧠 専門知識を注入しました\\n🔍 キーワード: React\\n📚 知識内容: Reactは..."}]}},{name:"save_knowledge",description:"暗号化された知識を保存します",inputSchema:{type:"object",properties:{knowledge:{type:"string",description:"保存する知識内容"},identifier:{type:"string",description:"知識の識別子"},token:{type:"string",description:"認証トークン"}},required:["knowledge","identifier","token"]},outputExample:{success:!0,content:[{type:"text",text:"💾 知識を暗号化して保存しました"}]}},{name:"list_prompts",description:"利用可能な暗号化プロンプトテンプレートを一覧表示します",inputSchema:{type:"object",properties:{category:{type:"string",description:"カテゴリフィルター(オプション)"},token:{type:"string",description:"認証トークン"}},required:["token"]},outputExample:{success:!0,content:[{type:"text",text:"📋 利用可能なプロンプト: システムアーキテクト, UI/UXデザイナー, 実装エージェント"}]}},{name:"get_debug_log_path",description:"デバッグログファイルのパスを取得します",inputSchema:{type:"object",properties:{},required:[]},outputExample:{success:!0,content:[{type:"text",text:"Debug log path: /tmp/portal-debug-123456.log"}]}}]}]}async executePlugin(e,t,i,s){return this.manifestRegistry.has(e)?new Promise((n,a)=>{const o={id:this.generateTaskId(),pluginId:e,toolName:t,args:i,userCredentials:s,resolve:n,reject:a,createdAt:new Date}
6
+ this.executionQueue.push(o),this.isProcessingQueue||setImmediate(()=>this.processExecutionQueue())}):{success:!1,error:`プラグイン '${e}' が見つかりません`}}async processExecutionQueue(){if(!this.isProcessingQueue){this.isProcessingQueue=!0
7
+ try{for(;this.executionQueue.length>0;){const e=Math.min(this.config.maxConcurrentExecution,this.executionQueue.length),t=this.executionQueue.splice(0,e).map(e=>this.executeTask(e))
8
+ await Promise.allSettled(t)}}finally{this.isProcessingQueue=!1}}}async executeTask(e){const t=Date.now()
9
+ let i
10
+ try{const s=await this.getOrLoadPlugin(e.pluginId)
11
+ if(!s)throw Error(`プラグイン '${e.pluginId}' の読み込みに失敗しました`)
12
+ i=await s.executeTool(e.toolName,e.args,e.userCredentials),this.recordExecution(e.pluginId,!0,Date.now()-t),e.resolve(i)}catch(s){this.recordExecution(e.pluginId,!1,Date.now()-t),i={success:!1,error:"プラグイン実行エラー: "+s,metadata:{pluginId:e.pluginId,toolName:e.toolName,error:s+""}},e.resolve(i)}}async getOrLoadPlugin(e){const t=this.pluginCache.get(e)
13
+ if(t)return t.lastUsed=new Date,t.usageCount++,t.plugin
14
+ this.pluginCache.size>=this.config.maxLoadedPlugins&&await this.evictLeastUsedPlugin()
15
+ const i=Date.now(),s=await this.pluginLoader.loadPlugin(e)
16
+ if(s){this.pluginCache.set(e,{plugin:s,lastUsed:new Date,usageCount:1})
17
+ const t=this.pluginStats.get(e)
18
+ t&&(t.loadTime=Date.now()-i)}return s}async evictLeastUsedPlugin(){let e=null,t=Date.now()
19
+ for(const[i,s]of this.pluginCache)s.lastUsed.getTime()<t&&(t=s.lastUsed.getTime(),e=i)
20
+ if(e){const t=this.pluginCache.get(e)
21
+ t&&(await t.plugin.shutdown(),this.pluginCache.delete(e))}}recordExecution(e,t,i){const s=this.pluginStats.get(e)
22
+ s&&(s.totalExecutions++,s.lastExecuted=new Date,t?s.successfulExecutions++:s.failedExecutions++,s.averageExecutionTime=(s.averageExecutionTime*(s.totalExecutions-1)+i)/s.totalExecutions)}startHealthCheckTimer(){this.healthCheckTimer=setInterval(async()=>{await this.performHealthChecks()},this.config.healthCheckIntervalMs)}startExecutionQueueProcessor(){setInterval(()=>{this.executionQueue.length>0&&!this.isProcessingQueue&&this.processExecutionQueue()},100)}async performHealthChecks(){const e=[]
23
+ for(const[t,i]of this.pluginCache)e.push(this.checkPluginHealth(t,i.plugin))
24
+ await Promise.allSettled(e)}async checkPluginHealth(e,t){try{const i=await t.healthCheck(),s=this.pluginStats.get(e)
25
+ s&&(s.healthStatus=i.status),i.status}catch(t){const i=this.pluginStats.get(e)
26
+ i&&(i.healthStatus="unhealthy")}}getAvailableTools(){const e=[]
27
+ for(const t of this.manifestRegistry.values())for(const i of t.tools)e.push({name:i.name,description:i.description,inputSchema:i.inputSchema})
28
+ return e}getPluginStats(){return Array.from(this.pluginStats.values())}async shutdown(){this.healthCheckTimer&&clearInterval(this.healthCheckTimer)
29
+ const e=[]
30
+ for(const[t,i]of this.pluginCache)e.push(i.plugin.shutdown())
31
+ await Promise.allSettled(e),this.pluginCache.clear()}generateTaskId(){return`task_${Date.now()}_${Math.random().toString(36).substr(2,9)}`}getPluginManifest(e){return this.manifestRegistry.get(e)}getRegisteredPlugins(){return Array.from(this.manifestRegistry.keys())}}exports.PluginManager=PluginManager,exports.pluginManager=new PluginManager