@nahisaho/shikigami 1.26.0 → 1.28.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.
- package/AGENTS.md +242 -33
- package/CHANGELOG.md +106 -0
- package/mcp-server/src/index.ts +31 -5
- package/mcp-server/src/tools/__tests__/save.test.ts +60 -3
- package/mcp-server/src/tools/save.ts +61 -8
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -6,10 +6,16 @@
|
|
|
6
6
|
|
|
7
7
|
## ⛔⛔⛔ 最重要ルール - 調査開始前に必ず読め ⛔⛔⛔
|
|
8
8
|
|
|
9
|
-
> **🚨
|
|
9
|
+
> **🚨 警告1**: リサーチ・調査・分析の依頼を受けた場合、**Web検索やファイル読み込みを行う前に**、
|
|
10
10
|
> 必ず `npx shikigami new <ProjectName>` を実行してプロジェクトフォルダを作成すること。
|
|
11
11
|
> **プロジェクト作成前の調査行為は禁止。**
|
|
12
12
|
|
|
13
|
+
> **🚨 警告2**: search/visitツールを実行したら、**必ず `save_research` MCPツールを呼び出すこと**。
|
|
14
|
+
> 保存しないと**research/ディレクトリに記録が残らない**。詳細は「4.2 リサーチ結果永続化ルール」参照。
|
|
15
|
+
|
|
16
|
+
> **🚨 警告3(v1.28.0)**: ユーザーの入力を受け取ったら、**必ず `save_prompt` MCPツールを呼び出すこと**。
|
|
17
|
+
> 最初のプロンプトだけでなく、**すべての回答・指示・フィードバックを保存する**。詳細は「4.1 プロンプト保存ルール」参照。
|
|
18
|
+
|
|
13
19
|
### 正しい実行順序(必ず守ること)
|
|
14
20
|
|
|
15
21
|
```
|
|
@@ -22,6 +28,10 @@
|
|
|
22
28
|
│ npx shikigami new <ProjectName> │
|
|
23
29
|
│ ⚠️ このコマンドを実行するまで調査禁止 │
|
|
24
30
|
├─────────────────────────────────────────────────────────────┤
|
|
31
|
+
│ ステップ2.5: ⭐ プロジェクトコンテキスト設定 ⭐ │
|
|
32
|
+
│ {"tool":"set_project","arguments":{"autoDetect":true}}│
|
|
33
|
+
│ ⚠️ これを実行しないとresearch/に保存できない │
|
|
34
|
+
├─────────────────────────────────────────────────────────────┤
|
|
25
35
|
│ ステップ3: 作成されたフォルダを確認 │
|
|
26
36
|
│ projects/pjXXXXX_<Name>_YYYYMMDD/ が存在するか │
|
|
27
37
|
├─────────────────────────────────────────────────────────────┤
|
|
@@ -33,6 +43,7 @@
|
|
|
33
43
|
│ ステップ6: 目的探索(1問1答形式で真の目的を探る) │
|
|
34
44
|
├─────────────────────────────────────────────────────────────┤
|
|
35
45
|
│ ステップ7: ここでようやくWeb検索・調査を開始してよい │
|
|
46
|
+
│ ⭐ search/visit実行後は必ずsave_researchを呼ぶ ⭐│
|
|
36
47
|
└─────────────────────────────────────────────────────────────┘
|
|
37
48
|
```
|
|
38
49
|
|
|
@@ -45,6 +56,11 @@
|
|
|
45
56
|
| プロジェクト作成前に情報収集 | ワークフロー違反 |
|
|
46
57
|
| 「まず調べてみます」と言う | Phase 0完了前は禁止 |
|
|
47
58
|
| 依頼を受けてすぐに調査開始 | 必ずプロジェクト作成が先 |
|
|
59
|
+
| **search後にsave_researchを呼ばない** | **research/に保存されない** |
|
|
60
|
+
| **visit後にsave_researchを呼ばない** | **research/に保存されない** |
|
|
61
|
+
| **set_projectを呼ばずに調査開始** | **保存先が不明になる** |
|
|
62
|
+
| **ユーザー入力後にsave_promptを呼ばない** | **prompts/に会話が残らない** |
|
|
63
|
+
| **最初のプロンプトのみ保存する** | **後続の重要な対話が失われる** |
|
|
48
64
|
|
|
49
65
|
### ✅ 正しい応答例
|
|
50
66
|
|
|
@@ -248,58 +264,212 @@ Phase 5: Completion(完了)
|
|
|
248
264
|
|
|
249
265
|
**禁止**: `research/` に最終レポートを保存、`reports/` に調査メモを保存
|
|
250
266
|
|
|
251
|
-
### 4.1 プロンプト保存ルール(v1.
|
|
267
|
+
### 4.1 プロンプト保存ルール(v1.28.0 Updated!)
|
|
268
|
+
|
|
269
|
+
> **🚨 重要**: ユーザーが入力した**すべてのプロンプト・回答・指示**を `prompts/` ディレクトリに保存すること。
|
|
270
|
+
> **最初のプロンプトだけでなく、セッション中のすべてのユーザー入力を記録する。**
|
|
252
271
|
|
|
253
|
-
|
|
272
|
+
#### ⚠️ 保存対象(v1.28.0 拡張)
|
|
254
273
|
|
|
255
|
-
|
|
|
274
|
+
| 保存対象 | 説明 | 保存タイミング |
|
|
256
275
|
|---------|------|--------------|
|
|
257
|
-
|
|
|
258
|
-
|
|
|
259
|
-
|
|
|
276
|
+
| **初回プロンプト** | リサーチ依頼の最初の入力 | Phase 0.5開始時 |
|
|
277
|
+
| **質問への回答** | Phase 1の1問1答での回答 | **回答を受け取るたび** |
|
|
278
|
+
| **修正指示** | 構造化プロンプトの修正要求 | **修正指示を受け取るたび** |
|
|
279
|
+
| **追加指示** | 調査中の追加要求・方向転換 | **追加指示を受け取るたび** |
|
|
280
|
+
| **フィードバック** | レポートへの修正要求 | **フィードバックを受け取るたび** |
|
|
281
|
+
| **承認・確認** | 「はい」「OK」などの承認 | **承認を受け取るたび** |
|
|
282
|
+
|
|
283
|
+
#### ⛔ 禁止行動
|
|
284
|
+
|
|
285
|
+
| 禁止行動 | 理由 |
|
|
286
|
+
|---------|------|
|
|
287
|
+
| 初回プロンプトのみ保存 | 後続の重要な対話が失われる |
|
|
288
|
+
| 回答を記録せずに次に進む | ナレッジの散逸 |
|
|
289
|
+
| save_promptを呼ばずに会話を続ける | prompts/に記録が残らない |
|
|
290
|
+
|
|
291
|
+
#### ✅ 必須フロー(v1.28.0)
|
|
292
|
+
|
|
293
|
+
```
|
|
294
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
295
|
+
│ ユーザー入力を受け取るたびに: │
|
|
296
|
+
│ │
|
|
297
|
+
│ 1. save_prompt MCPツールを呼び出す │
|
|
298
|
+
│ {"tool":"save_prompt","arguments":{ │
|
|
299
|
+
│ "content":"ユーザーの入力内容", │
|
|
300
|
+
│ "type":"answer" | "instruction" | "feedback" | "approval"│
|
|
301
|
+
│ }} │
|
|
302
|
+
│ │
|
|
303
|
+
│ 2. 処理を続行 │
|
|
304
|
+
└─────────────────────────────────────────────────────────────┘
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
#### save_prompt の type パラメータ
|
|
308
|
+
|
|
309
|
+
| type | 用途 | ファイル名例 |
|
|
310
|
+
|------|------|-------------|
|
|
311
|
+
| `"original"` | 最初のリサーチ依頼 | `prompt_original_20260127_100000.md` |
|
|
312
|
+
| `"structured"` | 構造化プロンプト(AI生成) | `prompt_structured_20260127_100500.md` |
|
|
313
|
+
| `"answer"` | 質問への回答 | `prompt_answer_20260127_101000.md` |
|
|
314
|
+
| `"instruction"` | 追加指示・修正要求 | `prompt_instruction_20260127_102000.md` |
|
|
315
|
+
| `"feedback"` | レポートへのフィードバック | `prompt_feedback_20260127_150000.md` |
|
|
316
|
+
| `"approval"` | 承認・確認 | `prompt_approval_20260127_101500.md` |
|
|
317
|
+
|
|
318
|
+
#### 保存ファイルフォーマット
|
|
260
319
|
|
|
261
|
-
**フォーマット(original-prompt.md)**:
|
|
262
320
|
```markdown
|
|
263
321
|
---
|
|
264
|
-
timestamp: "2026-01-27T10:
|
|
322
|
+
timestamp: "2026-01-27T10:10:00+09:00"
|
|
265
323
|
project_id: "pj00001"
|
|
324
|
+
type: "answer"
|
|
325
|
+
phase: "1"
|
|
326
|
+
sequence: 3
|
|
266
327
|
---
|
|
267
328
|
|
|
268
|
-
#
|
|
329
|
+
# User Input
|
|
330
|
+
|
|
331
|
+
[ユーザーの入力内容をそのまま記録]
|
|
269
332
|
|
|
270
|
-
|
|
333
|
+
## Context
|
|
334
|
+
|
|
335
|
+
- Previous question: [AIが聞いた質問]
|
|
336
|
+
- Phase: 1 (Purpose Discovery)
|
|
271
337
|
```
|
|
272
338
|
|
|
273
|
-
|
|
339
|
+
#### 会話ログの一元管理
|
|
340
|
+
|
|
341
|
+
すべてのプロンプトは `prompts/conversation-log.md` にも追記されます:
|
|
342
|
+
|
|
274
343
|
```markdown
|
|
275
|
-
|
|
276
|
-
timestamp: "2026-01-27T10:05:00+09:00"
|
|
277
|
-
project_id: "pj00001"
|
|
278
|
-
version: 1
|
|
279
|
-
approved: true
|
|
280
|
-
---
|
|
344
|
+
# Conversation Log
|
|
281
345
|
|
|
282
|
-
|
|
346
|
+
## Session: 2026-01-27
|
|
283
347
|
|
|
284
|
-
|
|
285
|
-
|
|
348
|
+
### [10:00:00] User (original)
|
|
349
|
+
レアメタルについて調べて
|
|
286
350
|
|
|
287
|
-
|
|
288
|
-
[
|
|
351
|
+
### [10:05:00] AI (structured)
|
|
352
|
+
[構造化プロンプトを表示]
|
|
289
353
|
|
|
290
|
-
|
|
291
|
-
|
|
354
|
+
### [10:06:00] User (approval)
|
|
355
|
+
はい、それでお願いします
|
|
292
356
|
|
|
293
|
-
|
|
294
|
-
|
|
357
|
+
### [10:07:00] AI (question)
|
|
358
|
+
この調査結果は誰が使いますか?
|
|
295
359
|
|
|
296
|
-
|
|
297
|
-
|
|
360
|
+
### [10:08:00] User (answer)
|
|
361
|
+
経営会議で使います
|
|
298
362
|
|
|
299
|
-
|
|
300
|
-
|
|
363
|
+
### [10:09:00] AI (question)
|
|
364
|
+
いつまでに必要ですか?
|
|
365
|
+
|
|
366
|
+
### [10:10:00] User (answer)
|
|
367
|
+
来週の金曜日までに
|
|
368
|
+
|
|
369
|
+
...
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
### 4.2 ⛔⛔⛔ リサーチ結果永続化ルール(v1.27.0 必須)⛔⛔⛔
|
|
373
|
+
|
|
374
|
+
> **🚨 最重要**: search/visitツールを実行したら、**必ず `save_research` MCPツールを呼び出してリサーチ結果を保存すること**。
|
|
375
|
+
> **保存しないとresearch/ディレクトリに記録が残らず、ナレッジが散逸する。**
|
|
376
|
+
|
|
377
|
+
#### ⚠️ 必須フロー(Phase 2 で毎回実行)
|
|
378
|
+
|
|
379
|
+
```
|
|
380
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
381
|
+
│ ステップ1: プロジェクト設定(Phase 0 完了直後に1回だけ) │
|
|
382
|
+
│ ↓ │
|
|
383
|
+
│ MCPツール: set_project を呼び出す │
|
|
384
|
+
│ {"tool":"set_project","arguments":{"autoDetect":true}}│
|
|
385
|
+
├─────────────────────────────────────────────────────────────┤
|
|
386
|
+
│ ステップ2: 検索実行 │
|
|
387
|
+
│ ↓ │
|
|
388
|
+
│ shikigami_search / search ツールを実行 │
|
|
389
|
+
├─────────────────────────────────────────────────────────────┤
|
|
390
|
+
│ ステップ3: ⭐ 検索結果を保存 ⭐ │
|
|
391
|
+
│ ↓ │
|
|
392
|
+
│ MCPツール: save_research を呼び出す │
|
|
393
|
+
│ {"tool":"save_research","arguments":{ │
|
|
394
|
+
│ "content":"検索結果の内容", │
|
|
395
|
+
│ "query":"検索クエリ", │
|
|
396
|
+
│ "source":"search" │
|
|
397
|
+
│ }} │
|
|
398
|
+
├─────────────────────────────────────────────────────────────┤
|
|
399
|
+
│ ステップ4: URL訪問実行 │
|
|
400
|
+
│ ↓ │
|
|
401
|
+
│ shikigami_visit / visit ツールを実行 │
|
|
402
|
+
├─────────────────────────────────────────────────────────────┤
|
|
403
|
+
│ ステップ5: ⭐ 訪問結果を保存 ⭐ │
|
|
404
|
+
│ ↓ │
|
|
405
|
+
│ MCPツール: save_research を呼び出す │
|
|
406
|
+
│ {"tool":"save_research","arguments":{ │
|
|
407
|
+
│ "content":"ページ内容の抽出結果", │
|
|
408
|
+
│ "query":"訪問したURL", │
|
|
409
|
+
│ "source":"visit" │
|
|
410
|
+
│ }} │
|
|
411
|
+
├─────────────────────────────────────────────────────────────┤
|
|
412
|
+
│ ステップ6: 分析・メモを保存(任意だが推奨) │
|
|
413
|
+
│ ↓ │
|
|
414
|
+
│ {"tool":"save_research","arguments":{ │
|
|
415
|
+
│ "content":"分析結果・考察・メモ", │
|
|
416
|
+
│ "query":"分析テーマ", │
|
|
417
|
+
│ "source":"manual" │
|
|
418
|
+
│ }} │
|
|
419
|
+
└─────────────────────────────────────────────────────────────┘
|
|
301
420
|
```
|
|
302
421
|
|
|
422
|
+
#### ❌ 禁止される行動パターン
|
|
423
|
+
|
|
424
|
+
| 禁止行動 | 理由 |
|
|
425
|
+
|---------|------|
|
|
426
|
+
| searchを実行してsave_researchを呼ばない | 検索結果がresearch/に保存されない |
|
|
427
|
+
| visitを実行してsave_researchを呼ばない | 訪問結果がresearch/に保存されない |
|
|
428
|
+
| set_projectを呼ばずにsave_researchを呼ぶ | 保存先プロジェクトが不明でエラー |
|
|
429
|
+
| search結果を単に表示して次に進む | ナレッジが散逸する |
|
|
430
|
+
|
|
431
|
+
#### ✅ 正しいコード例
|
|
432
|
+
|
|
433
|
+
```typescript
|
|
434
|
+
// ステップ1: プロジェクト設定(Phase 0完了直後に1回)
|
|
435
|
+
{"tool":"set_project","arguments":{"autoDetect":true}}
|
|
436
|
+
|
|
437
|
+
// ステップ2-3: 検索 → 保存
|
|
438
|
+
{"tool":"shikigami_search","arguments":{"query":"レアメタル市場動向 2025"}}
|
|
439
|
+
// 結果を受け取ったら即座に:
|
|
440
|
+
{"tool":"save_research","arguments":{
|
|
441
|
+
"content":"[検索結果の内容をここにコピー]",
|
|
442
|
+
"query":"レアメタル市場動向 2025",
|
|
443
|
+
"source":"search"
|
|
444
|
+
}}
|
|
445
|
+
|
|
446
|
+
// ステップ4-5: 訪問 → 保存
|
|
447
|
+
{"tool":"shikigami_visit","arguments":{"url":"https://example.com/article"}}
|
|
448
|
+
// 結果を受け取ったら即座に:
|
|
449
|
+
{"tool":"save_research","arguments":{
|
|
450
|
+
"content":"[ページ内容をここにコピー]",
|
|
451
|
+
"query":"https://example.com/article",
|
|
452
|
+
"source":"visit"
|
|
453
|
+
}}
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
#### 保存されるファイル
|
|
457
|
+
|
|
458
|
+
| sourceパラメータ | 保存先 | ファイル名例 |
|
|
459
|
+
|-----------------|--------|-------------|
|
|
460
|
+
| `"search"` | `research/` | `search_レアメタル市場動向_20260127_143052.md` |
|
|
461
|
+
| `"visit"` | `research/` | `visit_example.com_20260127_143105.md` |
|
|
462
|
+
| `"manual"` | `research/` | `manual_SWOT分析メモ_20260127_143200.md` |
|
|
463
|
+
|
|
464
|
+
#### MCPツール一覧(永続化関連)
|
|
465
|
+
|
|
466
|
+
| ツール | 用途 | 必須タイミング |
|
|
467
|
+
|--------|------|--------------|
|
|
468
|
+
| `set_project` | プロジェクトコンテキスト設定 | Phase 0完了直後(1回) |
|
|
469
|
+
| `get_project` | 現在のプロジェクト確認 | デバッグ時 |
|
|
470
|
+
| `save_research` | リサーチ結果をresearch/に保存 | **search/visit実行後毎回** |
|
|
471
|
+
| `save_prompt` | プロンプトをprompts/に保存 | Phase 0.5 |
|
|
472
|
+
|
|
303
473
|
### 5. Citation(引用)ルール
|
|
304
474
|
|
|
305
475
|
**すべてのデータ・事実主張にはソースURLを付与すること。URLなしの参考文献は禁止。**
|
|
@@ -398,18 +568,57 @@ approved: true
|
|
|
398
568
|
|
|
399
569
|
| 項目 | 詳細 |
|
|
400
570
|
|------|------|
|
|
401
|
-
| **バージョン** | 1.
|
|
571
|
+
| **バージョン** | 1.27.0 |
|
|
402
572
|
| **言語** | TypeScript |
|
|
403
573
|
| **ランタイム** | Node.js >= 20.0.0 |
|
|
404
574
|
| **Agent Skills** | 4スキル |
|
|
405
575
|
| **Prompts** | 16プロンプト |
|
|
406
576
|
| **フレームワーク** | 53定義 |
|
|
407
|
-
| **MCPツール** |
|
|
577
|
+
| **MCPツール** | 11ツール |
|
|
408
578
|
| **レポートテンプレート** | 33種類 |
|
|
409
579
|
| **テスト数** | 250+ |
|
|
410
580
|
|
|
411
581
|
---
|
|
412
582
|
|
|
583
|
+
## 🆕 v1.27.0 新機能(リサーチ結果永続化の必須化)
|
|
584
|
+
|
|
585
|
+
### save_research MCPツールの必須化
|
|
586
|
+
|
|
587
|
+
search/visitツール実行後に**必ず `save_research` MCPツールを呼び出す**ルールを追加しました。これによりリサーチ結果が確実に`research/`ディレクトリに保存されます。
|
|
588
|
+
|
|
589
|
+
#### 必須フロー
|
|
590
|
+
|
|
591
|
+
```
|
|
592
|
+
npx shikigami new <ProjectName>
|
|
593
|
+
↓
|
|
594
|
+
set_project(autoDetect: true) ← 新規追加(必須)
|
|
595
|
+
↓
|
|
596
|
+
search実行 → save_research(source: "search") ← 必須
|
|
597
|
+
↓
|
|
598
|
+
visit実行 → save_research(source: "visit") ← 必須
|
|
599
|
+
↓
|
|
600
|
+
分析メモ → save_research(source: "manual") ← 推奨
|
|
601
|
+
```
|
|
602
|
+
|
|
603
|
+
#### MCPツール
|
|
604
|
+
|
|
605
|
+
| ツール | 用途 | 必須タイミング |
|
|
606
|
+
|--------|------|--------------|
|
|
607
|
+
| `set_project` | プロジェクトコンテキスト設定 | Phase 0完了直後(1回) |
|
|
608
|
+
| `save_research` | リサーチ結果をresearch/に保存 | **search/visit実行後毎回** |
|
|
609
|
+
|
|
610
|
+
#### 保存されるファイル形式
|
|
611
|
+
|
|
612
|
+
| source | ファイル名例 |
|
|
613
|
+
|--------|-------------|
|
|
614
|
+
| `"search"` | `search_レアメタル市場_20260127_143052.md` |
|
|
615
|
+
| `"visit"` | `visit_example.com_20260127_143105.md` |
|
|
616
|
+
| `"manual"` | `manual_SWOT分析_20260127_143200.md` |
|
|
617
|
+
|
|
618
|
+
詳細は「4.2 リサーチ結果永続化ルール」セクション参照。
|
|
619
|
+
|
|
620
|
+
---
|
|
621
|
+
|
|
413
622
|
## 🆕 v1.22.0 新機能(Qiita記事作成強化)
|
|
414
623
|
|
|
415
624
|
### Qiita記事ダイレクト生成 - Writing Rules強制適用
|
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,112 @@ All notable changes to SHIKIGAMI will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.28.0] - 2026-01-27
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- **最初のプロンプトのみが保存される問題を修正**
|
|
13
|
+
- 問題: Phase 0.5の初回プロンプトだけが保存され、その後の回答・指示・フィードバックが保存されない
|
|
14
|
+
- 原因: save_promptのtypeが`original`, `structured`, `refinement`の3種のみだった
|
|
15
|
+
- 対策: 4つの新しいtypeを追加し、全てのユーザー入力を保存可能に
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- **save_prompt MCPツールの拡張**
|
|
20
|
+
- 新しいtypeパラメータ:
|
|
21
|
+
- `answer`: 質問への回答
|
|
22
|
+
- `instruction`: 追加指示・修正要求
|
|
23
|
+
- `feedback`: レポートへのフィードバック
|
|
24
|
+
- `approval`: 承認・確認
|
|
25
|
+
- 新しいパラメータ:
|
|
26
|
+
- `phase`: 現在のフェーズ(0, 0.5, 1, 2, 3, 4, 5)
|
|
27
|
+
- `sequence`: セッション内の連番
|
|
28
|
+
- `context`: コンテキスト情報(前の質問など)
|
|
29
|
+
|
|
30
|
+
- **会話ログ機能(conversation-log.md)**
|
|
31
|
+
- 全てのプロンプトを`prompts/conversation-log.md`に自動追記
|
|
32
|
+
- タイムスタンプ付きの時系列記録
|
|
33
|
+
- User/AIの役割とtypeを明記
|
|
34
|
+
|
|
35
|
+
- **AGENTS.md: 「最重要ルール」セクション強化**
|
|
36
|
+
- 警告3を追加: 「ユーザー入力を受け取ったら必ずsave_promptを呼ぶこと」
|
|
37
|
+
- 禁止行動パターンに2項目追加
|
|
38
|
+
|
|
39
|
+
- **AGENTS.md: 「4.1 プロンプト保存ルール」セクション全面更新**
|
|
40
|
+
- 保存対象表に6種類の入力タイプを追加
|
|
41
|
+
- 禁止行動セクション追加
|
|
42
|
+
- 必須フロー図解追加
|
|
43
|
+
- save_promptのtypeパラメータ表追加
|
|
44
|
+
- 保存ファイルフォーマット追加
|
|
45
|
+
- 会話ログの例追加
|
|
46
|
+
|
|
47
|
+
### Changed
|
|
48
|
+
|
|
49
|
+
- **ファイル命名規則の統一**
|
|
50
|
+
- 旧: `original-prompt_YYYYMMDD_HHMMSS.md`
|
|
51
|
+
- 新: `prompt_original_YYYYMMDD_HHMMSS.md`
|
|
52
|
+
- 全typeで`prompt_<type>_<date>_<time>.md`形式に統一
|
|
53
|
+
|
|
54
|
+
- **プロンプト保存の必須化**
|
|
55
|
+
```
|
|
56
|
+
ユーザー入力を受け取るたびに:
|
|
57
|
+
1. save_prompt MCPツールを呼び出す
|
|
58
|
+
2. 適切なtypeを指定 (answer/instruction/feedback/approval)
|
|
59
|
+
3. 処理を続行
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## [1.27.0] - 2026-01-27
|
|
65
|
+
|
|
66
|
+
### Fixed
|
|
67
|
+
|
|
68
|
+
- **リサーチ結果がresearch/に保存されない問題をAGENTS.md強化で修正**
|
|
69
|
+
- 問題: v1.26.0のPromptファイル更新だけでは、AI Agentが`save_research`の存在を認識しない場合がある
|
|
70
|
+
- 原因: AGENTS.md(AI Agentが最初に読むファイル)に`save_research`の必須ルールがなかった
|
|
71
|
+
- 対策: AGENTS.mdの「最重要ルール」と「絶対ルール」セクションに`save_research`必須指示を追加
|
|
72
|
+
|
|
73
|
+
### Added
|
|
74
|
+
|
|
75
|
+
- **AGENTS.md: 「最重要ルール」セクション強化**
|
|
76
|
+
- 警告2を追加: 「search/visit実行後は必ずsave_researchを呼ぶこと」
|
|
77
|
+
- 実行順序フローに「ステップ2.5: set_project実行」を追加
|
|
78
|
+
- ステップ7に「search/visit後は必ずsave_research」注記を追加
|
|
79
|
+
- 禁止行動パターンに3項目追加(save_research未呼び出し、set_project未実行)
|
|
80
|
+
|
|
81
|
+
- **AGENTS.md: 「4.2 リサーチ結果永続化ルール」セクション新規追加**
|
|
82
|
+
- 必須フロー図解(6ステップ)
|
|
83
|
+
- 禁止行動パターン表
|
|
84
|
+
- 正しいコード例(TypeScript形式)
|
|
85
|
+
- 保存されるファイル形式表
|
|
86
|
+
- MCPツール一覧(永続化関連)
|
|
87
|
+
|
|
88
|
+
- **AGENTS.md: 「v1.27.0 新機能」セクション追加**
|
|
89
|
+
- save_research MCPツールの必須化についての説明
|
|
90
|
+
- 必須フローの簡潔な図解
|
|
91
|
+
- 保存されるファイル形式
|
|
92
|
+
|
|
93
|
+
### Changed
|
|
94
|
+
|
|
95
|
+
- **AGENTS.md: プロジェクト概要のバージョン更新**
|
|
96
|
+
- バージョン: 1.22.0 → 1.27.0
|
|
97
|
+
- MCPツール数: 7 → 11
|
|
98
|
+
|
|
99
|
+
- **永続化フローの明確化**
|
|
100
|
+
```
|
|
101
|
+
Phase 0: npx shikigami new <ProjectName>
|
|
102
|
+
↓
|
|
103
|
+
set_project(autoDetect: true) ← 必須
|
|
104
|
+
↓
|
|
105
|
+
Phase 2: search → save_research(source: "search") ← 必須
|
|
106
|
+
↓
|
|
107
|
+
visit → save_research(source: "visit") ← 必須
|
|
108
|
+
↓
|
|
109
|
+
Phase 3: 分析 → save_research(source: "manual") ← 推奨
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
8
114
|
## [1.26.0] - 2026-01-27
|
|
9
115
|
|
|
10
116
|
### Fixed
|
package/mcp-server/src/index.ts
CHANGED
|
@@ -77,19 +77,27 @@ save_prompt, save_researchの前に必ず実行。
|
|
|
77
77
|
{
|
|
78
78
|
name: 'save_prompt',
|
|
79
79
|
description: `プロンプトをプロジェクトのprompts/ディレクトリに保存。
|
|
80
|
-
|
|
80
|
+
v1.28.0: 最初のプロンプトだけでなく、すべてのユーザー入力(回答・指示・フィードバック)を保存。
|
|
81
|
+
ユーザーから入力を受け取るたびに必ず呼び出すこと。
|
|
81
82
|
set_projectでプロジェクトを設定してから使用。`,
|
|
82
83
|
inputSchema: {
|
|
83
84
|
type: 'object',
|
|
84
85
|
properties: {
|
|
85
86
|
content: {
|
|
86
87
|
type: 'string',
|
|
87
|
-
description: '
|
|
88
|
+
description: '保存するプロンプト/ユーザー入力の内容',
|
|
88
89
|
},
|
|
89
90
|
type: {
|
|
90
91
|
type: 'string',
|
|
91
|
-
enum: ['original', 'structured', 'refinement'],
|
|
92
|
-
description:
|
|
92
|
+
enum: ['original', 'structured', 'refinement', 'answer', 'instruction', 'feedback', 'approval'],
|
|
93
|
+
description: `入力の種類:
|
|
94
|
+
- original: 最初のリサーチ依頼
|
|
95
|
+
- structured: 構造化プロンプト(AI生成)
|
|
96
|
+
- refinement: 構造化プロンプトの修正
|
|
97
|
+
- answer: 質問への回答(v1.28.0)
|
|
98
|
+
- instruction: 追加指示・修正要求(v1.28.0)
|
|
99
|
+
- feedback: レポートへのフィードバック(v1.28.0)
|
|
100
|
+
- approval: 承認・確認(v1.28.0)`,
|
|
93
101
|
},
|
|
94
102
|
filename: {
|
|
95
103
|
type: 'string',
|
|
@@ -99,6 +107,18 @@ set_projectでプロジェクトを設定してから使用。`,
|
|
|
99
107
|
type: 'number',
|
|
100
108
|
description: '修正バージョン番号(refinementタイプの場合)',
|
|
101
109
|
},
|
|
110
|
+
phase: {
|
|
111
|
+
type: 'string',
|
|
112
|
+
description: '現在のフェーズ(0, 0.5, 1, 2, 3, 4, 5)',
|
|
113
|
+
},
|
|
114
|
+
sequence: {
|
|
115
|
+
type: 'number',
|
|
116
|
+
description: 'セッション内の連番',
|
|
117
|
+
},
|
|
118
|
+
context: {
|
|
119
|
+
type: 'string',
|
|
120
|
+
description: 'コンテキスト情報(前の質問など)',
|
|
121
|
+
},
|
|
102
122
|
metadata: {
|
|
103
123
|
type: 'object',
|
|
104
124
|
description: '追加のメタデータ',
|
|
@@ -435,15 +455,21 @@ server.setRequestHandler(CallToolRequestSchema, async (request: CallToolRequest)
|
|
|
435
455
|
|
|
436
456
|
case 'save_prompt': {
|
|
437
457
|
const content = args?.content as string;
|
|
438
|
-
const type = args?.type as 'original' | 'structured' | 'refinement';
|
|
458
|
+
const type = args?.type as 'original' | 'structured' | 'refinement' | 'answer' | 'instruction' | 'feedback' | 'approval';
|
|
439
459
|
const filename = args?.filename as string | undefined;
|
|
440
460
|
const version = args?.version as number | undefined;
|
|
461
|
+
const phase = args?.phase as string | undefined;
|
|
462
|
+
const sequence = args?.sequence as number | undefined;
|
|
463
|
+
const context = args?.context as string | undefined;
|
|
441
464
|
const metadata = args?.metadata as Record<string, unknown> | undefined;
|
|
442
465
|
|
|
443
466
|
const result = await savePrompt(content, {
|
|
444
467
|
type,
|
|
445
468
|
filename,
|
|
446
469
|
version,
|
|
470
|
+
phase,
|
|
471
|
+
sequence,
|
|
472
|
+
context,
|
|
447
473
|
metadata,
|
|
448
474
|
});
|
|
449
475
|
|
|
@@ -70,7 +70,7 @@ describe('Save Module', () => {
|
|
|
70
70
|
|
|
71
71
|
expect(result.success).toBe(true);
|
|
72
72
|
expect(result.filePath).toContain('prompts');
|
|
73
|
-
expect(result.filePath).toContain('
|
|
73
|
+
expect(result.filePath).toContain('prompt_original');
|
|
74
74
|
expect(fs.writeFileSync).toHaveBeenCalled();
|
|
75
75
|
|
|
76
76
|
// Check content includes frontmatter
|
|
@@ -88,7 +88,7 @@ describe('Save Module', () => {
|
|
|
88
88
|
});
|
|
89
89
|
|
|
90
90
|
expect(result.success).toBe(true);
|
|
91
|
-
expect(result.filePath).toContain('
|
|
91
|
+
expect(result.filePath).toContain('prompt_structured');
|
|
92
92
|
|
|
93
93
|
const writeCall = vi.mocked(fs.writeFileSync).mock.calls[0];
|
|
94
94
|
const content = writeCall[1] as string;
|
|
@@ -102,13 +102,70 @@ describe('Save Module', () => {
|
|
|
102
102
|
});
|
|
103
103
|
|
|
104
104
|
expect(result.success).toBe(true);
|
|
105
|
-
expect(result.filePath).toContain('
|
|
105
|
+
expect(result.filePath).toContain('prompt_refinement-2');
|
|
106
106
|
|
|
107
107
|
const writeCall = vi.mocked(fs.writeFileSync).mock.calls[0];
|
|
108
108
|
const content = writeCall[1] as string;
|
|
109
109
|
expect(content).toContain('version: 2');
|
|
110
110
|
});
|
|
111
111
|
|
|
112
|
+
it('should save answer type (v1.28.0)', async () => {
|
|
113
|
+
const result = await savePrompt('User answer', {
|
|
114
|
+
type: 'answer',
|
|
115
|
+
phase: '1',
|
|
116
|
+
sequence: 3,
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
expect(result.success).toBe(true);
|
|
120
|
+
expect(result.filePath).toContain('prompt_answer');
|
|
121
|
+
|
|
122
|
+
const writeCall = vi.mocked(fs.writeFileSync).mock.calls[0];
|
|
123
|
+
const content = writeCall[1] as string;
|
|
124
|
+
expect(content).toContain('type: "answer"');
|
|
125
|
+
expect(content).toContain('phase: "1"');
|
|
126
|
+
expect(content).toContain('sequence: 3');
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it('should save instruction type (v1.28.0)', async () => {
|
|
130
|
+
const result = await savePrompt('Additional instruction', {
|
|
131
|
+
type: 'instruction',
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
expect(result.success).toBe(true);
|
|
135
|
+
expect(result.filePath).toContain('prompt_instruction');
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it('should save feedback type (v1.28.0)', async () => {
|
|
139
|
+
const result = await savePrompt('Report feedback', {
|
|
140
|
+
type: 'feedback',
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
expect(result.success).toBe(true);
|
|
144
|
+
expect(result.filePath).toContain('prompt_feedback');
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it('should save approval type (v1.28.0)', async () => {
|
|
148
|
+
const result = await savePrompt('Yes, approved', {
|
|
149
|
+
type: 'approval',
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
expect(result.success).toBe(true);
|
|
153
|
+
expect(result.filePath).toContain('prompt_approval');
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
it('should include context when provided (v1.28.0)', async () => {
|
|
157
|
+
const result = await savePrompt('User answer', {
|
|
158
|
+
type: 'answer',
|
|
159
|
+
context: 'Previous question: What is the purpose?',
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
expect(result.success).toBe(true);
|
|
163
|
+
const writeCall = vi.mocked(fs.writeFileSync).mock.calls[0];
|
|
164
|
+
const content = writeCall[1] as string;
|
|
165
|
+
expect(content).toContain('## Context');
|
|
166
|
+
expect(content).toContain('Previous question: What is the purpose?');
|
|
167
|
+
});
|
|
168
|
+
|
|
112
169
|
it('should use custom filename when provided', async () => {
|
|
113
170
|
const result = await savePrompt('Content', {
|
|
114
171
|
type: 'original',
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* File Save Module
|
|
3
|
-
* v1.
|
|
3
|
+
* v1.28.0 - REQ-SHIKIGAMI-016: プロンプト・検索結果の永続化
|
|
4
4
|
*
|
|
5
5
|
* プロンプトをprompts/に、検索結果をresearch/に保存する機能
|
|
6
|
+
* v1.28.0: すべてのユーザー入力(回答・指示・フィードバック)を保存
|
|
6
7
|
*/
|
|
7
8
|
|
|
8
9
|
import * as fs from 'fs';
|
|
@@ -17,11 +18,14 @@ export interface SaveResult {
|
|
|
17
18
|
timestamp: string;
|
|
18
19
|
}
|
|
19
20
|
|
|
20
|
-
//
|
|
21
|
+
// プロンプト保存オプション(v1.28.0 拡張)
|
|
21
22
|
export interface SavePromptOptions {
|
|
22
23
|
filename?: string;
|
|
23
|
-
type: 'original' | 'structured' | 'refinement';
|
|
24
|
+
type: 'original' | 'structured' | 'refinement' | 'answer' | 'instruction' | 'feedback' | 'approval';
|
|
24
25
|
version?: number;
|
|
26
|
+
phase?: string;
|
|
27
|
+
sequence?: number;
|
|
28
|
+
context?: string;
|
|
25
29
|
metadata?: Record<string, unknown>;
|
|
26
30
|
}
|
|
27
31
|
|
|
@@ -87,13 +91,25 @@ export async function savePrompt(
|
|
|
87
91
|
} else {
|
|
88
92
|
switch (options.type) {
|
|
89
93
|
case 'original':
|
|
90
|
-
filename = `
|
|
94
|
+
filename = `prompt_original_${dateStr}_${timeStr}.md`;
|
|
91
95
|
break;
|
|
92
96
|
case 'structured':
|
|
93
|
-
filename = `
|
|
97
|
+
filename = `prompt_structured_${dateStr}_${timeStr}.md`;
|
|
94
98
|
break;
|
|
95
99
|
case 'refinement':
|
|
96
|
-
filename = `
|
|
100
|
+
filename = `prompt_refinement-${options.version || 1}_${dateStr}_${timeStr}.md`;
|
|
101
|
+
break;
|
|
102
|
+
case 'answer':
|
|
103
|
+
filename = `prompt_answer_${dateStr}_${timeStr}.md`;
|
|
104
|
+
break;
|
|
105
|
+
case 'instruction':
|
|
106
|
+
filename = `prompt_instruction_${dateStr}_${timeStr}.md`;
|
|
107
|
+
break;
|
|
108
|
+
case 'feedback':
|
|
109
|
+
filename = `prompt_feedback_${dateStr}_${timeStr}.md`;
|
|
110
|
+
break;
|
|
111
|
+
case 'approval':
|
|
112
|
+
filename = `prompt_approval_${dateStr}_${timeStr}.md`;
|
|
97
113
|
break;
|
|
98
114
|
default:
|
|
99
115
|
filename = `prompt_${dateStr}_${timeStr}.md`;
|
|
@@ -106,22 +122,28 @@ export async function savePrompt(
|
|
|
106
122
|
project_id: project.projectId,
|
|
107
123
|
type: options.type,
|
|
108
124
|
...(options.version && { version: options.version }),
|
|
125
|
+
...(options.phase && { phase: options.phase }),
|
|
126
|
+
...(options.sequence && { sequence: options.sequence }),
|
|
109
127
|
...(options.metadata && { metadata: options.metadata }),
|
|
110
128
|
};
|
|
111
129
|
|
|
112
130
|
const fullContent = `---
|
|
113
131
|
timestamp: "${frontmatter.timestamp}"
|
|
114
132
|
project_id: "${frontmatter.project_id}"
|
|
115
|
-
type: "${frontmatter.type}"${frontmatter.version ? `\nversion: ${frontmatter.version}` : ''}
|
|
133
|
+
type: "${frontmatter.type}"${frontmatter.version ? `\nversion: ${frontmatter.version}` : ''}${frontmatter.phase ? `\nphase: "${frontmatter.phase}"` : ''}${frontmatter.sequence ? `\nsequence: ${frontmatter.sequence}` : ''}
|
|
116
134
|
---
|
|
117
135
|
|
|
118
136
|
${content}
|
|
119
|
-
`;
|
|
137
|
+
${options.context ? `\n## Context\n\n${options.context}\n` : ''}`;
|
|
120
138
|
|
|
121
139
|
const filePath = path.join(project.promptsDir, filename);
|
|
122
140
|
|
|
123
141
|
try {
|
|
124
142
|
fs.writeFileSync(filePath, fullContent, 'utf-8');
|
|
143
|
+
|
|
144
|
+
// 会話ログにも追記(v1.28.0)
|
|
145
|
+
await appendToConversationLog(project.promptsDir, content, options.type, timestamp);
|
|
146
|
+
|
|
125
147
|
return {
|
|
126
148
|
success: true,
|
|
127
149
|
filePath,
|
|
@@ -134,6 +156,37 @@ ${content}
|
|
|
134
156
|
}
|
|
135
157
|
}
|
|
136
158
|
|
|
159
|
+
/**
|
|
160
|
+
* 会話ログに追記(v1.28.0)
|
|
161
|
+
*/
|
|
162
|
+
async function appendToConversationLog(
|
|
163
|
+
promptsDir: string,
|
|
164
|
+
content: string,
|
|
165
|
+
type: string,
|
|
166
|
+
timestamp: string
|
|
167
|
+
): Promise<void> {
|
|
168
|
+
const logPath = path.join(promptsDir, 'conversation-log.md');
|
|
169
|
+
const time = timestamp.split('T')[1].split('.')[0];
|
|
170
|
+
const date = timestamp.split('T')[0];
|
|
171
|
+
|
|
172
|
+
// ログファイルが存在しない場合はヘッダーを作成
|
|
173
|
+
let logContent = '';
|
|
174
|
+
if (!fs.existsSync(logPath)) {
|
|
175
|
+
logContent = `# Conversation Log\n\n## Session: ${date}\n\n`;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// エントリを追加
|
|
179
|
+
const role = type === 'structured' ? 'AI' : 'User';
|
|
180
|
+
logContent += `### [${time}] ${role} (${type})\n\n${content}\n\n---\n\n`;
|
|
181
|
+
|
|
182
|
+
try {
|
|
183
|
+
fs.appendFileSync(logPath, logContent, 'utf-8');
|
|
184
|
+
} catch {
|
|
185
|
+
// ログ追記失敗は警告のみ(メイン処理は継続)
|
|
186
|
+
console.warn(`Warning: Failed to append to conversation log`);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
137
190
|
/**
|
|
138
191
|
* 検索結果を保存
|
|
139
192
|
*/
|
package/package.json
CHANGED