@unlaxer/dge-toolkit 2.1.1 → 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/bin/dge-tool.js +97 -1
- package/package.json +1 -1
- package/skills/dge-session.md +56 -2
- package/version.txt +1 -1
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
package/skills/dge-session.md
CHANGED
|
@@ -133,8 +133,62 @@ flow YAML の post_actions の id に応じて分岐:
|
|
|
133
133
|
### Step 9B: 前回コンテキスト + プロジェクトナビゲーション
|
|
134
134
|
プロジェクトファイルがあれば TreeView 表示。なければ前回サマリー + 3 択。
|
|
135
135
|
|
|
136
|
-
### Step 9C: 素の LLM
|
|
137
|
-
|
|
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.
|
|
1
|
+
2.1.2
|