@unlaxer/dge-toolkit 2.1.0 → 2.1.2

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/INTERNALS.md CHANGED
@@ -4,35 +4,92 @@ DGE toolkit の内部構造。カスタマイズする際の参考に。
4
4
 
5
5
  ## フロー図
6
6
 
7
+ ### 全体フロー(flow 自動判定 → 分岐)
8
+
7
9
  ```mermaid
8
10
  flowchart TD
9
- Start([DGE して]) --> S1["[1/10] Kit 読み込み"]
10
- S1 --> S2["[2/10] テーマ確認"]
11
- S2 --> S3["[3/10] テンプレート選択"]
12
- S3 --> S35["[3.5/10] パターン選択"]
13
- S35 --> S4["[4/10] キャラ選択 "]
14
- S4 --> S5["[5/10] 会話劇生成"]
15
- S5 --> S6["[6/10] 抽出(flow.extract)"]
16
- S6 --> S7["[7/10] ファイル保存 + プロジェクト更新"]
17
- S7 --> S8["[8/10] サマリー + 選択肢 ⏸"]
18
-
19
- S8 -->|"1. DGE を回す"| S9B["[9B] 前回コンテキスト + TreeView"]
20
- S8 -->|"2. 自動反復"| S9A["[9A] 自動反復モード"]
21
- S8 -->|"3. 実装する"| S10["[10/10] Spec 化(flow.generate)"]
22
- S8 -->|"4. 後で"| End([終了])
23
-
24
- S9B -->|テーマ選択| S2
25
- S9A -->|未収束| S5
11
+ Start(["DGE して"]) --> S0{"Step 0: flow 判定"}
12
+
13
+ S0 -->|"DGE して / 壁打ち"| Quick[" quick"]
14
+ S0 -->|"詳しく / Spec / 設計レビュー"| Full["🔍 design-review"]
15
+ S0 -->|"ブレスト / アイデア"| Brain["💡 brainstorm"]
16
+
17
+ subgraph Quick Flow
18
+ Q1["Kit 読み込み + dge-tool 検出"] --> Q2["テーマ確認"]
19
+ Q2 --> Q4["キャラ表示(確認なし)"]
20
+ Q4 --> Q5["会話劇生成"]
21
+ Q5 --> Q7["保存(MUST)"]
22
+ Q7 --> Q8["Gap 一覧 + 選択肢(MUST)"]
23
+ end
24
+
25
+ subgraph Design Review Flow
26
+ D1["Kit 読み込み + dge-tool 検出"] --> D2["テーマ確認"]
27
+ D2 --> D3["テンプレート選択"]
28
+ D3 --> D35["パターン選択"]
29
+ D35 --> D4["キャラ確認 ⏸"]
30
+ D4 --> D5["会話劇生成"]
31
+ D5 --> D6["Gap 構造化"]
32
+ D6 --> D7["保存(MUST)"]
33
+ D7 --> D8["Gap 一覧 + 選択肢(MUST)"]
34
+ end
35
+
36
+ subgraph Brainstorm Flow
37
+ B1["Kit 読み込み + dge-tool 検出"] --> B2["テーマ確認"]
38
+ B2 --> B4["キャラ確認 ⏸"]
39
+ B4 --> B5["会話劇生成(Yes-and)"]
40
+ B5 --> B7["保存(MUST)"]
41
+ B7 --> B8["アイデア一覧 + 選択肢(MUST)"]
42
+ end
43
+
44
+ Quick --> Q1
45
+ Full --> D1
46
+ Brain --> B1
47
+ ```
48
+
49
+ ### 選択肢後の分岐
50
+
51
+ ```mermaid
52
+ flowchart TD
53
+ S8["サマリー + 選択肢 ⏸"] --> C1{"ユーザー選択"}
54
+
55
+ C1 -->|"1. DGE を回す"| S9B["前回コンテキスト\n+ TreeView"]
56
+ C1 -->|"2. 自動反復"| S9A["自動反復モード\n(最大 5 回)"]
57
+ C1 -->|"3. 実装する"| S10["累積 Spec 化"]
58
+ C1 -->|"4. 素の LLM マージ"| S9C["subagent\n素レビュー → マージ"]
59
+ C1 -->|"5. 後で"| End([終了])
60
+
61
+ S9B -->|テーマ選択| S2([Step 2 へ])
62
+ S9A -->|未収束| S5([Step 5 へ])
26
63
  S9A -->|収束| S10
64
+ S9C --> Merge["マージ結果表示 ⏸"]
65
+ Merge -->|実装する| S10
66
+ Merge -->|後で| End
27
67
 
28
68
  S10 --> Review{"Spec レビュー ⏸"}
29
- Review -->|"1. OK"| Impl([実装開始])
30
- Review -->|"2. 修正"| S10
31
- Review -->|"3. 後で"| End
69
+ Review -->|OK| Impl([実装開始])
70
+ Review -->|修正| S10
71
+ Review -->|後で| End
32
72
  ```
