Skip to content

Commit dcc1386

Browse files
web-flowclaude
andcommitted
docs: ドキュメントリファクタリング - DRY原則強化・API同期
## 変更内容 ### APIドキュメントと実装の同期 - domain.md: LEVEL_CONFIGにthresholdフィールド追記 - infrastructure.md: 未記載機能追記 - log_debug(), StructuredLogger, get_structured_logger() - safe_file_operation(), safe_cleanup(), with_error_context() ### Skills共通パターンの抽出 - _implementation-notes.md: バリデーションパターン・共通エラーメッセージ追加 - digest-config/SKILL.md: 重複コード削除(約60行) - digest-setup/SKILL.md: 重複コード削除(約55行) ### Commands/Skills間の重複解消 - commands/digest.md: セットアップセクション・DigestAnalyzer呼び出しパターン簡素化(約50行) ## 効果 - 削減行数: 約165行 - メンテナンス性: Single Source of Truth強化 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent dfb4554 commit dcc1386

6 files changed

Lines changed: 266 additions & 183 deletions

File tree

EpisodicRAG/commands/digest.md

Lines changed: 8 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -338,41 +338,15 @@ python3 finalize_from_shadow.py {{type}} "承認されたタイトル"
338338

339339
---
340340

341-
## セットアップ・管理用スキル(初回セットアップ時またはトラブル時に使用)
341+
## セットアップ・管理用スキル
342342

343-
プラグイン初回使用時やトラブル時に使用するスキル
343+
初回セットアップ時やトラブル時に使用するスキル
344344

345-
### @digest-setup - 初期セットアップ
346-
347-
```bash
348-
@digest-setup セットアップを実行
349-
```
350-
351-
- 設定ファイル(.claude-plugin/config.json)作成
352-
- ディレクトリ作成(data/Loops, data/Digests, data/Essences)
353-
- 対話的に設定を選択
354-
355-
### @digest-auto - 最適階層の推奨
356-
357-
```bash
358-
@digest-auto 今生成できるダイジェストを教えて
359-
```
360-
361-
- 現在の状態を分析
362-
- 生成可能な階層を判定
363-
- 推奨アクションを提示
364-
- まだらボケ検出と警告
365-
366-
### @digest-config - 設定変更
367-
368-
```bash
369-
@digest-config 設定を変更したい
370-
@digest-config weekly threshold を 7 に変更
371-
```
372-
373-
- 現在の設定を表示
374-
- 対話的に設定項目を変更
375-
- 設定ファイルを更新
345+
| スキル | 用途 | 詳細 |
346+
|--------|------|------|
347+
| `@digest-setup` | 初期セットアップ | [digest-setup SKILL.md](../skills/digest-setup/SKILL.md) |
348+
| `@digest-auto` | 最適階層の推奨 | [digest-auto SKILL.md](../skills/digest-auto/SKILL.md) |
349+
| `@digest-config` | 設定変更 | [digest-config SKILL.md](../skills/digest-config/SKILL.md) |
376350

377351
---
378352

@@ -402,23 +376,7 @@ python3 finalize_from_shadow.py {{type}} "承認されたタイトル"
402376
```
403377

404378
2. **Task tool**: DigestAnalyzerエージェント起動
405-
```python
406-
Task(
407-
subagent_type="EpisodicRAG-Plugin:DigestAnalyzer",
408-
description="Analyze Loop0001 for Weekly digest",
409-
prompt="""
410-
分析対象ファイル: C:\\Users\\anyth\\DEV\\homunculus\\Weave\\EpisodicRAG\\Loops\\L00001_認知アーキテクチャ論.txt
411-
412-
このLoopファイルを深層分析し、以下の形式でJSON出力してください:
413-
{{
414-
"digest_type": "...",
415-
"keywords": [...],
416-
"abstract": {{"long": "...", "short": "..."}},
417-
"impression": {{"long": "...", "short": "..."}}
418-
}}
419-
"""
420-
)
421-
```
379+
> 📖 DigestAnalyzerの詳細な呼び出しパターンは [digest-analyzer.md](../agents/digest-analyzer.md) を参照
422380
423381
3. **Edit tool**: ShadowGrandDigest.txt更新
424382
```python

EpisodicRAG/docs/dev/api/domain.md

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,14 @@ from domain import (
3333
3434
```python
3535
LEVEL_CONFIG: Dict[str, Dict[str, Any]] = {
36-
"weekly": {"prefix": "W", "digits": 4, "dir": "1_Weekly", "source": "loops", "next": "monthly"},
37-
"monthly": {"prefix": "M", "digits": 4, "dir": "2_Monthly", "source": "weekly", "next": "quarterly"},
38-
"quarterly": {"prefix": "Q", "digits": 3, "dir": "3_Quarterly", "source": "monthly", "next": "annual"},
39-
"annual": {"prefix": "A", "digits": 3, "dir": "4_Annual", "source": "quarterly", "next": "triennial"},
40-
"triennial": {"prefix": "T", "digits": 2, "dir": "5_Triennial", "source": "annual", "next": "decadal"},
41-
"decadal": {"prefix": "D", "digits": 2, "dir": "6_Decadal", "source": "triennial", "next": "multi_decadal"},
42-
"multi_decadal": {"prefix": "MD", "digits": 2, "dir": "7_Multi-decadal", "source": "decadal", "next": "centurial"},
43-
"centurial": {"prefix": "C", "digits": 2, "dir": "8_Centurial", "source": "multi_decadal", "next": None}
36+
"weekly": {"prefix": "W", "digits": 4, "dir": "1_Weekly", "source": "loops", "next": "monthly", "threshold": 5},
37+
"monthly": {"prefix": "M", "digits": 4, "dir": "2_Monthly", "source": "weekly", "next": "quarterly", "threshold": 5},
38+
"quarterly": {"prefix": "Q", "digits": 3, "dir": "3_Quarterly", "source": "monthly", "next": "annual", "threshold": 3},
39+
"annual": {"prefix": "A", "digits": 3, "dir": "4_Annual", "source": "quarterly", "next": "triennial", "threshold": 4},
40+
"triennial": {"prefix": "T", "digits": 2, "dir": "5_Triennial", "source": "annual", "next": "decadal", "threshold": 3},
41+
"decadal": {"prefix": "D", "digits": 2, "dir": "6_Decadal", "source": "triennial", "next": "multi_decadal", "threshold": 3},
42+
"multi_decadal": {"prefix": "MD", "digits": 2, "dir": "7_Multi-decadal", "source": "decadal", "next": "centurial", "threshold": 3},
43+
"centurial": {"prefix": "C", "digits": 2, "dir": "8_Centurial", "source": "multi_decadal", "next": None, "threshold": 4}
4444
}
4545
```
4646

@@ -51,6 +51,7 @@ LEVEL_CONFIG: Dict[str, Dict[str, Any]] = {
5151
| `dir` | digests_path以下のサブディレクトリ名 | `1_Weekly` |
5252
| `source` | この階層を生成する際の入力元 | `loops`, `weekly` |
5353
| `next` | 確定時にカスケードする上位階層 | `monthly`, `None` |
54+
| `threshold` | ダイジェスト生成に必要なソースファイル数 | `5`, `3`, `4` |
5455

5556
### LEVEL_NAMES
5657

EpisodicRAG/docs/dev/api/infrastructure.md

Lines changed: 138 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,20 @@
77
> 📖 用語・共通概念は [用語集](../../../README.md) を参照
88
99
```python
10-
from infrastructure import load_json, save_json, log_info, log_error
11-
from infrastructure.file_scanner import scan_files, get_max_numbered_file
10+
from infrastructure import (
11+
# JSON操作
12+
load_json, save_json, load_json_with_template, file_exists, ensure_directory,
13+
# ファイルスキャン
14+
scan_files, get_files_by_pattern, get_max_numbered_file, filter_files_after_number, count_files,
15+
# ロギング
16+
get_logger, setup_logging, log_info, log_warning, log_error, log_debug,
17+
# 構造化ロギング
18+
StructuredLogger, get_structured_logger,
19+
# エラーハンドリング
20+
safe_file_operation, safe_cleanup, with_error_context,
21+
# ユーザーインタラクション
22+
get_default_confirm_callback,
23+
)
1224
```
1325

1426
---
@@ -194,6 +206,7 @@ def setup_logging(level: Optional[int] = None) -> logging.Logger
194206
def log_info(message: str) -> None
195207
def log_warning(message: str) -> None
196208
def log_error(message: str, exit_code: Optional[int] = None) -> None
209+
def log_debug(message: str) -> None
197210
```
198211

199212
環境変数でログ設定をカスタマイズ可能:
@@ -202,6 +215,129 @@ def log_error(message: str, exit_code: Optional[int] = None) -> None
202215

203216
---
204217

218+
## 構造化ロギング(infrastructure/structured_logging.py)
219+
220+
LOG_PREFIX_* 定数を使用したボイラープレートを統合し、一貫したログ出力を提供。
221+
222+
### get_structured_logger()
223+
224+
```python
225+
def get_structured_logger(name: str) -> StructuredLogger
226+
```
227+
228+
構造化ロガーのインスタンスを取得。
229+
230+
```python
231+
logger = get_structured_logger(__name__)
232+
logger.state("cascade_update", level="weekly", count=5)
233+
# -> [DEBUG] [STATE] cascade_update: level=weekly count=5
234+
```
235+
236+
### StructuredLogger
237+
238+
```python
239+
class StructuredLogger:
240+
def info(message: str) -> None # 一般的な情報ログ
241+
def state(message: str, **context) -> None # 状態変化のログ [STATE]
242+
def file_op(message: str, **context) -> None # ファイル操作のログ [FILE]
243+
def validation(message: str, **context) -> None # 検証処理のログ [VALIDATE]
244+
def decision(message: str, **context) -> None # 判断分岐のログ [DECISION]
245+
```
246+
247+
**使用例**:
248+
249+
```python
250+
logger = get_structured_logger(__name__)
251+
252+
# 従来のコード
253+
log_debug(f"{LOG_PREFIX_STATE} cascade_update: level={level}, count={count}")
254+
255+
# 新しいコード
256+
logger.state("cascade_update", level=level, count=count)
257+
```
258+
259+
---
260+
261+
## エラーハンドリング(infrastructure/error_handling.py)
262+
263+
ファイル操作等のエラー処理を統一するユーティリティ関数。
264+
265+
### safe_file_operation()
266+
267+
```python
268+
def safe_file_operation(
269+
operation: Callable[[], T],
270+
context: str,
271+
on_error: Optional[Callable[[Exception], T]] = None,
272+
*,
273+
reraise: bool = False,
274+
) -> Optional[T]
275+
```
276+
277+
ファイル操作を安全に実行するラッパー。一般的なファイルI/Oエラーをキャッチし、一貫した方法で処理する。
278+
279+
```python
280+
# 基本的な使用(エラーを無視)
281+
safe_file_operation(lambda: file_path.unlink(), "delete file")
282+
283+
# フォールバック付き
284+
result = safe_file_operation(
285+
lambda: load_json(path),
286+
"load config",
287+
on_error=lambda e: {}
288+
)
289+
290+
# エラーを再送出
291+
safe_file_operation(
292+
lambda: save_json(path, data),
293+
"save config",
294+
reraise=True
295+
)
296+
```
297+
298+
### safe_cleanup()
299+
300+
```python
301+
def safe_cleanup(
302+
cleanup_func: Callable[[], None],
303+
context: str,
304+
*,
305+
log_on_error: bool = True,
306+
) -> bool
307+
```
308+
309+
クリーンアップ操作を安全に実行する。エラーが発生しても処理を継続し、オプションで警告をログ出力。
310+
311+
```python
312+
success = safe_cleanup(
313+
lambda: temp_file.unlink(),
314+
"remove temporary file"
315+
)
316+
if not success:
317+
print("Cleanup failed but continuing...")
318+
```
319+
320+
### with_error_context()
321+
322+
```python
323+
def with_error_context(
324+
operation: Callable[[], T],
325+
context: str,
326+
error_type: type = FileIOError,
327+
) -> T
328+
```
329+
330+
操作を実行し、エラー時にコンテキスト付きの例外を送出。
331+
332+
```python
333+
data = with_error_context(
334+
lambda: json.load(f),
335+
"parsing config.json"
336+
)
337+
```
338+
339+
---
340+
205341
## ユーザーインタラクション(infrastructure/user_interaction.py)
206342

207343
### get_default_confirm_callback()

EpisodicRAG/skills/digest-config/SKILL.md

Lines changed: 1 addition & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -444,70 +444,7 @@ Thresholds:
444444

445445
## 実装時の注意事項
446446

447-
> 📖 共通の実装ガイドラインは [_implementation-notes.md](../shared/_implementation-notes.md) を参照してください。
448-
449-
### 本スキル固有の注意点
450-
451-
## バリデーション
452-
453-
### パスのバリデーション
454-
455-
```python
456-
def validate_path(path_str, plugin_root, must_exist=False):
457-
"""パスのバリデーション"""
458-
path = Path(path_str)
459-
460-
# 相対パスの場合、プラグインルート基準で解決
461-
if not path.is_absolute():
462-
path = plugin_root / path_str
463-
464-
# 存在確認(オプション)
465-
if must_exist and not path.exists():
466-
raise FileNotFoundError(f"パスが見つかりません: {path}")
467-
468-
return path
469-
```
470-
471-
### Threshold のバリデーション
472-
473-
```python
474-
def validate_threshold(value):
475-
"""Thresholdのバリデーション"""
476-
try:
477-
int_value = int(value)
478-
if int_value < 1:
479-
raise ValueError("Thresholdは1以上である必要があります")
480-
return int_value
481-
except ValueError:
482-
raise ValueError("Thresholdは整数である必要があります")
483-
```
484-
485-
## エラーハンドリング
486-
487-
```python
488-
# 設定ファイルが存在しない
489-
if not config_file.exists():
490-
print("❌ 設定ファイルが見つかりません")
491-
print("@digest-setup を実行してください")
492-
sys.exit(1)
493-
494-
# JSON読み込みエラー
495-
try:
496-
with open(config_file, 'r', encoding='utf-8') as f:
497-
config_data = json.load(f)
498-
except json.JSONDecodeError:
499-
print("❌ 設定ファイルが破損しています")
500-
print("@digest-setup で再セットアップしてください")
501-
sys.exit(1)
502-
503-
# 設定ファイル書き込みエラー
504-
try:
505-
with open(config_file, 'w', encoding='utf-8') as f:
506-
json.dump(config_data, f, indent=2, ensure_ascii=False)
507-
except Exception as e:
508-
print(f"❌ 設定ファイルの保存に失敗しました: {e}")
509-
sys.exit(1)
510-
```
447+
> 📖 共通の実装ガイドライン(バリデーション、エラーハンドリング)は [_implementation-notes.md](../shared/_implementation-notes.md) を参照してください。
511448
512449
## スキルの自律判断
513450

0 commit comments

Comments
 (0)