33
73
 
34
74
  ⏸ = ユーザーの応答を待つポイント
35
75
 
76
+ ## dge-tool モード
77
+
78
+ ```mermaid
79
+ flowchart LR
80
+ S1["Step 1:\ndge-tool version"] -->|成功| TM["🔧 Tool mode"]
81
+ S1 -->|失敗| SM["📝 Skill mode"]
82
+
83
+ TM --> S7T["Step 7: dge-tool save"]
84
+ TM --> S8T["Step 8: dge-tool prompt"]
85
+
86
+ SM --> S7S["Step 7: Write ツール"]
87
+ SM --> S8S["Step 8: 内蔵選択肢"]
88
+
89
+ S7T -->|失敗| S7S
90
+ S8T -->|失敗| S8S
91
+ ```
92
+
36
93
  ## データフロー図
37
94
 
38
95
  ```mermaid
@@ -44,33 +101,47 @@ flowchart LR
44
101
  P[patterns.md]
45
102
  F[flows/*.yaml]
46
103
  PJ[projects/*.md]
104
+ DT[dge-tool 検出]
47
105
  end
48
106
 
49
107
  subgraph Engine["DGE エンジン"]
50
- S5["Step 5: 会話劇生成"]
51
- S6["Step 6: 抽出\n(flow.extract.marker)"]
108
+ S0["Step 0: flow 判定"]
109
+ S5["Step 5: 会話劇生成\n(flow.extract.marker)"]
52
110
  S10["Step 10: Spec 生成\n(flow.generate.types)"]
111
+ S9C["Step 9C: subagent\n素 LLM マージ"]
53
112
  end
54
113
 
55
114
  subgraph Output["出力"]
56
115
  SE[sessions/*.md]
57
116
  SP[specs/*.md]
117
+ MR[sessions/*-merged.md]
58
118
  PR[projects/*.md 更新]
59
119
  end
60
120
 
61
- M & C & CC & P & F --> S5
121
+ M & C & CC & P --> S5
122
+ F --> S0
123
+ S0 --> S5
62
124
  PJ --> S5
63
- S5 --> S6
64
- S6 --> SE
65
- S6 --> S10
125
+ DT --> S5
126
+ S5 --> SE
127
+ S5 --> S10
128
+ S5 --> S9C
66
129
  S10 --> SP
67
- SE & SP --> PR
130
+ S9C --> MR
131
+ SE & SP & MR --> PR
68
132
  ```
69
133
 
70
134
  ## ステート図
71
135
 
72
136
  ```mermaid
73
137
  stateDiagram-v2
138
+ state "Flow ライフサイクル" as FL {
139
+ [*] --> quick: デフォルト
140
+ quick --> design_review: "詳しくやる"
141
+ quick --> brainstorm: "ブレストして"
142
+ design_review --> quick: "シンプルに戻す"
143
+ }
144
+
74
145
  state "プロジェクト" as Project {
75
146
  [*] --> not_started
76
147
  not_started --> explored: DGE session 実行
@@ -94,34 +165,50 @@ stateDiagram-v2
94
165
  }
95
166
  ```
96
167
 
168
+ ## 3 つの flow の比較
169
+
170
+ | | ⚡ quick | 🔍 design-review | 💡 brainstorm |
171
+ |---|---------|------------------|---------------|
172
+ | Steps | 5 | 10 | 6 |
173
+ | 共通 MUST | 3 | 3 | 3 |
174
+ | 固有 MUST | 0 | 4 | 1 |
175
+ | テンプレート | スキップ | 選択 | スキップ |
176
+ | パターン | 自動 | 選択 | 自動 |
177
+ | キャラ確認 | 表示のみ | 確認待ち | 確認待ち |
178
+ | 抽出 | Gap | Gap | アイデア |
179
+ | Spec 化 | なし | あり | なし |
180
+ | 話法 | 標準 | 標準 | Yes-and |
181
+
97
182
  ## Hook ポイント一覧
98
183
 
99
- Step でカスタマイズ可能なポイント。Level 1 YAML / ファイル追加で変更可能。Level 2 skill 編集(fork 推奨)。
100
-
101
- | Step | 名前 | Hook | Level |
102
- |------|------|------|-------|
103
- | 1 | Kit 読み込み | 読み込むファイル一覧 | 2 |
104
- | 2 | テーマ確認 | テーマの掘り下げロジック | 2 |
105
- | 3 | テンプレート選択 | テンプレートの追加 | 1(templates/ にファイル追加) |
106
- | 3.5 | パターン選択 | プリセットの追加・推奨マッピング | 1(patterns.md 編集) |
107
- | 4 | キャラ選択 | キャラの追加・推奨ロジック | 1(custom/characters/)/ 2(推奨ロジック) |
108
- | 5 | 会話劇生成 | ナレーション構造・Scene 構成 | 2 |
109
- | 6 | 抽出 | マーカー・フォーマット・カテゴリ | 1(flows/ YAML の extract) |
110
- | 7 | 保存 | 保存先・ファイル名規則 | 1(flows/ YAML output_dir)/ 2 |
111
- | 8 | 選択肢 | 選択肢の構成 | 1(flows/ YAML post_actions) |
112
- | 9A | 自動反復 | 収束判定・上限・ローテーション | 2 |
113
- | 9B | コンテキスト維持 | TreeView・テーマ選択 | 2 |
114
- | 10 | Spec 生成 | 成果物タイプ・テンプレート | 1(flows/ YAML generate) |
184
+ | Step | 名前 | Hook | Level | dge-tool |
185
+ |------|------|------|-------|----------|
186
+ | 0 | flow 判定 | trigger_keywords | 1(YAML) | — |
187
+ | 1 | Kit 読み込み | 読み込むファイル一覧 | 2 | version 検出 |
188
+ | 2 | テーマ確認 | 掘り下げロジック | 2 | — |
189
+ | 3 | テンプレート選択 | テンプレート追加 | 1(templates/) | — |
190
+ | 3.5 | パターン選択 | プリセット追加 | 1(patterns.md) | |
191
+ | 4 | キャラ選択 | キャラ追加・推奨 | 1(custom/)/ 2 | — |
192
+ | 5 | 会話劇生成 | ナレーション・Scene | 2 | — |
193
+ | 6 | 抽出 | マーカー・カテゴリ | 1(YAML extract) | |
194
+ | 7 | 保存 | 保存先・ファイル名 | 1(YAML output_dir) | **save** |
195
+ | 8 | 選択肢 | 選択肢構成 | 1(YAML post_actions) | **prompt** |
196
+ | 9A | 自動反復 | 収束判定・上限 | 2 | |
197
+ | 9B | コンテキスト | TreeView・テーマ | 2 | — |
198
+ | 9C | LLM マージ | subagent 実行 | 2 | — |
199
+ | 10 | Spec 生成 | 成果物タイプ | 1(YAML generate) | — |
115
200
 
116
201
  ## ファイルマップ
117
202
 
118
203
  | ファイル | 役割 | 誰が読む | 誰が書く |
119
204
  |---------|------|---------|---------|
120
- | method.md | メソッド本体 | Step 1 | 手動(toolkit 提供) |
121
- | characters/catalog.md | built-in キャラ | Step 1, 4 | 手動(toolkit 提供) |
122
- | custom/characters/*.md | カスタムキャラ | Step 1, 4 | dge-character-create skill |
123
- | patterns.md | 20 パターン + 5 プリセット | Step 1, 3.5 | 手動(toolkit 提供) |
124
- | flows/*.yaml | フロー定義 | Step 1, 6, 8, 10 | 手動 or フロー wizard(v2) |
205
+ | method.md | メソッド本体 | Step 1 | toolkit 提供 |
206
+ | characters/catalog.md | built-in 19 キャラ | Step 1, 4 | toolkit 提供 |
207
+ | custom/characters/*.md | カスタムキャラ | Step 1, 4 | dge-character-create |
208
+ | patterns.md | 20 パターン + 9 プリセット | Step 1, 3.5 | toolkit 提供 |
209
+ | dialogue-techniques.md | 8 会話技法 | Step 5 | toolkit 提供 |
210
+ | flows/*.yaml | フロー定義 | Step 0, 6, 7, 8, 10 | toolkit 提供 or ユーザー |
125
211
  | sessions/*.md | DGE session 出力 | Step 9B, 10 | Step 7(自動) |
126
212
  | specs/*.md | Spec ファイル | 実装時 | Step 10(自動) |
127
213
  | projects/*.md | プロジェクト管理 | Step 9B | Step 7(自動更新) |
214
+ | bin/dge-tool.js | MUST 強制 CLI | Step 1, 7, 8 | toolkit 提供 |
package/bin/dge-tool.js CHANGED
@@ -82,19 +82,112 @@ function cmdVersion() {
82
82
  console.log(`dge-tool v${VERSION}`);
83
83
  }
84
84
 
85
+ function cmdCompare() {
86
+ // Reads two JSON gap lists from stdin and generates comparison table
87
+ // Input format: { "dge": [...gaps], "plain": [...gaps] }
88
+ let input = '';
89
+ process.stdin.setEncoding('utf8');
90
+ process.stdin.on('data', chunk => { input += chunk; });
91
+ process.stdin.on('end', () => {
92
+ try {
93
+ const data = JSON.parse(input);
94
+ const dge = data.dge || [];
95
+ const plain = data.plain || [];
96
+
97
+ // Simple title-based dedup
98
+ const dgeSet = new Set(dge.map(g => g.gap.toLowerCase().trim()));
99
+ const plainSet = new Set(plain.map(g => g.gap.toLowerCase().trim()));
100
+
101
+ const both = [];
102
+ const dgeOnly = [];
103
+ const plainOnly = [];
104
+
105
+ for (const g of dge) {
106
+ const key = g.gap.toLowerCase().trim();
107
+ // Check if any plain gap is similar (substring match or word overlap)
108
+ let found = false;
109
+ for (const p of plain) {
110
+ const pKey = p.gap.toLowerCase().trim();
111
+ // Substring check (works for Japanese)
112
+ const isSubstring = key.includes(pKey) || pKey.includes(key);
113
+ // Word overlap for English
114
+ const gWords = new Set(key.split(/[\s/・、。]+/).filter(w => w.length > 1));
115
+ const pWords = new Set(pKey.split(/[\s/・、。]+/).filter(w => w.length > 1));
116
+ const overlap = [...gWords].filter(w => pWords.has(w)).length;
117
+ const similarity = overlap / Math.min(gWords.size, pWords.size);
118
+ if (isSubstring || similarity > 0.5) {
119
+ both.push({ ...g, source: '両方', plain_match: p.gap });
120
+ found = true;
121
+ plainSet.delete(pKey);
122
+ break;
123
+ }
124
+ }
125
+ if (!found) dgeOnly.push({ ...g, source: 'DGE のみ' });
126
+ }
127
+
128
+ for (const p of plain) {
129
+ const pKey = p.gap.toLowerCase().trim();
130
+ if (plainSet.has(pKey)) {
131
+ plainOnly.push({ ...p, source: '素のみ' });
132
+ }
133
+ }
134
+
135
+ // Stats
136
+ const dgeC = dge.filter(g => g.severity === 'Critical').length;
137
+ const dgeH = dge.filter(g => g.severity === 'High').length;
138
+ const plainC = plain.filter(g => g.severity === 'Critical').length;
139
+ const plainH = plain.filter(g => g.severity === 'High').length;
140
+
141
+ console.log('## マージ結果: DGE + 素の LLM(isolated)');
142
+ console.log('');
143
+ console.log('### 数値比較');
144
+ console.log('| 指標 | DGE | 素の LLM |');
145
+ console.log('|------|-----|---------|');
146
+ console.log(`| Gap 総数 | ${dge.length} | ${plain.length} |`);
147
+ console.log(`| Critical | ${dgeC} | ${plainC} |`);
148
+ console.log(`| High | ${dgeH} | ${plainH} |`);
149
+ console.log('');
150
+ console.log('### Gap 一覧(統合)');
151
+ console.log('| # | Gap | Source | Severity |');
152
+ console.log('|---|-----|--------|----------|');
153
+
154
+ let n = 1;
155
+ for (const g of both) {
156
+ console.log(`| ${n++} | ${g.gap} | 両方 | ${g.severity} |`);
157
+ }
158
+ for (const g of dgeOnly) {
159
+ console.log(`| ${n++} | ${g.gap} | DGE のみ | ${g.severity} |`);
160
+ }
161
+ for (const g of plainOnly) {
162
+ console.log(`| ${n++} | ${g.gap} | 素のみ | ${g.severity} |`);
163
+ }
164
+
165
+ console.log('');
166
+ console.log(`DGE のみ: ${dgeOnly.length} 件(深い洞察)`);
167
+ console.log(`素のみ: ${plainOnly.length} 件(網羅的チェック)`);
168
+ console.log(`両方: ${both.length} 件(確実に重要)`);
169
+ } catch (e) {
170
+ console.error('ERROR: invalid JSON input. Expected: { "dge": [...], "plain": [...] }');
171
+ process.exit(1);
172
+ }
173
+ });
174
+ }
175
+
85
176
  function cmdHelp() {
86
177
  console.log(`dge-tool v${VERSION} — DGE MUST enforcement CLI
87
178
 
88
179
  Commands:
89
180
  save <file> Save stdin to file (ensures MUST: always save)
90
181
  prompt [flow] Show numbered choices from flow YAML (ensures MUST: show choices)
182
+ compare Merge DGE + plain gaps from stdin JSON (isolated comparison)
91
183
  version Show version
92
184
  help Show this help
93
185
 
94
186
  Examples:
95
187
  echo "session content" | dge-tool save dge/sessions/auth-api.md
96
188
  dge-tool prompt quick
97
- dge-tool prompt design-review`);
189
+ dge-tool prompt design-review
190
+ echo '{"dge":[...],"plain":[...]}' | dge-tool compare`);
98
191
  }
99
192
 
100
193
  // Dispatch
@@ -105,6 +198,9 @@ switch (command) {
105
198
  case 'prompt':
106
199
  cmdPrompt();
107
200
  break;
201
+ case 'compare':
202
+ cmdCompare();
203
+ break;
108
204
  case 'version':
109
205
  case '-v':
110
206
  case '--version':
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unlaxer/dge-toolkit",
3
- "version": "2.1.0",
3
+ "version": "2.1.2",
4
4
  "description": "DGE (Dialogue-driven Gap Extraction) — 会話劇で設計の穴を発見するメソッドkit",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -133,8 +133,62 @@ flow YAML の post_actions の id に応じて分岐:
133
133
  ### Step 9B: 前回コンテキスト + プロジェクトナビゲーション
134
134
  プロジェクトファイルがあれば TreeView 表示。なければ前回サマリー + 3 択。
135
135
 
136
- ### Step 9C: 素の LLM マージ
137
- subagent で同じテーマを素でレビュー → DGE Gap とマージ → DGE のみ / 素のみ / 両方 をラベル付け。
136
+ ### Step 9C: 素の LLM マージ(isolated subagent)
137
+
138
+ **重要: DGE の結果を知らない独立した agent で素のレビューを行う。** これにより DGE の Gap を「補完する」バイアスを排除する。
139
+
140
+ 1. **isolated subagent を起動**: Agent ツールで `isolation: "worktree"` を指定。
141
+ DGE session の context を一切持たない別プロセスが実行する。
142
+
143
+ subagent へのプロンプト:
144
+ ```
145
+ 以下の設計ドキュメントをレビューしてください。
146
+ 問題点、考慮漏れ、矛盾を全て挙げてください。
147
+ 各問題に Category と Severity (Critical / High / Medium / Low) をつけてください。
148
+ テーブル形式で出力: | # | Gap | Category | Severity |
149
+
150
+ [テーマの設計ドキュメント / コンテキスト]
151
+ ```
152
+
153
+ **subagent には DGE の Gap 一覧や会話劇を渡さない。** 完全に独立したレビュー。
154
+
155
+ 2. **素の Gap 一覧を受け取る**
156
+
157
+ 3. **DGE の Gap と素の Gap をマージ**:
158
+ - Gap タイトルの意味的類似度で重複を判定
159
+ - 同じ問題 → 「両方」ラベル(信頼度が高い)
160
+ - DGE のみ → 「DGE のみ」ラベル(深い洞察の可能性)
161
+ - 素のみ → 「素のみ」ラベル(網羅的チェック)
162
+
163
+ 4. **比較表を表示**:
164
+ ```
165
+ ## マージ結果: DGE + 素の LLM(isolated)
166
+
167
+ ### 数値比較
168
+ | 指標 | DGE | 素の LLM |
169
+ |------|-----|---------|
170
+ | Gap 総数 | N | N |
171
+ | Critical | N | N |
172
+ | High | N | N |
173
+ | カテゴリ数 | N/11 | N/11 |
174
+
175
+ ### Gap 一覧(統合)
176
+ | # | Gap | Source | Severity |
177
+ |---|-----|--------|----------|
178
+ | 1 | [gap] | DGE のみ | High |
179
+ | 2 | [gap] | 両方 | Critical |
180
+ | 3 | [gap] | 素のみ | Medium |
181
+
182
+ DGE のみ: N 件(深い洞察)
183
+ 素のみ: N 件(網羅的チェック)
184
+ 両方: N 件(確実に重要)
185
+
186
+ どうしますか?
187
+ 1. 実装する → マージ済み Gap から Spec 化
188
+ 2. 後で
189
+ ```
190
+
191
+ 5. **マージ結果をファイルに保存**: `dge/sessions/{theme}-merged.md`
138
192
 
139
193
  ### Step 10: 累積 Spec 化(design-review のみ)
140
194
  同テーマの全 session Gap を統合 → Critical/High を Spec 化 → `dge/specs/` に保存。
package/version.txt CHANGED
@@ -1 +1 @@
1
- 2.1.0
1
+ 2.1.2